我正在通过使用一些键值对每个字节进行异或来进行加密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时,我发布了一个屏幕截图,显示我有访问冲突的情况(红线我标记了我在开始时执行的注入代码)
6)我知道这样的事实,默认情况下代码段只是可读和可执行的,但我的注入应用程序也增加了写入权限。
7)我使用的是Windows 8.1 64位
最后问题:
A)代码是否按照我的意愿行事?
B)向代码段添加写权限是否足以执行此操作(我知道有一些“写保护”机制,但我不知道任何细节)?
漏洞利用经常使用这种技术(或至少他们习惯),所以我想知道为什么这不起作用。另外我必须告诉我,当我只删除XOR操作时,程序运行正常(所以计算的地址是正确的)。
编辑: 以下是PEdump结果的链接:PEdump
答案 0 :(得分:0)
我找到了解决问题的方法。一般来说:汇编代码中存在错误 - 在xor操作中引用[cs:edx]
是错误的,应该只是[edx]
。为什么呢?
现在似乎段寄存器没有做我们(或至少我认为)的事情。我听说之前它们被用作每个段的基地址,而指令[cs:addr]
是代码段中的偏移量。
但是当你仔细观察我提供的照片中段寄存器的值时,你会看到那些寄存器实际上是一些主要引用0xFFFFFFFF地址的描述符!当我从指令中移除cs
时,它工作了!但后来我将二进制加载到调试器中,令人惊讶的是它被翻译成ds:[edx]
!再次,为什么DS(数据段)?那个我不知道的。但是这个问题的教训应该是不要使用这些寄存器。
如果您不同意或有任何澄清,请评论此答案。