我有两个类似的文件:
a.cpp
#include <iostream>
#include <cassert>
using namespace std;
int hack();
typedef int (*hackFunction)();
namespace secret
{
static int mysecret;
int _main(hackFunction hack)
{
cin >> mysecret;
assert(hack() == mysecret);
return 0;
}
}
int main()
{
return secret::_main(hack);
}
b.cpp
int hack()
{
return 31;
}
我无法编辑 a.cpp。 我想编写这样的 hack() 函数,以便它能够从 b.cpp 中获取 mysecret 值(我认为应该通过获取其地址来完成)。有什么方法可以做到这一点吗?
我试图反汇编文件。好像mysecret是存放在0x0(%%rip)中的,所以在cin'ed的时候如果能得到%%rip寄存器状态就可以得到。
最佳答案
它是特定于编译的。 你们不提供反汇编,所以我用gcc 7.2为例 ( https://godbolt.org/g/oUAvcG ),第 10-15 行:
mov esi, OFFSET FLAT:secret::mysecret ; move mysecret (value of address) to ESI
mov edi, OFFSET FLAT:std::cin ; pass handle to stdout
call std::basic_istream<char, std::char_traits<char> >::operator>>(int&) ; print mysecret
mov rax, QWORD PTR [rbp-8] ; move hack() address to RAX
call rax ; calls to hack() by register
我们无法从我们可以编写的代码中知道它的偏移量 (b.cpp
)
RIP
寄存器只显示处理器下一条指令的位置,而不是 mysecret
地址。
如果您现在调用 hack()
的约定,那么您只能确定返回地址。如果 mysecret
是常量,返回地址的偏移量将是您的答案,但您只有地址并且必须返回它的值。
如果 hack()
是 cdecl
,则返回地址将位于 hack()
开始处的 ESP
计算第10行和第16行地址的字节差,得到值。所以,hack() 将是这样的:
int __naked hack()
{
__asm
{
mov ecx, esp ; return value in main() after hack() is called
sub ecx, <value> ; <value> is the constant offset to mysecret address
mov eax, [ecx] ; read mysecret address hardcoded in assembly
mov eax, [eax] ; return mysecret value
ret ; extiting subroutine
}
}
此外,
关于c++ - 获取封装在namespace中的静态变量地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48132010/