[英]Trying to understand odd behavior of rsp and rbp registers
While playing around with detours I noticed this behavior that goes against my understanding of how registers rsp and rbp work.在玩弯路时,我注意到这种行为与我对寄存器 rsp 和 rbp 工作原理的理解背道而驰。 I am hooking another function, and my goal is to retain the state of the registers and flags for when I return back to the original function.
我正在挂钩另一个函数,我的目标是在我返回原始函数时保留寄存器和标志的状态。 Playing around with this, I noticed that the values of
rsp
and rbp
(and weirdly enough r15
) are changing during my detour without me touching them.玩弄这个,我注意到
rsp
和rbp
的值(奇怪的是r15
)在我绕道而行的过程中发生了变化,而我却没有碰它们。 Testing this further, my detour consists of me first dumping the values of all the registers (except rsp
, rbp
, and rip
) and flags sequentially to a specific address, pushing and popping all registers and flags, then dumping all the registers and flags again, and finally the instructions that my hook overwrote in the original function.进一步测试,我的绕道包括我首先将所有寄存器的值(除了
rsp
、 rbp
和rip
)和标志顺序转储到特定地址,推送和弹出所有寄存器和标志,然后再次转储所有寄存器和标志,最后是我的钩子在原始函数中覆盖的指令。
The x64 code of my detour is below:我绕道的x64代码如下:
;dump registers
mov rax, 0x1C122560000
mov [rax], rcx
mov [rax+0x8], rdx
mov [rax+0x10], rbx
mov [rax+0x18], rdi
mov [rax+0x20], rsi
mov [rax+0x28], r8
mov [rax+0x30], r9
mov [rax+0x38], r10
mov [rax+0x40], r11
mov [rax+0x48], r12
mov [rax+0x50], r13
mov [rax+0x58], r14
mov [rax+0x60], r15
mov [rax+0x68], rsp
mov [rax+0x70], rbp
;dump flags
push rcx
pushfq
pop rcx
mov [rax+100], rcx
pop rcx
pushfq
push rcx
push rdx
push rbx
push rdi
push rsi
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
;this is where my actual detour instructions would happen, but it is currently empty
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rsi
pop rdi
pop rbx
pop rdx
pop rcx
popfq
;dump registers
mov rax, 0x1C122560000
mov [rax+0x78], rcx
mov [rax+0x80], rdx
mov [rax+0x88], rbx
mov [rax+0x90], rdi
mov [rax+0x98], rsi
mov [rax+0xA0], r8
mov [rax+0xA8], r9
mov [rax+0xB0], r10
mov [rax+0xB8], r11
mov [rax+0xC0], r12
mov [rax+0xC8], r13
mov [rax+0xD0], r14
mov [rax+0xD8], r15
mov [rax+0xF0], rsp
mov [rax+0xF8], rbp
;dump flags
push rcx
pushfq
pop rcx
mov [rax+108], rcx
pop rcx
;original instructions (omitted)
...
...
...
ret
I am then reading the dumped registers from the address 0x1C122560000 with the corresponding offsets that each register was dumped with, and writing the results out.然后,我从地址 0x1C122560000 读取转储的寄存器以及每个寄存器转储的相应偏移量,并将结果写出。 This result is shown below (suffix
_1
marks value from the first dump, and _2
from the second dump):此结果如下所示(后缀
_1
标记来自第一个转储的值,后缀_2
来自第二个转储):
rcx_1: 23E5A6FEE00
rdx_1: 0
rbx_1: 3FFFAB921FE0
rdi_1: 3FF636D38F00
rsi_1: 23E5A6FEE00
r8_1: 0
r9_1: 3FFFAB921FE0
r10_1: 2C7
r11_1: 9E057FFA78
r12_1: 1
r13_1: 0
r14_1: 0
r15_1: 24600000000
rsp_1: 24600000000
rbp_1: 9E00000000
flags_1: 0
rcx_2: 23E5A6FEE00
rdx_2: 0
rbx_2: 3FFFAB921FE0
rdi_2: 3FF636D38F00
rsi_2: 23E5A6FEE00
r8_2: 0
r9_2: 3FFFAB921FE0
r10_2: 2C7
r11_2: 9E057FFA78
r12_2: 1
r13_2: 0
r14_2: 0
r15_2: 0
rsp_2: 9E057FF750
rbp_2: 9E057FF860
flags_2: 0
I struggle to understand how the value of the registers rsp
, rbp
, and r15
are changing between the dumps, and the same "pattern" repeats every time the original function is called (all three registers change every time, every other register stays the same).我很难理解寄存器
rsp
、 rbp
和r15
的值在转储之间是如何变化的,并且每次调用原始函数时都会重复相同的“模式”(所有三个寄存器每次都变化,其他每个寄存器都保持不变)。 To my understanding, the equal amount of pushes and pops should return the stack frame to point to the same address.据我了解,相同数量的推送和弹出应该返回堆栈帧以指向相同的地址。 Am I missing something very obvious about how these registers work?
我是否遗漏了一些关于这些寄存器如何工作的非常明显的东西? Is my approach to saving and restoring the original state of the hooked function by pushing and popping the registers flawed?
我通过推送和弹出寄存器来保存和恢复挂钩函数的原始状态的方法是否有缺陷?
mov [rax+0x60], r15 mov [rax+0x68], rsp
mov [rax+100], rcx
You are overwriting the stored values of R15 (at +96) and RSP (at +104), since the offset that you use in mov [rax+100], rcx
is in decimal (+100).您正在覆盖 R15(+96 处)和 RSP(+104 处)的存储值,因为您在
mov [rax+100], rcx
中使用的偏移量为十进制(+100)。
Same thing happens in mov [rax+108], rcx
, changing the stored value of RBP.同样的事情发生在
mov [rax+108], rcx
中,改变了 RBP 的存储值。 Solution use hexadecimal as was intended:解决方案按预期使用十六进制:
mov [rax+0x100], rcx
...
mov [rax+0x108], rcx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.