Ada*_*der 5 c windows x86 assembly
我有一个应用程序,它创建.textwin32进程的段转储.然后它将基本块上的代码分开.基本块是一组一个接一个地执行的指令(跳转始终是这些基本块的最后指令).这是一个例子:
Basic block 1
mov ecx, dword ptr [ecx]
test ecx, ecx
je 00401013h
Basic block 2
mov eax, dword ptr [ecx]
call dword ptr [eax+08h]
Basic block 3
test eax, eax
je 0040100Ah
Basic block 4
mov edx, dword ptr [eax]
push 00000001h
mov ecx, eax
call dword ptr [edx]
Basic block 5
ret 000008h
Run Code Online (Sandbox Code Playgroud)
现在我想在函数中对这些基本块进行分组 - 比如哪些基本块构成一个函数.什么是算法?我必须记住,ret一个函数中可能有很多指令.如何检测fast_call功能?
将块分组为函数的最简单算法是:
call some_address说明进行呼叫的所有地址ret,那么你就完成了这个功能ret.您需要识别组织循环的跳转,这样您的程序本身就不会因为进入无限循环而挂起问题:
call [some_address]而不是call some_addressjump some_address不会call some_address紧跟其后retcall some_address可以使用push some_address+ retOR push some_address+ 的组合进行模拟jmp some_other_address您可以使用一些启发式方法通过查找最常见的prolog指令序列来确定函数的起始位置:
push ebp
mov ebp, esp
Run Code Online (Sandbox Code Playgroud)
同样,如果在禁止帧指针的情况下编译函数,这可能不起作用(即,它们使用esp而不是ebp在堆栈上访问它们的参数,这是可能的).
编译器(例如MSVC++)也可以用int 3指令填充功能间空间,并且也可以作为即将到来的功能开始的提示.
至于区分各种调用约定,它可能是最简单的查看符号(当然,如果你有它们).MSVC++生成不同的名称前缀和后缀,例如:
如果无法从符号中提取此信息,则必须分析代码以查看参数如何传递给函数以及函数或其调用者是否将其从堆栈中删除.