📄 sysmap.c
字号:
//code by ftts
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include "sysmap.h"
#define MAX_SYSTEM_MAP_SIZE 0x16E360 /* 1.5M*/
typedef struct _SYSTEM_MAP_RECORD
{
unsigned long addr;
char *symbol_name;
}SYSTEM_MAP_RECORD,*PSYSTEM_MAP_RECORD;
typedef struct _SYSTEM_MAP
{
int record_count;
char * symbol_buffer_offset;
int free_symbol_buffer_size;
SYSTEM_MAP_RECORD map_record[1];
}SYSTEM_MAP,*PSYSTEM_MAP;
PSYSTEM_MAP psm = 0;
int read_line(char *lp,char *Out,int max)
{
int i;
for(i=0;;i++)
{
if(lp[i]==0)
break;
if(i>max)
{
*Out = 0;
break;
}
if(lp[i]==0xd || lp[i]==0xa)
break;
Out[i]=lp[i];
}
return i+1;
}
int get_record_count(char *szmap,int *symbol_size)
{
char sztemp[0x100];
int count = 0;
int symlen;
*symbol_size = 0;
while(*szmap)
{
memset(sztemp,0,0x100);
szmap += read_line(szmap,sztemp,0x100 -1);
if(*sztemp == 0)
break;
symlen = strlen(sztemp+11);
if(symlen <= 0)
break;
*symbol_size += symlen+1;
count++;
}
return count;
}
char CharToNum(char c)
{
if(c>='0'&& c<='9')
return c-=0x30;
if(c>='A'&&c<='F')
return c-=0x37;
if(c>='a'&& c<='f')
return c-=0x57;
return 0;
}
unsigned long read_hex_addr(char *szhex)
{
unsigned long addr = 0;
int i;
addr = CharToNum(*szhex);
for (i = 1; i < 8 ; i++)
{
addr = addr<<4;
addr |=CharToNum(szhex[i]);
}
return addr;
}
int load_record(char *szmap,PSYSTEM_MAP psm)
{
char sztemp[0x100];
int count = 0;
int symlen;
while(*szmap)
{
memset(sztemp,0,0x100);
szmap += read_line(szmap,sztemp,0x100 -1);
if(*sztemp == 0)
break;
symlen = strlen(sztemp+11);
if(symlen <= 0)
break;
psm->map_record[count].symbol_name = psm->symbol_buffer_offset;
if(psm->free_symbol_buffer_size < symlen)
break;
psm->map_record[count].addr = read_hex_addr(sztemp);
strncpy(psm->symbol_buffer_offset,sztemp+11,symlen);
psm->symbol_buffer_offset +=symlen+1;
psm->free_symbol_buffer_size -=symlen+1;
count++;
}
if(count == psm->record_count)
return 1;
else
return 0;
return 1;
}
unsigned long get_addr_from_map(char *szname)
{
int i;
if(psm == 0)
return 0;
for (i = 0; i < psm->record_count ; i++)
{
if(strcmp(szname,psm->map_record[i].symbol_name) == 0)
return psm->map_record[i].addr;
}
return 0;
}
int get_kernel_version(char *szVersion)
{
struct file *file;
char sztemp[51],*p;
int size;
/*open the file */
file = filp_open("/proc/version",0,0);
if (IS_ERR(file))
{
PTR_ERR(file);
return -1;
}
memset(sztemp,0,51);
size = kernel_read(file,0,sztemp,50);
filp_close(file,0);
if(size != 50)
return -2;
if(strncmp(sztemp,"Linux version ",14)!=0)
return -3;
p = strchr(sztemp+14,' ');
if(p == 0)
return -4;
*p = 0;
strcpy(szVersion,sztemp+14);
return 0;
}
int read_file_to_buffer(char *file_name,char **out_buf,int max_read_size)
{
char *szbuf;
struct file *file;
loff_t lof;
int file_size,read_size;
*out_buf = 0;
/*open the file */
file = filp_open(file_name,0,0);
if (IS_ERR(file))
{
PTR_ERR(file);
return 0;
}
/*check and get file size */
lof = 0;
lof = vfs_llseek(file,lof,SEEK_END);
file_size = lof;
if(file_size > max_read_size)
{
filp_close(file,0);
return 0;
}
vfs_llseek(file,lof,SEEK_SET);
/* printk("file size = %2d \n",file_size);*/
/*allocate memory*/
szbuf = vmalloc(file_size +5);
/* printk("buffer = %p \n",szbuf);*/
if(szbuf == 0)
{
filp_close(file,0);
return 0;
}
memset(szbuf+file_size,0,5);
read_size = kernel_read(file,0,szbuf,file_size);
/* printk("read size = %2d \n",read_size);*/
if(read_size != file_size)
{
filp_close(file,0);
vfree(szbuf);
return 0;
}
filp_close(file,0);
*out_buf = szbuf;
return read_size;
}
int load_system_map()
{
char map_name[100];
char *szmap;
int map_size =0;
int record_count,symbol_size;
int sm_size;
memset(map_name,0,100);
strcpy(map_name,"/boot/System.map-");
if(get_kernel_version(map_name+strlen(map_name))!=0)
return -1;
/* printk("System map name is %s\n",map_name);*/
map_size = read_file_to_buffer(map_name,&szmap,MAX_SYSTEM_MAP_SIZE);
if(map_size == 0)
return -1;
printk("map file size is %2d\n",map_size);
record_count = get_record_count(szmap,&symbol_size);
sm_size = sizeof(SYSTEM_MAP)+(sizeof(SYSTEM_MAP_RECORD)*record_count)+symbol_size;
psm = (PSYSTEM_MAP)vmalloc(sm_size);
if(psm == 0)
{
vfree(szmap);
return -2;
}
memset(psm,0,sm_size);
psm->free_symbol_buffer_size = symbol_size;
psm->symbol_buffer_offset = (char *)psm+sizeof(SYSTEM_MAP)+(sizeof(SYSTEM_MAP_RECORD)*(record_count-1));
psm->record_count = record_count;
load_record(szmap,psm);
vfree(szmap);
//test
// unsigned long addr;
// addr = get_addr_from_map("do_syscall_trace");
// printk("%p\n",(void *)addr);
return 0;
}
void unload_system_map()
{
if(psm)
vfree(psm);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -