📄 crudcom2.cpp
字号:
{
memory.meta[i].local = 0;
//memory.meta[i].decompiled = 0;
}
}
bool reparse(U8 target);
};
static void load_operand(expr_t *&expr, U4 value, expr_t *table[])
{
if(value >= 0x80000000)
{
value -= 0x80000000;
if(value == no_void)
{
expr = NULL;
return;
}
else
// et_reg_reg // subtype is 0. u.data[0] is argsize_*, u.data[1] is 1st reg index, u.data[2] is 2nd reg index.
if(value > no__begin_x86_regs && value < no__end_x86_regs)
{
expr = new expr_t();
expr->subtype = 0;
switch(value)
{
case no_x86_ah: expr->type = et_reg; expr->u.data[0] = argsize_8; expr->u.data[1] = 4; break;
case no_x86_al: expr->type = et_reg; expr->u.data[0] = argsize_8; expr->u.data[1] = 0; break;
case no_x86_dl: expr->type = et_reg; expr->u.data[0] = argsize_8; expr->u.data[1] = 2; break;
case no_x86_ax: expr->type = et_reg; expr->u.data[0] = argsize_16; expr->u.data[1] = 0; break;
case no_x86_dx: expr->type = et_reg; expr->u.data[0] = argsize_16; expr->u.data[1] = 2; break;
case no_x86_eax: expr->type = et_reg; expr->u.data[0] = argsize_32; expr->u.data[1] = 0; break;
case no_x86_edx: expr->type = et_reg; expr->u.data[0] = argsize_32; expr->u.data[1] = 2; break;
case no_x86_rax: expr->type = et_reg; expr->u.data[0] = argsize_64; expr->u.data[1] = 0; break;
case no_x86_rdx: expr->type = et_reg; expr->u.data[0] = argsize_64; expr->u.data[1] = 2; break;
case no_x86_dx_ax: expr->type = et_reg_reg; expr->u.data[0] = argsize_16; expr->u.data[1] = 2; expr->u.data[2] = 0; break;
case no_x86_edx_eax: expr->type = et_reg_reg; expr->u.data[0] = argsize_32; expr->u.data[1] = 2; expr->u.data[2] = 0; break;
case no_x86_rdx_rax: expr->type = et_reg_reg; expr->u.data[0] = argsize_64; expr->u.data[1] = 2; expr->u.data[2] = 0; break;
default:
throw std::runtime_error("invalid register");
break;
}
}
else
{
expr = new expr_t();
expr->type = et_nodeoperand;
expr->subtype = value;
}
}
else
{
expr = table[value];
}
}
#include "reparse.h"
std::set<U8> test_visited;
std::list<bb_t *> test_list;
void test_dfs(bb_t *node)
{
if(test_visited.find(node->address) != test_visited.end())
return;
test_visited.insert(node->address);
// call all out edges
std::vector<bb_t *>::iterator i = node->out_edges.end();
for(;;)
{
if(i == node->out_edges.begin())
break;
--i;
if((*i)->proc == node->proc)
test_dfs(*i);
}
test_list.push_front(node);
}
std::string int_to_string(U4 value, const char *fmt)
{
char buf[1024];
std::sprintf(buf, fmt, value);
return std::string(buf);
}
std::string expr_to_string(expr_t *expr)
{
const char *reg8[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
const char *reg16[] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"};
const char *reg32[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
const char *sregs[] = {"es", "cs", "ss", "ds", "fs", "gs", "ss", "ds"};
std::string s;
if(expr->type == et_nodetype)
{
if(expr->subtype == nt__x86_cc)
{
s = get_ll_cc_text(expr->u.subexpr[0]->u.data[0]);
return s;
}
s = strings_nt[expr->subtype];
if(expr->subtype == nt_zx || expr->subtype == nt_sx || expr->subtype == nt_trunc || expr->subtype == nt_deref || expr->subtype == nt_stack ||
expr->subtype == nt_quest
)
{
s += "<" + get_node_size_text(expr->size) + ">";
}
s += "(";
for(int i = 0; i < 3; ++i)
{
if(expr->u.subexpr[i] == NULL)
break;
if(i != 0)
s += ", ";
s += expr_to_string(expr->u.subexpr[i]);
}
s += ")";
return s;
}
if(expr->type == et_nodeoperand)
{
s = strings_no[expr->subtype];
return s;
}
if(expr->type == et_asgn)
{
if(expr->u.subexpr[0]->type == et_nodetype && expr->u.subexpr[0]->subtype == nt_tmp)
{
// asgn(tmp, value) -- needs size.
s = get_node_size_text(expr->u.subexpr[0]->size);
s += " tmp" + int_to_string(expr->u.subexpr[0]->u.subexpr[0]->u.data[0], "%d");
s += " = ";
s += expr_to_string(expr->u.subexpr[1]);
s += ";";
}
else
{
s = expr_to_string(expr->u.subexpr[0]);
s += " = ";
s += expr_to_string(expr->u.subexpr[1]);
s += ";";
}
}
else
if(expr->type == et_literal32)
{
if(expr->u.data[0] >= 10)
s += "0x";
s += int_to_string(expr->u.data[0], "%x");
}
else
if(expr->type == et_reg)
{
// subtype is 0 for general register, u.data[0] is argsize_*, u.data[1] is register index number
if(expr->subtype == 0)
{
if(expr->u.data[0] == argsize_8)
s += std::string("x86_") + reg8[expr->u.data[1]];
else
if(expr->u.data[0] == argsize_16)
s += std::string("x86_") + reg16[expr->u.data[1]];
else
s += std::string("x86_") + reg32[expr->u.data[1]];
}
}
else
if(expr->type == et_reg_reg)
{
// subtype is 0 for general register, u.data[0] is argsize_*, u.data[1] is register index number
if(expr->subtype == 0)
{
if(expr->u.data[0] == argsize_8)
s += std::string("x86_") + reg8[expr->u.data[1]] + ":x86_" + reg8[expr->u.data[2]];
else
if(expr->u.data[0] == argsize_16)
s += std::string("x86_") + reg16[expr->u.data[1]] + ":x86_" + reg16[expr->u.data[2]];
else
s += std::string("x86_") + reg32[expr->u.data[1]] + ":x86_" + reg32[expr->u.data[2]];
}
}
else
if(expr->type == et_ea16 || expr->type == et_ea32 || expr->type == et_ea64)
{
if((expr->subtype & 128) == 0)
{
// print any seg reg.
s += std::string("x86_") + sregs[expr->subtype & 7] + "+";
}
U1 base = expr->u.data[0] & 31;
U1 index = (expr->u.data[0] >> 5) & 31;
U1 scale = (expr->subtype & 0x7f) / 8;
const char **ptrs;
if(expr->type == et_ea16)
ptrs = reg16;
else
ptrs = reg32;
if(base != 31)
s += std::string("x86_") + ptrs[base];
if(index != 31)
{
if(base != 31)
s += "+";
s += std::string("x86_") + ptrs[index];
if(scale != 0)
s += std::string("*") + int_to_string(1 << scale, "%d");
}
if(expr->u.data[1] != 0 || (index == 31 && base == 31))
{
if(index != 31 || base != 31)
s += "+";
s += std::string("0x") + int_to_string(expr->u.data[1], "%x");
}
}
// et_ea16, // subtype is segreg + 8 * index_shift. u.data[0] is base + 32 * index (use 31 for none). data[1] is disp.
// et_ea32, // subtype is segreg + 8 * index_shift. u.data[0] is base + 32 * index (use 31 for none). data[1] is disp.
// et_ea64, // subtype is segreg + 8 * index_shift. u.data[0] is base + 32 * index (use 31 for none). data[1] is disp.
return s;
}
void do_test(U8 image_base)
{
for(std::list<bb_t *>::iterator i = test_list.begin(); i != test_list.end(); ++i)
{
bb_t *node = *i;
/*std::cout << std::endl;
std::cout << std::hex << (U4)node->address << std::dec << ":" << std::endl;
std::cout << "out:";
{
for(std::vector<bb_t *>::iterator i = node->out_edges.begin(); i != node->out_edges.end(); ++i)
std::cout << " " << std::hex << (*i)->address << std::dec;
}
std::cout << std::endl;
std::cout << "in:";
{
for(std::set<bb_t *>::iterator i = node->in_edges.begin(); i != node->in_edges.end(); ++i)
std::cout << " " << std::hex << (*i)->address << std::dec;
}*/
if(!(*i)->hcode.empty())
std::cout << "loc_" << std::hex << (U4)(node->address + image_base) << ":" << std::dec << std::endl;
/*std::cout << std::endl;
std::cout << "def:" << std::endl;
node->def.debug();
std::cout << std::endl;
std::cout << "live_use:" << std::endl;
node->live_use.debug();
std::cout << std::endl;*/
// print opcodes.
//int line = 0;
for(std::list<hcode_t>::iterator j = (*i)->hcode.begin(); j != (*i)->hcode.end(); ++j)
{
//++line;
if(j->opcode == ht_expr)
{
std::cout << " " << /*line << ". " <<*/ expr_to_string(*j->operands.begin());
std::cout << std::endl;
}
else
if(j->opcode == ht_call)
{
std::cout << std::hex << " fn_" << (U4)((*i)->out_edges[1]->address + image_base) << "() then goto " <<
"fn_" << (U4)((*i)->out_edges[0]->address + image_base) << ";" << std::dec << std::endl;
;
}
else
if(j->opcode == ht_jump)
{
std::cout << std::hex << " goto loc_" << (U4)((*i)->out_edges[0]->address + image_base) << ";" << std::dec << std::endl;
}
else
if(j->opcode == ht_jcond)
{
// jcond--print hll expr here ?
std::cout << " if (";
std::list<expr_t *>::iterator e = j->operands.begin();
if(j->operands.front() != NULL)
{
//std::cout << "cc=" << j->operands.front()->u.data[0];
std::cout << get_ll_cc_text(j->operands.front()->u.data[0]);
}
++e;
if(*e != NULL)
{
if(j->operands.front() != 0)
std::cout<<" && ";
if((U1)((*e)->u.data[0]) == (U1)argsize_16)
std::cout << "cx";
else
if((U1)((*e)->u.data[0]) == (U1)argsize_32)
std::cout << "ecx";
else
std::cout << "rcx";
if((*e)->u.data[0] >= 0x200)
std::cout << "!=";
else
std::cout << "==";
std::cout << "0";
}
std::cout << std::hex << ") goto loc_" << (U4)((*i)->out_edges[1]->address + image_base) << " else goto " <<
"loc_" << (U4)((*i)->out_edges[0]->address + image_base) << ";" << std::dec << std::endl;
}
else
{
std::cout << " " << ht_strings[j->opcode] << " ";
if(!j->operands.empty())
{
std::cout << "(";
for(std::list<expr_t *>::iterator k = j->operands.begin(); k != j->operands.end(); ++k)
{
if(k != j->operands.begin())
std::cout << ", ";
if(*k == NULL)
std::cout << "(Null)";
else
std::cout << expr_to_string(*k);
}
std::cout << ")";
}
std::cout << std::endl;
}
}
}
}
// If you encounter an unhandled instruction, or a locked instruction, clear 'decompile' to false.
void dataflow_t::dataflow(procedure_t &p, parser_call_t &j)
{
// always try to decompile even if we know it won't work, so we can build
// the control flow graph properly.
//if(j.decompile == false)
// return;
//U8 target = p.address;
reparser_t reparser(memory, dsz, p, procs, xgraph);
bool success = reparser.reparse(p.address);
if(!success || p.root == NULL)
{
#if 0
// Don't kill input edges, and don't delete this procedure.
// Was going to: kill all input edges!
for(bb_map_t::iterator i = p.map.begin(); i != p.map.end(); ++i)
{
bb_t &bb = i->second;
for(std::vector<bb_t *>::iterator j = bb.out_edges.begin(); j != bb.out_edges.end(); ++j)
{
if((*j)->proc != &p)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -