Skip to content

Commit

Permalink
DBG: resolved issue #1383 (still print autocomments for constant valu…
Browse files Browse the repository at this point in the history
…es with 'Autocomment on CIP' enabled)
  • Loading branch information
mrexodia committed Dec 17, 2016
1 parent 177ad66 commit 1ebcb07
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 103 deletions.
153 changes: 80 additions & 73 deletions src/dbg/_exports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,96 +263,103 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
comment = StringUtils::sprintf("%s:%u", StringUtils::Utf16ToUtf8(filename + len).c_str(), line.LineNumber);
retval = true;
}
if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //no line number
{
DISASM_INSTR instr;
String temp_string;
ADDRINFO newinfo;
char string_text[MAX_STRING_SIZE] = "";

Capstone cp;
disasmget(cp, addr, &instr);
DISASM_INSTR instr;
String temp_string;
ADDRINFO newinfo;
char string_text[MAX_STRING_SIZE] = "";

Capstone cp;
auto getregs = !bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP);
disasmget(cp, addr, &instr, getregs);

//Ignore register values when not on CIP and OnlyCipAutoComments is enabled: https://github.com/x64dbg/x64dbg/issues/1383
if(!getregs)
{
for(int i = 0; i < instr.argcount; i++)
{
memset(&newinfo, 0, sizeof(ADDRINFO));
newinfo.flags = flaglabel;
instr.arg[i].value = instr.arg[i].constant;
}

STRING_TYPE strtype = str_none;
for(int i = 0; i < instr.argcount; i++)
{
memset(&newinfo, 0, sizeof(ADDRINFO));
newinfo.flags = flaglabel;

STRING_TYPE strtype = str_none;

if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label
if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label
{
auto constant = instr.arg[i].constant;
if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.InGroup(CS_GRP_CALL))
temp_string.assign("call $0");
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.InGroup(CS_GRP_JUMP))
temp_string.assign("jmp $0");
else if(instr.type == instr_branch)
continue;
else if(instr.arg[i].type == arg_normal && constant < 256 && (isprint(int(constant)) || isspace(int(constant))) && (strstr(instr.instruction, "cmp") || strstr(instr.instruction, "mov")))
{
auto constant = instr.arg[i].constant;
if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.InGroup(CS_GRP_CALL))
temp_string.assign("call $0");
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.InGroup(CS_GRP_JUMP))
temp_string.assign("jmp $0");
else if(instr.type == instr_branch)
continue;
else if(instr.arg[i].type == arg_normal && constant < 256 && (isprint(int(constant)) || isspace(int(constant))) && (strstr(instr.instruction, "cmp") || strstr(instr.instruction, "mov")))
{
temp_string.assign(instr.arg[i].mnemonic);
temp_string.push_back(':');
temp_string.push_back('\'');
temp_string.append(StringUtils::Escape((unsigned char)constant));
temp_string.push_back('\'');
}
else if(DbgGetStringAt(instr.arg[i].constant, string_text))
{
temp_string.assign(instr.arg[i].mnemonic);
temp_string.push_back(':');
temp_string.append(string_text);
}
temp_string.assign(instr.arg[i].mnemonic);
temp_string.push_back(':');
temp_string.push_back('\'');
temp_string.append(StringUtils::Escape((unsigned char)constant));
temp_string.push_back('\'');
}
else if(instr.arg[i].memvalue && (DbgGetStringAt(instr.arg[i].memvalue, string_text) || _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo)))
else if(DbgGetStringAt(instr.arg[i].constant, string_text))
{
if(*string_text)
{
temp_string.assign("[");
temp_string.append(instr.arg[i].mnemonic);
temp_string.push_back(']');
temp_string.push_back(':');
temp_string.append(string_text);
}
else if(*newinfo.label)
{
temp_string.assign("[");
temp_string.append(instr.arg[i].mnemonic);
temp_string.push_back(']');
temp_string.push_back(':');
temp_string.append(newinfo.label);
}
temp_string.assign(instr.arg[i].mnemonic);
temp_string.push_back(':');
temp_string.append(string_text);
}
else if(instr.arg[i].value && (DbgGetStringAt(instr.arg[i].value, string_text) || _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo)))
}
else if(instr.arg[i].memvalue && (DbgGetStringAt(instr.arg[i].memvalue, string_text) || _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo)))
{
if(*string_text)
{
if(instr.type != instr_normal) //stack/jumps (eg add esp,4 or jmp 401110) cannot directly point to strings
{
if(*newinfo.label)
{
temp_string = instr.arg[i].mnemonic;
temp_string.push_back(':');
temp_string.append(newinfo.label);
}
}
else if(*string_text)
temp_string.assign("[");
temp_string.append(instr.arg[i].mnemonic);
temp_string.push_back(']');
temp_string.push_back(':');
temp_string.append(string_text);
}
else if(*newinfo.label)
{
temp_string.assign("[");
temp_string.append(instr.arg[i].mnemonic);
temp_string.push_back(']');
temp_string.push_back(':');
temp_string.append(newinfo.label);
}
}
else if(instr.arg[i].value && (DbgGetStringAt(instr.arg[i].value, string_text) || _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo)))
{
if(instr.type != instr_normal) //stack/jumps (eg add esp, 4 or jmp 401110) cannot directly point to strings
{
if(*newinfo.label)
{
temp_string = instr.arg[i].mnemonic;
temp_string.push_back(':');
temp_string.append(string_text);
temp_string.append(newinfo.label);
}
}
else
continue;
else if(*string_text)
{
temp_string = instr.arg[i].mnemonic;
temp_string.push_back(':');
temp_string.append(string_text);
}
}
else
continue;

if(!strstr(comment.c_str(), temp_string.c_str())) //avoid duplicate comments
if(!strstr(comment.c_str(), temp_string.c_str())) //avoid duplicate comments
{
if(!comment.empty())
{
if(!comment.empty())
{
comment.push_back(',');
comment.push_back(' ');
}
comment.append(temp_string);
retval = true;
comment.push_back(',');
comment.push_back(' ');
}
comment.append(temp_string);
retval = true;
}
}

Expand Down
36 changes: 11 additions & 25 deletions src/dbg/disasm_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@ const char* disasmtext(duint addr)
return instruction;
}

static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg)
static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg, bool getregs)
{
auto value = cp.ResolveOpValue(opindex, [&](x86_reg reg)
auto value = cp.ResolveOpValue(opindex, [&cp, getregs](x86_reg reg)
{
auto regName = cp.RegName(reg);
auto regName = getregs ? cp.RegName(reg) : nullptr;
return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching
});
const auto & op = cp[opindex];
Expand Down Expand Up @@ -199,7 +199,7 @@ static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg)
}
}

void disasmget(Capstone & cp, unsigned char* buffer, duint addr, DISASM_INSTR* instr)
void disasmget(Capstone & cp, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs)
{
memset(instr, 0, sizeof(DISASM_INSTR));
cp.Disassemble(addr, buffer, MAX_DISASM_BUFFER);
Expand All @@ -224,10 +224,10 @@ void disasmget(Capstone & cp, unsigned char* buffer, duint addr, DISASM_INSTR* i
instr->type = instr_normal;
instr->argcount = cp.x86().op_count <= 3 ? cp.x86().op_count : 3;
for(int i = 0; i < instr->argcount; i++)
HandleCapstoneOperand(cp, i, &instr->arg[i]);
HandleCapstoneOperand(cp, i, &instr->arg[i], getregs);
}

void disasmget(Capstone & cp, duint addr, DISASM_INSTR* instr)
void disasmget(Capstone & cp, duint addr, DISASM_INSTR* instr, bool getregs)
{
if(!DbgIsDebugging())
{
Expand All @@ -237,18 +237,18 @@ void disasmget(Capstone & cp, duint addr, DISASM_INSTR* instr)
}
unsigned char buffer[MAX_DISASM_BUFFER] = "";
if(MemRead(addr, buffer, sizeof(buffer)))
disasmget(cp, buffer, addr, instr);
disasmget(cp, buffer, addr, instr, getregs);
else
memset(instr, 0, sizeof(DISASM_INSTR)); // Buffer overflow
}

void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr)
void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs)
{
Capstone cp;
disasmget(cp, buffer, addr, instr);
disasmget(cp, buffer, addr, instr, getregs);
}

void disasmget(duint addr, DISASM_INSTR* instr)
void disasmget(duint addr, DISASM_INSTR* instr, bool getregs)
{
if(!DbgIsDebugging())
{
Expand All @@ -258,25 +258,11 @@ void disasmget(duint addr, DISASM_INSTR* instr)
}
unsigned char buffer[MAX_DISASM_BUFFER] = "";
if(MemRead(addr, buffer, sizeof(buffer)))
disasmget(buffer, addr, instr);
disasmget(buffer, addr, instr, getregs);
else
memset(instr, 0, sizeof(DISASM_INSTR)); // Buffer overflow
}

void disasmprint(duint addr)
{
DISASM_INSTR instr;
memset(&instr, 0, sizeof(instr));
disasmget(addr, &instr);
dprintf(">%d:\"%s\":\n", instr.type, instr.instruction);
for(int i = 0; i < instr.argcount; i++)
#ifdef _WIN64
dprintf(" %d:%d:%llX:%llX:%llX\n", i, instr.arg[i].type, instr.arg[i].constant, instr.arg[i].value, instr.arg[i].memvalue);
#else //x86
dprintf(" %d:%d:%X:%X:%X\n", i, instr.arg[i].type, instr.arg[i].constant, instr.arg[i].value, instr.arg[i].memvalue);
#endif //_WIN64
}

static bool isasciistring(const unsigned char* data, int maxlen)
{
int len = 0;
Expand Down
9 changes: 4 additions & 5 deletions src/dbg/disasm_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n);
duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n);
const char* disasmtext(duint addr);
void disasmprint(duint addr);
void disasmget(Capstone & cp, unsigned char* buffer, duint addr, DISASM_INSTR* instr);
void disasmget(Capstone & cp, duint addr, DISASM_INSTR* instr);
void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr);
void disasmget(duint addr, DISASM_INSTR* instr);
void disasmget(Capstone & cp, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs = true);
void disasmget(Capstone & cp, duint addr, DISASM_INSTR* instr, bool getregs = true);
void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs = true);
void disasmget(duint addr, DISASM_INSTR* instr, bool getregs = true);
bool disasmispossiblestring(duint addr);
bool disasmgetstringat(duint addr, STRING_TYPE* type, char* ascii, char* unicode, int maxlen);
int disasmgetsize(duint addr, unsigned char* data);
Expand Down

0 comments on commit 1ebcb07

Please sign in to comment.