GCC 4.92
默认优化 -Os
dwecx = 0x6ccc7ecb;
dwcall = dwso + 0x123456;
asm(“mov %1,%%ecx;call %0”::“m”(dwcall),“m”(dwecx));
dwcall = dwso + 0x777777;
asm(“pushl $0;mov %1,%%ecx;call %0”::“m”(dwcall),“m”(dwecx));
编译后的反汇编代码
lea edx, dword ptr ds:[eax+0x123456]
sub esp, 0x10
mov dword ptr ss:[esp+0x1C], eax
mov dword ptr ss:[esp+0x18], edx
mov ecx, dword ptr ss:[esp+0x1C]
call dword ptr ss:[esp+0x18]
add ebx, 0x777777
mov dword ptr ss:[esp+0x18], ebx
push 0x0
mov ecx, dword ptr ss:[esp+0x1C]
call dword ptr ss:[esp+0x18]
add esp, 0x28
pop ebx
retn
看红色代码,我 push 0 以后,esp-4 了,他传的局部变量地址没变,这样程序肯定是错的,应该是
push 0x0
mov ecx, dword ptr ss:[esp+0x20]
call dword ptr ss:[esp+0x1c]
搞得我途血啊啊啊啊!!!
关闭优化,他会默认使用 ebp-XXX,这样就不会出现这个错误了
唠叨一句,这 AT&T 语法的汇编看得我蛋疼,眼都花了,要是能支持 intel 格式的汇编语法该多好,简洁干净
再看
mov dword ptr ss:[esp+0xC], 0x40 ; |
mov dword ptr ss:[esp+0x8], 0x1000 ; |
mov dword ptr ss:[esp+0x4], 0x95D0 ; |
mov dword ptr ss:[esp], 0x0 ; |
我承认这样传参数调用 api 速度快,但是我关闭了优化你好歹也把 push 体现出来啊,我保存寄存器值用的 push %eax,丫自作聪明把我保存的数据直接 mov esp 抹掉了!!!