我有一个小的静态库( .a
)。 在静态库中是一个指向一个大的,静态分配的一维数组的指针。
当我将代码链接到这个库时,指针的地址在各个位置被硬编码,通过反汇编很容易find。 问题是,我想我的代码能够访问这个数组(图书馆是错误的,我想知道为什么)。
当然,通过反汇编,将该地址硬编码到我的代码中,然后重新编译,这将是微不足道的。 这不会是一个问题,除了库可以用不同的方式configuration其他模块,并且数组的指针根据链接的模块而改变。
我有什么select获得该指针? 因为数组的起始状态是可预测的,所以我可以遍历内存,用信号处理程序捕捉段错误,直到find合理的东西。 有没有更好的办法?
由于你的库是一个.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
化它objcopy --globalize-symbol=some_array
,然后按照上面的步骤继续。
那么如何确定描述该数组的符号是什么? 运行objdump -dr foo.o
,其中foo.o
包含您知道引用该数组的指令。 将出现在引用指令旁边的重定位将告诉您名称。
最后运行nm foo.o | grep some_array
nm foo.o | grep some_array
。 如果你看到00000XX D some_array
,你就完成了 – 这个数组是全局可见的(对于B
是相同的)。 如果你看到000XX d some_array
,你需要首先全球化(同样适用于b
)。
更新:
-dr到objectdump没有工作
对,因为符号原来是本地的,重定位可能是指.bss + 0xNNN
。
00000000006b5ec0 b grid
00000000006c8620 b grid
00000000006da4a0 b grid
00000000006ec320 b grid
00000000006fe1a0 b grid
您必须在最终链接的可执行文件上运行nm
,而不是归档中的个别foo.o
对象。 在你的二进制文件中有五个独立的静态数组叫grid
,只有第一个是你显然关心的那个。
声明“extern int grid [];” 并使用它给出了一个未定义的参考
这是对本地符号的期望:库中的代码是这样的:
// foo.c static char grid[1000];
而且不能从foo.o
外部引用这个grid
,而没有首先foo.o
化这个符号。
出于安全原因,我不允许在服务器上运行库的更改二进制文件
我希望你明白,这个论点是完全的BS :如果你可以将自己的代码链接到二进制文件,那么你可以在服务器上做任何事情 (受到用户ID限制)。 你已经被信任了。 如果他不信任你,修改第三方库应该是服务器管理员最担心的问题。