分类: C/C++
2008-09-24 11:40:53
VC6下的几行简单的代码:
|
对应的汇编代码:
|
1.
EBP是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:
push ebp ;保存当前ebp
mov ebp,esp ;EBP设为当前堆栈指针
sub esp, xxx ;预留xxx字节给函数临时变量.减小stack的指针(注意,stack是从内存的高端向低端生长的),为局部变量保留一些空间,这里的44h不是固定的,由编译器计算得来
...
这样一来,EBP 构成了该函数的一个框架, 在EBP上方分别是原来的EBP, 返回地址和参数. EBP下方则是临时变量. 函数返回时作:
mov esp,ebp即可.恢复esp,ebp,这时函数的返回地址就在栈顶,调用ret就可以返回了。
2.
00401016 push ebx
00401017 push esi
00401018 push edi
EBX是"基地址"(base)寄存器, 在内存寻址时存放基地址.ESI/EDI分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.
3.
00401019 lea edi,[ebp-44h]
0040101C mov ecx,11h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
用0xCC填充局部变量空间。这是Debug模式特有的,如果是字符串,你就看到被初始化成"烫烫烫烫烫烫"
4.
00401028 mov dword ptr [ebp-4],5
[ebp-4]就是第一个局部变量a了
5.
0040102F xor eax,eax
函数的结果都是放在eax中(ps:你可以在vc的watch窗口输入@EAX,就可以直接看到函数返回值了)