Insert binary instructions for the Linux kernel function and calibration offset craft

Earlier he wrote two articles about the heterozygous juggler craft aspects:
https://blog.csdn.net/dog250/article/details/105129254
https://blog.csdn.net/dog250/article/details/105093969
not very quickly, because when I move a complete function to another, I deliberately avoid using relative address offset calibration instruction addressing core issues , also are called for simplicity.

Lost calibration instructions, binary hook technology has lost its soul!

Then, this paper we will face relatively offset calibration instruction address for addressing the problem.

First, we look foregoing that hook_read function:

static ssize_t hook_read(struct file *file, char __user *ubuf, size_t count, loff_t *ppos)
{
	int n = 0;
	char kb[16];
	if (*ppos != 0) {
		return 0;
	}

	n = sprintf(kb, "%d", 1234);
	memcpy(ubuf, kb, n);
	*ppos += n;
	return n;
}

We look at its dis disassembly:

crash> dis hook_read
0xffffffffa0374000 <hook_read>: nopl   0x0(%rax,%rax,1) [FTRACE NOP]
0xffffffffa0374005 <hook_read+5>:       push   %rbp
0xffffffffa0374006 <hook_read+6>:       mov    %rsp,%rbp
0xffffffffa0374009 <hook_read+9>:       push   %r13
0xffffffffa037400b <hook_read+11>:      push   %r12
0xffffffffa037400d <hook_read+13>:      push   %rbx
0xffffffffa037400e <hook_read+14>:      mov    %rcx,%rbx
0xffffffffa0374011 <hook_read+17>:      sub    $0x18,%rsp
0xffffffffa0374015 <hook_read+21>:      mov    %gs:0x28,%rax
0xffffffffa037401e <hook_read+30>:      mov    %rax,-0x20(%rbp)
0xffffffffa0374022 <hook_read+34>:      xor    %eax,%eax
0xffffffffa0374024 <hook_read+36>:      cmpq   $0x0,(%rcx)
0xffffffffa0374028 <hook_read+40>:      jne    0xffffffffa037405a <hook_read+90>
0xffffffffa037402a <hook_read+42>:      lea    -0x30(%rbp),%rdi
0xffffffffa037402e <hook_read+46>:      mov    %rsi,%r13
0xffffffffa0374031 <hook_read+49>:      mov    $0x4d2,%edx
0xffffffffa0374036 <hook_read+54>:      mov    $0xffffffffa0375024,%rsi
0xffffffffa037403d <hook_read+61>:      callq  0xffffffff812fd960 <sprintf>
0xffffffffa0374042 <hook_read+66>:      lea    -0x30(%rbp),%rsi
0xffffffffa0374046 <hook_read+70>:      movslq %eax,%r12
0xffffffffa0374049 <hook_read+73>:      mov    %r13,%rdi
0xffffffffa037404c <hook_read+76>:      mov    %r12,%rdx
0xffffffffa037404f <hook_read+79>:      callq  0xffffffff812ff530 <__memcpy>
0xffffffffa0374054 <hook_read+84>:      add    %r12,(%rbx)
0xffffffffa0374057 <hook_read+87>:      mov    %r12,%rax
0xffffffffa037405a <hook_read+90>:      mov    -0x20(%rbp),%rdx
0xffffffffa037405e <hook_read+94>:      xor    %gs:0x28,%rdx
0xffffffffa0374067 <hook_read+103>:     jne    0xffffffffa0374074 <hook_read+116>
0xffffffffa0374069 <hook_read+105>:     add    $0x18,%rsp
0xffffffffa037406d <hook_read+109>:     pop    %rbx
0xffffffffa037406e <hook_read+110>:     pop    %r12
0xffffffffa0374070 <hook_read+112>:     pop    %r13
0xffffffffa0374072 <hook_read+114>:     pop    %rbp
0xffffffffa0374073 <hook_read+115>:     retq
0xffffffffa0374074 <hook_read+116>:     callq  0xffffffff81074510 <__stack_chk_fail>

OK, now let's techniques described previously by copying it to another location:

void test_sub1(void) __attribute__ ((aligned (1024)));
void test_sub2(void) __attribute__ ((aligned (1024)));
void test_sub1(void)
{
	printk("yes\n");
}
void test_sub2(void)
{
	printk("yes yes\n");
}
...
char *addr = 0xffffffffa0374000;
p = test_sub1;

_text_poke_smp(p, addr, 130);

Then we look at the disassembly test_sub1 of what it had:

crash> dis ffffffffa037f000 80
0xffffffffa037f000 <test_sub1>: nopl   0x0(%rax,%rax,1) [FTRACE NOP]
0xffffffffa037f005 <test_sub1+5>:       push   %rbp
0xffffffffa037f006 <test_sub1+6>:       mov    %rsp,%rbp
0xffffffffa037f009 <test_sub1+9>:       push   %r13
0xffffffffa037f00b <test_sub1+11>:      push   %r12
0xffffffffa037f00d <test_sub1+13>:      push   %rbx
0xffffffffa037f00e <test_sub1+14>:      mov    %rcx,%rbx
0xffffffffa037f011 <test_sub1+17>:      sub    $0x18,%rsp
0xffffffffa037f015 <test_sub1+21>:      mov    %gs:0x28,%rax
0xffffffffa037f01e <test_sub1+30>:      mov    %rax,-0x20(%rbp)
0xffffffffa037f022 <test_sub1+34>:      xor    %eax,%eax
0xffffffffa037f024 <test_sub1+36>:      cmpq   $0x0,(%rcx)
0xffffffffa037f024 <test_sub1+36>:      cmpq   $0x0,(%rcx)
0xffffffffa037f028 <test_sub1+40>:      jne    0xffffffffa037f05a <test_sub1+90>
0xffffffffa037f02a <test_sub1+42>:      lea    -0x30(%rbp),%rdi
0xffffffffa037f02e <test_sub1+46>:      mov    %rsi,%r13
0xffffffffa037f031 <test_sub1+49>:      mov    $0x4d2,%edx
0xffffffffa037f036 <test_sub1+54>:      mov    $0xffffffffa0375024,%rsi
0xffffffffa037f03d <test_sub1+61>:      callq  0xffffffff81313960 <__dynamic_netdev_dbg+48>
0xffffffffa037f042 <test_sub1+66>:      lea    -0x30(%rbp),%rsi
0xffffffffa037f046 <test_sub1+70>:      movslq %eax,%r12
0xffffffffa037f049 <test_sub1+73>:      mov    %r13,%rdi
0xffffffffa037f04c <test_sub1+76>:      mov    %r12,%rdx
0xffffffffa037f04f <test_sub1+79>:      callq  0xffffffff8130a530 <assoc_array_gc+1168>
0xffffffffa037f054 <test_sub1+84>:      add    %r12,(%rbx)
0xffffffffa037f057 <test_sub1+87>:      mov    %r12,%rax
0xffffffffa037f05a <test_sub1+90>:      mov    -0x20(%rbp),%rdx
0xffffffffa037f05e <test_sub1+94>:      xor    %gs:0x28,%rdx
0xffffffffa037f067 <test_sub1+103>:     jne    0xffffffffa037f074 <test_sub1+116>

All hell broke loose, like what __dynamic_netdev_dbg, call assoc_array_gc such nonsense! If you run it, the system will run fly!

This is because we do not address them relatively calibration caused.

We have to do is very simple, only need to scan RELATIVE ADDRESS instruction can, like for example "0xe8 call", "0xe9 jmp " and so on.

Take the following hook_read instructions example:

0xffffffffa037403d <hook_read+61>:      callq  0xffffffff812fd960 <sprintf>

We try to disassemble it:

crash> rd -8 0xffffffffa037403d
ffffffffa037403d:  e8                                                .
crash> rd -8 0xffffffffa037403e
ffffffffa037403e:  1e                                                .
crash> rd -8 0xffffffffa037403f
ffffffffa037403f:  99                                                .
crash> rd -8 0xffffffffa0374040
ffffffffa0374040:  f8                                                .
crash> rd -8 0xffffffffa0374041
ffffffffa0374041:  e0                                                .
crash> rd -8 0xffffffffa0374042
ffffffffa0374042:  48                                                H
crash> rd -32 0xffffffffa037403e
ffffffffa037403e:  e0f8991e

OK, we know 0xe0f8991e is a relative shift, we only need a new function, use it minus the offset additional function, is the original offset, the approach is very simple, as follows:

	unsigned int off;
	unsigned int v;
	...
	p = test_sub1;
	addr = _hook_read;
	pos = (unsigned int)((long)p - (long)addr);
	v = *((unsigned int *)&addr[62]);
	v -= off;

	_text_poke_smp(&p[62], &v, 4);

Shining this way, we put a similar function throughout all calibration instructions, dis again, you will see the correct result:

crash> dis ffffffffa0365000 80
0xffffffffa0365000 <test_sub1>: nopl   0x0(%rax,%rax,1) [FTRACE NOP]
0xffffffffa0365005 <test_sub1+5>:       push   %rbp
0xffffffffa0365006 <test_sub1+6>:       mov    %rsp,%rbp
0xffffffffa0365009 <test_sub1+9>:       push   %r13
0xffffffffa036500b <test_sub1+11>:      push   %r12
0xffffffffa036500d <test_sub1+13>:      push   %rbx
0xffffffffa036500e <test_sub1+14>:      mov    %rcx,%rbx
0xffffffffa0365011 <test_sub1+17>:      sub    $0x18,%rsp
0xffffffffa0365015 <test_sub1+21>:      mov    %gs:0x28,%rax
0xffffffffa036501e <test_sub1+30>:      mov    %rax,-0x20(%rbp)
0xffffffffa0365022 <test_sub1+34>:      xor    %eax,%eax
0xffffffffa0365024 <test_sub1+36>:      cmpq   $0x0,(%rcx)
0xffffffffa0365028 <test_sub1+40>:      jne    0xffffffffa036505a <test_sub1+90>
0xffffffffa036502a <test_sub1+42>:      lea    -0x30(%rbp),%rdi
0xffffffffa036502e <test_sub1+46>:      mov    %rsi,%r13
0xffffffffa0365031 <test_sub1+49>:      mov    $0x4d2,%edx
0xffffffffa0365036 <test_sub1+54>:      mov    $0xffffffffa0375024,%rsi
0xffffffffa036503d <test_sub1+61>:      callq  0xffffffff812fd960 <sprintf>
0xffffffffa0365042 <test_sub1+66>:      lea    -0x30(%rbp),%rsi
0xffffffffa0365046 <test_sub1+70>:      movslq %eax,%r12
0xffffffffa0365049 <test_sub1+73>:      mov    %r13,%rdi
0xffffffffa036504c <test_sub1+76>:      mov    %r12,%rdx
0xffffffffa036504f <test_sub1+79>:      callq  0xffffffff812ff530 <__memcpy>
0xffffffffa0365054 <test_sub1+84>:      add    %r12,(%rbx)
0xffffffffa0365057 <test_sub1+87>:      mov    %r12,%rax
0xffffffffa036505a <test_sub1+90>:      mov    -0x20(%rbp),%rdx
0xffffffffa036505e <test_sub1+94>:      xor    %gs:0x28,%rdx
0xffffffffa0365067 <test_sub1+103>:     jne    0xffffffffa0365074 <test_sub1+116>
0xffffffffa0365069 <test_sub1+105>:     add    $0x18,%rsp
0xffffffffa036506d <test_sub1+109>:     pop    %rbx
0xffffffffa036506e <test_sub1+110>:     pop    %r12
0xffffffffa0365070 <test_sub1+112>:     pop    %r13
0xffffffffa0365072 <test_sub1+114>:     pop    %rbp
// 以下即我们需要插入的7个字节的指令
0xffffffffa0365073 <test_sub1+115>:     incl   0xffffffff81977890
0xffffffffa036507a <test_sub1+122>:     retq

For more complex cases, nothing more than manual labor children only, basic way binary hook is the same:

  • Scan all instruction sequence.
  • Calibration function for the relative addressing external command, so the operand move function of subtracting the offset value.

Of course, this is only the workers of juggling it, the manager will definitely dis.


Wenzhou shoes wet, rain water not fat!

Released 1580 original articles · won praise 5111 · Views 11,130,000 +

Guess you like

Origin blog.csdn.net/dog250/article/details/105135219