Question

I am doing experiments on encrypting PE code segment by XORing each byte with some key value. So far I managed to XOR this segment and inject at the end of code segment binary code that is decoding by XORing again with the same value. Of course I also updated AddressOfEntryPoint to be equal of decoder's address.

But when I calculate address of first byte to be XORed (it is equal to the first byte before decoder - because I will be going up) and I try to do this I receive access violation.

Now the details:

1) as a test PE I use some super easy console "hello world" app in plain C++

2) injected decoder code is written in NASM assembler, then assembled to binary and then injected at the end of .text section of test PE. Its code is below:

    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> and <CODE_SIZE> are replaced (before assembling) with proper values by my another app that is doing injection

4) when first loop iteration is passing, final EDX value is equal to the address of byte just before call get_proc, checked with Immunity Debugger

5) here I post a screenshot presenting situation when I have access violation when attempting to do XOR on first byte (with red line I marked my injected code that is executed at the beginning) enter image description here

6) I am aware of the fact, that by default code segment is only readable and executable, but my injecting app also adds write permission.

7) I am using Windows 8.1 64-bit

And finally questions:

A) Is presented code doing what I want it to do?

B) Is adding write permission to code segment enough to perform this operation (I know that there are some "write protection" mechanisms, but I don't know any details)?

Exploits are often using this technique (or at least they used to), so I wonder why isn't this working. In addition I have to tell, that when I remove only XOR operations, then program works fine (so calculated addresses are correct).

EDIT: Here is link to PEdump result: PEdump

Was it helpful?

Solution

I found solution to my problem. In general: there was a mistake in assembler code - referencing [cs:edx] in xor operation is wrong, should be just [edx]. Why?

It seems that now segment registers are not doing what we (or at least I) think. I heard that previously they were used as base address for each segment and instruction [cs:addr] was an offset within code segment.

But when you look closer at the values of segment registers in the photo I provided in question, you will see that those registers are in fact some descriptors that reference mainly 0xFFFFFFFF address! When I removed cs from instruction it worked! But then I loaded binary into debugger and suprisingly it was translated into ds:[edx] ! Again, why DS (data segment)? That one I don't know. But lesson from this issue should be to not to use those registers.

If you don't agree or you have any clarification please comment this answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top