在我的简单C程序上进行逆向工程

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.正如您所看到的,启用符号需要付出很大的代价,这可以通过调试选项菜单的反汇编部分来完成.