一、自制系统调用
(1)Linux内核(基于Linux_2.6.22)
1、在syscalls.h中申明函数:
asmlinkage void sys_hello(const char __user * buf, int count);
2、在calls.S中加入sys_hello
/* 350 */ CALL(sys_timerfd)
CALL(sys_eventfd)
CALL(sys_hello)
3、在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);
}
}
(2)写一个应用函数test_system_call.c
#include <errno.h>
#include <unistd.h>
//#include <sysdep.h>
//#if defined(__thumb__) || defined(__ARM_EABI__)
//#define __NR_SYSCALL_BASE 0
//#else
#define __NR_SYSCALL_BASE 0x900000
//#endif
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");
}
int main(int argc, char **argv)
{
printf("in app, call hello\n");
hello("www.100ask.net", 15);
return 0;
}
二、编写进程查看器
使用自制的系统调用打断点(无需网络gdbserver)
主要方式:
1、 根据反汇编文件找到一条简单的指令,确定机器码(可执行文件中),把它替换为swi val。
84cc: e5823000 str r3, [r2]
84d0: e51b3010 ldr r3, [fp, #-16]
84d4: e2833002 add r3, r3, #2 ; 0x2
// 因为这条指令比较简单
// 把它替换为swi指令"ef900160 swi 0x00900160"
2、执行程序(修改后的可执行文件)
3、进入sys_hello,
在sys_hello中打印信息,
执行原来的指令,
返回。
asmlinkage void sys_hello(const char __user * buf, int count)
{
static int cnt = 0;
int val;
int ret;
struct pt_regs *regs;
/* 1. 输出一些调试信息 */
/* 应用程序test_sc的反汇编里: 0001078c <cnt>: */
/* 应用程序test_sc_sleep的反汇编里: 000107c8 <cnt>: */
// 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. 返回 */
if (++cnt == 5)
{
copy_from_user(&val, (const void __user *)0x8504, 4);
printk("[0x8504] code = 0x%x\n", val);
printk("regs->ARM_lr = 0x%x\n", regs->ARM_lr);
val = 0xe2833002;
//if (copy_to_user((const void __user *)0x8504, &val, 4))
// printk("restore code error!\n");
ret = access_process_vm(current, 0x8504, &val, 4, 1);
printk("access_process_vm ret = %d\n", ret);
cnt = 0;
}
return;
}