gpt4 book ai didi

reverse-engineering - 对我的简单 C 程序进行逆向工程

转载 作者:行者123 更新时间:2023-12-04 08:08:51 28 4
gpt4 key购买 nike

我想开始学习逆向工程。
所以我决定从简单的开始。
我创建了这个简单的程序:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
printf ("Hello World!\n");
system("PAUSE");
return 0;
}

我在 Ollydbg 中对它进行了伪装。
所以我想尝试将 printf 更改为“World Hello”。
但我不知道现在该怎么办。
你能指导我,或者至少告诉我理论上应该做什么吗?

最佳答案

在这种情况下,您需要编辑传递给 printf 的字符串,但首先我们需要获取它的地址。查看调用 printf 的代码,我们将看到类似以下内容的内容:

PUSH mymodule.1234567
CALL printf
ADD ESP,4

因此,如果我们通过 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 来完成保存。

在调试器模式下(也就是附加时),使用右键单击并从 copy to executable 上下文菜单选项中选择一个选项来完成保存。

更新

如果您正在调试 GCC 生成的代码,它通常会避免生成 PUSH 并倾向于使用 MOV [ESP+c],c/r/m 将变量直接放入堆栈。使用 GCC 编译您的示例,您会看到类似于(对于 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 部分条目,以便您可以更改它。找到它的更长方法是使用右键单击上下文菜单中可用的二进制搜索,但这通常是对文本字符串的浪费。

为了涵盖所有基础,假设我们需要从入口点获取代码。
如果我们从模块入口点导航到代码的位置,我们将像这样遵循链:
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 ,然后,我们到这里结束(这是 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

现在我们知道调用 main 的签名需要 3 个参数,我们也知道它将在应用程序清理和退出之前调用,因此我们得到 GCCOllyT.00401AFC 。如您所见,启用符号需要付出高昂的代价,这可以从调试选项菜单的反汇编部分完成。

关于reverse-engineering - 对我的简单 C 程序进行逆向工程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8672896/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com