假设 – 关于为*现有*静态/dynamic库制作头文件

我想了解更多关于unix / linux和这个问题popup到我的头 – 让我们说我做了一个静态/dynamic库(.a或.so),并失去了C / C ++源代码和头文件。 默认nm输出给我的符号的名称,但我需要知道返回types和参数计数/types来制作标题。 是否有可能得到这个额外的信息以某种方式反向devise给定的库头?

您标记了C和C ++,两者之间的答案略有不同。

对于C ++,类的方法名称中嵌入了符号名称中的类型信息。 你只需要弄清楚编译这个库的编译器是怎样的一个名字。

对于C来说,没有真正的干净的方法来做到这一点。 您可以拆开程序集,分析哪些寄存器和堆栈区域在未被写入的情况下读取,以找出函数需要多少个参数。 这将需要知道任何编译器编译库所使用的调用约定。

同样,你可以看看每个参数是如何在程序集中使用的。 如果你看到它被用在一个加载指令中,它很可能是某种类型的指针,而如果你看到它被用在算术中,它可能是某种类型的整数。

对于返回类型,可以在返回指令之前检查是否有任何看起来有意义的东西放在返回寄存器中。 同样,这需要了解您的平台调用约定的知识。

下面是我将如何在ARM程序集中做的一个例子。

我知道ARM中的参数传递到寄存器r0到r3,返回值存储在寄存器r0中。 考虑到这一点,我们可以开始逆向工程。 让我们来看看两个函数的汇编,并试图找出函数原型是什么。

00000000 <func1>: 0: e3510000 cmp r1, #0 4: 0a000007 beq 28 <func1+0x28> 8: e0801001 add r1, r0, r1 c: e1a03000 mov r3, r0 10: e3a00000 mov r0, #0 14: e4d32001 ldrb r2, [r3], #1 18: e1530001 cmp r3, r1 1c: e0800002 add r0, r0, r2 20: 1afffffb bne 14 <func1+0x14> 24: e12fff1e bx lr 28: e1a00001 mov r0, r1 2c: e12fff1e bx lr 

如果我们看一下这里,r0和r1在写入之前都会被读取。 我们也可以看到r2和r3是在读之前写的。 因此我们可以推断func1最多有两个参数。

我们也意识到,r0被移动到r3,然后作为ldrb的地址,这是一个从内存中加载一个字节的指令。 因此,我们推断第一个参数是一个指针。 因为指令只加载一个字节,我们也可以告诉它可能是指向某种一种字节数据类型的指针。

r1中的第二个参数似乎除了比较和添加指令外似乎都没有使用,所以它可能是一个整数。

在每个bx lr (一个返回调用者指令)之前,有些东西放在r0中,所以我们推断函数返回某种类型的值。

如果这个函数提供给我,我猜测函数原型看起来像这样:

 int func1(unsigned char *, int); 

原版的:

 unsigned int func1(void *, unsigned int); 

这是另一个功能

 00000030 <func2>: 30: e0822001 add r2, r2, r1 34: e5c02000 strb r2, [r0] 38: e12fff1e bx lr 

这个很简单

我们看到r0,r1和r2都是在写入之前读取的,所以我们可以猜测函数有三个参数。 r0用作strb指令(存储字节)的地址,所以它可能是一个指针。 同样,它只存储一个字节,所以它可能是一个指向字节大小的数据类型的指针。

另外两个只用于add指令,所以可能是整数。

似乎没有任何东西放在r0的末尾,所以函数或者返回第一个参数或者不返回一个值。

我猜想原型将是下列之一

 void func2(unsigned char *, int, int); unsigned char *func2(unsigned char *, int, int); 

原版的:

 void func2(char *, char, char); 

请记住,不同的处理器指令集的调用者/被调用者的约定会有所不同,并且在使用c和c ++库的时候,您已经意识到了名称变形,您可以尝试以下方法:

  gdb <executable> .... disas <function name> .... Here you can make a wild guess about the type of return value and parameters using the bit size of those values written on stack making use of assembly code.