繁体   English   中英

试图理解 rsp 和 rbp 寄存器的奇怪行为

[英]Trying to understand odd behavior of rsp and rbp registers

在玩弯路时,我注意到这种行为与我对寄存器 rsp 和 rbp 工作原理的理解背道而驰。 我正在挂钩另一个函数,我的目标是在我返回原始函数时保留寄存器和标志的状态。 玩弄这个,我注意到rsprbp的值(奇怪的是r15 )在我绕道而行的过程中发生了变化,而我却没有碰它们。 进一步测试,我的绕道包括我首先将所有寄存器的值(除了rsprbprip )和标志顺序转储到特定地址,推送和弹出所有寄存器和标志,然后再次转储所有寄存器和标志,最后是我的钩子在原始函数中覆盖的指令。

我绕道的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

然后,我从地址 0x1C122560000 读取转储的寄存器以及每个寄存器转储的相应偏移量,并将结果写出。 此结果如下所示(后缀_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

我很难理解寄存器rsprbpr15的值在转储之间是如何变化的,并且每次调用原始函数时都会重复相同的“模式”(所有三个寄存器每次都变化,其他每个寄存器都保持不变)。 据我了解,相同数量的推送和弹出应该返回堆栈帧以指向相同的地址。 我是否遗漏了一些关于这些寄存器如何工作的非常明显的东西? 我通过推送和弹出寄存器来保存和恢复挂钩函数的原始状态的方法是否有缺陷?

mov [rax+0x60], r15 mov [rax+0x68], rsp
 mov [rax+100], rcx

您正在覆盖 R15(+96 处)和 RSP(+104 处)的存储值,因为您在mov [rax+100], rcx中使用的偏移量为十进制(+100)。

同样的事情发生在mov [rax+108], rcx中,改变了 RBP 的存储值。 解决方案按预期使用十六进制:

mov [rax+0x100], rcx
...
mov [rax+0x108], rcx

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM