(reversing)return 到 c 中的指定位置,程序集
(reversing)return to specified location in c , assembly
我想修改下面的c代码和汇编代码只弹出一个消息框。
现在弹出'failed'消息框然后弹出'success'消息框但我想知道"Func"函数后只弹出'success'消息框的方法叫做。
我得到一个提示,答案与"RET(assembly)"有关,我不知道如何修改汇编代码和c代码。
RET 是前一个函数的 return 地址,不是吗?那么如何在代码的任一侧更改此值?
我知道 RET 是在调用 Func 函数之前保存的,所以我该怎么做???请有人帮助我!
#include <windows.h>
#include <stdio.h>
void Func(int n1, char ch) {
int sum;
sum = n1 + ch;
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) {
Func(10, 'A');
MessageBox(0, "Failed", "", 0);
MessageBox(0, "Success", "", 0);
return 0;
}
编译了 c 代码,在 ollydbg 中看起来像这样。
// Func
00401000 /$ 55 PUSH EBP
00401001 |. 8BEC MOV EBP,ESP
00401003 |. 51 PUSH ECX
00401004 |. 0FBE45 0C MOVSX EAX,BYTE PTR SS:[EBP+C]
00401008 |. 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8]
0040100B |. 03C8 ADD ECX,EAX
0040100D |. 894D FC MOV DWORD PTR SS:[EBP-4],ECX
00401010 |. 8BE5 MOV ESP,EBP
00401012 |. 5D POP EBP
00401013 \. C3 RETN
// WinMain
00401014 /$ 55 PUSH EBP
00401015 |. 8BEC MOV EBP,ESP
00401017 |. 6A 41 PUSH 41 ; /Arg2 = 00000041
00401019 |. 6A 0A PUSH 0A ; |Arg1 = 0000000A
0040101B |. E8 E0FFFFFF CALL test.00401000 ; \test.00401000
00401020 |. 83C4 08 ADD ESP,8
00401023 |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401025 |. 68 A0544000 PUSH test.004054A0 ; |Title = ""
0040102A |. 68 30504000 PUSH test.00405030 ; |Text = "Failed"
0040102F |. 6A 00 PUSH 0 ; |hOwner = NULL
00401031 |. FF15 94404000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00401037 |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401039 |. 68 A4544000 PUSH test.004054A4 ; |Title = ""
0040103E |. 68 38504000 PUSH test.00405038 ; |Text = "Success"
00401043 |. 6A 00 PUSH 0 ; |hOwner = NULL
00401045 |. FF15 94404000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
0040104B |. 33C0 XOR EAX,EAX
0040104D |. 5D POP EBP
0040104E \. C2 1000 RETN 10
这些 __stdcall、__cdecl、__fastcall 函数是否与此问题相关?
或者也许是 RETN 论点?
如果我理解正确你的问题 - 你需要修改你的 C 代码来使一个 MessageBox
调用消失,而不是从源代码中删除一个调用。最简单的方法是修改函数 return 地址以直接跳转到第二个 MessageBox
。让我们用一个简单的例子来说明这种方法。
#include <stdio.h>
void test(){}
int main(void)
{
test();
printf("%s\n", "test1");
printf("%s\n", "test2");
return(0);
}
main
函数的反汇编(相关):
来自 test
函数的 Return 地址将是 011B17F3
。如果我们想跳过第一个 printf
调用,我们希望它是 011B1805
。所以它必须增加 0x12
.
为此,我们必须从堆栈中检索保存的 return 地址,增加它,然后将其写回。
void test()
{
__asm
{
mov eax, [ebp+4]
add eax, 0x12
mov [ebp+4], eax
}
}
我想修改下面的c代码和汇编代码只弹出一个消息框。 现在弹出'failed'消息框然后弹出'success'消息框但我想知道"Func"函数后只弹出'success'消息框的方法叫做。
我得到一个提示,答案与"RET(assembly)"有关,我不知道如何修改汇编代码和c代码。 RET 是前一个函数的 return 地址,不是吗?那么如何在代码的任一侧更改此值?
我知道 RET 是在调用 Func 函数之前保存的,所以我该怎么做???请有人帮助我!
#include <windows.h>
#include <stdio.h>
void Func(int n1, char ch) {
int sum;
sum = n1 + ch;
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) {
Func(10, 'A');
MessageBox(0, "Failed", "", 0);
MessageBox(0, "Success", "", 0);
return 0;
}
编译了 c 代码,在 ollydbg 中看起来像这样。
// Func
00401000 /$ 55 PUSH EBP
00401001 |. 8BEC MOV EBP,ESP
00401003 |. 51 PUSH ECX
00401004 |. 0FBE45 0C MOVSX EAX,BYTE PTR SS:[EBP+C]
00401008 |. 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8]
0040100B |. 03C8 ADD ECX,EAX
0040100D |. 894D FC MOV DWORD PTR SS:[EBP-4],ECX
00401010 |. 8BE5 MOV ESP,EBP
00401012 |. 5D POP EBP
00401013 \. C3 RETN
// WinMain
00401014 /$ 55 PUSH EBP
00401015 |. 8BEC MOV EBP,ESP
00401017 |. 6A 41 PUSH 41 ; /Arg2 = 00000041
00401019 |. 6A 0A PUSH 0A ; |Arg1 = 0000000A
0040101B |. E8 E0FFFFFF CALL test.00401000 ; \test.00401000
00401020 |. 83C4 08 ADD ESP,8
00401023 |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401025 |. 68 A0544000 PUSH test.004054A0 ; |Title = ""
0040102A |. 68 30504000 PUSH test.00405030 ; |Text = "Failed"
0040102F |. 6A 00 PUSH 0 ; |hOwner = NULL
00401031 |. FF15 94404000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00401037 |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401039 |. 68 A4544000 PUSH test.004054A4 ; |Title = ""
0040103E |. 68 38504000 PUSH test.00405038 ; |Text = "Success"
00401043 |. 6A 00 PUSH 0 ; |hOwner = NULL
00401045 |. FF15 94404000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
0040104B |. 33C0 XOR EAX,EAX
0040104D |. 5D POP EBP
0040104E \. C2 1000 RETN 10
这些 __stdcall、__cdecl、__fastcall 函数是否与此问题相关? 或者也许是 RETN 论点?
如果我理解正确你的问题 - 你需要修改你的 C 代码来使一个 MessageBox
调用消失,而不是从源代码中删除一个调用。最简单的方法是修改函数 return 地址以直接跳转到第二个 MessageBox
。让我们用一个简单的例子来说明这种方法。
#include <stdio.h>
void test(){}
int main(void)
{
test();
printf("%s\n", "test1");
printf("%s\n", "test2");
return(0);
}
main
函数的反汇编(相关):
test
函数的 Return 地址将是 011B17F3
。如果我们想跳过第一个 printf
调用,我们希望它是 011B1805
。所以它必须增加 0x12
.
为此,我们必须从堆栈中检索保存的 return 地址,增加它,然后将其写回。
void test()
{
__asm
{
mov eax, [ebp+4]
add eax, 0x12
mov [ebp+4], eax
}
}