⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysmap.c

📁 linux unified kernel test
💻 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 + -