rootkit for linux 7.大杀器---反汇编引擎xde
2008-11-12 22:22
591 查看
今天在找net_device.hard_start_xmit的偏移的时候,发现手动波完全不能用了。于是,在网上找了ade的开源反汇编引擎,用asm自己再写了一遍,大概知道了流程。
不是有意改成xde的,是我记错了名字。把ade记成了xde。。
今天发现自己的汇编底子不行啊,c -> asm 都这么吃力,更何况 asm -> c。
关于反汇编引擎,网上有教程的,也有开源的example,但不多。如果有啥不清楚,可以查 intel 的那几本手册的,那个讲得最清楚。
经过测试,发现ade不支持prefetchnta指令。这jb指令是在 list_for_each_rcu 里出现的。都不知道啥意思,不过改了 ade_table 的一个字段的值就能正常反汇编了。
贴代码贴代码:
EXPORT_LABEL(xde_table)
.long C_MODRM // 00
.long C_MODRM // 01
.long C_MODRM // 02
.long C_MODRM // 03
.long C_DATA1 // 04
.long C_DATA66 // 05
.long C_BAD // 06
.long C_BAD // 07
.long C_MODRM // 08
.long C_MODRM // 09
.long C_MODRM // 0A
.long C_MODRM // 0B
.long C_DATA1 // 0C
.long C_DATA66 // 0D
.long C_BAD // 0E
.long C_OPCODE2 // 0F
.long C_MODRM+C_BAD // 10
.long C_MODRM // 11
.long C_MODRM+C_BAD // 12
.long C_MODRM // 13
.long C_DATA1+C_BAD // 14
.long C_DATA66+C_BAD // 15
.long C_BAD // 16
.long C_BAD // 17
.long C_MODRM+C_BAD // 18
.long C_MODRM // 19
.long C_MODRM // 1A
.long C_MODRM // 1B
.long C_DATA1+C_BAD // 1C
.long C_DATA66+C_BAD // 1D
.long C_BAD // 1E
.long C_BAD // 1F
.long C_MODRM // 20
.long C_MODRM // 21
.long C_MODRM // 22
.long C_MODRM // 23
.long C_DATA1 // 24
.long C_DATA66 // 25
.long C_SEG+C_BAD // 26
.long C_BAD // 27
.long C_MODRM // 28
.long C_MODRM // 29
.long C_MODRM // 2A
.long C_MODRM // 2B
.long C_DATA1 // 2C
.long C_DATA66 // 2D
.long C_SEG+C_BAD // 2E
.long C_BAD // 2F
.long C_MODRM // 30
.long C_MODRM // 31
.long C_MODRM // 32
.long C_MODRM // 33
.long C_DATA1 // 34
.long C_DATA66 // 35
.long C_SEG+C_BAD // 36
.long C_BAD // 37
.long C_MODRM // 38
.long C_MODRM // 39
.long C_MODRM // 3A
.long C_MODRM // 3B
.long C_DATA1 // 3C
.long C_DATA66 // 3D
.long C_SEG+C_BAD // 3E
.long C_BAD // 3F
.long 0 // 40
.long 0 // 41
.long 0 // 42
.long 0 // 43
.long C_BAD // 44
.long 0 // 45
.long 0 // 46
.long 0 // 47
.long 0 // 48
.long 0 // 49
.long 0 // 4A
.long 0 // 4B
.long C_BAD // 4C
.long 0 // 4D
.long 0 // 4E
.long 0 // 4F
.long 0 // 50
.long 0 // 51
.long 0 // 52
.long 0 // 53
.long 0 // 54
.long 0 // 55
.long 0 // 56
.long 0 // 57
.long 0 // 58
.long 0 // 59
.long 0 // 5A
.long 0 // 5B
.long C_BAD // 5C
.long 0 // 5D
.long 0 // 5E
.long 0 // 5F
.long C_BAD // 60
.long C_BAD // 61
.long C_MODRM+C_BAD // 62
.long C_MODRM+C_BAD // 63
.long C_SEG // 64
.long C_SEG+C_BAD // 65
.long C_66 // 66
.long C_67 // 67
.long C_DATA66 // 68
.long C_MODRM+C_DATA66 // 69
.long C_DATA1 // 6A
.long C_MODRM+C_DATA1 // 6B
.long C_BAD // 6C
.long C_BAD // 6D
.long C_BAD // 6E
.long C_BAD // 6F
.long C_DATA1+C_REL+C_BAD // 70
.long C_DATA1+C_REL+C_BAD // 71
.long C_DATA1+C_REL // 72
.long C_DATA1+C_REL // 73
.long C_DATA1+C_REL // 74
.long C_DATA1+C_REL // 75
.long C_DATA1+C_REL // 76
.long C_DATA1+C_REL // 77
.long C_DATA1+C_REL // 78
.long C_DATA1+C_REL // 79
.long C_DATA1+C_REL+C_BAD // 7A
.long C_DATA1+C_REL+C_BAD // 7B
.long C_DATA1+C_REL // 7C
.long C_DATA1+C_REL // 7D
.long C_DATA1+C_REL // 7E
.long C_DATA1+C_REL // 7F
.long C_MODRM+C_DATA1 // 80
.long C_MODRM+C_DATA66 // 81
.long C_MODRM+C_DATA1+C_BAD // 82
.long C_MODRM+C_DATA1 // 83
.long C_MODRM // 84
.long C_MODRM // 85
.long C_MODRM // 86
.long C_MODRM // 87
.long C_MODRM // 88
.long C_MODRM // 89
.long C_MODRM // 8A
.long C_MODRM // 8B
.long C_MODRM+C_BAD // 8C
.long C_MODRM // 8D
.long C_MODRM+C_BAD // 8E
.long C_MODRM // 8F
.long 0 // 90
.long 0 // 91
.long 0 // 92
.long C_BAD // 93
.long C_BAD // 94
.long C_BAD // 95
.long C_BAD // 96
.long C_BAD // 97
.long C_BAD // 98
.long 0 // 99
.long C_DATA66+C_DATA2+C_BAD // 9A
.long 0 // 9B
.long C_BAD // 9C
.long C_BAD // 9D
.long C_BAD // 9E
.long C_BAD // 9F
.long C_ADDR67 // A0
.long C_ADDR67 // A1
.long C_ADDR67 // A2
.long C_ADDR67 // A3
.long 0 // A4
.long 0 // A5
.long 0 // A6
.long 0 // A7
.long C_DATA1 // A8
.long C_DATA66 // A9
.long 0 // AA
.long 0 // AB
.long 0 // AC
.long C_BAD // AD
.long 0 // AE
.long C_BAD // AF
.long C_DATA1 // B0
.long C_DATA1 // B1
.long C_DATA1 // B2
.long C_DATA1 // B3
.long C_DATA1 // B4
.long C_DATA1 // B5
.long C_DATA1+C_BAD // B6
.long C_DATA1+C_BAD // B7
.long C_DATA66 // B8
.long C_DATA66 // B9
.long C_DATA66 // BA
.long C_DATA66 // BB
.long C_DATA66+C_BAD // BC
.long C_DATA66 // BD
.long C_DATA66 // BE
.long C_DATA66 // BF
.long C_MODRM+C_DATA1 // C0
.long C_MODRM+C_DATA1 // C1
.long C_DATA2+C_STOP // C2
.long C_STOP // C3
.long C_MODRM+C_BAD // C4
.long C_MODRM+C_BAD // C5
.long C_MODRM+C_DATA1 // C6
.long C_MODRM+C_DATA66 // C7
.long C_DATA2+C_DATA1 // C8
.long 0 // C9
.long C_DATA2+C_STOP+C_BAD // CA
.long C_STOP+C_BAD // CB
.long C_BAD // CC
.long C_DATA1 // CD
.long C_BAD // CE
.long C_STOP+C_BAD // CF
.long C_MODRM // D0
.long C_MODRM // D1
.long C_MODRM // D2
.long C_MODRM // D3
.long C_DATA1+C_BAD // D4
.long C_DATA1+C_BAD // D5
.long C_BAD // D6
.long C_BAD // D7
.long C_MODRM // D8
.long C_MODRM // D9
.long C_MODRM // DA
.long C_MODRM // DB
.long C_MODRM // DC
.long C_MODRM // DD
.long C_MODRM // DE
.long C_MODRM // DF
.long C_DATA1+C_REL+C_BAD // E0
.long C_DATA1+C_REL+C_BAD // E1
.long C_DATA1+C_REL // E2
.long C_DATA1+C_REL // E3
.long C_DATA1+C_BAD // E4
.long C_DATA1+C_BAD // E5
.long C_DATA1+C_BAD // E6
.long C_DATA1+C_BAD // E7
.long C_DATA66+C_REL // E8
.long C_DATA66+C_REL+C_STOP // E9
.long C_DATA66+C_DATA2+C_BAD // EA
.long C_DATA1+C_REL+C_STOP // EB
.long C_BAD // EC
.long C_BAD // ED
.long C_BAD // EE
.long C_BAD // EF
.long C_LOCK+C_BAD // F0
.long C_BAD // F1
.long C_REP // F2
.long C_REP // F3
.long C_BAD // F4
.long C_BAD // F5
.long C_MODRM // F6
.long C_MODRM // F7
.long 0 // F8
.long 0 // F9
.long C_BAD // FA
.long C_BAD // FB
.long 0 // FC
.long 0 // FD
.long C_MODRM // FE
.long C_MODRM // FF
.long C_MODRM // 00
.long C_MODRM // 01
.long C_MODRM // 02
.long C_MODRM // 03
.long C_ERROR // 04
.long C_ERROR // 05
.long 0 // 06
.long C_ERROR // 07
.long 0 // 08
.long 0 // 09
.long 0 // 0A
.long 0 // 0B
.long C_ERROR // 0C
.long C_ERROR // 0D
.long C_ERROR // 0E
.long C_ERROR // 0F
.long C_ERROR // 10
.long C_ERROR // 11
.long C_ERROR // 12
.long C_ERROR // 13
.long C_ERROR // 14
.long C_ERROR // 15
.long C_ERROR // 16
.long C_ERROR // 17
.long C_MODRM // 18
.long C_ERROR // 19
.long C_ERROR // 1A
.long C_ERROR // 1B
.long C_ERROR // 1C
.long C_ERROR // 1D
.long C_ERROR // 1E
.long C_ERROR // 1F
.long C_ERROR // 20
.long C_ERROR // 21
.long C_ERROR // 22
.long C_ERROR // 23
.long C_ERROR // 24
.long C_ERROR // 25
.long C_ERROR // 26
.long C_ERROR // 27
.long C_ERROR // 28
.long C_ERROR // 29
.long C_ERROR // 2A
.long C_ERROR // 2B
.long C_ERROR // 2C
.long C_ERROR // 2D
.long C_ERROR // 2E
.long C_ERROR // 2F
.long C_ERROR // 30
.long C_ERROR // 31
.long C_ERROR // 32
.long C_ERROR // 33
.long C_ERROR // 34
.long C_ERROR // 35
.long C_ERROR // 36
.long C_ERROR // 37
.long C_ERROR // 38
.long C_ERROR // 39
.long C_ERROR // 3A
.long C_ERROR // 3B
.long C_ERROR // 3C
.long C_ERROR // 3D
.long C_ERROR // 3E
.long C_ERROR // 3F
.long C_MODRM // 40
.long C_MODRM // 41
.long C_MODRM // 42
.long C_MODRM // 43
.long C_MODRM // 44
.long C_MODRM // 45
.long C_MODRM // 46
.long C_MODRM // 47
.long C_MODRM // 48
.long C_MODRM // 49
.long C_MODRM // 4A
.long C_MODRM // 4B
.long C_MODRM // 4C
.long C_MODRM // 4D
.long C_MODRM // 4E
.long C_MODRM // 4F
.long C_ERROR // 50
.long C_ERROR // 51
.long C_ERROR // 52
.long C_ERROR // 53
.long C_ERROR // 54
.long C_ERROR // 55
.long C_ERROR // 56
.long C_ERROR // 57
.long C_ERROR // 58
.long C_ERROR // 59
.long C_ERROR // 5A
.long C_ERROR // 5B
.long C_ERROR // 5C
.long C_ERROR // 5D
.long C_ERROR // 5E
.long C_ERROR // 5F
.long C_ERROR // 60
.long C_ERROR // 61
.long C_ERROR // 62
.long C_ERROR // 63
.long C_ERROR // 64
.long C_ERROR // 65
.long C_ERROR // 66
.long C_ERROR // 67
.long C_ERROR // 68
.long C_ERROR // 69
.long C_ERROR // 6A
.long C_ERROR // 6B
.long C_ERROR // 6C
.long C_ERROR // 6D
.long C_ERROR // 6E
.long C_ERROR // 6F
.long C_ERROR // 70
.long C_ERROR // 71
.long C_ERROR // 72
.long C_ERROR // 73
.long C_ERROR // 74
.long C_ERROR // 75
.long C_ERROR // 76
.long C_ERROR // 77
.long C_ERROR // 78
.long C_ERROR // 79
.long C_ERROR // 7A
.long C_ERROR // 7B
.long C_ERROR // 7C
.long C_ERROR // 7D
.long C_ERROR // 7E
.long C_ERROR // 7F
.long C_DATA66+C_REL // 80
.long C_DATA66+C_REL // 81
.long C_DATA66+C_REL // 82
.long C_DATA66+C_REL // 83
.long C_DATA66+C_REL // 84
.long C_DATA66+C_REL // 85
.long C_DATA66+C_REL // 86
.long C_DATA66+C_REL // 87
.long C_DATA66+C_REL // 88
.long C_DATA66+C_REL // 89
.long C_DATA66+C_REL // 8A
.long C_DATA66+C_REL // 8B
.long C_DATA66+C_REL // 8C
.long C_DATA66+C_REL // 8D
.long C_DATA66+C_REL // 8E
.long C_DATA66+C_REL // 8F
.long C_MODRM // 90
.long C_MODRM // 91
.long C_MODRM // 92
.long C_MODRM // 93
.long C_MODRM // 94
.long C_MODRM // 95
.long C_MODRM // 96
.long C_MODRM // 97
.long C_MODRM // 98
.long C_MODRM // 99
.long C_MODRM // 9A
.long C_MODRM // 9B
.long C_MODRM // 9C
.long C_MODRM // 9D
.long C_MODRM // 9E
.long C_MODRM // 9F
.long 0 // A0
.long 0 // A1
.long 0 // A2
.long C_MODRM // A3
.long C_MODRM+C_DATA1 // A4
.long C_MODRM // A5
.long C_ERROR // A6
.long C_ERROR // A7
.long 0 // A8
.long 0 // A9
.long 0 // AA
.long C_MODRM // AB
.long C_MODRM+C_DATA1 // AC
.long C_MODRM // AD
.long C_ERROR // AE
.long C_MODRM // AF
.long C_MODRM // B0
.long C_MODRM // B1
.long C_MODRM // B2
.long C_MODRM // B3
.long C_MODRM // B4
.long C_MODRM // B5
.long C_MODRM // B6
.long C_MODRM // B7
.long C_ERROR // B8
.long C_ERROR // B9
.long C_MODRM+C_DATA1 // BA
.long C_MODRM // BB
.long C_MODRM // BC
.long C_MODRM // BD
.long C_MODRM // BE
.long C_MODRM // BF
.long C_MODRM // C0
.long C_MODRM // C1
.long C_ERROR // C2
.long C_ERROR // C3
.long C_ERROR // C4
.long C_ERROR // C5
.long C_ERROR // C6
.long C_ERROR // C7
.long 0 // C8
.long 0 // C9
.long 0 // CA
.long 0 // CB
.long 0 // CC
.long C_DATA1 // CD
.long 0 // CE
.long 0 // CF
.long C_ERROR // D0
.long C_ERROR // D1
.long C_ERROR // D2
.long C_ERROR // D3
.long C_ERROR // D4
.long C_ERROR // D5
.long C_ERROR // D6
.long C_ERROR // D7
.long C_ERROR // D8
.long C_ERROR // D9
.long C_ERROR // DA
.long C_ERROR // DB
.long C_ERROR // DC
.long C_ERROR // DD
.long C_ERROR // DE
.long C_ERROR // DF
.long C_ERROR // E0
.long C_ERROR // E1
.long C_ERROR // E2
.long C_ERROR // E3
.long C_ERROR // E4
.long C_ERROR // E5
.long C_ERROR // E6
.long C_ERROR // E7
.long C_ERROR // E8
.long C_ERROR // E9
.long C_ERROR // EA
.long C_ERROR // EB
.long C_ERROR // EC
.long C_ERROR // ED
.long C_ERROR // EE
.long C_ERROR // EF
.long C_ERROR // F0
.long C_ERROR // F1
.long C_ERROR // F2
.long C_ERROR // F3
.long C_ERROR // F4
.long C_ERROR // F5
.long C_ERROR // F6
.long C_ERROR // F7
.long C_ERROR // F8
.long C_ERROR // F9
.long C_ERROR // FA
.long C_ERROR // FB
.long C_ERROR // FC
.long C_ERROR // FD
.long C_ERROR // FE
.long C_ERROR // FF
#define C_ERROR 0xFFFFFFFF
#define C_ADDR1 0x00000001 //操作码中地址大小的位字段(字节)
#define C_ADDR2 0x00000002
#define C_ADDR4 0x00000004 //(双字)
#define C_LOCK 0x00000008 //加锁前缀
#define C_67 0x00000010 //地址大小修饰前缀(16/32位)
#define C_66 0x00000020 //操作数大小修饰前缀(16/32位)
#define C_REP 0x00000040 //重复前缀
#define C_SEG 0x00000080 //段寄存器前缀
#define C_ANYPREFIX (C_66+C_67+C_LOCK+C_REP+C_SEG)
#define C_DATA1 0x00000100 //操作码中数据大小的位字段
#define C_DATA2 0x00000200
#define C_DATA4 0x00000400
#define C_SIB 0x00000800 //SIB字节
#define C_ADDR67 0x00001000 //地址字节数为disasm_defaddr
#define C_DATA66 0x00002000 //数据字节数为disasm_defdata
#define C_MODRM 0x00004000 //MODRM字节
#define C_BAD 0x00008000
#define C_OPCODE2 0x00010000 //操作码第二个字节
#define C_REL 0x00020000 // 这是跳转指令jxx或者call
#define C_STOP 0x00040000 // 这是回跳指令,ret_code或者jmp
/*
struct dism
{
BYTE defaddr; // 00
BYTE defdata; // 01
DWORD len; // 02 03 04 05
DWORD flag; // 06 07 08 09
DWORD addrsize; // 0A 0B 0C 0D
DWORD datasize; // 0E 0F 10 11
BYTE rep; // 12
BYTE seg; // 13
BYTE opcode; // 14
BYTE opcode2; // 15
BYTE modrm; // 16
BYTE sib; // 17
BYTE addr[8]; // 18
BYTE data[8]; // 20
};
*/
#define dism_defaddr 0x0
#define dism_defdata 0x1
#define dism_len 0x2
#define dism_flag 0x6
#define dism_addrsize 0xa
#define dism_datasize 0xe
#define dism_rep 0x12
#define dism_seg 0x13
#define dism_opcode 0x14
#define dism_opcode2 0x15
#define dism_modrm 0x16
#define dism_sib 0x17
#define dism_addr 0x18
#define dism_data 0x20
#define sizeof_dism 0x28
#include "xde_table.s"
// int fastcall xde_dism(void *code, struct dism *di);
// @code: the code to dism
// @di: the dism struct
// ret_codeurn: dism->len
EXPORT_LABEL(xde_dism)
#define ret_code 0
#define mod 4
#define rm 5
#define opcode 6
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
movl %eax, %esi
movl %edx, %edi
subl $0x20, %esp
movl %esi, opcode(%esp)
movl $0x28, %ecx
movl %edi, %eax
1: movb $0, (%eax)
incl %eax
loop 1b
// memset(di, 0, sizeof(*di));
movb $4, dism_defdata(%edi)
movb $4, dism_defaddr(%edi)
movl $0, ret_code(%esp)
// ret_code = 0;
movw (%esi), %bx
cmpw $0x0000, %bx
jz xd_out
cmpw $0xFFFF, %bx
jz xd_out
// if (*code == 0xFFFF || *code == 0x0)
// ret_codeurn 0;
repeat_prefix:
movzbl (%esi), %eax
incl %esi
GET_ADDR(xde_table, %ebx)
movl 0(%ebx, %eax, 4), %ecx
// c = *code++;
// t = xde_table[c];
testl $C_ANYPREFIX, %ecx
jz 1f
// if (t & C_ANYPREFIX) {
testl %ecx, dism_flag(%edi)
jz 2f
// if (t & dism->flag) {
movl $0, ret_code(%esp)
jmp xd_out
// ret_codeurn 0;
2:// }
orl %ecx, dism_flag(%edi)
// dism->flag |= t;
testl $C_67, %ecx
jz 3f
// if (t & C_67)
xorb $6, dism_defaddr(%edi)
// di->defaddr ^= 6;
jmp 6f
3:
testl $C_66, %ecx
jz 4f
// if (t & C_66)
xorb $6, dism_defdata(%edi)
// di->defdata ^= 6;
jmp 6f
4:
testl $C_SEG, %ecx
jz 7f
// if (t & C_SEG)
movb %al, dism_seg(%edi)
// di->seg = c;
jmp 6f
7:
testl $C_REP, %ecx
jz 6f
// if (t & C_REP)
movb %al, dism_rep(%edi)
// di->req = c;
6:
jmp repeat_prefix
1:
// }
orl %ecx, dism_flag(%edi)
movb %al, dism_opcode(%edi)
// di->flag |= t; di->opcode = c;
cmpb $0x0F, %al
jnz 5f
// if (c == 0x0F) {
movzbl (%esi), %eax
incl %esi
// c = *code++;
movb %al, dism_opcode2(%edi)
GET_ADDR(xde_table, %ebx)
movl (256 * 4)(%ebx, %eax, 4), %ecx
orl %ecx, dism_flag(%edi)
// di->opcode2 = c; flag |= xde_table[256 + c];
cmpl $C_ERROR, dism_flag(%edi)
jnz 8f
// if (flags == C_ERROR) {
movl $0, ret_code(%esp)
jmp xd_out
// ret_codeurn 0;
8:
// }
jmp 9f
5:
cmpb $0xF7, %al
jnz 10f
// } else if (c == 0xF7) {
movb (%esi), %bl
testb $0x38, %bl
jnz 11f
// if (!(*code & 0x38))
orl $C_DATA66, dism_flag(%edi)
// di->flag |= C_DATA66;
11:
jmp 9f
10:
cmpb $0xF6, %al
jnz 9f
// } else if (c == 0xF6) {
movb (%esi), %bl
testb $0x38, %bl
jnz 12f
// if (!(*code & 0x38))
orl $C_DATA66, dism_flag(%edi)
// di->flag |= C_DATA1;
12:
// }
9:
testl $C_MODRM, dism_flag(%edi)
jz 13f
// if (flag & C_MODRM) {
movb (%esi), %al
incl %esi
// c = *code++
movb %al, dism_modrm(%edi)
// di->modrm = c;
movb %al, %ah
andb $0x38, %ah
cmpb $0x20, %ah
jnz 14f
cmpb $0xFF, dism_opcode(%edi)
jnz 14f
// if ((c & 0x38) == 0x20 && dism->opcode == 0xFF)
orl $C_STOP, dism_flag(%edi)
// di->flag |= C_STOP
14:
movb %al, mod(%esp)
andb $0xC0, mod(%esp)
movb %al, rm(%esp)
andb $0x07, rm(%esp)
// mod = c & 0xC0; rm = c & 0x07;
cmpb $0xC0, mod(%esp)
jz 15f
// if (mod != 0xC0) {
cmpb $0x4, dism_defaddr(%edi)
jnz 18f
// if (di->defaddr == 0x4) {
cmpb $0x4, rm(%esp)
jnz 24f
// if (rm == 4) {
orl $C_SIB, dism_flag(%edi)
// di->flag |= C_SIB;
movzbl (%esi), %eax
incl %esi
// c = *code++;
movb %al, dism_sib(%edi)
// di->sib = c;
movb %al, rm(%esp)
andb $0x7, rm(%esp)
// rm = c & 0x7;
24:
// }
cmpb $0x40, mod(%esp)
jnz 17f
// if (mod == 0x40)
orl $C_ADDR1, dism_flag(%edi)
// di->flag |= C_ADDR1;
jmp 21f
17:
cmpb $0x80, mod(%esp)
jnz 19f
// else if (mod == 0x80)
orl $C_ADDR4, dism_flag(%edi)
// di->flag |= C_ADDR4;
jmp 21f
19:
cmpb $0x5, rm(%esp)
jnz 21f
// else if (rm == 5)
orl $C_ADDR4, dism_flag(%edi)
// di->flag |= C_ADDR4;
21:
jmp 20f
18:
// } else {
cmpb $0x40, mod(%esp)
jnz 22f
// if (mod == 0x40)
orl $C_ADDR1, dism_flag(%edi)
// di->flag |= C_ADDR1;
jmp 23f
22:
cmpb $0x80, mod(%esp)
jz 24f
// else if (mod == 0x80)
orl $C_ADDR2, dism_flag(%edi)
// di->flag |= C_ADDR2;
jmp 23f
24:
cmpb $0x6, rm(%esp)
// else if (rm == 6)
orl $C_ADDR2, dism_flag(%edi)
// di->flag |= C_ADDR2;
23:
20:
// }
15:
// }
13:
// }
movl dism_flag(%edi), %eax
movl %eax, %ebx
movl %eax, %ecx
andl $(C_ADDR1 | C_ADDR2 | C_ADDR4), %eax
andl $(C_DATA1 | C_DATA2 | C_DATA4), %ebx
shrl $8, %ebx
testl $C_ADDR67, %ecx
jz 1f
addb dism_defaddr(%edi), %al
1:
testl $C_DATA66, %ecx
jz 2f
addb dism_defdata(%edi), %bl
2:
movl %eax, dism_addrsize(%edi)
movl %ebx, dism_datasize(%edi)
movl %edi, %edx
movl %eax, %ecx
leal dism_addr(%edx), %edi
cld; rep movsb
movl %ebx, %ecx
leal dism_data(%edx), %edi
cld; rep movsb
subl opcode(%esp), %esi
movl %esi, ret_code(%esp)
movl %esi, dism_len(%edx)
xd_out:
movl ret_code(%esp), %eax
addl $0x20, %esp
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
ret
#undef opcode
#undef retcode
#undef mod
#undef rm
好了,现在大杀器已经准备完毕了,那我们怎么用呢?
我们看看这个dev_hart_start_xmit的反汇编:
00000000 <.data>:
0: 55 push %ebp
1: 89 c5 mov %eax,%ebp
3: 57 push %edi
4: 56 push %esi
5: 53 push %ebx
6: 83 ec 10 sub $0x10,%esp
9: 89 54 24 0c mov %edx,0xc(%esp)
d: 8b 00 mov (%eax),%eax
。。。。
177: 89 d8 mov %ebx,%eax
179: c7 03 00 00 00 00 movl $0x0,(%ebx)
17f: 8b 54 24 0c mov 0xc(%esp),%edx
183: ff 92 8c 02 00 00 call *0x28c(%edx)
189: 85 c0 test %eax,%eax
18b: 89 c2 mov %eax,%edx
18d: 0f 85 07 01 00 00 jne 0x29a
原文如下:
int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
if (likely(!skb->next)) {
if (!list_empty(&ptype_all))
dev_queue_xmit_nit(skb, dev);
if (netif_needs_gso(dev, skb)) {
if (unlikely(dev_gso_segment(skb)))
goto out_kfree_skb;
if (skb->next)
goto gso;
}
return dev->hard_start_xmit(skb, dev);
}
gso:
do {
struct sk_buff *nskb = skb->next;
int rc;
skb->next = nskb->next;
nskb->next = NULL;
rc = dev->hard_start_xmit(nskb, dev);
if (unlikely(rc)) {
nskb->next = skb->next;
skb->next = nskb;
return rc;
}
if (unlikely(netif_queue_stopped(dev) && skb->next))
return NETDEV_TX_BUSY;
} while (skb->next);
skb->destructor = DEV_GSO_CB(skb)->destructor;
out_kfree_skb:
kfree_skb(skb);
return 0;
}
很明显,我们要找的是 call *0x28c(%edx) 这句话。
我们先调用 xde_dism 函数逐条逐条地反汇编。如果有一条指令,opcode 段是 0xff,modrm 段的前 5 bit 是 10010。其中 mod 取 10 的时候表示这条指令是一个寄存器加一个偏移的寻址形式。reg / opcode 段为 010 的时候表示这个指令是 call ,而且地址段的长度是4个字节。最后面的 r/m 段不管,是因为它有可能是 %edx,也有可能是别的。就是找到了 call *0x28c(%edx) 。也就等于找到了 hard_start_xmit 的偏移。
我也看了下其他版本的源码,发现这招是可行的。
找偏移的代码如下:
GET_STR("dev_hard_start_xmit", %eax)
movl $19, %edx
call ksym_lookup
jz loader_out
movl %eax, %esi
movl %esi, 4(%esp)
__DPRINT("<3>dev_hard_start_xmit is %lx/n")
leal 0x200(%eax), %edi
call 1f
.fill sizeof_dism
1: popl %edx
2: movl %esi, %eax
call xde_dism
testl %eax, %eax
jz loader_out
// xde_dism(dev_hard_start_xmit, dism);
addl %eax, %esi
cmpl %edi, %esi
jbe 3f
// if (p > dev_hard_start_xmit + 0x200)
// return;
cmpl $6, dism_len(%edx)
jnz 2b
cmpb $0xff, dism_opcode(%edx)
jnz 2b
andb $0xF8, dism_modrm(%edx)
cmpb $0x90, dism_modrm(%edx)
jnz 2b
// if (!(di->opcode == 0xff && (di->modrm & 0xF8) == 0x90))
// continue;
// found
movl dism_addr(%edx), %ecx
movl %ecx, 4(%esp)
__DPRINT("<3>net_device.hard_start_xmit is %lx/n")
3:
所以,现在我们可以获得 hard_start_xmit 的偏移了,也就是说,我们可以调用指定设备来发包了。所以下一章,我们将看看怎么发包。
离占领网络不远了,加油!
不是有意改成xde的,是我记错了名字。把ade记成了xde。。
今天发现自己的汇编底子不行啊,c -> asm 都这么吃力,更何况 asm -> c。
关于反汇编引擎,网上有教程的,也有开源的example,但不多。如果有啥不清楚,可以查 intel 的那几本手册的,那个讲得最清楚。
经过测试,发现ade不支持prefetchnta指令。这jb指令是在 list_for_each_rcu 里出现的。都不知道啥意思,不过改了 ade_table 的一个字段的值就能正常反汇编了。
贴代码贴代码:
EXPORT_LABEL(xde_table)
.long C_MODRM // 00
.long C_MODRM // 01
.long C_MODRM // 02
.long C_MODRM // 03
.long C_DATA1 // 04
.long C_DATA66 // 05
.long C_BAD // 06
.long C_BAD // 07
.long C_MODRM // 08
.long C_MODRM // 09
.long C_MODRM // 0A
.long C_MODRM // 0B
.long C_DATA1 // 0C
.long C_DATA66 // 0D
.long C_BAD // 0E
.long C_OPCODE2 // 0F
.long C_MODRM+C_BAD // 10
.long C_MODRM // 11
.long C_MODRM+C_BAD // 12
.long C_MODRM // 13
.long C_DATA1+C_BAD // 14
.long C_DATA66+C_BAD // 15
.long C_BAD // 16
.long C_BAD // 17
.long C_MODRM+C_BAD // 18
.long C_MODRM // 19
.long C_MODRM // 1A
.long C_MODRM // 1B
.long C_DATA1+C_BAD // 1C
.long C_DATA66+C_BAD // 1D
.long C_BAD // 1E
.long C_BAD // 1F
.long C_MODRM // 20
.long C_MODRM // 21
.long C_MODRM // 22
.long C_MODRM // 23
.long C_DATA1 // 24
.long C_DATA66 // 25
.long C_SEG+C_BAD // 26
.long C_BAD // 27
.long C_MODRM // 28
.long C_MODRM // 29
.long C_MODRM // 2A
.long C_MODRM // 2B
.long C_DATA1 // 2C
.long C_DATA66 // 2D
.long C_SEG+C_BAD // 2E
.long C_BAD // 2F
.long C_MODRM // 30
.long C_MODRM // 31
.long C_MODRM // 32
.long C_MODRM // 33
.long C_DATA1 // 34
.long C_DATA66 // 35
.long C_SEG+C_BAD // 36
.long C_BAD // 37
.long C_MODRM // 38
.long C_MODRM // 39
.long C_MODRM // 3A
.long C_MODRM // 3B
.long C_DATA1 // 3C
.long C_DATA66 // 3D
.long C_SEG+C_BAD // 3E
.long C_BAD // 3F
.long 0 // 40
.long 0 // 41
.long 0 // 42
.long 0 // 43
.long C_BAD // 44
.long 0 // 45
.long 0 // 46
.long 0 // 47
.long 0 // 48
.long 0 // 49
.long 0 // 4A
.long 0 // 4B
.long C_BAD // 4C
.long 0 // 4D
.long 0 // 4E
.long 0 // 4F
.long 0 // 50
.long 0 // 51
.long 0 // 52
.long 0 // 53
.long 0 // 54
.long 0 // 55
.long 0 // 56
.long 0 // 57
.long 0 // 58
.long 0 // 59
.long 0 // 5A
.long 0 // 5B
.long C_BAD // 5C
.long 0 // 5D
.long 0 // 5E
.long 0 // 5F
.long C_BAD // 60
.long C_BAD // 61
.long C_MODRM+C_BAD // 62
.long C_MODRM+C_BAD // 63
.long C_SEG // 64
.long C_SEG+C_BAD // 65
.long C_66 // 66
.long C_67 // 67
.long C_DATA66 // 68
.long C_MODRM+C_DATA66 // 69
.long C_DATA1 // 6A
.long C_MODRM+C_DATA1 // 6B
.long C_BAD // 6C
.long C_BAD // 6D
.long C_BAD // 6E
.long C_BAD // 6F
.long C_DATA1+C_REL+C_BAD // 70
.long C_DATA1+C_REL+C_BAD // 71
.long C_DATA1+C_REL // 72
.long C_DATA1+C_REL // 73
.long C_DATA1+C_REL // 74
.long C_DATA1+C_REL // 75
.long C_DATA1+C_REL // 76
.long C_DATA1+C_REL // 77
.long C_DATA1+C_REL // 78
.long C_DATA1+C_REL // 79
.long C_DATA1+C_REL+C_BAD // 7A
.long C_DATA1+C_REL+C_BAD // 7B
.long C_DATA1+C_REL // 7C
.long C_DATA1+C_REL // 7D
.long C_DATA1+C_REL // 7E
.long C_DATA1+C_REL // 7F
.long C_MODRM+C_DATA1 // 80
.long C_MODRM+C_DATA66 // 81
.long C_MODRM+C_DATA1+C_BAD // 82
.long C_MODRM+C_DATA1 // 83
.long C_MODRM // 84
.long C_MODRM // 85
.long C_MODRM // 86
.long C_MODRM // 87
.long C_MODRM // 88
.long C_MODRM // 89
.long C_MODRM // 8A
.long C_MODRM // 8B
.long C_MODRM+C_BAD // 8C
.long C_MODRM // 8D
.long C_MODRM+C_BAD // 8E
.long C_MODRM // 8F
.long 0 // 90
.long 0 // 91
.long 0 // 92
.long C_BAD // 93
.long C_BAD // 94
.long C_BAD // 95
.long C_BAD // 96
.long C_BAD // 97
.long C_BAD // 98
.long 0 // 99
.long C_DATA66+C_DATA2+C_BAD // 9A
.long 0 // 9B
.long C_BAD // 9C
.long C_BAD // 9D
.long C_BAD // 9E
.long C_BAD // 9F
.long C_ADDR67 // A0
.long C_ADDR67 // A1
.long C_ADDR67 // A2
.long C_ADDR67 // A3
.long 0 // A4
.long 0 // A5
.long 0 // A6
.long 0 // A7
.long C_DATA1 // A8
.long C_DATA66 // A9
.long 0 // AA
.long 0 // AB
.long 0 // AC
.long C_BAD // AD
.long 0 // AE
.long C_BAD // AF
.long C_DATA1 // B0
.long C_DATA1 // B1
.long C_DATA1 // B2
.long C_DATA1 // B3
.long C_DATA1 // B4
.long C_DATA1 // B5
.long C_DATA1+C_BAD // B6
.long C_DATA1+C_BAD // B7
.long C_DATA66 // B8
.long C_DATA66 // B9
.long C_DATA66 // BA
.long C_DATA66 // BB
.long C_DATA66+C_BAD // BC
.long C_DATA66 // BD
.long C_DATA66 // BE
.long C_DATA66 // BF
.long C_MODRM+C_DATA1 // C0
.long C_MODRM+C_DATA1 // C1
.long C_DATA2+C_STOP // C2
.long C_STOP // C3
.long C_MODRM+C_BAD // C4
.long C_MODRM+C_BAD // C5
.long C_MODRM+C_DATA1 // C6
.long C_MODRM+C_DATA66 // C7
.long C_DATA2+C_DATA1 // C8
.long 0 // C9
.long C_DATA2+C_STOP+C_BAD // CA
.long C_STOP+C_BAD // CB
.long C_BAD // CC
.long C_DATA1 // CD
.long C_BAD // CE
.long C_STOP+C_BAD // CF
.long C_MODRM // D0
.long C_MODRM // D1
.long C_MODRM // D2
.long C_MODRM // D3
.long C_DATA1+C_BAD // D4
.long C_DATA1+C_BAD // D5
.long C_BAD // D6
.long C_BAD // D7
.long C_MODRM // D8
.long C_MODRM // D9
.long C_MODRM // DA
.long C_MODRM // DB
.long C_MODRM // DC
.long C_MODRM // DD
.long C_MODRM // DE
.long C_MODRM // DF
.long C_DATA1+C_REL+C_BAD // E0
.long C_DATA1+C_REL+C_BAD // E1
.long C_DATA1+C_REL // E2
.long C_DATA1+C_REL // E3
.long C_DATA1+C_BAD // E4
.long C_DATA1+C_BAD // E5
.long C_DATA1+C_BAD // E6
.long C_DATA1+C_BAD // E7
.long C_DATA66+C_REL // E8
.long C_DATA66+C_REL+C_STOP // E9
.long C_DATA66+C_DATA2+C_BAD // EA
.long C_DATA1+C_REL+C_STOP // EB
.long C_BAD // EC
.long C_BAD // ED
.long C_BAD // EE
.long C_BAD // EF
.long C_LOCK+C_BAD // F0
.long C_BAD // F1
.long C_REP // F2
.long C_REP // F3
.long C_BAD // F4
.long C_BAD // F5
.long C_MODRM // F6
.long C_MODRM // F7
.long 0 // F8
.long 0 // F9
.long C_BAD // FA
.long C_BAD // FB
.long 0 // FC
.long 0 // FD
.long C_MODRM // FE
.long C_MODRM // FF
.long C_MODRM // 00
.long C_MODRM // 01
.long C_MODRM // 02
.long C_MODRM // 03
.long C_ERROR // 04
.long C_ERROR // 05
.long 0 // 06
.long C_ERROR // 07
.long 0 // 08
.long 0 // 09
.long 0 // 0A
.long 0 // 0B
.long C_ERROR // 0C
.long C_ERROR // 0D
.long C_ERROR // 0E
.long C_ERROR // 0F
.long C_ERROR // 10
.long C_ERROR // 11
.long C_ERROR // 12
.long C_ERROR // 13
.long C_ERROR // 14
.long C_ERROR // 15
.long C_ERROR // 16
.long C_ERROR // 17
.long C_MODRM // 18
.long C_ERROR // 19
.long C_ERROR // 1A
.long C_ERROR // 1B
.long C_ERROR // 1C
.long C_ERROR // 1D
.long C_ERROR // 1E
.long C_ERROR // 1F
.long C_ERROR // 20
.long C_ERROR // 21
.long C_ERROR // 22
.long C_ERROR // 23
.long C_ERROR // 24
.long C_ERROR // 25
.long C_ERROR // 26
.long C_ERROR // 27
.long C_ERROR // 28
.long C_ERROR // 29
.long C_ERROR // 2A
.long C_ERROR // 2B
.long C_ERROR // 2C
.long C_ERROR // 2D
.long C_ERROR // 2E
.long C_ERROR // 2F
.long C_ERROR // 30
.long C_ERROR // 31
.long C_ERROR // 32
.long C_ERROR // 33
.long C_ERROR // 34
.long C_ERROR // 35
.long C_ERROR // 36
.long C_ERROR // 37
.long C_ERROR // 38
.long C_ERROR // 39
.long C_ERROR // 3A
.long C_ERROR // 3B
.long C_ERROR // 3C
.long C_ERROR // 3D
.long C_ERROR // 3E
.long C_ERROR // 3F
.long C_MODRM // 40
.long C_MODRM // 41
.long C_MODRM // 42
.long C_MODRM // 43
.long C_MODRM // 44
.long C_MODRM // 45
.long C_MODRM // 46
.long C_MODRM // 47
.long C_MODRM // 48
.long C_MODRM // 49
.long C_MODRM // 4A
.long C_MODRM // 4B
.long C_MODRM // 4C
.long C_MODRM // 4D
.long C_MODRM // 4E
.long C_MODRM // 4F
.long C_ERROR // 50
.long C_ERROR // 51
.long C_ERROR // 52
.long C_ERROR // 53
.long C_ERROR // 54
.long C_ERROR // 55
.long C_ERROR // 56
.long C_ERROR // 57
.long C_ERROR // 58
.long C_ERROR // 59
.long C_ERROR // 5A
.long C_ERROR // 5B
.long C_ERROR // 5C
.long C_ERROR // 5D
.long C_ERROR // 5E
.long C_ERROR // 5F
.long C_ERROR // 60
.long C_ERROR // 61
.long C_ERROR // 62
.long C_ERROR // 63
.long C_ERROR // 64
.long C_ERROR // 65
.long C_ERROR // 66
.long C_ERROR // 67
.long C_ERROR // 68
.long C_ERROR // 69
.long C_ERROR // 6A
.long C_ERROR // 6B
.long C_ERROR // 6C
.long C_ERROR // 6D
.long C_ERROR // 6E
.long C_ERROR // 6F
.long C_ERROR // 70
.long C_ERROR // 71
.long C_ERROR // 72
.long C_ERROR // 73
.long C_ERROR // 74
.long C_ERROR // 75
.long C_ERROR // 76
.long C_ERROR // 77
.long C_ERROR // 78
.long C_ERROR // 79
.long C_ERROR // 7A
.long C_ERROR // 7B
.long C_ERROR // 7C
.long C_ERROR // 7D
.long C_ERROR // 7E
.long C_ERROR // 7F
.long C_DATA66+C_REL // 80
.long C_DATA66+C_REL // 81
.long C_DATA66+C_REL // 82
.long C_DATA66+C_REL // 83
.long C_DATA66+C_REL // 84
.long C_DATA66+C_REL // 85
.long C_DATA66+C_REL // 86
.long C_DATA66+C_REL // 87
.long C_DATA66+C_REL // 88
.long C_DATA66+C_REL // 89
.long C_DATA66+C_REL // 8A
.long C_DATA66+C_REL // 8B
.long C_DATA66+C_REL // 8C
.long C_DATA66+C_REL // 8D
.long C_DATA66+C_REL // 8E
.long C_DATA66+C_REL // 8F
.long C_MODRM // 90
.long C_MODRM // 91
.long C_MODRM // 92
.long C_MODRM // 93
.long C_MODRM // 94
.long C_MODRM // 95
.long C_MODRM // 96
.long C_MODRM // 97
.long C_MODRM // 98
.long C_MODRM // 99
.long C_MODRM // 9A
.long C_MODRM // 9B
.long C_MODRM // 9C
.long C_MODRM // 9D
.long C_MODRM // 9E
.long C_MODRM // 9F
.long 0 // A0
.long 0 // A1
.long 0 // A2
.long C_MODRM // A3
.long C_MODRM+C_DATA1 // A4
.long C_MODRM // A5
.long C_ERROR // A6
.long C_ERROR // A7
.long 0 // A8
.long 0 // A9
.long 0 // AA
.long C_MODRM // AB
.long C_MODRM+C_DATA1 // AC
.long C_MODRM // AD
.long C_ERROR // AE
.long C_MODRM // AF
.long C_MODRM // B0
.long C_MODRM // B1
.long C_MODRM // B2
.long C_MODRM // B3
.long C_MODRM // B4
.long C_MODRM // B5
.long C_MODRM // B6
.long C_MODRM // B7
.long C_ERROR // B8
.long C_ERROR // B9
.long C_MODRM+C_DATA1 // BA
.long C_MODRM // BB
.long C_MODRM // BC
.long C_MODRM // BD
.long C_MODRM // BE
.long C_MODRM // BF
.long C_MODRM // C0
.long C_MODRM // C1
.long C_ERROR // C2
.long C_ERROR // C3
.long C_ERROR // C4
.long C_ERROR // C5
.long C_ERROR // C6
.long C_ERROR // C7
.long 0 // C8
.long 0 // C9
.long 0 // CA
.long 0 // CB
.long 0 // CC
.long C_DATA1 // CD
.long 0 // CE
.long 0 // CF
.long C_ERROR // D0
.long C_ERROR // D1
.long C_ERROR // D2
.long C_ERROR // D3
.long C_ERROR // D4
.long C_ERROR // D5
.long C_ERROR // D6
.long C_ERROR // D7
.long C_ERROR // D8
.long C_ERROR // D9
.long C_ERROR // DA
.long C_ERROR // DB
.long C_ERROR // DC
.long C_ERROR // DD
.long C_ERROR // DE
.long C_ERROR // DF
.long C_ERROR // E0
.long C_ERROR // E1
.long C_ERROR // E2
.long C_ERROR // E3
.long C_ERROR // E4
.long C_ERROR // E5
.long C_ERROR // E6
.long C_ERROR // E7
.long C_ERROR // E8
.long C_ERROR // E9
.long C_ERROR // EA
.long C_ERROR // EB
.long C_ERROR // EC
.long C_ERROR // ED
.long C_ERROR // EE
.long C_ERROR // EF
.long C_ERROR // F0
.long C_ERROR // F1
.long C_ERROR // F2
.long C_ERROR // F3
.long C_ERROR // F4
.long C_ERROR // F5
.long C_ERROR // F6
.long C_ERROR // F7
.long C_ERROR // F8
.long C_ERROR // F9
.long C_ERROR // FA
.long C_ERROR // FB
.long C_ERROR // FC
.long C_ERROR // FD
.long C_ERROR // FE
.long C_ERROR // FF
#define C_ERROR 0xFFFFFFFF
#define C_ADDR1 0x00000001 //操作码中地址大小的位字段(字节)
#define C_ADDR2 0x00000002
#define C_ADDR4 0x00000004 //(双字)
#define C_LOCK 0x00000008 //加锁前缀
#define C_67 0x00000010 //地址大小修饰前缀(16/32位)
#define C_66 0x00000020 //操作数大小修饰前缀(16/32位)
#define C_REP 0x00000040 //重复前缀
#define C_SEG 0x00000080 //段寄存器前缀
#define C_ANYPREFIX (C_66+C_67+C_LOCK+C_REP+C_SEG)
#define C_DATA1 0x00000100 //操作码中数据大小的位字段
#define C_DATA2 0x00000200
#define C_DATA4 0x00000400
#define C_SIB 0x00000800 //SIB字节
#define C_ADDR67 0x00001000 //地址字节数为disasm_defaddr
#define C_DATA66 0x00002000 //数据字节数为disasm_defdata
#define C_MODRM 0x00004000 //MODRM字节
#define C_BAD 0x00008000
#define C_OPCODE2 0x00010000 //操作码第二个字节
#define C_REL 0x00020000 // 这是跳转指令jxx或者call
#define C_STOP 0x00040000 // 这是回跳指令,ret_code或者jmp
/*
struct dism
{
BYTE defaddr; // 00
BYTE defdata; // 01
DWORD len; // 02 03 04 05
DWORD flag; // 06 07 08 09
DWORD addrsize; // 0A 0B 0C 0D
DWORD datasize; // 0E 0F 10 11
BYTE rep; // 12
BYTE seg; // 13
BYTE opcode; // 14
BYTE opcode2; // 15
BYTE modrm; // 16
BYTE sib; // 17
BYTE addr[8]; // 18
BYTE data[8]; // 20
};
*/
#define dism_defaddr 0x0
#define dism_defdata 0x1
#define dism_len 0x2
#define dism_flag 0x6
#define dism_addrsize 0xa
#define dism_datasize 0xe
#define dism_rep 0x12
#define dism_seg 0x13
#define dism_opcode 0x14
#define dism_opcode2 0x15
#define dism_modrm 0x16
#define dism_sib 0x17
#define dism_addr 0x18
#define dism_data 0x20
#define sizeof_dism 0x28
#include "xde_table.s"
// int fastcall xde_dism(void *code, struct dism *di);
// @code: the code to dism
// @di: the dism struct
// ret_codeurn: dism->len
EXPORT_LABEL(xde_dism)
#define ret_code 0
#define mod 4
#define rm 5
#define opcode 6
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
movl %eax, %esi
movl %edx, %edi
subl $0x20, %esp
movl %esi, opcode(%esp)
movl $0x28, %ecx
movl %edi, %eax
1: movb $0, (%eax)
incl %eax
loop 1b
// memset(di, 0, sizeof(*di));
movb $4, dism_defdata(%edi)
movb $4, dism_defaddr(%edi)
movl $0, ret_code(%esp)
// ret_code = 0;
movw (%esi), %bx
cmpw $0x0000, %bx
jz xd_out
cmpw $0xFFFF, %bx
jz xd_out
// if (*code == 0xFFFF || *code == 0x0)
// ret_codeurn 0;
repeat_prefix:
movzbl (%esi), %eax
incl %esi
GET_ADDR(xde_table, %ebx)
movl 0(%ebx, %eax, 4), %ecx
// c = *code++;
// t = xde_table[c];
testl $C_ANYPREFIX, %ecx
jz 1f
// if (t & C_ANYPREFIX) {
testl %ecx, dism_flag(%edi)
jz 2f
// if (t & dism->flag) {
movl $0, ret_code(%esp)
jmp xd_out
// ret_codeurn 0;
2:// }
orl %ecx, dism_flag(%edi)
// dism->flag |= t;
testl $C_67, %ecx
jz 3f
// if (t & C_67)
xorb $6, dism_defaddr(%edi)
// di->defaddr ^= 6;
jmp 6f
3:
testl $C_66, %ecx
jz 4f
// if (t & C_66)
xorb $6, dism_defdata(%edi)
// di->defdata ^= 6;
jmp 6f
4:
testl $C_SEG, %ecx
jz 7f
// if (t & C_SEG)
movb %al, dism_seg(%edi)
// di->seg = c;
jmp 6f
7:
testl $C_REP, %ecx
jz 6f
// if (t & C_REP)
movb %al, dism_rep(%edi)
// di->req = c;
6:
jmp repeat_prefix
1:
// }
orl %ecx, dism_flag(%edi)
movb %al, dism_opcode(%edi)
// di->flag |= t; di->opcode = c;
cmpb $0x0F, %al
jnz 5f
// if (c == 0x0F) {
movzbl (%esi), %eax
incl %esi
// c = *code++;
movb %al, dism_opcode2(%edi)
GET_ADDR(xde_table, %ebx)
movl (256 * 4)(%ebx, %eax, 4), %ecx
orl %ecx, dism_flag(%edi)
// di->opcode2 = c; flag |= xde_table[256 + c];
cmpl $C_ERROR, dism_flag(%edi)
jnz 8f
// if (flags == C_ERROR) {
movl $0, ret_code(%esp)
jmp xd_out
// ret_codeurn 0;
8:
// }
jmp 9f
5:
cmpb $0xF7, %al
jnz 10f
// } else if (c == 0xF7) {
movb (%esi), %bl
testb $0x38, %bl
jnz 11f
// if (!(*code & 0x38))
orl $C_DATA66, dism_flag(%edi)
// di->flag |= C_DATA66;
11:
jmp 9f
10:
cmpb $0xF6, %al
jnz 9f
// } else if (c == 0xF6) {
movb (%esi), %bl
testb $0x38, %bl
jnz 12f
// if (!(*code & 0x38))
orl $C_DATA66, dism_flag(%edi)
// di->flag |= C_DATA1;
12:
// }
9:
testl $C_MODRM, dism_flag(%edi)
jz 13f
// if (flag & C_MODRM) {
movb (%esi), %al
incl %esi
// c = *code++
movb %al, dism_modrm(%edi)
// di->modrm = c;
movb %al, %ah
andb $0x38, %ah
cmpb $0x20, %ah
jnz 14f
cmpb $0xFF, dism_opcode(%edi)
jnz 14f
// if ((c & 0x38) == 0x20 && dism->opcode == 0xFF)
orl $C_STOP, dism_flag(%edi)
// di->flag |= C_STOP
14:
movb %al, mod(%esp)
andb $0xC0, mod(%esp)
movb %al, rm(%esp)
andb $0x07, rm(%esp)
// mod = c & 0xC0; rm = c & 0x07;
cmpb $0xC0, mod(%esp)
jz 15f
// if (mod != 0xC0) {
cmpb $0x4, dism_defaddr(%edi)
jnz 18f
// if (di->defaddr == 0x4) {
cmpb $0x4, rm(%esp)
jnz 24f
// if (rm == 4) {
orl $C_SIB, dism_flag(%edi)
// di->flag |= C_SIB;
movzbl (%esi), %eax
incl %esi
// c = *code++;
movb %al, dism_sib(%edi)
// di->sib = c;
movb %al, rm(%esp)
andb $0x7, rm(%esp)
// rm = c & 0x7;
24:
// }
cmpb $0x40, mod(%esp)
jnz 17f
// if (mod == 0x40)
orl $C_ADDR1, dism_flag(%edi)
// di->flag |= C_ADDR1;
jmp 21f
17:
cmpb $0x80, mod(%esp)
jnz 19f
// else if (mod == 0x80)
orl $C_ADDR4, dism_flag(%edi)
// di->flag |= C_ADDR4;
jmp 21f
19:
cmpb $0x5, rm(%esp)
jnz 21f
// else if (rm == 5)
orl $C_ADDR4, dism_flag(%edi)
// di->flag |= C_ADDR4;
21:
jmp 20f
18:
// } else {
cmpb $0x40, mod(%esp)
jnz 22f
// if (mod == 0x40)
orl $C_ADDR1, dism_flag(%edi)
// di->flag |= C_ADDR1;
jmp 23f
22:
cmpb $0x80, mod(%esp)
jz 24f
// else if (mod == 0x80)
orl $C_ADDR2, dism_flag(%edi)
// di->flag |= C_ADDR2;
jmp 23f
24:
cmpb $0x6, rm(%esp)
// else if (rm == 6)
orl $C_ADDR2, dism_flag(%edi)
// di->flag |= C_ADDR2;
23:
20:
// }
15:
// }
13:
// }
movl dism_flag(%edi), %eax
movl %eax, %ebx
movl %eax, %ecx
andl $(C_ADDR1 | C_ADDR2 | C_ADDR4), %eax
andl $(C_DATA1 | C_DATA2 | C_DATA4), %ebx
shrl $8, %ebx
testl $C_ADDR67, %ecx
jz 1f
addb dism_defaddr(%edi), %al
1:
testl $C_DATA66, %ecx
jz 2f
addb dism_defdata(%edi), %bl
2:
movl %eax, dism_addrsize(%edi)
movl %ebx, dism_datasize(%edi)
movl %edi, %edx
movl %eax, %ecx
leal dism_addr(%edx), %edi
cld; rep movsb
movl %ebx, %ecx
leal dism_data(%edx), %edi
cld; rep movsb
subl opcode(%esp), %esi
movl %esi, ret_code(%esp)
movl %esi, dism_len(%edx)
xd_out:
movl ret_code(%esp), %eax
addl $0x20, %esp
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
ret
#undef opcode
#undef retcode
#undef mod
#undef rm
好了,现在大杀器已经准备完毕了,那我们怎么用呢?
我们看看这个dev_hart_start_xmit的反汇编:
00000000 <.data>:
0: 55 push %ebp
1: 89 c5 mov %eax,%ebp
3: 57 push %edi
4: 56 push %esi
5: 53 push %ebx
6: 83 ec 10 sub $0x10,%esp
9: 89 54 24 0c mov %edx,0xc(%esp)
d: 8b 00 mov (%eax),%eax
。。。。
177: 89 d8 mov %ebx,%eax
179: c7 03 00 00 00 00 movl $0x0,(%ebx)
17f: 8b 54 24 0c mov 0xc(%esp),%edx
183: ff 92 8c 02 00 00 call *0x28c(%edx)
189: 85 c0 test %eax,%eax
18b: 89 c2 mov %eax,%edx
18d: 0f 85 07 01 00 00 jne 0x29a
原文如下:
int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
if (likely(!skb->next)) {
if (!list_empty(&ptype_all))
dev_queue_xmit_nit(skb, dev);
if (netif_needs_gso(dev, skb)) {
if (unlikely(dev_gso_segment(skb)))
goto out_kfree_skb;
if (skb->next)
goto gso;
}
return dev->hard_start_xmit(skb, dev);
}
gso:
do {
struct sk_buff *nskb = skb->next;
int rc;
skb->next = nskb->next;
nskb->next = NULL;
rc = dev->hard_start_xmit(nskb, dev);
if (unlikely(rc)) {
nskb->next = skb->next;
skb->next = nskb;
return rc;
}
if (unlikely(netif_queue_stopped(dev) && skb->next))
return NETDEV_TX_BUSY;
} while (skb->next);
skb->destructor = DEV_GSO_CB(skb)->destructor;
out_kfree_skb:
kfree_skb(skb);
return 0;
}
很明显,我们要找的是 call *0x28c(%edx) 这句话。
我们先调用 xde_dism 函数逐条逐条地反汇编。如果有一条指令,opcode 段是 0xff,modrm 段的前 5 bit 是 10010。其中 mod 取 10 的时候表示这条指令是一个寄存器加一个偏移的寻址形式。reg / opcode 段为 010 的时候表示这个指令是 call ,而且地址段的长度是4个字节。最后面的 r/m 段不管,是因为它有可能是 %edx,也有可能是别的。就是找到了 call *0x28c(%edx) 。也就等于找到了 hard_start_xmit 的偏移。
我也看了下其他版本的源码,发现这招是可行的。
找偏移的代码如下:
GET_STR("dev_hard_start_xmit", %eax)
movl $19, %edx
call ksym_lookup
jz loader_out
movl %eax, %esi
movl %esi, 4(%esp)
__DPRINT("<3>dev_hard_start_xmit is %lx/n")
leal 0x200(%eax), %edi
call 1f
.fill sizeof_dism
1: popl %edx
2: movl %esi, %eax
call xde_dism
testl %eax, %eax
jz loader_out
// xde_dism(dev_hard_start_xmit, dism);
addl %eax, %esi
cmpl %edi, %esi
jbe 3f
// if (p > dev_hard_start_xmit + 0x200)
// return;
cmpl $6, dism_len(%edx)
jnz 2b
cmpb $0xff, dism_opcode(%edx)
jnz 2b
andb $0xF8, dism_modrm(%edx)
cmpb $0x90, dism_modrm(%edx)
jnz 2b
// if (!(di->opcode == 0xff && (di->modrm & 0xF8) == 0x90))
// continue;
// found
movl dism_addr(%edx), %ecx
movl %ecx, 4(%esp)
__DPRINT("<3>net_device.hard_start_xmit is %lx/n")
3:
所以,现在我们可以获得 hard_start_xmit 的偏移了,也就是说,我们可以调用指定设备来发包了。所以下一章,我们将看看怎么发包。
离占领网络不远了,加油!
相关文章推荐
- Linux AT&T 汇编错误:Error: invalid instruction suffix for `push'
- rootkit for linux 8.大大杀器---“模拟法”获得字段偏移
- rootkit for linux 10.小结
- rootkit for linux 12.枚举目录
- rootkit for linux 5.啥是skb
- Linux gcc for 循环中 i=i++ 会造成死循环问题及 ++i / i++ 汇编分析
- rootkit for linux 16.获取tcp可用端口号
- rootkit for linux 3.小窥数据链路层
- Linux gcc for 循环中 i=i++ 会造成死循环问题及 ++i / i++ 汇编分析
- rootkit for linux 18.tcp原理概述
- rootkit for linux 11.“寻找入口点”的改进方法
- rootkit for linux 14.file handle
- rootkit for linux 2.寻找入口点
- rootkit for linux 6.截获skb
- xde反汇编引擎源码
- rootkit for linux 15.寻找eth设备
- xde反汇编引擎源码
- rootkit for linux 19.山寨tcpip协议栈--连接的建立和初始化.doc
- rootkit for linux 17.ip、tcp数据报
- rootkit for linux 13.指令查找代码的简化