gpt4 book ai didi

c++ - 通过链接另一个目标文件来劫持函数的实现

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:49:38 26 4
gpt4 key购买 nike

我听说可以通过链接函数所在的对象文件与您编写的另一个对象文件来覆盖/劫持/破解函数的实现。我一直在玩,似乎我只能在一种情况下让它工作。但是,我想知道除了所描述的情况之外,是否有可能在其他情况下实现此结果(如下所示)。

使用的编译器:TDM-GCC 4.9.2

操作系统:Windows 8 64 位

下面描述劫持“成功”的情况:

这是一个名为 sample.cpp 的示例源

#include <iostream>

int returnOne();

int main()
{
std::cout << "returnOne() returns " << returnOne();

return 0;
}

编译:

g++ -c sample.cpp -o sample.o

nm.exe检查目标文件后,我的函数的名称是:__Z9returnOnev

所以,进入另一个来源hack.cpp :

extern "C" int _Z9returnOnev()
{
return 5; //rather than return 1
}

编译:

g++ -c hack.cpp -o hack.o

现在我用 hack.o“重新创建”可执行文件文件:

g++ -Wl,--allow-multiple-definition hack.o sample.o -o sample.exe

运行时,sample.exe产生:

returnOne() returns 5

那么劫持成功了。

现在,如果我在任何时候提供 returnOne() 的实现在原始来源中,此技术不再有效。如:

#include <iostream>

int returnOne();

int main()
{
std::cout << "returnOne() returns " << returnOne();

return 0;
}

int returnOne()
{
return 1;
}

它编译正常,但调用时,该函数每次都使用原始实现。

所以,我想知道如果函数的实现已经在原始源代码中定义,是否有可能以这种方式“劫持”一个函数的实现,或者只有当它的原型(prototype)被定义时才有可能?


编辑(2015 年 7 月 15 日):
我还编译了 w/o 优化,如:

g++ -Wl,--allow-multiple-definition,-O0 hack.o sample.o -o sample.exe

但是,问题依然存在。


编辑 2(2015 年 7 月 15 日):
好的,我清理了,然后使用 -O0 开关编译并链接了所有内容:

g++ -O0 -c sample.cpp -o sample.o

g++ -O0 -c hack.cpp -o hack.o

g++ -Wl,--allow-multiple-definition,-O0 hack.o sample.o -o sample.exe

它仍然返回 1。

最佳答案

不,在那种情况下不可能覆盖函数实现。

您的编译器在编译源文件时通常会做的是创建一个包含函数签名(标识符+参数类型)和函数地址的表。当您的代码中有函数调用时,编译器会尝试使用此签名调用该函数。这就是为什么您需要一个链接器 - #include 语句实际上在编译之前将所有声明复制到您的代码中,以便您拥有正确的签名。然后链接器添加可调用函数的地址。如果您的 main.cpp 中有函数定义,则编译器/链接器无需在其他任何地方查找定义。

关于c++ - 通过链接另一个目标文件来劫持函数的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31398000/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com