【问题标题】:Why do I receive access violation when writting to code segment in assembly?为什么在汇编中写入代码段时会收到访问冲突?
【发布时间】:2014-02-11 20:38:04
【问题描述】:

我正在通过将每个字节与某个键值进行异或来加密 PE 代码段的实验。到目前为止,我设法对该段进行异或,并在代码段的末尾注入二进制代码,该二进制代码再次通过异或以相同的值进行解码。当然,我还更新了 AddressOfEntryPoint 使其与解码器的地址相同。

但是当我计算要异或的第一个字节的地址时(它等于解码器之前的第一个字节 - 因为我会上升)并且我尝试这样做时收到访问冲突。

现在详细介绍:

1) 作为测试 PE,我使用纯 C++ 中的一些超级简单的控制台“hello world”应用程序

2) 注入的解码器代码用 NASM 汇编器编写,然后汇编成二进制,然后在测试 PE 的 .text 部分的末尾注入。其代码如下:

    call    get_proc            ; push return address

get_proc:
    pop     esi                 ; pop current address
    sub     esi, 0x5            ; esi = address of injected code, 0x5 = size of call instruction

    xor     ebx, ebx            ; clear registers
    xor     ecx, ecx            ;

    mov     bl,  <DECODER_KEY>  ; decoder key
    mov     ecx, <CODE_SIZE>    ; encoded code size

    sub     esi, ecx            ; esi = address of encoded code

decoder_loop:
    mov     edx, esi            ; construct encoded byte address
    add     edx, ecx            ;
    dec     edx                 ;
    xor     byte [cs:edx], bl   ; decode
    loop    decoder_loop        ; loop back

    jmp     esi                 ; jump back to decoded code

3) &lt;DECODER_KEY&gt;&lt;CODE_SIZE&gt; 被我的另一个正在执行注入的应用替换为(在组装之前)适当的值

4) 当第一次循环迭代通过时,最终的 EDX 值等于 call get_proc 之前的字节地址,使用免疫调试器检查

5) 在这里,我发布了一个屏幕截图,展示了我在尝试对第一个字节执行 XOR 时遇到访问冲突的情况(用红线标记了我在开头执行的注入代码)

6) 我知道,默认情况下代码段仅可读和可执行,但我的注入应用程序也添加了写权限。

7) 我使用的是 Windows 8.1 64 位

最后是问题:

A) 呈现的代码是否在执行我希望它执行的操作?

B) 对代码段添加写权限是否足以执行此操作(我知道有一些“写保护”机制,但我不知道任何细节)?

漏洞经常使用这种技术(或者至少他们曾经使用过),所以我想知道为什么这不起作用。另外我必须说,当我只删除 XOR 操作时,程序可以正常工作(所以计算的地址是正确的)。

编辑: 这是指向 PEdump 结果的链接:PEdump

【问题讨论】:

  • 您声称您的注入应用程序添加了写入权限,但没有显示任何证据。 XOR 引发 AV 的事实表明它实际上不可写。另请注意,写入代码段可能会导致您的程序被标记为恶意软件。
  • 我现在唯一能想到的证据是指向 PEdump 结果的链接:link 我在测试时也关闭了 AV。但是您在我的代码或其他假设中看到任何逻辑错误吗?
  • 您的 dbg 说 AV 正在读取地址 0xffffffff。如何?顺便说一句,你会破坏所有的重定位,所以使用IMAGE_FILE_RELOCS_STRIPPED 标志。
  • 这个 0xFFFFFFFF 是另一个好问题,我不知道为什么会这样......我对汇编程序很陌生,也许有一些错误。
  • 如果您是汇编程序新手,我建议您使用比代码修补更简单的方法来发展您的技能。这就像让您的驾驶学习者获得许可并决定驾驶 F1 赛车。

标签: windows assembly nasm portable-executable malware


【解决方案1】:

我找到了解决问题的方法。一般来说:汇编代码有一个错误——在异或运算中引用[cs:edx]是错误的,应该只是[edx]。为什么?

现在段寄存器似乎并没有像我们(或至少我)认为的那样。我听说以前它们被用作每个段的基地址,指令[cs:addr] 是代码段内的偏移量。

但是当您仔细查看我提供的照片中的段寄存器的值时,您会发现这些寄存器实际上是一些主要引用 0xFFFFFFFF 地址的描述符!当我从指令中删除 cs 时,它起作用了!但后来我将二进制文件加载到调试器中,令人惊讶的是它被翻译成ds:[edx]!再次,为什么是 DS(数据段)?那个我不知道。但是这个问题的教训应该是不要使用这些寄存器。

如果您不同意或有任何澄清,请评论此答案。

【讨论】:

  • 在 Win32 中,cs、ds 和 es 段选择器都映射到完整的地址空间,但是 cs 可能有一个标志集,阻止使用该选择器进行写入。
猜你喜欢
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
相关资源
最近更新 更多