fun*_*err 6 reverse-engineering ollydbg
我想开始学习逆向工程.所以我决定开始简单.我创建了这个简单的程序:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf ("Hello World!\n");
system("PAUSE");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在Ollydbg中将其分解.所以我想尝试将printf更改为"World Hello".但我现在不知道该怎么做.你能指导我,或者至少告诉我理论上应该做些什么吗?
Nec*_*lis 11
在这种情况下,您需要编辑传递给的字符串printf,但首先我们需要获取其地址.通过查看广告代码printf,我们将看到类似的内容:
PUSH mymodule.1234567
CALL printf
ADD ESP,4
Run Code Online (Sandbox Code Playgroud)
所以如果我们去地址0x1234567,通过ctrl+ g,我们会看到:
01234567 48 65 6C 6C 6F 20 57 6F 72 6C 64 0A 00 00 00 00 Hello World.....
Run Code Online (Sandbox Code Playgroud)
所以现在您可以将该字符串编辑为您想要的任何内容,只要您不溢出可用空间并保留空终止符即可.
保存更改取决于您如何加载二进制文件(通过附加或只是冷查看),最简单的方法是通过冷查看(使用olly纯粹作为反汇编程序/汇编程序).通过view -> file右键单击并disassemble从上下文菜单中选择它的访问权限.在此模式下,通过右键单击并save file从上下文菜单中选择来完成保存.
在调试器模式下(也称为连接时),使用右键单击完成保存,然后从copy to executable上下文菜单选项中选择一个选项.
如果您正在调试GCC生成的代码,它通常会避免生成PUSH并且有利于将变量直接放入堆栈中MOV [ESP+c],c/r/m.使用GCC编译您的示例,您会看到类似于(for main)的代码:
00401AFC /$ PUSH EBP
00401AFD |. MOV EBP,ESP
00401AFF |. AND ESP,FFFFFFF0
00401B02 |. SUB ESP,10
00401B05 |. CALL GCCOllyT.0040182C
00401B0A |. MOV DWORD PTR SS:[ESP],GCCOllyT.00403024 ; ||ASCII "Hello World!"
00401B11 |. CALL <JMP.&msvcrt.puts> ; |\puts
00401B16 |. MOV DWORD PTR SS:[ESP],GCCOllyT.00403031 ; |ASCII "PAUSE"
00401B1D |. CALL <JMP.&msvcrt.system> ; \system
00401B22 |. XOR EAX,EAX
00401B24 |. LEAVE
00401B25 \. RETN
Run Code Online (Sandbox Code Playgroud)
这里重要的是要注意GCC优化了对呼叫printf的调用puts.在这种情况下你知道你正在寻找的字符串,你可以在调试器模式下使用olly,右键单击并选择search for -> all referenced text strings,然后从列表中简单地选择你想要的字符串以找到使用它的代码,或者按照其地址来找到它的.data部分条目,以便您可以更改它.找到它的更长方法是使用右键单击上下文菜单中提供的二进制搜索,但这通常是文本字符串的浪费.
为了涵盖所有基础,我们假设我们需要从入口点获取代码.如果我们从模块入口点导航到代码,我们将遵循这样的链:
GCCOllyT.<ModuleEntryPoint> 0> $ >PUSH EBP
0040126D . >MOV EBP,ESP
0040126F . >SUB ESP,18
00401272 . >MOV DWORD PTR SS:[ESP],1
00401279 . >CALL DWORD PTR DS:[<&msvcrt.__set_app_type>; msvcrt.__set_app_type
0040127F . >CALL GCCOllyT.00401000
00401284 . >PUSH EBP
00401285 . >MOV EBP,ESP
00401287 . >SUB ESP,18
0040128A . >MOV DWORD PTR SS:[ESP],2
00401291 . >CALL DWORD PTR DS:[<&msvcrt.__set_app_type>; msvcrt.__set_app_type
00401297 . >CALL GCCOllyT.00401000
0040129C $ >PUSH EBP
0040129D . >MOV EBP,ESP
0040129F . >SUB ESP,8
004012A2 . >MOV EAX,DWORD PTR DS:[<&msvcrt.atexit>]
004012A7 . >LEAVE
004012A8 . >JMP EAX
Run Code Online (Sandbox Code Playgroud)
从这里我们看到唯一可行的呼叫GCCOllyT.00401000,在此之后,我们最终在这里(这是GCC mainCRTstartup):
00401000 /$ >PUSH EBP
00401001 |. >MOV EBP,ESP
00401003 |. >PUSH EBX
00401004 |. >SUB ESP,34
00401007 |. >MOV EAX,DWORD PTR DS:[403038]
0040100C |. >TEST EAX,EAX
0040100E |. >JE SHORT GCCOllyT.0040102C
00401010 |. >MOV DWORD PTR SS:[ESP+8],0
00401018 |. >MOV DWORD PTR SS:[ESP+4],2
00401020 |. >MOV DWORD PTR SS:[ESP],0
00401027 |. >CALL EAX
00401029 |. >SUB ESP,0C
0040102C |> >MOV DWORD PTR SS:[ESP],GCCOllyT.00401110 ; |
00401033 |. >CALL <JMP.&KERNEL32.SetUnhandledExceptionFilter> ; \SetUnhandledExceptionFilter
00401038 |. >PUSH EAX
00401039 |. >CALL GCCOllyT.004013CC
0040103E |. >CALL GCCOllyT.004014AC
00401043 |. >MOV DWORD PTR SS:[EBP-10],0
0040104A |. >LEA EAX,DWORD PTR SS:[EBP-10]
0040104D |. >MOV DWORD PTR SS:[ESP+10],EAX
00401051 |. >MOV EAX,DWORD PTR DS:[402000]
00401056 |. >MOV DWORD PTR SS:[ESP+C],EAX
0040105A |. >LEA EAX,DWORD PTR SS:[EBP-C]
0040105D |. >MOV DWORD PTR SS:[ESP+8],EAX
00401061 |. >MOV DWORD PTR SS:[ESP+4],GCCOllyT.00404004
00401069 |. >MOV DWORD PTR SS:[ESP],GCCOllyT.00404000
00401070 |. >CALL <JMP.&msvcrt.__getmainargs>
00401075 |. >MOV EAX,DWORD PTR DS:[404018]
0040107A |. >TEST EAX,EAX
0040107C |. >JNZ SHORT GCCOllyT.004010C8
0040107E |> >CALL <JMP.&msvcrt.__p__fmode>
00401083 |. >MOV EDX,DWORD PTR DS:[402004]
00401089 |. >MOV DWORD PTR DS:[EAX],EDX
0040108B |. >CALL GCCOllyT.004015E4
00401090 |. >AND ESP,FFFFFFF0
00401093 |. >CALL GCCOllyT.0040182C
00401098 |. >CALL <JMP.&msvcrt.__p__environ>
0040109D |. >MOV EAX,DWORD PTR DS:[EAX]
0040109F |. >MOV DWORD PTR SS:[ESP+8],EAX
004010A3 |. >MOV EAX,DWORD PTR DS:[404004]
004010A8 |. >MOV DWORD PTR SS:[ESP+4],EAX
004010AC |. >MOV EAX,DWORD PTR DS:[404000]
004010B1 |. >MOV DWORD PTR SS:[ESP],EAX
004010B4 |. >CALL GCCOllyT.00401AFC
004010B9 |. >MOV EBX,EAX ; |
004010BB |. >CALL <JMP.&msvcrt._cexit> ; |[msvcrt._cexit
004010C0 |. >MOV DWORD PTR SS:[ESP],EBX ; |
004010C3 |. >CALL <JMP.&KERNEL32.ExitProcess> ; \ExitProcess
004010C8 |> >MOV DWORD PTR DS:[402004],EAX ; |||
004010CD |. >MOV DWORD PTR SS:[ESP+4],EAX ; |||
004010D1 |. >MOV EBX,DWORD PTR DS:[<&msvcrt._iob>] ; |||msvcrt._iob
004010D7 |. >MOV EAX,DWORD PTR DS:[EBX+10] ; |||
004010DA |. >MOV DWORD PTR SS:[ESP],EAX ; |||
004010DD |. >CALL <JMP.&msvcrt._setmode> ; ||\_setmode
004010E2 |. >MOV EAX,DWORD PTR DS:[404018] ; ||
004010E7 |. >MOV DWORD PTR SS:[ESP+4],EAX ; ||
004010EB |. >MOV EAX,DWORD PTR DS:[EBX+30] ; ||
004010EE |. >MOV DWORD PTR SS:[ESP],EAX ; ||
004010F1 |. >CALL <JMP.&msvcrt._setmode> ; |\_setmode
004010F6 |. >MOV EAX,DWORD PTR DS:[404018] ; |
004010FB |. >MOV DWORD PTR SS:[ESP+4],EAX ; |
004010FF |. >MOV EAX,DWORD PTR DS:[EBX+50] ; |
00401102 |. >MOV DWORD PTR SS:[ESP],EAX ; |
00401105 |. >CALL <JMP.&msvcrt._setmode> ; \_setmode
0040110A \.^>JMP GCCOllyT.0040107E
Run Code Online (Sandbox Code Playgroud)
现在我们知道调用的签名main需要3个args,我们也知道它会在 app清理和退出之前被调用,因此我们得到了GCCOllyT.00401AFC.正如您所看到的,启用符号需要付出很大的代价,这可以通过调试选项菜单的反汇编部分来完成.