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

📄 command_parse.c

📁 linux内核调试小工具.可以读写指定地址上的数据
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>

#include "command_parse.h"

#define MAX_ADDR_LEN 16
#define MAX_SYMS_NAME_LEN 128

//#define DEBUG
char *read_line(char *buf, size_t count, struct file *fp);
char read_char(struct file *fp);
void * search_symbol(char *input_symbol);

char fill_test[129] = {0xfe};    
char func_para[MAX_COMMAND_STR_NUM][MAX_COMMAND_STR_LEN] = {{0},{0}};
extern struct file *sym_file;

COMMAND_TABLE ksh_cmd[MAX_COMMAN_NR] = 
{
    {"help", 0, help,               "print this msg"},
    //{"?", 0, help,                  "print this msg"},
    {"d",    2, dump_mem,           "display memory, usage:d addr,[len]"},
    {"p",    2, get_var,            "print value of var, usage:p var_name,[width]"},
    {"r",    5, run_func,           "run a func arg1, arg2...arg4"   },
    {"s",    3, set_var,            "set value of var,usage:s var_name,[width],value"},
    {"f",    3, fill_mem,           "fill a block of memory with value, usage: f addr,length,value"},
    {{0},    0, (FUNCTION)NULL,     {0}             }
};

/*
搜索命令
返回值:
 >0:命令的索引
 -1:没有找到命令 
*/
int search_cmd(char *cmd_str)
{
    int index = 0;
    
    while(ksh_cmd[index].function)
    {
        if(strcmp(ksh_cmd[index].name, cmd_str) == 0)
        {
            return index;
        }
        index++;
    }
    return -1;
}

/*解析并执行输入的命令*/
int execute_cmd(char *usr_input, char *output)
{
    char cmd_str[MAX_COMMAND_STR_LEN] = {0};
    char seps[] = " ,\t\n\r";
    int i = 0, cmd_index = -1;
    char *token = NULL;
    int output_len = 0;

#ifdef DEBUG
    printk("usr_input = %s\n", usr_input);
#endif

    token = (char *)strtok(usr_input, seps);
    
    if(token == NULL)
    {
        return 0;
    }
    
    strncpy(cmd_str, token, MAX_COMMAND_STR_LEN);
   
    cmd_index = search_cmd(cmd_str);
    if(cmd_index < 0)
    {
        output_len += sprintf(&output[output_len], "TODO: unknown cmd\n");
        return output_len;
    }

    token = (char *)strtok(NULL, seps);

    
    while((token != NULL) && (i < MAX_COMMAND_STR_NUM)) 
    {        
        strncpy(&func_para[i][0], token, MAX_COMMAND_STR_LEN);
#ifdef DEBUG
        printk("token[%d] = %s\n", i, token);
        printk("func_para[%d] = %s\n", i, &func_para[i][0]);
#endif      
        i++;
        token = (char *)strtok(NULL, seps);
    }

    output_len += (ksh_cmd[cmd_index].function)(cmd_index, i, &output[output_len]);

    return output_len;
    
}

int help(int para_count, int input_count, char *output)
{
    int index = 0;
    int output_len = 0;

    output_len += sprintf(&output[output_len], "COMMAND\t\tPARA_NR\t\tHELP\n");
    output_len += sprintf(&output[output_len], "--------------------------------------------------\n");
    while(ksh_cmd[index].function)
    {
        output_len += sprintf(&output[output_len], "%s:\t\t%d\t\t%s\n", ksh_cmd[index].name, ksh_cmd[index].para_num, ksh_cmd[index].help_string);
        index++;
    }
    return output_len;
}

int dump_mem(int cmd_index, int input_count, char *output)
{
    UINT32 addr = 0;
    UINT16 length = 0;
    char *paddr = NULL;
    int output_len = 0;
    
#ifdef DEBUG    
    int temp = 0;
    while(temp < input_count)
    {
        printk("func_para[%d]:%s\n", temp, &func_para[temp][0]);
        temp++;
    }
#endif

    if(input_count > ksh_cmd[cmd_index].para_num || input_count == 0)
    {
        output_len += sprintf(&output[output_len], "Too many args or too few args. usage:\n");
        output_len += sprintf(&output[output_len], "%s\n", ksh_cmd[cmd_index].help_string);
        return output_len;
    }
    
    
    /*检查并转换输入格式*/
    /*TODO:判断地址的合法性*/
    paddr = &func_para[0][0];
    addr = simple_strtoul(paddr, NULL, 0);
    if ((addr == 0) 
        && (strcmp(paddr,"0")!=0) 
        && (strcmp(paddr,"0x0")!=0) 
        && (strcmp(paddr,"00")!=0) 
        && (strcmp(paddr,"0x00")!=0))
    {
        output_len += sprintf(&output[output_len], "format of addr is wrong\n");
        return output_len;
    }
    if(input_count == 1)
    {
        length = 128;
    }else
    {
        length = simple_strtol(&func_para[1][0], NULL, 0);
        if(length == 0) 
        {
            output_len += sprintf(&output[output_len], "format of length is wrong, or length is 0\n");
            return output_len;
        }else if(length > 4095){
            output_len += sprintf(&output[output_len], "length > 4095, not supported!\n");
            return output_len;        	
        }
        
       
    }
    
    output_len += print_mem((UINT8*)addr, length, &output[output_len]);
    return output_len;
}

int print_mem(UINT8 *addr, UINT16 length, char *output)
{
    int i;
    int output_len = 0;
    
	output_len += sprintf(&output[output_len], "addr = 0x%08x, length = %d", (UINT32)addr, length);
	
	/*debug*/
	//addr = (UINT8*)(&func_para[0][0]); 
	
    for(i = 0; i < length; i++)
    {
        if((i%16)==0)
        {
            output_len += sprintf(&output[output_len], "\n0x%08x: ", (UINT32)&addr[i]);
        }else if((i%8)==0)
        {
            output_len += sprintf(&output[output_len], "- ");
        }
        output_len += sprintf(&output[output_len], "%2.2x ", (UINT8)addr[i]);
    }
    output_len += sprintf(&output[output_len], "\n");
    
    return output_len;
}

/*打印变量的数值*/
int get_var(int cmd_index, int input_count, char *output)
{
    void * var_addr = NULL;
    int output_len = 0;
    int width = 0;
    
    if(sym_file == NULL)
    {
        output_len += sprintf(&output[output_len],"Should not run to here %s\n", __func__);
        return output_len;
    }
    
    if(input_count == 0)
    {
        output_len += sprintf(&output[output_len], "Missed var name, %s\n", ksh_cmd[cmd_index].help_string);
        return output_len;
    }
    
    /*解析符号表,找到对应的变量*/
    var_addr = search_symbol(&func_para[0][0]);
    if(var_addr == NULL)
    {
        output_len += sprintf(&output[output_len],"Undefined symbol '%s'\n", &func_para[0][0]);
        return output_len;
    }else
    {
        output_len += sprintf(&output[output_len],"%s @ 0x%08x\n", &func_para[0][0], (UINT32)var_addr);
    }
  
    if(input_count == 1){
        /*p var_name width*/
        width = sizeof(UINT32);
    }else{
        width = simple_strtoul(&func_para[1][0], NULL, 0);
    }
    
    switch(width){
        case 1:
            output_len += sprintf(&output[output_len], "%s = %d = 0x%08x\n", \
                &func_para[0][0], *((UINT8*)var_addr), *((UINT8*)var_addr));
            break;
        case 2:
            output_len += sprintf(&output[output_len], "%s = %d = 0x%08x\n", \
                &func_para[0][0], *((UINT16*)var_addr), *((UINT16*)var_addr));            
            break;
        case 4:
            output_len += sprintf(&output[output_len], "%s = %d = 0x%08x\n", \
                &func_para[0][0], *((UINT32*)var_addr), *((UINT32*)var_addr));            
            break;
        default:
            output_len += sprintf(&output[output_len], "%s = %d = 0x%08x\n", \
                &func_para[0][0], *((UINT32*)var_addr), *((UINT32*)var_addr));            
            break;
    }
   
    return output_len;
}

/*执行一个内核函数*/
int run_func(int cmd_index, int input_count, char *output)
{
    void * func_addr = NULL;
    int output_len = 0;
    UINT32 res = 0;
    if(sym_file == NULL)
    {
        output_len += sprintf(&output[output_len],"Should not run to here %s\n", __func__);
        return output_len;
    }
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -