Commit 6b486258 authored by Rafael Kitover's avatar Rafael Kitover
Browse files

fix some ELF parsing vulnerabilities #255

Implement the recommendations described in issue #255 by @zzazzdzz:

- Check bounds when reading ELF program header sections.

- Skip reading ELF section headers if the string table pointer is NULL.

- Increase the buffer size for dissassembled instructions in the
  dissassembly view and pass the buffer size to the disArm() and
  disThumb() functions so that rudimentary bounds checking can be done.

Also add the constants WORK_RAM_SIZE and ROM_SIZE to reduce incidence of
magic numbers and make the code a bit cleaner.
parent c63d3640
...@@ -76,7 +76,7 @@ static profile_segment* profilSegment = NULL; ...@@ -76,7 +76,7 @@ static profile_segment* profilSegment = NULL;
#endif #endif
#ifdef BKPT_SUPPORT #ifdef BKPT_SUPPORT
uint8_t freezeWorkRAM[0x40000]; uint8_t freezeWorkRAM[WORK_RAM_SIZE];
uint8_t freezeInternalRAM[0x8000]; uint8_t freezeInternalRAM[0x8000];
uint8_t freezeVRAM[0x18000]; uint8_t freezeVRAM[0x18000];
uint8_t freezePRAM[0x400]; uint8_t freezePRAM[0x400];
...@@ -459,7 +459,7 @@ variable_desc saveGameStruct[] = { ...@@ -459,7 +459,7 @@ variable_desc saveGameStruct[] = {
{ NULL, 0 } { NULL, 0 }
}; };
static int romSize = 0x2000000; static int romSize = ROM_SIZE;
#ifdef PROFILING #ifdef PROFILING
void cpuProfil(profile_segment* seg) void cpuProfil(profile_segment* seg)
...@@ -596,7 +596,7 @@ unsigned int CPUWriteState(uint8_t* data, unsigned size) ...@@ -596,7 +596,7 @@ unsigned int CPUWriteState(uint8_t* data, unsigned size)
utilWriteMem(data, internalRAM, 0x8000); utilWriteMem(data, internalRAM, 0x8000);
utilWriteMem(data, paletteRAM, 0x400); utilWriteMem(data, paletteRAM, 0x400);
utilWriteMem(data, workRAM, 0x40000); utilWriteMem(data, workRAM, WORK_RAM_SIZE);
utilWriteMem(data, vram, 0x20000); utilWriteMem(data, vram, 0x20000);
utilWriteMem(data, oam, 0x400); utilWriteMem(data, oam, 0x400);
utilWriteMem(data, pix, 4 * 240 * 160); utilWriteMem(data, pix, 4 * 240 * 160);
...@@ -646,7 +646,7 @@ bool CPUReadState(const uint8_t* data, unsigned size) ...@@ -646,7 +646,7 @@ bool CPUReadState(const uint8_t* data, unsigned size)
utilReadMem(internalRAM, data, 0x8000); utilReadMem(internalRAM, data, 0x8000);
utilReadMem(paletteRAM, data, 0x400); utilReadMem(paletteRAM, data, 0x400);
utilReadMem(workRAM, data, 0x40000); utilReadMem(workRAM, data, WORK_RAM_SIZE);
utilReadMem(vram, data, 0x20000); utilReadMem(vram, data, 0x20000);
utilReadMem(oam, data, 0x400); utilReadMem(oam, data, 0x400);
utilReadMem(pix, data, 4 * 240 * 160); utilReadMem(pix, data, 4 * 240 * 160);
...@@ -710,7 +710,7 @@ static bool CPUWriteState(gzFile gzFile) ...@@ -710,7 +710,7 @@ static bool CPUWriteState(gzFile gzFile)
utilGzWrite(gzFile, internalRAM, 0x8000); utilGzWrite(gzFile, internalRAM, 0x8000);
utilGzWrite(gzFile, paletteRAM, 0x400); utilGzWrite(gzFile, paletteRAM, 0x400);
utilGzWrite(gzFile, workRAM, 0x40000); utilGzWrite(gzFile, workRAM, WORK_RAM_SIZE);
utilGzWrite(gzFile, vram, 0x20000); utilGzWrite(gzFile, vram, 0x20000);
utilGzWrite(gzFile, oam, 0x400); utilGzWrite(gzFile, oam, 0x400);
utilGzWrite(gzFile, pix, 4 * 241 * 162); utilGzWrite(gzFile, pix, 4 * 241 * 162);
...@@ -824,7 +824,7 @@ static bool CPUReadState(gzFile gzFile) ...@@ -824,7 +824,7 @@ static bool CPUReadState(gzFile gzFile)
utilGzRead(gzFile, internalRAM, 0x8000); utilGzRead(gzFile, internalRAM, 0x8000);
utilGzRead(gzFile, paletteRAM, 0x400); utilGzRead(gzFile, paletteRAM, 0x400);
utilGzRead(gzFile, workRAM, 0x40000); utilGzRead(gzFile, workRAM, WORK_RAM_SIZE);
utilGzRead(gzFile, vram, 0x20000); utilGzRead(gzFile, vram, 0x20000);
utilGzRead(gzFile, oam, 0x400); utilGzRead(gzFile, oam, 0x400);
if (version < SAVE_GAME_VERSION_6) if (version < SAVE_GAME_VERSION_6)
...@@ -1467,20 +1467,20 @@ void SetMapMasks() ...@@ -1467,20 +1467,20 @@ void SetMapMasks()
int CPULoadRom(const char* szFile) int CPULoadRom(const char* szFile)
{ {
romSize = 0x2000000; romSize = ROM_SIZE;
if (rom != NULL) { if (rom != NULL) {
CPUCleanUp(); CPUCleanUp();
} }
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
rom = (uint8_t*)malloc(0x2000000); rom = (uint8_t*)malloc(romSize);
if (rom == NULL) { if (rom == NULL) {
systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
"ROM"); "ROM");
return 0; return 0;
} }
workRAM = (uint8_t*)calloc(1, 0x40000); workRAM = (uint8_t*)calloc(1, WORK_RAM_SIZE);
if (workRAM == NULL) { if (workRAM == NULL) {
systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
"WRAM"); "WRAM");
...@@ -1527,7 +1527,7 @@ int CPULoadRom(const char* szFile) ...@@ -1527,7 +1527,7 @@ int CPULoadRom(const char* szFile)
uint16_t* temp = (uint16_t*)(rom + ((romSize + 1) & ~1)); uint16_t* temp = (uint16_t*)(rom + ((romSize + 1) & ~1));
int i; int i;
for (i = (romSize + 1) & ~1; i < 0x2000000; i += 2) { for (i = (romSize + 1) & ~1; i < romSize; i += 2) {
WRITE16LE(temp, (i >> 1) & 0xFFFF); WRITE16LE(temp, (i >> 1) & 0xFFFF);
temp++; temp++;
} }
...@@ -1593,20 +1593,20 @@ int CPULoadRom(const char* szFile) ...@@ -1593,20 +1593,20 @@ int CPULoadRom(const char* szFile)
int CPULoadRomData(const char* data, int size) int CPULoadRomData(const char* data, int size)
{ {
romSize = 0x2000000; romSize = ROM_SIZE;
if (rom != NULL) { if (rom != NULL) {
CPUCleanUp(); CPUCleanUp();
} }
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
rom = (uint8_t*)malloc(0x2000000); rom = (uint8_t*)malloc(romSize);
if (rom == NULL) { if (rom == NULL) {
systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
"ROM"); "ROM");
return 0; return 0;
} }
workRAM = (uint8_t*)calloc(1, 0x40000); workRAM = (uint8_t*)calloc(1, WORK_RAM_SIZE);
if (workRAM == NULL) { if (workRAM == NULL) {
systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
"WRAM"); "WRAM");
...@@ -1620,7 +1620,7 @@ int CPULoadRomData(const char* data, int size) ...@@ -1620,7 +1620,7 @@ int CPULoadRomData(const char* data, int size)
uint16_t* temp = (uint16_t*)(rom + ((romSize + 1) & ~1)); uint16_t* temp = (uint16_t*)(rom + ((romSize + 1) & ~1));
int i; int i;
for (i = (romSize + 1) & ~1; i < 0x2000000; i += 2) { for (i = (romSize + 1) & ~1; i < romSize; i += 2) {
WRITE16LE(temp, (i >> 1) & 0xFFFF); WRITE16LE(temp, (i >> 1) & 0xFFFF);
temp++; temp++;
} }
......
...@@ -153,6 +153,9 @@ extern struct EmulatedSystem GBASystem; ...@@ -153,6 +153,9 @@ extern struct EmulatedSystem GBASystem;
#define R14_FIQ 43 #define R14_FIQ 43
#define SPSR_FIQ 44 #define SPSR_FIQ 44
#define WORK_RAM_SIZE 0x40000
#define ROM_SIZE 0x2000000
#include "Cheats.h" #include "Cheats.h"
#include "EEprom.h" #include "EEprom.h"
#include "Flash.h" #include "Flash.h"
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
/* Arm/Thumb command set disassembler */ /* Arm/Thumb command set disassembler */
/************************************************************************/ /************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <cstring>
#include "../System.h" #include "../System.h"
#include "../common/Port.h" #include "../common/Port.h"
...@@ -214,8 +215,13 @@ char* addHex(char* dest, int siz, uint32_t val) ...@@ -214,8 +215,13 @@ char* addHex(char* dest, int siz, uint32_t val)
return dest; return dest;
} }
int disArm(uint32_t offset, char* dest, int flags) int disArm(uint32_t offset, char* dest, unsigned dest_sz, int flags)
{ {
if (dest_sz < 80) {
*dest = '\0';
return 4;
}
uint32_t opcode = debuggerReadMemory(offset); uint32_t opcode = debuggerReadMemory(offset);
const Opcodes* sp = armOpcodes; const Opcodes* sp = armOpcodes;
...@@ -523,8 +529,15 @@ int disArm(uint32_t offset, char* dest, int flags) ...@@ -523,8 +529,15 @@ int disArm(uint32_t offset, char* dest, int flags)
return 4; return 4;
} }
int disThumb(uint32_t offset, char* dest, int flags) int disThumb(uint32_t offset, char* dest, unsigned dest_sz, int flags)
{ {
if (dest_sz < 80) {
*dest = '\0';
return 2;
}
char* end = dest + dest_sz;
uint32_t opcode = debuggerReadHalfWord(offset); uint32_t opcode = debuggerReadHalfWord(offset);
const Opcodes* sp = thumbOpcodes; const Opcodes* sp = thumbOpcodes;
...@@ -597,7 +610,7 @@ int disThumb(uint32_t offset, char* dest, int flags) ...@@ -597,7 +610,7 @@ int disThumb(uint32_t offset, char* dest, int flags)
*dest++ = '$'; *dest++ = '$';
dest = addHex(dest, 32, value); dest = addHex(dest, 32, value);
const char* s = elfGetAddressSymbol(value); const char* s = elfGetAddressSymbol(value);
if (*s) { if (*s && (dest + strlen(s) + 1) < end) {
*dest++ = ' '; *dest++ = ' ';
dest = addStr(dest, s); dest = addStr(dest, s);
} }
...@@ -607,7 +620,7 @@ int disThumb(uint32_t offset, char* dest, int flags) ...@@ -607,7 +620,7 @@ int disThumb(uint32_t offset, char* dest, int flags)
*dest++ = '$'; *dest++ = '$';
dest = addHex(dest, 32, value); dest = addHex(dest, 32, value);
const char* s = elfGetAddressSymbol(value); const char* s = elfGetAddressSymbol(value);
if (*s) { if (*s && (dest + strlen(s) + 1) < end) {
*dest++ = ' '; *dest++ = ' ';
dest = addStr(dest, s); dest = addStr(dest, s);
} }
...@@ -694,7 +707,7 @@ int disThumb(uint32_t offset, char* dest, int flags) ...@@ -694,7 +707,7 @@ int disThumb(uint32_t offset, char* dest, int flags)
*dest++ = '$'; *dest++ = '$';
dest = addHex(dest, 32, offset + 4 + add); dest = addHex(dest, 32, offset + 4 + add);
const char* s = elfGetAddressSymbol(offset + 4 + add); const char* s = elfGetAddressSymbol(offset + 4 + add);
if (*s) { if (*s && (dest + strlen(s) + 3) < end) {
*dest++ = ' '; *dest++ = ' ';
*dest++ = '('; *dest++ = '(';
dest = addStr(dest, s); dest = addStr(dest, s);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define DIS_VIEW_ADDRESS 1 #define DIS_VIEW_ADDRESS 1
#define DIS_VIEW_CODE 2 #define DIS_VIEW_CODE 2
int disThumb(uint32_t offset, char* dest, int flags); int disThumb(uint32_t offset, char* dest, unsigned dest_sz, int flags);
int disArm(uint32_t offset, char* dest, int flags); int disArm(uint32_t offset, char* dest, unsigned dest_sz, int flags);
#endif // __ARMDIS_H__ #endif // __ARMDIS_H__
...@@ -852,7 +852,7 @@ void BIOS_RegisterRamReset(uint32_t flags) ...@@ -852,7 +852,7 @@ void BIOS_RegisterRamReset(uint32_t flags)
if (flags) { if (flags) {
if (flags & 0x01) { if (flags & 0x01) {
// clear work RAM // clear work RAM
memset(workRAM, 0, 0x40000); memset(workRAM, 0, WORK_RAM_SIZE);
} }
if (flags & 0x02) { if (flags & 0x02) {
// clear internal RAM // clear internal RAM
......
...@@ -843,6 +843,9 @@ uint8_t* elfReadSection(uint8_t* data, ELFSectionHeader* sh) ...@@ -843,6 +843,9 @@ uint8_t* elfReadSection(uint8_t* data, ELFSectionHeader* sh)
ELFSectionHeader* elfGetSectionByName(const char* name) ELFSectionHeader* elfGetSectionByName(const char* name)
{ {
if (elfSectionHeadersStringTable == NULL)
return NULL;
for (int i = 0; i < elfSectionHeadersCount; i++) { for (int i = 0; i < elfSectionHeadersCount; i++) {
if (strcmp(name, if (strcmp(name,
&elfSectionHeadersStringTable[READ32LE(&elfSectionHeaders[i]->name)]) &elfSectionHeadersStringTable[READ32LE(&elfSectionHeaders[i]->name)])
...@@ -2538,7 +2541,7 @@ void elfReadSymtab(uint8_t* data) ...@@ -2538,7 +2541,7 @@ void elfReadSymtab(uint8_t* data)
// free(symtab); // free(symtab);
} }
bool elfReadProgram(ELFHeader* eh, uint8_t* data, int& size, bool parseDebug) bool elfReadProgram(ELFHeader* eh, uint8_t* data, unsigned long data_size, int& size, bool parseDebug)
{ {
int count = READ16LE(&eh->e_phnum); int count = READ16LE(&eh->e_phnum);
int i; int i;
...@@ -2559,32 +2562,54 @@ bool elfReadProgram(ELFHeader* eh, uint8_t* data, int& size, bool parseDebug) ...@@ -2559,32 +2562,54 @@ bool elfReadProgram(ELFHeader* eh, uint8_t* data, int& size, bool parseDebug)
// printf("PH %d %08x %08x %08x %08x %08x %08x %08x %08x\n", // printf("PH %d %08x %08x %08x %08x %08x %08x %08x %08x\n",
// i, ph->type, ph->offset, ph->vaddr, ph->paddr, // i, ph->type, ph->offset, ph->vaddr, ph->paddr,
// ph->filesz, ph->memsz, ph->flags, ph->align); // ph->filesz, ph->memsz, ph->flags, ph->align);
unsigned address = READ32LE(&ph->paddr);
unsigned offset = READ32LE(&ph->offset);
unsigned section_size = READ32LE(&ph->filesz);
if (offset > data_size || section_size > data_size || offset + section_size > data_size)
continue;
uint8_t* source = data + offset;
if (cpuIsMultiBoot) { if (cpuIsMultiBoot) {
if (READ32LE(&ph->paddr) >= 0x2000000 && READ32LE(&ph->paddr) <= 0x203ffff) { unsigned effective_address = address - 0x2000000;
memcpy(&workRAM[READ32LE(&ph->paddr) & 0x3ffff],
data + READ32LE(&ph->offset), if (effective_address + section_size < WORK_RAM_SIZE) {
READ32LE(&ph->filesz)); memcpy(&workRAM[effective_address], source, section_size);
size += READ32LE(&ph->filesz); size += section_size;
} }
} else { } else {
if (READ32LE(&ph->paddr) >= 0x8000000 && READ32LE(&ph->paddr) <= 0x9ffffff) { unsigned effective_address = address - 0x8000000;
memcpy(&rom[READ32LE(&ph->paddr) & 0x1ffffff],
data + READ32LE(&ph->offset), if (effective_address + section_size < ROM_SIZE) {
READ32LE(&ph->filesz)); memcpy(&rom[effective_address], source, section_size);
size += READ32LE(&ph->filesz); size += section_size;
} }
} }
} }
char* stringTable = NULL; // these must be pre-declared or clang barfs on the goto statement
ELFSectionHeader** sh = NULL;
char* stringTable = NULL;
// read section headers (if string table is good)
if (READ16LE(&eh->e_shstrndx) == 0)
goto end;
// read section headers
p = data + READ32LE(&eh->e_shoff); p = data + READ32LE(&eh->e_shoff);
count = READ16LE(&eh->e_shnum); count = READ16LE(&eh->e_shnum);
ELFSectionHeader** sh = (ELFSectionHeader**) sh = (ELFSectionHeader**)
malloc(sizeof(ELFSectionHeader*) * count); malloc(sizeof(ELFSectionHeader*) * count);
stringTable = (char*)elfReadSection(data, sh[READ16LE(&eh->e_shstrndx)]);
elfSectionHeaders = sh;
elfSectionHeadersStringTable = stringTable;
elfSectionHeadersCount = count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
sh[i] = (ELFSectionHeader*)p; sh[i] = (ELFSectionHeader*)p;
p += sizeof(ELFSectionHeader); p += sizeof(ELFSectionHeader);
...@@ -2592,15 +2617,6 @@ bool elfReadProgram(ELFHeader* eh, uint8_t* data, int& size, bool parseDebug) ...@@ -2592,15 +2617,6 @@ bool elfReadProgram(ELFHeader* eh, uint8_t* data, int& size, bool parseDebug)
p += READ16LE(&eh->e_shentsize) - sizeof(ELFSectionHeader); p += READ16LE(&eh->e_shentsize) - sizeof(ELFSectionHeader);
} }
if (READ16LE(&eh->e_shstrndx) != 0) {
stringTable = (char*)elfReadSection(data,
sh[READ16LE(&eh->e_shstrndx)]);
}
elfSectionHeaders = sh;
elfSectionHeadersStringTable = stringTable;
elfSectionHeadersCount = count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
// printf("SH %d %-20s %08x %08x %08x %08x %08x %08x %08x %08x\n", // printf("SH %d %-20s %08x %08x %08x %08x %08x %08x %08x %08x\n",
// i, &stringTable[sh[i]->name], sh[i]->name, sh[i]->type, // i, &stringTable[sh[i]->name], sh[i]->name, sh[i]->type,
...@@ -2703,7 +2719,7 @@ extern bool parseDebug; ...@@ -2703,7 +2719,7 @@ extern bool parseDebug;
bool elfRead(const char* name, int& siz, FILE* f) bool elfRead(const char* name, int& siz, FILE* f)
{ {
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
long size = ftell(f); unsigned long size = ftell(f);
elfFileData = (uint8_t*)malloc(size); elfFileData = (uint8_t*)malloc(size);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
int res = fread(elfFileData, 1, size, f); int res = fread(elfFileData, 1, size, f);
...@@ -2724,7 +2740,7 @@ bool elfRead(const char* name, int& siz, FILE* f) ...@@ -2724,7 +2740,7 @@ bool elfRead(const char* name, int& siz, FILE* f)
return false; return false;
} }
if (!elfReadProgram(header, elfFileData, siz, parseDebug)) { if (!elfReadProgram(header, elfFileData, size, siz, parseDebug)) {
free(elfFileData); free(elfFileData);
elfFileData = NULL; elfFileData = NULL;
return false; return false;
......
...@@ -1355,7 +1355,7 @@ static void debuggerBreakChange(int n, char** args) ...@@ -1355,7 +1355,7 @@ static void debuggerBreakChange(int n, char** args)
static void debuggerDisassembleArm(FILE* f, uint32_t pc, int count) static void debuggerDisassembleArm(FILE* f, uint32_t pc, int count)
{ {
char buffer[80]; char buffer[4096];
int i = 0; int i = 0;
uint32_t len = 0; uint32_t len = 0;
char format[30]; char format[30];
...@@ -1367,14 +1367,14 @@ static void debuggerDisassembleArm(FILE* f, uint32_t pc, int count) ...@@ -1367,14 +1367,14 @@ static void debuggerDisassembleArm(FILE* f, uint32_t pc, int count)
sprintf(format, "%%08x %%-%ds %%s\n", len); sprintf(format, "%%08x %%-%ds %%s\n", len);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
uint32_t addr = pc; uint32_t addr = pc;
pc += disArm(pc, buffer, 2); pc += disArm(pc, buffer, 4096, 2);
fprintf(f, format, addr, elfGetAddressSymbol(addr), buffer); fprintf(f, format, addr, elfGetAddressSymbol(addr), buffer);
} }
} }
static void debuggerDisassembleThumb(FILE* f, uint32_t pc, int count) static void debuggerDisassembleThumb(FILE* f, uint32_t pc, int count)
{ {
char buffer[80]; char buffer[4096];
int i = 0; int i = 0;
uint32_t len = 0; uint32_t len = 0;
char format[30]; char format[30];
...@@ -1387,7 +1387,7 @@ static void debuggerDisassembleThumb(FILE* f, uint32_t pc, int count) ...@@ -1387,7 +1387,7 @@ static void debuggerDisassembleThumb(FILE* f, uint32_t pc, int count)
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
uint32_t addr = pc; uint32_t addr = pc;
pc += disThumb(pc, buffer, 2); pc += disThumb(pc, buffer, 4096, 2);
fprintf(f, format, addr, elfGetAddressSymbol(addr), buffer); fprintf(f, format, addr, elfGetAddressSymbol(addr), buffer);
} }
} }
......
...@@ -146,7 +146,7 @@ public: ...@@ -146,7 +146,7 @@ public:
// what an unsafe calling convention // what an unsafe calling convention
// examination of disArm shows that max len is 69 chars // examination of disArm shows that max len is 69 chars
// (e.g. 0x081cb6db), and I assume disThumb is shorter // (e.g. 0x081cb6db), and I assume disThumb is shorter
char buf[80]; char buf[4096];
dis->strings.clear(); dis->strings.clear();
dis->addrs.clear(); dis->addrs.clear();
uint32_t addr = dis->topaddr; uint32_t addr = dis->topaddr;
...@@ -157,9 +157,9 @@ public: ...@@ -157,9 +157,9 @@ public:
dis->addrs.push_back(addr); dis->addrs.push_back(addr);
if (arm) if (arm)
addr += disArm(addr, buf, DIS_VIEW_CODE | DIS_VIEW_ADDRESS); addr += disArm(addr, buf, 4096, DIS_VIEW_CODE | DIS_VIEW_ADDRESS);
else else
addr += disThumb(addr, buf, DIS_VIEW_CODE | DIS_VIEW_ADDRESS); addr += disThumb(addr, buf, 4096, DIS_VIEW_CODE | DIS_VIEW_ADDRESS);
dis->strings.push_back(wxString(buf, wxConvLibc)); dis->strings.push_back(wxString(buf, wxConvLibc));
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment