📄 reparse.h
字号:
// reparse.h
// Copyright (C) 2008 Willow Schlanger
bool reparser_t::reparse(U8 target)
{
U8 mytarget = target;
std::set<U8> locals;
locals.insert(target);
int x;
decode_state_t s;
s.dsz = dsz;
U8 bytesleft, offset, tmp;
specialized_tcode_t sp;
expr_t *expr[X86S_SEMANTICS_MAX_SIZE];
U4 expr_count;
icode_t icode_table[ICODE_PEEP_SIZE];
UINT icode_start, icode_size;
bool is_start = true;
bb_t *curbb;
curbb = &(proc.map[target]);
proc.root = curbb;
curbb->address = target;
curbb->proc = &proc;
bool no_decompile = false;
// now parse this procedure.
while(!locals.empty())
{
target = *locals.begin();
locals.erase(locals.begin());
//printf("Now parsing locals starting at %08x\n", (U4)target);
//std::cout << "+" << std::hex << (U4)target << std::endl;
icode_start = ICODE_PEEP_SIZE - 1;
icode_size = 0;
if(proc.map.find(target) == proc.map.end())
{
throw std::runtime_error("Basic block not found.");
}
curbb = &(proc.map[target]);
sp.clear(); // clear temporaries (for now)...
again:
//std::cout << " " << std::hex << (U4)target << std::endl;
if(memory.meta[target].local == 1)
{
// already been here - part of current procedure.
// --- do we need to do anything special here?
continue;
}
if(!is_start)
{
if(memory.meta[target].entry == 1)
{
// proc -> INVOKEs target. put in a synthetic jmp.
//printf("%08x - calls %08x [+]\n", (U4)myproc, (U4)target);
tmp = target;
if(memory.meta[tmp].entry == 0 || procs.find(tmp) == procs.end() || procs[tmp].root == NULL)
{
//throw std::runtime_error("Invokation to unknown procedure (1)");
continue;
}
if(memory.meta[tmp].decompiled == 0 && tmp != mytarget)
no_decompile = true;
if(!no_decompile)
{
// *** add synthetic jump hcode here.
curbb->hcode.push_back(hcode_t());
curbb->hcode.back().opcode = ht_jump;
// fixme--add any arguments here.
}
bb_t &bb2 = *procs[tmp].root;
//bb2.address = tmp;
//bb2.proc = &proc;
//locals.insert(tmp);
bb2.in_edges.insert(curbb);
curbb->out_edges.push_back(&bb2);
#if 0
bb_t &bb = &procs[target];
bb.address = target;
bb.proc = &proc;
bb.in_edges.insert(curbb);
curbb->out_edges.push_back(&bb);
#endif
continue;
}
}
is_start = false;
if(memory.meta[target].branch == 1 && target != curbb->address)
{
curbb->hcode.push_back(hcode_t());
curbb->hcode.back().opcode = ht_jump;
//if()
{
bb_t &bb = proc.map[target];
bb.address = target;
bb.proc = &proc;
bb.in_edges.insert(curbb);
curbb->out_edges.push_back(&bb);
curbb = &bb;
}
}
s.insn = memory.image + target;
icode_start = (icode_start + 1) & (ICODE_PEEP_SIZE - 1);
s.icode = icode_table + icode_start;
if(icode_size < ICODE_PEEP_SIZE)
++icode_size;
bytesleft = memory.image_size - target;
if(bytesleft > 15)
bytesleft = 15;
s.end = s.insn + bytesleft;
x = decode(s);
if(x != 0)
{
no_decompile = true;
break;
}
if(memory.meta[target].entry == 0)
memory.meta[target].local = 1;
// look at insn here.
// look at instruciton here.
switch(encodings[s.encoding].insn)
{
case insn__ret:
case insn__retf:
case insn__retfnum:
case insn__retnum:
case insn__iret:
// I don't want to specify out edges for returns...
// fixme--add expression to return.
if(!no_decompile)
{
curbb->hcode.push_back(hcode_t());
curbb->hcode.back().opcode = ht_ret;
// fixme--add ANY arguments here.
}
continue;
case insn_jmp:
{
icode_start = ICODE_PEEP_SIZE - 1;
icode_size = 0;
// fixme: add 64-bit support here. Also do something about memory.cs_base.
offset = (U8)s.icode->imm + (U8)target + (U8)s.size + (U8)memory.image_base;
offset &= memory.rip_mask;
if(offset < (U8)memory.image_base)
throw std::runtime_error("jmp above image base");
target = offset - (U8)memory.image_base;
//memory.meta[target].branch = 1;
s.insn = memory.image + target;
//printf("jmp to %08x\n", offset);
if(memory.meta[target].entry == 1)
{
if(memory.meta[target].decompiled == 0)
no_decompile = true;
}
if(!no_decompile)
{
curbb->hcode.push_back(hcode_t());
curbb->hcode.back().opcode = ht_jump;
// fixme--add ANY arguments here.
}
bb_t &bb = proc.map[target];
bb.address = target;
bb.proc = &proc;
bb.in_edges.insert(curbb);
curbb->out_edges.push_back(&bb);
curbb = &bb;
goto again;
}
case insn_call:
{
//icode_start = ICODE_PEEP_SIZE - 1;
//icode_size = 0;
// fixme: add 64-bit support here. Also do something about memory.cs_base.
offset = (U8)target + (U8)s.size + (U8)memory.image_base;
offset &= memory.rip_mask;
tmp = offset - (U8)memory.image_base;
if(s.icode->imm != 0)
{
bb_t &bb = proc.map[tmp];
bb.address = tmp;
bb.proc = &proc;
bb.in_edges.insert(curbb);
curbb->out_edges.push_back(&bb);
if(memory.meta[tmp].entry == 0)
locals.insert(tmp);
}
offset = (U8)s.icode->imm + (U8)target + (U8)s.size + (U8)memory.image_base;
offset &= memory.rip_mask;
tmp = offset - (U8)memory.image_base;
if(tmp != mytarget) // bugfix
if(memory.meta[tmp].entry == 0 || procs.find(tmp) == procs.end() || procs[tmp].root == NULL)
{
no_decompile = true;
continue;
//throw std::runtime_error("Invokation to unknown procedure (2)");
}
if(memory.meta[tmp].decompiled == 0 && tmp != mytarget)
no_decompile = true;
if(!no_decompile)
{
curbb->hcode.push_back(hcode_t());
curbb->hcode.back().opcode = ht_call;
curbb->hcode.back().operands.push_back(NULL); // direct call.
curbb->hcode.back().operands.push_back(NULL); // this is arguments - we use 'void' for now
// fixme--add arguments here.
}
bb_t &bb2 = *procs[tmp].root;
//bb2.address = tmp;
//bb2.proc = &proc;
//locals.insert(tmp);
bb2.in_edges.insert(curbb);
curbb->out_edges.push_back(&bb2);
continue;
}
case insn__jcc:
case insn__jrcxz:
case insn__loopnz:
case insn__loopz:
case insn__loop:
{
//icode_start = ICODE_PEEP_SIZE - 1;
//icode_size = 0;
// fixme: add 64-bit support here. Also do something about memory.cs_base.
offset = (U8)target + (U8)s.size + (U8)memory.image_base;
offset &= memory.rip_mask;
tmp = offset - (U8)memory.image_base;
curbb->hcode.push_back(hcode_t());
curbb->hcode.back().opcode = ht_jcond;
// *** first argument is condition code value, 0..15.
// *** second argument is NULL, or is argsize_16/argsize_32/argsize_64 for cx/ecx/rcx
// *** 3nd argument is hll expression.
// *** any of these 3 args may be NULL.
switch(encodings[s.encoding].insn)
{
case insn__jcc:
curbb->hcode.back().operands.push_back(new expr_t());
curbb->hcode.back().operands.back()->make_literal32(s.icode->argvalue[1]);
curbb->hcode.back().operands.push_back(NULL);
break;
case insn__jrcxz:
curbb->hcode.back().operands.push_back(NULL);
curbb->hcode.back().operands.push_back(new expr_t());
curbb->hcode.back().operands.back()->make_literal32(s.icode->asz + 0x100);
break;
case insn__loopnz:
curbb->hcode.back().operands.push_back(new expr_t());
curbb->hcode.back().operands.back()->make_literal32(5);
curbb->hcode.back().operands.push_back(new expr_t());
curbb->hcode.back().operands.back()->make_literal32(s.icode->asz + 0x300);
break;
case insn__loopz:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -