C ++如何读取函数的第一对字节数? (32位机器)

问题描述 投票:2回答:2

假设我有一个这样的函数(完全随机,我只是在30秒内写出一个例子)

bool exampleAuthetnication(char *a, char *b)
{
    bool didAuthenticate = false;
    if(strcmp(a, b) == 0)
    {
        didAuthenticate = true;
    }

    if(didAuthenticate)
    {
        return true;
    }
    else
    {
        stopExecutable();
        return false;
    }
}

我将如何阅读此函数的前几个字节?

我想出了这个

int functionByteArray[10];
for (int i = 0; i < 10; i++)
{
    functionByteArray[i] = *(int*)(((int)&exampleAuthetnication) + (0x04 * i));
}

它背后的逻辑是我们得到函数的内存地址(在这种情况下是exampleAuthetnication())然后我们转换为int指针然后dereferance获取我们试图读取的当前字节行的值然后存储在functionByteArray中,但它似乎没有正常工作。我究竟做错了什么?我正在努力实现的目标是什么?

c++ security assembly memory tampering
2个回答
4
投票

理论上(根据C ++ 11标准),您甚至无法将函数指针转换为数据指针(在Harvard architectures代码和数据位于不同的存储器和不同的地址空间)。某些操作系统或处理器也可能禁止读取可执行文件code segments(请参阅NX bit)。

实际上,在运行某些操作系统(如Linux或Windows)的x86-64(或32位x86)上,功能代码是一个字节序列,可以是未对齐的,并且位于其进程的(公共)虚拟地址空间中。所以你至少应该有char functionByteArray[40];,你可以使用std::memcpy<string>做一些

std::memcpy(functionByteArray, (char*)&exampleAuthetnication,
            sizeof(functionByteArray));

最后你的代码是错误的,因为-on x86-64值得注意 - int与指针的大小不同(所以(int)&exampleAuthetnication正在丢失地址的高位字节)。你应该至少使用intptr_t。并且int比代码具有更强的对齐约束。

顺便说一下,您可能还会要求编译器显示生成的汇编代码。使用GCCexampleAhtetnication编译你的g++ -O -fverbose-asm -S C ++代码并查看生成的.s文件。

请注意,C ++编译器可能会将optimize从代码段“移除”某个函数(例如,因为该函数已在任何地方内联),或者将函数代码分成几个部分,或者将exampleAhtetnication代码“放在”另一个函数内部...


-1
投票

C ++源代码不是计算机执行的指令列表;它是描述程序含义的语句集合。

您的编译器会解释这些语句并生成实际的指令序列(通过汇编阶段),这些指令实际上可以在我们的物理现实中执行。

用于执行此操作的语言不提供用于检查构成编译程序的字节的任何工具。你通过未定义行为的魔力,所有你投射函数指针等的尝试可能会随机地给你一些类似的数据,但结果就是:undefined。

如果要检查已编译的可执行文件,请从程序外部执行此操作。例如,您可以使用十六进制编辑器。

© www.soinside.com 2019 - 2024. All rights reserved.