新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 应用调试-----自制系统调用、编写进程查看器

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

作者: 时间:2016-11-21 来源:网络 收藏
把29th_app_system_callkernel里的文件复制到内核目录
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] = ;
printk("sys_hello: %sn", 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, %0n" // save the argment in r0 //
"mov r1, %1n" // save the argment in r0 //
"swi %2n" // 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 hellon");
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 = %dn", 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 = %dn", val);
// 3. 返回 //
return;
}
被用于测试的应用程序如下:
while (1)
{
printf("Hello, cnt = %d, i = %dn", cnt, i);
cnt++;
i = i + 2;
sleep(5);
}
修改了可执行文件的i = i + 2; 替换为swi指令进入sys_hello,再返回。



评论


技术专区

关闭