对于《黑客反汇编揭密》第11章[反汇编防范技术]的示例242进行编译肯定是不能成功的,我把它完成如下:
/*
* FileName: CopyStack.c
* Edit: iawen
* Date: 2009/04/24
*/
#include
void Demo(int (*_printf)(const char *,...)){
_printf("Hello,World\n");
return;
}
int main(int argc,char *argv[]){
char buff[1000]; //所有变量提前声明
int a;
unsigned int func_len;
int (*_printf)(const char *,...);
int (*_main)(int,char **);
void (*_Demo)(int (*)(const char *,...));
_printf=printf;
_main=main; //及下面那句,是书本上忽略的
_Demo=Demo; //必须加上,不然出错。--不知道是印刷遗漏还是^&^……
func_len=(unsigned int)_main-(unsigned int)_Demo;
for(a=0;abuff[a]=((char*)_Demo)[a];
_Demo=(void(*)(int(*)(const char*,...)))&buff[0];
_Demo(_printf);
return 0;
}
在没有使用优化选项编译后得到的反汇编:
00401010 /$ 55 push ebp
00401011 |. 8BEC mov ebp,esp
00401013 |. 81EC 04040000 sub esp,404
00401019 |. A1 10C04000 mov eax,dword ptr ds:[40C010]
0040101E |. 33C5 xor eax,ebp
00401020 |. 8945 F4 mov dword ptr ss:[ebp-C],eax
00401023 |. C785 00FCFFFF A41040>mov dword ptr ss:[ebp-400],CopyStac>; _printf=printf//;004010A4
0040102D |. C785 04FCFFFF 101040>mov dword ptr ss:[ebp-3FC],CopyStac>; _main=main//即入口地址:00401010
00401037 |. C745 FC 00104000 mov dword ptr ss:[ebp-4],CopyStac.0>; _Demo=Demo//即:00401000
0040103E |. 8B85 04FCFFFF mov eax,dword ptr ss:[ebp-3FC]
00401044 |. 2B45 FC sub eax,dword ptr ss:[ebp-4]
00401047 |. 8985 FCFBFFFF mov dword ptr ss:[ebp-404],eax
0040104D |. C745 F8 00000000 mov dword ptr ss:[ebp-8],0
00401054 |. EB 09 jmp short CopyStac.0040105F
00401056 |> 8B4D F8 /mov ecx,dword ptr ss:[ebp-8]
00401059 |. 83C1 01 |add ecx,1
0040105C |. 894D F8 |mov dword ptr ss:[ebp-8],ecx
0040105F |> 8B55 F8 mov edx,dword ptr ss:[ebp-8]
00401062 |. 3B95 FCFBFFFF |cmp edx,dword ptr ss:[ebp-404]
00401068 |. 73 14 |jnb short CopyStac.0040107E
0040106A |. 8B45 FC |mov eax,dword ptr ss:[ebp-4]
0040106D |. 0345 F8 |add eax,dword ptr ss:[ebp-8]
00401070 |. 8B4D F8 |mov ecx,dword ptr ss:[ebp-8]
00401073 |. 8A10 |mov dl,byte ptr ds:[eax]
00401075 |. 88940D 08FCFFFF |mov byte ptr ss:[ebp+ecx-3F8],dl
0040107C |.^ EB D8 \jmp short CopyStac.00401056 ; for(a=0;a<func_len;a++)
0040107E |> 8D85 08FCFFFF lea eax,dword ptr ss:[ebp-3F8] ; buff[a]=((char*)_Demo)[a];
00401084 |. 8945 FC mov dword ptr ss:[ebp-4],eax
00401087 |. 8B8D 00FCFFFF mov ecx,dword ptr ss:[ebp-400]
0040108D |. 51 push ecx
0040108E |. FF55 FC call dword ptr ss:[ebp-4] ; _Demo(_printf);
00401091 |. 83C4 04 add esp,4
00401094 |. 33C0 xor eax,eax
00401096 |. 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
00401099 |. 33CD xor ecx,ebp
0040109B |. E8 C9000000 call CopyStac.00401169
004010A0 |. 8BE5 mov esp,ebp
004010A2 |. 5D pop ebp
004010A3 \. C3 retn
我们再看一下Demo函数:
00401000 /. 55 push ebp
00401001 |. 8BEC mov ebp,esp
00401003 |. 68 00C04000 push CopyStac.0040C000 ; ASCII "Hello,World
"
00401008 |. FF55 08 call dword ptr ss:[ebp+8]
0040100B |. 83C4 04 add esp,4
0040100E |. 5D pop ebp
0040100F \. C3 retn
在循环结束后,即运行到0040107E时,我们留意一下堆栈:
0012FB74 00000010
0012FB78 004010A4 CopyStac.004010A4
0012FB7C 00401010 入口地址
0012FB80 68EC8B55
0012FB84 0040C000 ASCII "Hello,World
"
0012FB88 830855FF
0012FB8C C35D04C4
0012FB90 02480248
0012FB94 02480248
这是在没有对buff初始化的情况下,里面填充了太多的垃圾,我们把buff初始化一下后,就得到:
0012FB74 00000010
0012FB78 004010C1 CopyStac.004010C1
0012FB7C 00401010 入口地址
0012FB80 68EC8B55
0012FB84 0040C000 ASCII "Hello,World
"
0012FB88 830855FF
0012FB8C C35D04C4
0012FB90 00000000
0012FB94 00000000