调试分析
1.先分析个典型函数调用堆栈结构
图中代码复制在下面,注释详解。
142: int main(int argc, char* argv[])
143: {
00401590 push ebp
00401591 mov ebp,esp //前两行保存ebp寄存器
00401593 sub esp,40h //开辟提升栈空间
00401596 push ebx
00401597 push esi
00401598 push edi //这三行保存寄存器环境
00401599 lea edi,[ebp-40h]
0040159C mov ecx,10h
004015A1 mov eax,0CCCCCCCCh
004015A6 rep stos dword ptr [edi] //这四行填充开辟空间,eax->edi循环赋值
144: CopyFileBufferToImageBuffer();
004015A8 call @ILT+0(CopyFileBufferToImageBuffer) (00401005)
145: return 0;
004015AD xor eax,eax
146: }
004015AF pop edi
004015B0 pop esi
004015B1 pop ebx //这三行恢复原先寄存器值,恢复原先环境
004015B2 add esp,40h //C(__cdecl)调用方式,调用者(Main) 平衡栈帧
004015B5 cmp ebp,esp //检测栈区是否平衡
004015B7 call __chkesp (00403e80) //检测平衡函数
004015BC mov esp,ebp
004015BE pop ebp //恢复ebp值,回到上个栈帧
004015BF ret
2.函数中普通变量汇编赋值方式(局部变量)
结论:
普通变量(没有复杂的C中的结构体类型),赋值方式传递到栈中保存。
3.验证C调用约定传参顺序
说明:
MyFilePath是一个全局数组
pFileBuffer一个指针
ReadPEFile(MyFilePath,&pFileBuffer);
004013F0 lea eax,[ebp-4] //先传递pFileBuffer变量的地址
004013F3 push eax //&pFileBuffer先被压入栈
004013F4 push offset string "C:\\Documents and Settings\\Admini"... (00426188) //后压入MyFilePath的偏移(一个全局地址00426188)
004013F9 call @ILT+15(ReadPEFile) (00401014)
004013FE add esp,8 //调用者平衡堆栈
结构体类型汇编赋值分析
图有点重合,下面附上一样的代码
说明:
PIMAGE_NT_HEADERS 是一个结构,pNtHeader是它的一个变量。
要取pNtHeader结构体里面的变量,汇编里面分两步取
一,先取得结构体变量pNtHeader的地址值
二,根据偏移取值,如下是50h。(由上图右下角的结果做差可验证)
ImageSize = pNtHeader->OptionalHeader.SizeOfImage;
0040142C mov eax,dword ptr [ebp-10h] //[ebp-10h]是存储pNtHeader的地址
0040142F mov ecx,dword ptr [eax+50h] //取出结构体偏移的值
00401432 mov dword ptr [ebp-20h],ecx
for 循环执行流
删除了一些无关执行流的代码如下(注释说明执行流过程)
for(int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++)
00401475 mov dword ptr [ebp-24h],0 //int i = 0;
0040147C jmp CopyFileBufferToImageBuffer+0E7h (00401487)
0040147E mov ecx,dword ptr [ebp-24h] // i++
00401481 add ecx,1
00401484 mov dword ptr [ebp-24h],ecx
00401487 mov edx,dword ptr [ebp-10h] // i < 判断 (00401487)
0040148A xor eax,eax
0040148C mov ax,word ptr [edx+6]
00401490 cmp dword ptr [ebp-24h],eax
00401493 jge CopyFileBufferToImageBuffer+142h (004014e2) //与for中判断条件相反
135: }
004014E0 jmp CopyFileBufferToImageBuffer+0DEh (0040147e) //向上回到执行i++与i<的判断流程中