微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 应用调试-----自制系统调用、编写进程查看器

应用调试-----自制系统调用、编写进程查看器

时间:11-21 来源:互联网 点击:
把29th_app_system_call\kernel里的文件复制到内核目录

syscalls.h ==> include/linux

read_write.c ==> fs/

calls.S ==> arch/arm/kernel

解析:当应用程序调用open、read、write函数时会执行swi val指令,从而引发一个异常,就像中断一样,就会进入内核的异常处理函数里面,根据不同的val值来调用sys_open、sys_read、sys_write(虚拟文件系统VFS),并根据操作不同的文件属性(C:字符型设备,主设备号)在chrdev数组中找到file_operations类型的结构体指针,通过file_operations结构体指针找到对应的open、read、write(first_drv_open,first_drv_write)驱动函数。可以利用驱动程序查看应用程序当中全局变量、局部变量的信息,并打印出来。

故首先在calls.S 中:

// 350

CALL(sys_timerfd)

CALL(sys_eventfd)

CALL(sys_hello) //增加sys_hello的注册

再在read_write.c 中实现sys_hello函数体:

asmlinkage void sys_hello(const char __user * buf, int count)

{

char ker_buf[100];

if (buf)

{

copy_from_user(ker_buf, buf, (count < 100) ? count : 100);

ker_buf[99] = \0;

printk("sys_hello: %s\n", ker_buf);

}

}

在syscalls.h中声明:

asmlinkage void sys_hello(const char __user * buf, int count);

再仿照glib.c中open、read等仿写hello函数:

void hello(char *buf, int count)

{

// swi //

asm ("mov r0, %0\n" // save the argment in r0 //

"mov r1, %1\n" // save the argment in r0 //

"swi %2\n" // do the system call //

:

: "r"(buf), "r"(count), "i" (__NR_SYSCALL_BASE + 352)

: "r0", "r1");

}

再在应用程序中调用hello函数:

int main(int argc, char **argv)

{

printf("in app, call hello\n");

hello("www.100ask.net", 15);

return 0;

}

以上只是在应用程序调用hello函数时发生SWI中断后利用驱动程序sys_hello打印传入的字符串,也可以修改应用程序编译后产生可执行文件中的机器码,替换成swi指令,利用swi指令进入sys_hello,在sys_hello中打印观察应用程序当中的变量信息,再执行被替换的指令后返回,如下:

asmlinkage void sys_hello(const char __user * buf, int count)

{

int val;

struct pt_regs *regs;

// 1. 输出一些调试信息 //

// 应用程序test_sc的反汇编里: 0001078c : //

// 应用程序test_sc_sleep的反汇编里: 000107c8 : //

//copy_from_user(&val, (const void __user *)0x0001078c, 4);

copy_from_user(&val, (const void __user *)0x000107c8, 4);

printk("sys_hello: cnt = %d\n", val);

// 2. 执行被替换的指令: add r3, r3, #2 ; 0x2 //

// 搜 pt_regs , 在它的结果里再搜 current //

regs = task_pt_regs(current);

regs->ARM_r3 += 2;

// 打印局部变量i //

copy_from_user(&val, (const void __user *)(regs->ARM_fp - 16), 4);

printk("sys_hello: i = %d\n", val);

// 3. 返回 //

return;

}

被用于测试的应用程序如下:

while (1)

{

printf("Hello, cnt = %d, i = %d\n", cnt, i);

cnt++;

i = i + 2;

sleep(5);

}

修改了可执行文件的i = i + 2; 替换为swi指令进入sys_hello,再返回。


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top