使用签名恢复二进制文件符号表
为了识别静态链接且被去除符号的库函数,IDA会用签名匹配IDA数据库中的函数,如果匹配上会自动重命名函数。通过实例演示整个流程
制作过程签名恢复符号表使用的样例代码。(包含标准库中多个测试函数)
//
// Created by js-v on 2022/12/7.
//
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
printf("函数开始执行!!!");
printf("hello-world!");
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = memcmp(str1, str2, 5);
printf("strcpy,memcmp函数被使用ret=%d。",ret);
const char dest[] = "oldstring";
const char src[] = "newstring";
printf("Before memmove dest = %s, src = %s\n", dest, src);
memmove(dest, src, 10);
printf("After memmove dest = %s, src = %s\n", dest, src);
char buffer[50];
char* s = "runoobcom";
// 读取字符串并存储在 buffer 中
int j = snprintf(buffer, 6, "%s\n", s);
// 输出 buffer及字符数
printf("string:\n%s\ncharacter count = %d\n", buffer, j);
char str3[80];
sprintf(str3, "Pi 的值 = %s", s);
printf("函数sprinf已经被执行输出字符串%s。",str3);
int day, year;
char weekday[20], month[20], dtm[100];
strcpy( dtm, "Saturday March 25 1989" );
sscanf( dtm, "%s %s %d %d", weekday, month, &day, &year );
printf("%s %d, %d = %s\n", month, day, year, weekday );
char str4[] = "This is source";
char str5[] = "This is destination";
strcat(str5, str4);
printf("最终的目标字符串: |%s|", str5);
char str6[15];
char str7[15];
int ret2;
strcpy(str6, "abcdef");
strcpy(str7, "ABCDEF");
ret2 = strncmp(str6, str7, 4);
printf("函数strncmp已经执行ret2的结果=%n",ret2);
char str8[30] = "2030300 This is test";
char *ptr1;
long ret3;
ret3 = strtol(str8, &ptr1, 10);
printf("strtol函数已经执行-数字(无符号长整数)是 %ld\n", ret3);
printf("字符串部分是 |%s|", ptr1);
char *ptr2;
long ret6;
ret6 = strtoul(str8, &ptr2, 10);
printf("strtoul函数已经执行-数字(无符号长整数)是 %lu\n", ret6);
printf("字符串部分是 |%s|", ptr2);
const char str9[] = "http://www.runoob.com";
const char ch = '.';
char *ret4;
char *ret5;
ret4 = strchr(str9, ch);
printf("函数strchr已经执行-|%c| 之后的字符串是 - |%s|\n", ch, ret4);
ret5 = strrchr(str9, ch);
printf("函数strrchr已经执行-|%c| 之后的字符串是 - |%s|\n", ch, ret5);
char str10[50];
int len;
strcpy(str10, "This is runoob.com");
len = strlen(str10);
printf("函数strlen已经执行-|%s| 的长度是 |%d|\n", str10, len);
char str11[50];
strcpy(str11,"This is string.h library function");
printf("函数memset已经执行---------");
puts(str11);
memset(str11,'$',7);
puts(str11);
return 0;
}
构建交叉编译环境来编译样例代码,没有交叉编译环境可以参考 使用脚本自动生成交叉编译链

静态编译
./arm-none-linux-gnueabi-gcc --static hello.c -o hellos
去除符号
./arm-none-linux-gnueabi-strip hellos
注意:这里的去除符号使用的strip一定是要在交叉编译环境下的 arm-none-linux-gnueabi-strip 命令,否则会遇到如下的提示无法识别文件的错误,可以看到默认使用的是本机的strip命令。

使用命令查看去除符号表之后静态连接的文件。

使用IDA打开编译后的文件,可以看见函数名称已经不能够正常的被识别。

这里以交叉编译环境下的libc.a这个静态库为例制作并应用IDA签名
- 获取libc.a(libc的静态库),一般在交叉编译环境中的lib目录,使用find、grep命令查找即可。
- 下载FLAIR 插件(工具包),使用pelf(pattern)根据libc.a 创建模版文件。
./pelf libc.a libc-demo.pat

- 根据pat模版文件,制作签名文件。-n代表注释。注意,制作签名文件时,看你存在冲突,修改一下冲突的一个文件(libc-demo.exc),如果有两个以上的冲突,选择要的那一个,前面输入+即可,修改exc文件之后再次./sigmake。
- 复制sig文件到 IDA安装目录下sig/arm的目录下。打开IDA 加载编译好的文件的页面, shift+F5,右键添加新的签名文件。

可以在IDA中看见使用签名已经识别出了751个函数,左侧淡蓝色背景的函数,都是签名所识别出来的。

浙公网安备 33010602011771号