2

我有一个小型静态库 ( .a)。在静态库中有一个指针,它指向一个大的、静态分配的一维数组。

当我将我的代码链接到这个库时,指针的地址被硬编码在不同的位置,通过反汇编很容易找到。问题是,我希望我的代码能够访问该数组(库出现故障,我想知道原因)。

自然地,通过反汇编、将该地址硬编码到我的代码中,然后重新编译来获得该指针是微不足道的。这不是问题,除非库可以与其他模块以不同的方式配置,并且数组的指针会根据链接的模块而变化。

获取该指针有哪些选择?因为数组的起始状态是可预测的,所以我可以遍历内存,用信号处理程序捕获段错误,直到找到看起来合理的东西。有没有更好的办法?

4

1 回答 1

4

由于您的库是一个.a档案库,因此我假设您使用的是某种 UNIX。

全局数组应该有一个与之关联的符号名称。您的工作会更容易或更难,具体取决于描述它的符号类型。

如果有描述这个数组的全局符号,那么你可以直接引用它,例如

extern char some_array[];
for (int i = 0; i < 100; i++) printf("%2d: 0x%2x\n", i, some_array[i]);

如果符号是本地的,那么您可以先用 将其全球化objcopy --globalize-symbol=some_array,然后按上述方法进行操作。

那么如何确定描述该数组的符号是什么?Run objdump -dr foo.o,其中foo.o包含您知道引用该数组的指令。将出现在引用说明旁边的重定位将告诉您名称。

最后,运行nm foo.o | grep some_array。如果您看到00000XX D some_array,您就完成了——该数组是全局可见的(对于 也是如此B)。如果看到000XX d some_array,则需要先将其全球化(对于 也是如此b)。

更新:

到 objectdump 的 -dr 不起作用

对,因为这个符号原来是本地的,所以重定位可能是指.bss + 0xNNN.

00000000006b5ec0 b grid
00000000006c8620 b grid
00000000006da4a0 b grid
00000000006ec320 b grid
00000000006fe1a0 b grid

您必须nm在最终链接的可执行文件上运行,而不是在foo.o存档中的单个对象上运行。在您的二进制文件中调用了五个单独的静态数组grid,只有第一个是您显然关心的。

声明“外部 int 网格 [];” 并使用它给出一个未定义的引用

这是本地符号的预期:库中的代码类似于:

// foo.c
static char grid[1000];

如果不先将符号全球化,就不grid能从外部引用它。foo.o

出于安全原因,我不允许在我们的服务器上运行已更改的库二进制文件

我希望你明白这个论点完全是废话:如果你可以将自己的代码链接到那个二进制文件中,那么你可以在服务器上做任何事情(受用户 ID 限制);你已经被信任了。如果服务器管理员不信任您,修改第三方库应该是服务器管理员最不担心的。

于 2012-04-27T03:53:58.640 回答