OneShell

I fight for a brighter tomorrow

0%

gdb添加调试符号

在调试无符号的程序时,有时候在IDA中已经对某一个数据结构进行了符号恢复,此时想要将符号导入到gdb中。解决的办法就是:

  1. 写一个定义和使用了该数据结构的C程序
  2. 编译,且带符号
  3. 在gdb中使用add-symbol-file命令导入该程序的的符号

例如,假设有如下的一个程序,编译出来之后去掉了调试符号,则在gdb中无法打印出来list数据结构。而我们在IDA中根据上下文恢复出来了list结构体,并且在调试的过程中,还想打印出来Stulist这个链表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>

struct list {
int num;
char *name;
struct list *next;
};

struct list *Stulist;

int main() {
struct list *studentA = (struct list*)malloc(sizeof(struct list));
studentA->num = 0;
studentA->name = "studentA";
studentA->next = NULL;
Stulist = studentA;

struct list *studentB = (struct list*)malloc(sizeof(struct list));
studentB->num = 1;
studentB->name = "studentB";
studentB->next = studentA;
Stulist = studentB;

return 0;

}

那么我们首先需要做的是,根据恢复出来的数据结构重新写一个如下的定义和使用了数据结构的C程序,然后编译时带上符号:gcc -g data.c -o data

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <stdlib.h>

struct list {
int num;
char *name;
struct list *next;
};

int main() {
struct list* test;
return 0;
}

在gdb中调试,执行命令如下:

1
2
add-symbol-file data # 从data中导入符号
p *(struct list*) 0x4052a0 # 在指定位置查看数据结构

undifined

如果我们还需要进一步打印链表Stulist的信息,可以写一个如下的gdb定义,用来遍历链表:

1
2
3
4
5
6
7
define plist
set $iter = *(struct list*)$arg0
while $iter
print $iter
set $iter = *$iter.next
end
end

undifined

参考链接