Thread "hijacking" producing undefined-behaviour like data misalignment exceptions

0

I am not very experienced with assembly of any sort, but I am learning the ropes. What I am attempting to do is detour a thread's execution to run my shellcode and return it's execution as normal. My methodology is as follows:

  1. Open a handle to the target thread, suspend it and grab it's context.
  2. Write some information to the target process such as the target thread's current instruction pointer (for returning to the original routine) and extra information for my detour routine, including it's address. I have been using (LoadLibraryA) for injecting dll into the process.
  3. Mutate the shellcode so it cointains and immediate pointer to the data cited in step 2 and make sure it will return the control back to the original routine with the same stack and registers.
  4. Allocate some memory for the shellcode and write it into the process.
  5. Make the thread's instruction pointer point to the shellcode and resume the thread.

Here's the part I cannot understand: The thread is always hijacked succesfully, injecting the dll and returning to original routine, but about half of the time the process crashes after that. When it does crash, it excepts with 0x80000002: Datatype misalignment during it's normal routine.

I then proceeded to step through the thread with breakpoints and concluded that both the stack and the registers were exactly the same right before the thread "hijacking" and before returing, except for the ZF and PF flags (Not sure why, I thought I accounted for restoring flags in my code).

I am using https://defuse.ca/online-x86-assembler.htm for generating machine code from assembly and storing it inside an array of byte in my C++ code. In my x86 version of the code it works flawlessly everytime.

This is the amd64 code I came up with for the shellcode:

sub rsp, 0x08    ; open up a gap on the stack for later

push rax  ; push all the general purpose registers and flags onto the stack
push rcx
push rdx
push rbx
push rbp
push rsi
push rdi
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
pushfq

mov rbx, 0xDEADBEEFDEADBEEF   ; this immediate get's set to a pointer to the data I cited on step 2
mov rdi, [rbx + 0x8]   ; offset 0x8 (on my data) contains the old RIP
mov [rsp + 0x80], rdi  ; write the return address (old RIP) onto the gap I opened onto the stack before
lea rcx, [rbx + 0x18]  ; offset 0x18 points the argument I wish to pass to my routine function
call [rbx + 0x10]      ; offset 0x10 points to my detour routine
mov [rbx], rax         ; store the return value from my routine into offset 0x00 of my data

popfq      ; pop all the general purpose registers and flags in reverse order
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rbp
pop rbx
pop rdx
pop rcx
pop rax

ret   ; return to the old RIP

The data I talked about many times is actually this little struct:

struct Data64
{
    PVOID result; // 0x00, the return buffer
    PVOID pReturn; // 0x08, the original EIP
    PVOID pProcedure; // 0x10, the pointer to my procedure, like (LoadLibraryA)
    PVOID argument; // 0x18, the rest of the allocated page
};

I have allocated a PAGE_READWRITE for this data struct and a PAGE_EXECUTE_READWRITE for my shellcode.

I am aware that this incredibly vague and that there are many more variables into play, I don't expect a direct answer, perhaps just a way to relate what I'm doing with the 0x80000002: Datatype misalignment I'm getting, all I could come up with was checking the stack and registers, and those were absolutely fine.

assembly
x86-64
memory-alignment
shellcode
machine-code
asked on Stack Overflow Jul 22, 2020 by Luiz • edited Jul 22, 2020 by Peter Cordes

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0