-
-
[旧帖]
[原创](申请邀请码)本人在csdn上回复的一帖子(邀请码已发)
0.00雪花
-
发表于:
2009-9-8 14:26
1346
-
[旧帖] [原创](申请邀请码)本人在csdn上回复的一帖子(邀请码已发)
0.00雪花
【原创】在csdn回复的一篇帖子(申请邀请码)
以下是本人在csdn汇编语言论坛回复的一片帖子及其解决方法的详细解释,希望大家能多多关注,有不对的地方多多指教。另外想通过本贴获得梦寐以求的看雪论坛的邀请码,希望能得到版主大人的垂青,呵呵。
帖子主题:关于函数跳转的问题
发问贴帖子原文:
这样的,我在弄一个函数跳转
就是说 main 里面调用 A, 而A里面执行完了,本来要返回到main的,现在我通过一些试把返回地址改了
让它返回A时,跳到函数 B里面去了,,,但是跳到B里面去了,我没办法 再返回 main了
也就是恢复不了程序正确执行流程了
Assembly code:
int funAdd( int a, int b )
{
int nR = 0;
__asm{
mov ecx, [ebp+4];//我知道了,ebp+4 不是函数要返回时的地址 //这里我替换为funDel的地址
lea eax, [ebp+4];//得到栈里面的函数返回地址的地址
mov ebx, dword ptr[a];//要返回的地址,在参数a里面;;
mov [eax],ebx;//这里窜改掉 funAdd的返回地址,让返回的EIP指向 funDel函数的地址
mov ebx,dword ptr
;
mov dword ptr[nR],ecx;//把原来的真正的返回地址保存到ECX里面
}
return nR;
}//这里返回了,并没有返回到main函数里面,而是执行了一条jmp指令
int funDel()
{
//我调试时,当funAdd返回时,跳到了一条 jmp funDel(XXXXXX)汇编代码,XXXXXX正好是函数的 //funDel地址
//看来CPU已经间接执行到这里了;;
//现在问题出来了,我想返回到main函数里面调用call dword ptr[fA]的下一条指令,
//就是返不回去了;;麻烦大家指点吓
return 0;
}
int main(int,char**)
{
int fA = (int)&funAdd;
int rs = 0;
int fD = (int)&funDel;
__asm{
push dword ptr[fD];
push dword ptr[fD];
call dword ptr[fA];
mov rs,eax; //我希望funDel返回,自动返到这里
add esp,8;
};
return 0;
}
以下是我的解决问题的代码及其详细解释:
#include <stdio.h>
int address=0; //用于存储在main函数中要返回到的地址(注意要用全局变量)
int funAdd( int a, int b )
{ //请参考下面用od反汇编出的代码
int nR = 0;
__asm{
mov ecx, [ebp+4];//应当返回到的地址的值,存入ecx
lea eax, [ebp+4];//应当返回到的地址的值的地址即ebp+4,存入eax
mov ebx, dword ptr[a];//第一个参数的值既要返回的地址入ebx
mov [eax],ebx;//将应当返回到的地址替换为ebx
mov ebx,dword ptr;
mov dword ptr[nR],ecx;
}
return nR;
}
int funDel()
{
__asm{
lea eax,[ebp+4];//将应当返回到的地址值的地址存入eax
mov ebx,address;//将要返回到main中的地址存入ebx
add ebx,7;//这里是关键,由于楼主要返回到main中add esp,8
//address中存储的是pop eax指令的地址,而他们之间有
//pop eax(反汇编码占两个字节),mov address,eax(两个字节),call dword //ptr【fA】(三个),所以加7
mov [eax],ebx;//替换地址
}
return 0;
}
int main(int,char**)
{
int fA = (int)&funAdd;
int rs = 0;
int fD = (int)&funDel;
_asm{
push dword ptr [fD];
push dword ptr [fD];
call find //这里是关键,eip已指向pop eax,将eip入栈
find:
pop eax;//将地址值弹入eax
mov address,eax;//存入address
call dword ptr [fA];
add esp,8;
};
printf("success !");
return 0;
}
od反汇编源码:(有了上面的讲解,相信大家都能看懂)
请大家注意,代码没有优化 !
funAdd():
00401030 /> 55 PUSH EBP
00401031 |. 8BEC MOV EBP,ESP
00401033 |. 83EC 44 SUB ESP,44
00401036 |. 53 PUSH EBX
00401037 |. 56 PUSH ESI
00401038 |. 57 PUSH EDI
00401039 |. 8D7D BC LEA EDI,DWORD PTR SS:[EBP-44]
0040103C |. B9 11000000 MOV ECX,11
00401041 |. B8 CCCCCCCC MOV EAX,CCCCCCCC
00401046 |. F3:AB REP STOS DWORD PTR ES:[EDI]
00401048 |. C745 FC 000000>MOV DWORD PTR SS:[EBP-4],0
0040104F |. 8B4D 04 MOV ECX,DWORD PTR SS:[EBP+4]
00401052 |. 8D45 04 LEA EAX,DWORD PTR SS:[EBP+4]
00401055 |. 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+8]
00401058 |. 8918 MOV DWORD PTR DS:[EAX],EBX
0040105A |. 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C]
0040105D |. 894D FC MOV DWORD PTR SS:[EBP-4],ECX
00401060 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00401063 |. 5F POP EDI
00401064 |. 5E POP ESI
00401065 |. 5B POP EBX
00401066 |. 83C4 44 ADD ESP,44
00401069 |. 3BEC CMP EBP,ESP
0040106B |. E8 F0000000 CALL test.00401160
00401070 |. 8BE5 MOV ESP,EBP
00401072 |. 5D POP EBP
00401073 \. C3 RETN
funDel()
00401090 /> 55 PUSH EBP
00401091 |. 8BEC MOV EBP,ESP
00401093 |. 83EC 40 SUB ESP,40
00401096 |. 53 PUSH EBX
00401097 |. 56 PUSH ESI
00401098 |. 57 PUSH EDI
00401099 |. 8D7D C0 LEA EDI,DWORD PTR SS:[EBP-40]
0040109C |. B9 10000000 MOV ECX,10
004010A1 |. B8 CCCCCCCC MOV EAX,CCCCCCCC
004010A6 |. F3:AB REP STOS DWORD PTR ES:[EDI]
004010A8 |. 8D45 04 LEA EAX,DWORD PTR SS:[EBP+4]
004010AB |. 8B1D 487C4200 MOV EBX,DWORD PTR DS:[427C48]
004010B1 |. 83C3 07 ADD EBX,7
004010B4 |. 8918 MOV DWORD PTR DS:[EAX],EBX
004010B6 |. 33C0 XOR EAX,EAX
004010B8 |. 5F POP EDI
004010B9 |. 5E POP ESI
004010BA |. 5B POP EBX
004010BB |. 83C4 40 ADD ESP,40
004010BE |. 3BEC CMP EBP,ESP
004010C0 |. E8 9B000000 CALL test.00401160
004010C5 |. 8BE5 MOV ESP,EBP
004010C7 |. 5D POP EBP
004010C8 \. C3 RETN
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!