📄 cfuncstep1.cpp
字号:
while (pos)
{
AsmCode* pasm = m_asmlist->GetNext(pos);
if (pasm->iAddRemove != 0)
continue;
XCPUCODE* pxcpu = &pasm->xcpu;
if (pxcpu->opcode == C_CALL && pxcpu->op[0].mode == OP_Near)
{
CFunc* pfunc = g_Cexe2c->GetFunc(pxcpu->op[0].nearptr.offset);
if (pfunc == NULL)
continue;
if (pfunc->m_IfLibFunc && pfunc->m_functype != NULL)
{
CFuncType* fctype = pfunc->m_functype;
if (!strcmp(fctype->m_internal_name, "_EH_prolog"))
{
strcmp(fctype->m_internal_name, "_EH_prolog");
pasm->iAddRemove = 1;
AsmCode* pnew;
//push ebp
pnew = AsmCode::new_AsmCode();
pnew->iAddRemove = 2;
pnew->xcpu.opcode = C_PUSH;
pnew->xcpu.op[0].mode = OP_Register;
pnew->xcpu.op[0].opersize = 4;
pnew->xcpu.op[0].reg.reg_index = _EBP_;
m_asmlist->InsertBefore(pos, pnew);
//mov ebp, esp
pnew = AsmCode::new_AsmCode();
pnew->iAddRemove = 2;
pnew->xcpu.opcode = C_MOV;
pnew->xcpu.op[0].mode = OP_Register;
pnew->xcpu.op[0].opersize = 4;
pnew->xcpu.op[0].reg.reg_index = _EBP_;
pnew->xcpu.op[1].mode = OP_Register;
pnew->xcpu.op[1].opersize = 4;
pnew->xcpu.op[1].reg.reg_index = _ESP_;
m_asmlist->InsertBefore(pos, pnew);
}
}
}
}
}
void CFuncLL::Prepare_CallFunc()
{//把本函数中call到的函数都prepare一遍
POSITION pos = m_asmlist->GetHeadPosition();
while (pos)
{
AsmCode* pasm = m_asmlist->GetNext(pos);
XCPUCODE* pxcpu = &pasm->xcpu;
if (pxcpu->opcode == C_CALL && pxcpu->op[0].mode == OP_Near)
{
CFunc* pfunc = g_Cexe2c->GetFunc(pxcpu->op[0].nearptr.offset);
if (pfunc == NULL)
continue;
pfunc->PrepareFunc();
}
}
}
bool CFuncLL::Fill_Stack_1()
{//为什么总是true呢
POSITION pos = m_asmlist->GetHeadPosition();
AsmCode* pasm = 0;
if (pos)
pasm = m_asmlist->GetNext(pos);
while (pos)
{
AsmCode* p0 = pasm;
pasm = m_asmlist->GetNext(pos);
if (stack_stack(p0,pasm))
return true;
}
return false;
}
bool CFuncLL::Check_Stack()
// 检查该函数的stack是否平衡
{
POSITION pos = this->m_asmlist->GetHeadPosition();
signed int lastesp = 0;
while (pos)
{
AsmCode* p = this->m_asmlist->GetNext(pos);
signed int esp = p->esp_level;
if (esp == ESP_UNKNOWN)
return false;
if (lastesp != ESP_UNKNOWN && lastesp != ESP_IGNORE && esp != lastesp)
return false;
if (p->xcpu.IsJxx() || p->xcpu.IsJmpNear())
{
ea_t jmpto = p->xcpu.op[0].nearptr.offset;
AsmCode* p = ea2pasm(jmpto);
if (esp != p->esp_level)
return false;
}
if (p->xcpu.opcode == C_RET)
{
if (esp != 0)
return false;
}
lastesp = p->esp_level_next;
}
return true;
}
bool CFuncLL::Fill_Stack_Info()
{
AsmCode* pasm = this->m_asmlist->GetHead();
if (pasm->linear == 0x401150)
{
pasm->linear = 0x401150;
}
pasm->esp_level = 0; // I know the first one
for (int i=0;;i++)
{ //这里会死循环
if ((i % 1000) == 0)
nop();
if ( Fill_Stack_1() )
continue;
break;
}
if (! Check_Stack())
return false;
return true;
}
int CFuncLL::Get_Ret_Purge()
//return -1 for fail
{
int retn = -1;
POSITION pos = this->m_asmlist->GetHeadPosition();
while (pos)
{
AsmCode* pasm = this->m_asmlist->GetNext(pos);
XCPUCODE* pxcpu = &pasm->xcpu;
if (pxcpu->opcode == C_RET) //找到了ret语句
{
int r = 0;
if (pxcpu->op[0].mode == OP_Immed) // means RET n
{
r = pxcpu->op[0].immed.immed_value;
}
if (retn == -1)
retn = r;
else if (retn != r) //两个Ret不一致?
return -1;
}
}
if (retn == -1)
{
//alert_prtf("why not find RET ? func = %x", this->m_head_off);
//myexit(2);
//return false;
}
return retn;
}
CString CFuncLL::GetLabelName(ea_t ea)
{
CString retn;
CFunc* pfunc = g_Cexe2c->GetFunc(ea);
if (pfunc != NULL)
{
retn = pfunc->m_funcname;
return retn;
}
AsmCode* pasm = this->ea2pasm(ea);
if (pasm != NULL && pasm->h.label.ref_j != NULL)
{
retn = pasm->h.label.label_name;
return retn;
}
return retn;
}
void CFuncLL::prtout_asm(CFunc* pfunc, CVarLL* pvarll, CXmlOutPro* out)
{
out->XMLbegin(XT_Function, pfunc);
out->XMLbegin(XT_FuncName, pfunc);
out->prtt(pfunc->m_funcname);
out->XMLend(XT_FuncName);
out->prtspace();
out->prtt("proc");
out->endline();
pvarll->prtout(out);
out->endline();
this->prtout_asm_1(pvarll, out);
out->XMLbegin(XT_FuncName, pfunc);
out->prtt(pfunc->m_funcname);
out->XMLend(XT_FuncName);
out->prtspace();
out->prtt("endp");
out->endline();
out->XMLend(XT_Function);
}
void CFuncLL::prtout_asm_1(CVarLL* pvarll, CXmlOutPro* out)
{ // 按运行代码以ASM显示func,对其中的GAP能指出来
ea_t last = 0xffffffff;
POSITION pos = this->m_asmlist->GetHeadPosition();
while (pos)
{
AsmCode* pasm = this->m_asmlist->GetNext(pos);
if (pasm->iAddRemove == 2)
continue;
ea_t ea = pasm->linear;
char buf[280];
DWORD n;
if (pasm->xcpu.opcode == C_JCASE)
{
n = 0;
sprintf(buf,"case jmp to %x",pasm->xcpu.op[0].nearptr.offset);
}
else
{
st_IDA_OUT idaout;
CDisasm the;
//n = the.Disassembler(buf, ea2ptr(ea), ea);
n = the.Disassembler_X(ea2ptr(ea), ea, &idaout);
XCPUCODE* pxcpu = the.get_xcpu();
if (pxcpu->op[0].mode == OP_Near)
{
ea_t linear = pxcpu->op[0].nearptr.offset;
CString labelname = this->GetLabelName(linear);
if (!labelname.IsEmpty())
{
idaout.Par1Str = labelname;
}
}
else if (pxcpu->op[0].mode == OP_Address)
{
OPERITEM* op = &pxcpu->op[0];
if (op->addr.base_reg_index == _ESP_
|| (op->addr.base_reg_index == _NOREG_
&& op->addr.off_reg_index == _ESP_
&& op->addr.off_reg_scale == 1))
{
signed int level = pasm->esp_level + op->addr.off_value;
st_VarLL* p = pvarll->LookUp_VarLL(level- pvarll->m_VarRange_L);
if (p != NULL)
{
idaout.Par1Str += '.';
idaout.Par1Str += p->Name;
}
}
}
else if (pxcpu->op[1].mode == OP_Address)
{
OPERITEM* op = &pxcpu->op[1];
if (op->addr.base_reg_index == _ESP_
|| (op->addr.base_reg_index == _NOREG_
&& op->addr.off_reg_index == _ESP_
&& op->addr.off_reg_scale == 1))
{
signed int level = pasm->esp_level + op->addr.off_value;
st_VarLL* p = pvarll->LookUp_VarLL(level- pvarll->m_VarRange_L);
if (p != NULL)
{
idaout.Par2Str += '.';
idaout.Par2Str += p->Name;
}
}
}
idaout.output(buf);
}
if (last != 0xffffffff && ea != last)
out->prtl("// gap here");
if (pasm->h.label.ref_j != NULL)
{
//asm_prtl("%s:", pasm->h.label.label_name);
out->prtf("%s:", pasm->h.label.label_name);
out->endline();
}
//asm_prtl("%4x %x %s",-pasm->esp_level, ea, buf);
if (pasm->esp_level == ESP_UNKNOWN)
{
out->prtt(" "); //四个空格的位置要留
}
else
out->prtf("%4x", -pasm->esp_level);
out->prtspace();
out->XMLbegin(XT_AsmOffset, (void*)ea);
out->prtf("%x", ea);
out->XMLend(XT_AsmOffset);
out->prtt(buf);
out->endline();
last = ea+n;
}
}
void CFuncLL::GetVarRange(signed int& VarRange_L, signed int& VarRange_H)
{
/*
如果一个函数开头是:
0 401010 SUB ESP,00000190
190 401016 LEA ECX,[ESP+00]
则 VarRange_L = -190h
则 VarRange_H = 0
写作
0 401010 SUB ESP,00000190
190 401016 LEA ECX,[ESP+v_00]
*/
signed int L = 0;
signed int H = 0;
POSITION pos = this->m_asmlist->GetHeadPosition();
while (pos)
{
AsmCode* pasm = this->m_asmlist->GetNext(pos);
signed int last = pasm->esp_level;
signed int here = pasm->esp_level_next;
if (pasm->xcpu.opcode == C_SUB || pasm->xcpu.opcode == C_ADD)
{
if (last - here > H - L)
{
H = last;
L = here;
}
}
}
if (H - L > 0)
{
VarRange_H = H;
VarRange_L = L;
}
}
void CVarLL::prtout(CXmlOutPro* out)
{
int curlevel = 0;
int maxlevel = this->m_VarRange_H - this->m_VarRange_L;
POSITION pos = this->m_varll_list.GetHeadPosition();
while (pos)
{
st_VarLL* p = this->m_varll_list.GetNext(pos);
if (curlevel > p->off)
{
out->prtl("error, var collapse!!!");
curlevel = p->off;
}
else if (curlevel < p->off)
{
out->prtl("gap len = %x", p->off - curlevel);
curlevel = p->off;
}
/*asm_prtl("%s equ %s %x", p->Name,
(p->size == 1) ? "BYTE ptr" :
(p->size == 2) ? "WORD ptr" :
(p->size == 4) ? "DWORD ptr" : "",
p->off); */
out->prtspace(4);
out->XMLbegin(XT_Symbol, p);
out->prtt(p->Name);
out->XMLend(XT_Symbol);
out->prtt("equ");
out->prtspace();
out->prtt((p->size == 1) ? "BYTE ptr" :
(p->size == 2) ? "WORD ptr" :
(p->size == 4) ? "DWORD ptr" : "");
out->prtspace();
if (p->array != 1)
{
out->XMLbegin(XT_Number, NULL);
out->prtf("%xh", p->array);
out->XMLend(XT_Number);
out->prtt("dup");
out->prtspace();
}
out->XMLbegin(XT_Number, NULL);
out->prtf("%xh", p->off);
out->XMLend(XT_Number);
out->endline();
curlevel += p->size * p->array;
}
if (curlevel < maxlevel)
{
out->prtl(" gap len = %xh", maxlevel - curlevel);
}
}
st_VarLL* CVarLL::LookUp_VarLL(int off)
{
POSITION pos = this->m_varll_list.GetHeadPosition();
while (pos)
{
st_VarLL* p = this->m_varll_list.GetNext(pos);
if (p->off == off)
return p;
}
return NULL;
}
void CVarLL::AddRef(signed int level, int opersize)
{
if (level < this->m_VarRange_H && level >= this->m_VarRange_L)
{
}
else
return;
int off = level - this->m_VarRange_L; //这个是>=0的
st_VarLL* pnew = this->LookUp_VarLL(off);
if (pnew != NULL)
return;
pnew = new st_VarLL;
pnew->off = off;
pnew->size = opersize;
sprintf(pnew->Name, "v_%x", off);
if (this->m_varll_list.IsEmpty())
{
this->m_varll_list.AddTail(pnew);
}
else
{//有序列表
POSITION pos = this->m_varll_list.GetHeadPosition();
while (pos)
{
POSITION savpos = pos;
st_VarLL* p = this->m_varll_list.GetNext(pos);
if (p->off > off)
{
this->m_varll_list.InsertBefore(savpos, pnew);
return;
}
}
this->m_varll_list.AddTail(pnew);
}
}
void CFuncLL::VarLL_Analysis_1(CVarLL* pvarll, OPERITEM* op, AsmCode* pasm)
{
if (op->mode != OP_Address)
return;
if (op->addr.base_reg_index == _ESP_
|| (op->addr.base_reg_index == _NOREG_
&& op->addr.off_reg_index == _ESP_
&& op->addr.off_reg_scale == 1))
{
signed int level = pasm->esp_level + op->addr.off_value;
pvarll->AddRef(level, op->opersize);
}
if (op->addr.base_reg_index == _EBP_)
{
//怎么写?
}
}
void CFuncLL::VarLL_Analysis(CVarLL* pvarll)
{
POSITION pos = this->m_asmlist->GetHeadPosition();
while (pos)
{
AsmCode* pasm = this->m_asmlist->GetNext(pos);
if (pasm->xcpu.op[0].mode == OP_Address)
this->VarLL_Analysis_1(pvarll, &pasm->xcpu.op[0], pasm);
if (pasm->xcpu.op[1].mode == OP_Address)
this->VarLL_Analysis_1(pvarll, &pasm->xcpu.op[1], pasm);
}
}
AsmCode* ea2pasm(ea_t ea, AsmCodeList* m_asmlist)
{
POSITION pos = m_asmlist->GetHeadPosition();
while (pos)
{
AsmCode* p = m_asmlist->GetNext(pos);
if (p->linear == ea)
return p;
}
assert_msg(0,"whye here");
return NULL;
}
void CJxxLabel::Label_Analysis()
{
POSITION pos = this->m_asmlist->GetHeadPosition();
while (pos)
{
AsmCode* p = this->m_asmlist->GetNext(pos);
assert(p->h.type == i_Nothing); //以前没对h分析过
if (p->xcpu.IsJxx() || p->xcpu.IsJmpNear())
{
ea_t jmpto = p->xcpu.op[0].nearptr.offset;
AsmCode* plabel = ea2pasm(jmpto, m_asmlist);
p->h.type = i_Jump;
if (p->xcpu.IsJmpNear())
p->h.jmp.jmp_type = JMP_jmp;
p->h.jmp.the_label = plabel;
if (plabel->h.label.ref_j == NULL)
{
plabel->h.label.ref_j = p;
sprintf(plabel->h.label.label_name, "loc_%x", plabel->linear);
}
else
{
p->h.jmp.next_ref_of_this_label = plabel->h.label.ref_j;
plabel->h.label.ref_j = p;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -