用变量替换静态值

逆向工程 拆卸 ollydbg 指针
2021-06-11 07:44:18

我正在尝试替换静态值:

MOV DWORD PTR SS:[EBP-30],4c

使用来自特定地址的值:

MOV DWORD PTR SS:[EBP-30],400400 // MOV DWORD PTR SS:[EBP-30],OFFSET 400400

SS:[EBP-30]没有被设置为来自 的值0x400400

我是新手,但我认为这会起作用:

MOV DWORD PTR SS:[EBP-30],DWORD PTR DS:[400400]

但我想不是因为ollydbg给出了错误。

来自的值0x400400int 10064 00 00 00为什么不起作用?我的选择是什么?

我也在考虑做类似的事情:

MOV ECX,DWORD PTR DS:[400400]
MOV DWORD PTR SS:[EBP-30],ECX

但是我不知道如何在ollydbg中添加新的指令我也担心它会更改所有地址。

2个回答

让我们把它分开一点。我会跳过一些你可能已经理解的东西,但如果有些东西不清楚,我们可能需要扩展它。


MOV DWORD PTR SS:[EBP-30],400400

MOV DWORD PTR SS:[EBP-30],DWORD PTR DS:[400400]

语法有点奇怪,但我们可以理解您想MOV用两个内存操作数对 a 进行编码我们来看看一些文档

参考:https : //www.felixcloutier.com/x86/MOV.html

没有可能的编码来MOV接受m32,m32随着m32理解为是一个32位的指针。

这种情况并不明显,但不幸的是。

参考:https : //stackoverflow.com/a/33799523/10279341

如果您关心为什么这是一个很好的答案,但它只是补充阅读,对这种情况并不重要。


因此,如果我们想使用 x86 将内存复制到内存中:

参考:https : //stackoverflow.com/a/1299094/10279341

普遍接受的解决方案是使用寄存器作为临时值存储。

请注意,我们需要保存正在使用的寄存器的状态,否则我们可能会意外更改程序状态。

MOV ECX,DWORD PTR DS:[400400]

MOV DWORD PTR SS:[EBP-30],ECX

所以这是在正确的轨道上。但是我们需要ECX事先保存以防其他人正在使用它。

0x00000000: 51                  push ecx
0x00000001: 8b 0d 00 04 40 00   mov ecx, dword ptr [0x400400]
0x00000007: 89 4d e2            mov dword ptr [ebp - 0x1e], ecx
0x0000000a: 59                  pop ecx

这应该做你想要的。我们ECX通过将其压入堆栈来保存将地址处的值加载0x400400ECX. 然后将 的值写入ECX内存中[EBP-0x1E],然后恢复ECX到之前的值。


那么我们如何将其修补到二进制图像中呢?

上面的程序集长度为 11 个字节,我们的目标是更改指令

0: c7 45 e2 4c 00 00 00 mov DWORD PTR [ebp-0x1e],0x4c

我们可以看到有 7 个字节长。

我们可以通过使用“代码洞穴”来获得这些额外的 4 个字节。我们将执行重定向到未使用的内存位,执行我们的代码,然后跳回。

参考:https : //www.codeproject.com/Articles/20240/The-Beginners-Guide-to-Codecaves

简而言之,我们正在寻找在 exe 映像中分配/映射的“空白空间”,最好在 .text 部分,但在任何情况下都不会被程序使用由于默认情况下 Windows PE 中的 SectionAlignment 为 4096,这几乎会出现在每个可执行映像中。

实现这一点的最简单方法是在我们试图修改的同一内存区域中找到未使用的字节。

使用 ollydbg 查找/应用代码洞的基本方法如下所示:

https://medium.com/@vysec.private/backdoor-101-f318110e1fcb


在为我们的洞穴找到合适的内存后,在 shellcode 中打补丁:

0x00000000: 51                  push ecx
0x00000001: 8b 0d 00 04 40 00   mov ecx, dword ptr [0x400400]
0x00000007: 89 4d e2            mov dword ptr [ebp - 0x1e], ecx
0x0000000a: 59                  pop ecx

使用 ollydbg 的汇编程序。

然后改变的原始指令mov DWORD PTR [ebp-0x1e],0x4cJMP x哪里x是你的shellcode地址,同一模块/形象。

如果需要,用 0x90 (NOP) 覆盖其余的指令字节。所以我们最终得到:

c7 45 e2 4c 00 00 00 - 原始说明

e9 xx xx xx xx 90 90 - JMP rel32 加 2 个 NOP

x86 JMP 参考:https : //c9x.me/x86/html/file_module_x86_id_147.html

之后,pop ecx在我们的代码洞穴回来组装:JMP y

其中y是紧跟在 之后的指令地址mov DWORD PTR [ebp-0x1e],0x4c当你跳出代码洞时,你最终应该跳过 NOP 指令,这就是为什么我说它们是可选的。


概括,

  1. 组装我们的 shellcode,记录正确的 x86 ASM 并保留程序状态。

  2. 如果没有足够的空间来修补内嵌指令,请识别代码洞穴。

  3. 应用代码洞并组装两条JMP指令以将执行 (1) 重定向到代码洞,(2) 返回到原始代码下一条指令。

内存到内存MOV不存在。您可以尝试以下操作:

    MOV eax, DWORD PTR DS : [400400]
    MOV DWORD PTR SS : [EBP - 30], eax

另请检查绝对数字是否在您的汇编程序中被解释为十六进制值。