【发布时间】:2018-10-26 12:57:28
【问题描述】:
我觉得有点愚蠢,但我正在努力在 C 中取消引用指针(+ 添加偏移量)。 我想在 C 中重新创建的是这种行为:
movabs rax, 0xdeadbeef
add rax, 0xa
mov rax, QWORD PTR [rax]
所以最后 rax 应该是:*(0xdeadbeef+0xa)
尤其是与mov rax, QWORD PTR [rax] 等效的值会很重要,因为我需要使用计算出的值并检索当时存储的数据(=不同的地址)。
我尝试了很多东西,但这是我目前的阶段:
void *ptr = (void*)0xdeadbeef;
void *ptr2 = *(void*)(ptr+0xa);
翻译成这样:
0x7ffff7fe6050: mov QWORD PTR [rbp-0x38],rax
0x7ffff7fe6054: mov rax,QWORD PTR [rbp-0x38]
0x7ffff7fe6058: add rax,0xa
编辑:它实际上并没有编译,我在此处提供的 C 代码中犯了一个错误,无法弄清楚哪些代码实际编译为此。无论如何,这并不重要,因为主要目标是将 ASM 转换为 C 并且现在问题已解决。感谢大家的参与。
所以前两行基本上没有用,只是将值添加到我的地址中,仅此而已。我需要将其解释为地址并在此时检索值。
此时存储在这些位置的数据无关紧要。基本上我想做的是在内存中找到一个特定的值,并且我知道一种添加偏移量和取消引用指针以达到我的目标的方法。最后一步只是从我的地址到当时的实际数据类型的类型转换。
我知道这对你们中的一些人来说可能看起来微不足道,但我对 C 不是很熟悉,所以我在这里苦苦挣扎......
【问题讨论】:
-
这是不可能的,因为
void *ptr2 = *(void*)(ptr+0xa);不编译,所以不可能生成代码。 -
你的 C 代码有问题,你正在计算一个新指针,然后当它是一个 void* 时取消引用它,最终得到一个(坏的)void 类型并将它分配给一个 void*。
-
为什么要使用 10 字节
movabs rax, 0xdeadbeef而不是 5 字节mov eax, 0xdeadbeef?两者都将 RAX 设置为相同的值。为什么不用一条指令来做呢?movabs rax, [0xdeadbeef + 0xa]可以使用从 64 位绝对地址 (felixcloutier.com/x86/MOV.html) 加载的mov的仅 AL/AX/EAX/RAX 形式。 (它不适合 32 位符号扩展disp32,因为设置了低 32 的高位,这与位置相关代码中的普通静态地址不同)。具有 32 位地址大小覆盖的常规mov也可以工作,大约 7 个字节。 -
@Jabberwocky 和 Matthieu 哦!很抱歉,一定是添加了错误的 C 代码 - 我尝试了很多强制转换、取消引用和括号...我将更新示例,但我的实际问题仍然存在。
-
在 C 语言中,您也可以用一条语句完成整个操作。喜欢
void *ptr = *(void**)(0xdeadbeef + 0xa);。除了避免取消引用未按 8 =alignof(void*)对齐的void**的未定义行为外,您还想使用memcpy。
标签: c pointers assembly x86-64 intel