在汇编时写入代码段时为什么会收到访问冲突?

时间:2014-02-11 20:38:05

标签: windows assembly nasm portable-executable malware

我正在通过使用一些键值对每个字节进行异或来进行加密PE代码段的实验。到目前为止,我设法对此段进行异或,并在代码段二进制代码的末尾注入,该代码段通过XORing再次使用相同的值进行解码。当然,我还将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)<DECODER_KEY><CODE_SIZE>被正在进行注射的另一个应用程序替换为(在组装之前)正确的值

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

5)在这里,当我尝试在第一个字节上执行XOR时,我发布了一个屏幕截图,显示我有访问冲突的情况(红线我标记了我在开始时执行的注入代码)enter image description here

6)我知道这样的事实,默认情况下代码段只是可读和可执行的,但我的注入应用程序也增加了写入权限。

7)我使用的是Windows 8.1 64位

最后问题:

A)代码是否按照我的意愿行事?

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

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

编辑: 以下是PEdump结果的链接:PEdump

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法。一般来说:汇编代码中存在错误 - 在xor操作中引用[cs:edx]是错误的,应该只是[edx]。为什么呢?

现在似乎段寄存器没有做我们(或至少我认为)的事情。我听说之前它们被用作每个段的基地址,而指令[cs:addr]是代码段中的偏移量。

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

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