n_value);
/* set the address to jump to */ *(unsigned long *)&code[1] = nl[1].n_value;
if(kvm_write(kd,nl[0].n_value,code,sizeof(code)) < 0) { fprintf(stderr,"ERROR: %sn",kvm_geterr(kd)); exit(-1); }
printf("Written the jumpn");
if(kvm_close(kd) < 0) { fprintf(stderr,"ERROR: %sn",kvm_geterr(kd)); exit(-1); }
exit(0); } 4.3 替换内核代码
为了避免修改已经存在的表,我们可以采用jump的方法,但是我们还是必须要提供自己的代码,有些时候这可能很方便的修改已经存在 的代码,但是这不是通用的方法,因为它不能修补版本高的内核(???)并且取决于编译器的实现。
为了鉴别用户是否是root 或者超级用户,内核调用suser,然后suser返回并调用super_xxx,这将会检查用户是否是root,并授予某些 特权,比如原始套节字,我提供了一个例子来演示修改已经存在的代码,首先我们要找到这个函数的地址,用 nm /kernel | grep super_xxx 或者用 tools/findsym 查找suser_xxx,在我的电脑上它是0xc019d538,你的也会差不多,现在我们来看一下 这里的代码
# objdump -d /kernel --start-address=0xc019d538 | more
/kernel: file format elf32-i386
Disassembly of section .text:
c019d538 : c019d538: 55 push %ebp c019d539: 89 e5 mov %esp,%ebp c019d53b: 8b 45 08 mov 0x8(%ebp),%eax //参数 cred c019d53e: 8b 55 0c mov 0xc(%ebp),%edx //参数 proc c019d541: 85 c0 test %eax,%eax //!cred c019d543: 75 20 jne c019d565 c019d545: 85 d2 test %edx,%edx c019d547: 75 13 jne c019d55c c019d549: 68 90 df 36 c0 push $0xc036df90 c019d54e: e8 5d db 00 00 call c01ab0b0 //printf c019d553: b8 01 00 00 00 mov $0x1,%eax c019d558: eb 32 jmp c019d58c c019d55a: 89 f6 mov %esi,%esi c019d55c: 85 c0 test %eax,%eax // !cred c019d55e: 75 05 jne c019d565 c019d560: 8b 42 10 mov 0x10(%edx),%eax c019d563: 8b 00 mov (%eax),%eax c019d565: 83 78 04 00 cmpl $0x0,0x4(%eax) //cred->cr_uid != 0 c019d569: 75 e8 jne c019d553 c019d56b: 85 d2 test %edx,%edx c019d56d: 74 1b je c019d58a c019d56f: 83 ba 60 01 00 00 00 cmpl $0x0,0x160(%edx) c019d576: 74 07 je c019d57f c019d578: 8b 45 10 mov 0x10(%ebp),%eax c019d57b: a8 01 test $0x1,%al c019d57d: 74 d4 je c019d553 c019d57f: 85 d2 test %edx,%edx c019d581: 74 07 je c019d58a c019d583: 80 8a 72 01 00 00 02 orb $0x2,0x172(%edx) c019d58a: 31 c0 xor %eax,%eax c019d58c: c9 leave c019d58d: c3 ret c019d58e: 89 f6 mov %esi,%esi
这里是反汇编的代码,下面是源代码,在/sys/kern/kern_prot.c int suser_xxx(cred, proc, flag) struct ucred *cred; struct proc *proc; int flag; { if (!cred && !proc) { printf("suser_xxx(): THINK!n"); &
|