在这种情况下,您需要编辑传递给的字符串 printf ,但首先我们需要得到它的地址。看广告代码来电话 printf ,我们将看到类似的内容:
printf
PUSH mymodule.1234567 CALL printf ADD ESP,4
所以,如果我们去地址 0x1234567 ,通过 CTRL + G ,我们会看到:
0x1234567
01234567 48 65 6C 6C 6F 20 57 6F 72 6C 64 0A 00 00 00 00 Hello World.....
所以现在您可以将该字符串编辑为您想要的任何内容,只要您不溢出可用空间并保留空终止符即可。
保存更改取决于您如何加载二进制文件(通过附加或只是冷查看),最简单的方法是通过冷查看(使用olly纯粹作为反汇编程序/汇编程序)。它通过访问 view -> file 然后右键单击并选择 disassemble 从上下文菜单中。在此模式下,通过右键单击并选择来完成保存 save file 从上下文菜单中。
view -> file
disassemble
save file
在调试器模式下(也称为连接时),使用右键单击完成保存,然后从中选择一个选项 copy to executable 上下文菜单选项。
copy to executable
如果您正在调试GCC生成的代码,它通常会避免生成 PUSH 使用的是将变量直接放入堆栈中 MOV [ESP+c],c/r/m 。用GCC编译你的例子,你会看到类似的代码(for main ):
PUSH
MOV [ESP+c],c/r/m
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
重要的是要注意GCC优化了调用 printf 打电话给 puts 。在这样的情况下,您知道要查找的字符串,可以在调试器模式下使用olly,右键单击并选择 search for -> all referenced text strings ,然后从列表中简单地选择所需的字符串以查找使用它的代码,或者按照其地址查找它 .data 部分条目,以便您可以更改它。找到它的更长方法是使用右键单击上下文菜单中提供的二进制搜索,但这通常是文本字符串的浪费。
puts
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
从这里我们看到唯一可行的呼叫 GCCOllyT.00401000 在那之后,我们到此为止(这是海湾合作委员会 mainCRTstartup ):
GCCOllyT.00401000
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
现在我们知道了呼叫的签名 main 需要3个参数,我们也知道它会被调用 之前 应用程序清理并退出,因此我们得到 GCCOllyT.00401AFC 。正如您所看到的,启用符号需要付出很大的代价,这可以通过调试选项菜单的反汇编部分来完成。
GCCOllyT.00401AFC