我写了这个简单的内核模块:
#include <linux/module.h> // for printk()
int init( void )
{
printk( "n Kello, everybody! nn" );
return 0;
}
void exit( void )
{
printk( "n Goodbye now... nn" );
}
MODULE_LICENSE("GPL");
module_init(init);
module_exit(exit);
我试图理解代码是如何转换为asm的,所以我对它进行了反思:
root@ubuntu:/home/alex/Desktop/KModule# objdump -D kmodule.ko
kmodule.ko: file format elf64-x86-64
Disassembly of section .note.gnu.build-id:
0000000000000000 <.note.gnu.build-id>:
0: 04 00 add $0x0,%al
2: 00 00 add %al,(%rax)
4: 14 00 adc $0x0,%al
6: 00 00 add %al,(%rax)
8: 03 00 add (%rax),%eax
a: 00 00 add %al,(%rax)
c: 47 rex.RXB
d: 4e 55 rex.WRX push %rbp
f: 00 5e ef add %bl,-0x11(%rsi)
12: 7d 73 jge 87 <__mod_vermagic5+0x4f>
14: 83 47 e9 4d addl $0x4d,-0x17(%rdi)
18: 98 cwtl
19: eb b8 jmp ffffffffffffffd3 <__mod_vermagic5+0xffffffffffffff9b>
1b: eb 18 jmp 35 <__module_depends+0x6>
1d: fb sti
1e: 84 28 test %ch,(%rax)
20: 73 db jae fffffffffffffffd <__mod_vermagic5+0xffffffffffffffc5>
22: 51 push %rcx
23: e4 .byte 0xe4
Disassembly of section .text:
0000000000000000 <init>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: e8 00 00 00 00 callq 9 <init+0x9>
9: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
10: 31 c0 xor %eax,%eax
12: e8 00 00 00 00 callq 17 <init+0x17>
17: 31 c0 xor %eax,%eax
19: 5d pop %rbp
1a: c3 retq
1b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000000020 <cleanup_module>:
20: 55 push %rbp
21: 48 89 e5 mov %rsp,%rbp
24: e8 00 00 00 00 callq 29 <cleanup_module+0x9>
29: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
30: 31 c0 xor %eax,%eax
32: e8 00 00 00 00 callq 37 <cleanup_module+0x17>
37: 5d pop %rbp
38: c3 retq
39: 00 00 add %al,(%rax)
...
Disassembly of section .rodata.str1.1:
0000000000000000 <.rodata.str1.1>:
0: 0a 20 or (%rax),%ah
2: 20 20 and %ah,(%rax)
4: 4b rex.WXB
5: 65 gs
6: 6c insb (%dx),%es:(%rdi)
7: 6c insb (%dx),%es:(%rdi)
8: 6f outsl %ds:(%rsi),(%dx)
9: 2c 20 sub $0x20,%al
b: 65 gs
c: 76 65 jbe 73 <__mod_vermagic5+0x3b>
e: 72 79 jb 89 <__mod_vermagic5+0x51>
10: 62 (bad)
11: 6f outsl %ds:(%rsi),(%dx)
12: 64 fs
13: 79 21 jns 36 <__module_depends+0x7>
15: 20 0a and %cl,(%rdx)
17: 0a 00 or (%rax),%al
19: 0a 20 or (%rax),%ah
1b: 20 20 and %ah,(%rax)
1d: 47 6f rex.RXB outsl %ds:(%rsi),(%dx)
1f: 6f outsl %ds:(%rsi),(%dx)
20: 64 fs
21: 62 (bad)
22: 79 65 jns 89 <__mod_vermagic5+0x51>
24: 20 6e 6f and %ch,0x6f(%rsi)
27: 77 2e ja 57 <__mod_vermagic5+0x1f>
29: 2e 2e 20 0a cs and %cl,%cs:(%rdx)
2d: 0a 00 or (%rax),%al
Disassembly of section .modinfo:
0000000000000000 <__mod_license27>:
0: 6c insb (%dx),%es:(%rdi)
1: 69 63 65 6e 73 65 3d imul $0x3d65736e,0x65(%rbx),%esp
8: 47 50 rex.RXB push %r8
a: 4c 00 73 72 rex.WR add %r14b,0x72(%rbx)
000000000000000c <__mod_srcversion31>:
c: 73 72 jae 80 <__mod_vermagic5+0x48>
e: 63 76 65 movslq 0x65(%rsi),%esi
11: 72 73 jb 86 <__mod_vermagic5+0x4e>
13: 69 6f 6e 3d 45 33 46 imul $0x4633453d,0x6e(%rdi),%ebp
1a: 38 45 32 cmp %al,0x32(%rbp)
1d: 30 39 xor %bh,(%rcx)
1f: 34 37 xor $0x37,%al
21: 44 32 31 xor (%rcx),%r14b
24: 33 30 xor (%rax),%esi
26: 32 35 44 36 39 34 xor 0x34393644(%rip),%dh # 34393670 <__mod_vermagic5+0x34393638>
2c: 34 45 xor $0x45,%al
...
000000000000002f <__module_depends>:
2f: 64 fs
30: 65 gs
31: 70 65 jo 98 <__mod_vermagic5+0x60>
33: 6e outsb %ds:(%rsi),(%dx)
34: 64 fs
35: 73 3d jae 74 <__mod_vermagic5+0x3c>
...
0000000000000038 <__mod_vermagic5>:
38: 76 65 jbe 9f <__mod_vermagic5+0x67>
3a: 72 6d jb a9 <__mod_vermagic5+0x71>
3c: 61 (bad)
3d: 67 69 63 3d 33 2e 30 imul $0x2e302e33,0x3d(%ebx),%esp
44: 2e
45: 30 2d 31 36 2d 67 xor %ch,0x672d3631(%rip) # 672d367c <__mod_vermagic5+0x672d3644>
4b: 65 6e outsb %gs:(%rsi),(%dx)
4d: 65 gs
4e: 72 69 jb b9 <__mod_vermagic5+0x81>
50: 63 20 movslq (%rax),%esp
52: 53 push %rbx
53: 4d 50 rex.WRB push %r8
55: 20 6d 6f and %ch,0x6f(%rbp)
58: 64 fs
59: 5f pop %rdi
5a: 75 6e jne ca <__mod_vermagic5+0x92>
5c: 6c insb (%dx),%es:(%rdi)
5d: 6f outsl %ds:(%rsi),(%dx)
5e: 61 (bad)
5f: 64 20 6d 6f and %ch,%fs:0x6f(%rbp)
63: 64 fs
64: 76 65 jbe cb <__mod_vermagic5+0x93>
66: 72 73 jb db <__mod_vermagic5+0xa3>
68: 69 .byte 0x69
69: 6f outsl %ds:(%rsi),(%dx)
6a: 6e outsb %ds:(%rsi),(%dx)
6b: 73 20 jae 8d <__mod_vermagic5+0x55>
...
Disassembly of section __mcount_loc:
0000000000000000 <__mcount_loc>:
...
Disassembly of section __versions:
0000000000000000 <____versions>:
0: 73 24 jae 26 <____versions+0x26>
2: 57 push %rdi
3: 41 00 00 add %al,(%r8)
6: 00 00 add %al,(%rax)
8: 6d insl (%dx),%es:(%rdi)
9: 6f outsl %ds:(%rsi),(%dx)
a: 64 fs
b: 75 6c jne 79 <____versions+0x79>
d: 65 gs
e: 5f pop %rdi
f: 6c insb (%dx),%es:(%rdi)
10: 61 (bad)
11: 79 6f jns 82 <____versions+0x82>
13: 75 74 jne 89 <____versions+0x89>
...
3d: 00 00 add %al,(%rax)
3f: 00 49 a0 add %cl,-0x60(%rcx)
42: e1 27 loope 6b <____versions+0x6b>
44: 00 00 add %al,(%rax)
46: 00 00 add %al,(%rax)
48: 70 72 jo bc <____versions+0xbc>
4a: 69 6e 74 6b 00 00 00 imul $0x6b,0x74(%rsi),%ebp
...
7d: 00 00 add %al,(%rax)
7f: 00 9a 0f 39 b4 00 add %bl,0xb4390f(%rdx)
85: 00 00 add %al,(%rax)
87: 00 6d 63 add %ch,0x63(%rbp)
8a: 6f outsl %ds:(%rsi),(%dx)
8b: 75 6e jne fb <__mod_vermagic5+0xc3>
8d: 74 00 je 8f <____versions+0x8f>
...
Disassembly of section .gnu.linkonce.this_module:
0000000000000000 <__this_module>:
...
18: 6b 6d 6f 64 imul $0x64,0x6f(%rbp),%ebp
1c: 75 6c jne 8a <__this_module+0x8a>
1e: 65 00 00 add %al,%gs:(%rax)
...
Disassembly of section .comment:
0000000000000000 <.comment>:
0: 00 47 43 add %al,0x43(%rdi)
3: 43 3a 20 rex.XB cmp (%r8),%spl
6: 28 55 62 sub %dl,0x62(%rbp)
9: 75 6e jne 79 <__mod_vermagic5+0x41>
b: 74 75 je 82 <__mod_vermagic5+0x4a>
d: 2f (bad)
e: 4c 69 6e 61 72 6f 20 imul $0x34206f72,0x61(%rsi),%r13
15: 34
16: 2e 36 2e 31 2d 39 75 cs ss xor %ebp,%cs:%ss:0x75627539(%rip) # 75627558 <__mod_vermagic5+0x75627520>
1d: 62 75
1f: 6e outsb %ds:(%rsi),(%dx)
20: 74 75 je 97 <__mod_vermagic5+0x5f>
22: 33 29 xor (%rcx),%ebp
24: 20 34 2e and %dh,(%rsi,%rbp,1)
27: 36 2e 31 00 ss xor %eax,%cs:%ss:(%rax)
2b: 00 47 43 add %al,0x43(%rdi)
2e: 43 3a 20 rex.XB cmp (%r8),%spl
31: 28 55 62 sub %dl,0x62(%rbp)
34: 75 6e jne a4 <__mod_vermagic5+0x6c>
36: 74 75 je ad <__mod_vermagic5+0x75>
38: 2f (bad)
39: 4c 69 6e 61 72 6f 20 imul $0x34206f72,0x61(%rsi),%r13
40: 34
41: 2e 36 2e 31 2d 39 75 cs ss xor %ebp,%cs:%ss:0x75627539(%rip) # 75627583 <__mod_vermagic5+0x7562754b>
48: 62 75
4a: 6e outsb %ds:(%rsi),(%dx)
4b: 74 75 je c2 <__mod_vermagic5+0x8a>
4d: 33 29 xor (%rcx),%ebp
4f: 20 34 2e and %dh,(%rsi,%rbp,1)
52: 36 2e 31 00 ss xor %eax,%cs:%ss:(%rax)
但有些东西与其他东西并不相符......
如何调用printk函数?我只能看到“callq 9”,而且这个偏移并没有告诉我任何事情......这是下一条指令..那么什么?消息“Kello”被正确打印但我无法找到发生这种情况的代码!
此外..这段代码如何在.rodata.str1.1部分中访问字符串“Kello etc ..”?如果这是映射到ds寄存器的程序段,那么不应该像“ds:0”那样访问它吗?
我很困惑..
答案 0 :(得分:32)
内核模块是可重定位的,并在加载时链接到内核中。实际的内存地址仅在那时确定。这是因为在编译时不知道内核函数的地址和加载模块的地址。
如果查看所有call
指令的字节码,您将看到它们都有四个零字节。加载模块时,这些字节将替换为实际的功能地址。对于字符串地址也是如此:在指令mov $0x0,%rdi
中,零将被替换为正确的地址。
您看到callq 9
和callq 17
等指令的原因是call
指令指定地址相对于下一条指令。由于存储在文件中的相对地址为0,因此反汇编程序将显示它,好像call
指令正在调用它后面的指令。
使用objdump -r
应该显示模块的重定位。