什么是SSDT?
SSDT(系统服务数据表)是Linux内核中的一项重要数据结构,它包含了系统所有可用服务的相关信息,例如服务名称、地址和挂钩函数。提取SSDT对于研究内核、逆向工程恶意软件以及进行安全分析至关重要。
提取SSDT的
提取SSDT的 有多种,最常见的是:
1. **KeServiceDescriptorTable**:这是一个全局内核变量,指向SSDT的起始地址。
2. **_SystemServiceTable**:这是一个全局变量,也指向SSDT的起始地址。
3. **procfs**:可以通过/proc/kallsyms文件获取SSDT的符号地址。
使用KeServiceDescriptorTable提取SSDT
c
include
static struct kallsyms_syms *find_symbol(char *name) {
struct kallsyms_syms *sym;
sym = kallsyms_lookup_name(name);
if (sym == NULL) {
return NULL;
}
return sym;
}
static void extract_ssdt(void) {
struct kallsyms_syms *sym;
unsigned long *ssdt;
sym = find_symbol("KeServiceDescriptorTable");
if (sym == NULL) {
return;
}
ssdt = (unsigned long *)sym->value;
// 解析SSDT并进行进一步分析
}
使用_SystemServiceTable提取SSDT
该 与上述类似,只需将"KeServiceDescriptorTable"替换为"_SystemServiceTable"即可。
使用procfs提取SSDT
include
include
include
static unsigned long *parse_kallsyms(char *line) {
char *ptr, *end;
unsigned long addr;
ptr = line;
while (*ptr && *ptr != ' ') {
ptr++;
}
if (*ptr == '\0') {
return NULL;
}
addr = strtoul(ptr, &end, 16);
if (*end != ' ') {
return NULL;
}
ptr = end + 1;
while (*ptr && *ptr != ' ') {
ptr++;
}
if (*ptr == '\0') {
return NULL;
}
return (unsigned long *)addr;
}
static void extract_ssdt(void) {
FILE *fp;
char buffer[1024];
unsigned long *ssdt;
fp = fopen("/proc/kallsyms", "r");
if (fp == NULL) {
return;
}
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
ssdt = parse_kallsyms(buffer);
if (ssdt != NULL && strstr(buffer, "__x64_syscalls_start") != NULL) {
// 解析SSDT并进行进一步分析
break;
}
}
fclose(fp);
}