c++ - 获取封装在namespace中的静态变量地址

标签 c++ assembly

我有两个类似的文件:

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/

相关文章:

c++ - 在 C++ 中,什么是虚拟基类?

c++ 在运算符重载函数中创建、分配新变量并将其与两个对象进行比较。

c++ - 使用 log4cxx 进行日志记录和过滤

assembly - 将我的解决方案从十进制转换为十六进制

c++ - std::shared_ptr 线程安全

c++ - C++ 需要函数原型(prototype)吗?

c++ - ICC 中的 -O3 搞乱了内在函数,与 -O1 或 -O2 或相应的手动组装一起使用

c++ - 汇编操作的时间

gcc - 为什么即使从未访问堆栈,arm-gcc 也会递减/递增堆栈指针?

assembly - 在 MASM 的宏中使用本地标签的问题