I have a mechanism that maps memory addresses to other memory addresses, e.g.:
{
0x10000 -> 0xA0000
0x20000 -> 0x99000000
0x340000 -> 0x50000000 ; Stack in this example
}
Some example data:
loc 0xA0000: 0x20000
I'm running code in a simulated environment where the code thinks it's located somewhere, but in reality it is located somewhere else. Therefore I need to instrument every memory access, implicit or explicit, so that any reads or writes happens to the actual memory location and not the one the program thinks it's accessing. This means memory addresses can be passed around in the program as their original value as long the actual access has its address translated so the access is redirected behind the scenes. It also means certain instructions such as call
or jmp
must go through the same translation, so that the program believes it's actually calling or jumping to the original value, but the destination is translated behind the scenes.
I'm not entirely sure how to achieve this due to the CISC nature of x86. For example, just look at the breakdown of some instructions:
mov eax, 0x10000
; Stays as "mov eax, 0x10000" since it's not a memory access
mov ebx, [eax]
; 0x10000->0xA0000
; becomes "mov ebx, [0xA0000]" which loads 0x20000
push eax
; (stack)0x340000->0x50000000
; becomes "push 0x10000 to 0x50000000"
call eax
; 0x10000->0xA0000
; becomes "call 0xA0000"
call [0x10000]
; 0x10000->0xA0000, 0x20000->0x99000000
; becomes "read what's in 0xA0000, receive 0x20000, convert that to 0x99000000, call 0x99000000"
I don't think a disassembler or decomposer would be fine-grained enough for my needs since I need to know every implicit memory access per instruction, so that leaves me with using intermediate representations such as OpenREIL. However, it won't be enough to just transform the instruction into its corresponding low-level building blocks (IR) and pass every memory access found therein through the mapping mechanism, as I would also need to transform it back to x86 instructions so I can actually run it.
Any suggestions? x86 to LLVM IR, do some changes, then back to x86, perhaps?