Windows驱动开发学习记录- x86 InlineHook字节数计算(使用Hook Api lib 0.4 for C)

Hook Api lib 0.4 for C原文及源代码地址链接 《 [原创]Hook Api lib 0.4 for C 》

一、使用背景

        最新在学习SSDT Inline Hook,一般在Hook开头进行一个JMP,例如Near Jmp,或者一个Far Jmp。

        Near Jmp机器码为 E9 xx xx xx xx,一共五个字节;Far Jmp机器码为 EA xx xx xx xx 08 00,其中驱动中段址为08。

        在Hook时保存原调用函数对应的字节数,然后修改其为跳转到自定义函数。

        以Windows XP SP3中的 NtOpenFile为例,其反汇编如下:

nt!NtOpenFile:
8057b1a0 8bff         mov     edi, edi
8057b1a2 55           push    ebp
8057b1a3 8bec         mov     ebp, esp
8057b1a5 33c0         xor     eax, eax
8057b1a7 50           push    eax
8057b1a8 50           push    eax
8057b1a9 50           push    eax
8057b1aa 50           push    eax
8057b1ab 50           push    eax
8057b1ac ff751c       push    dword ptr [ebp+1Ch]
8057b1af 6a01         push    1
8057b1b1 ff7518       push    dword ptr [ebp+18h]
8057b1b4 50           push    eax
8057b1b5 50           push    eax
8057b1b6 ff7514       push    dword ptr [ebp+14h]
8057b1b9 ff7510       push    dword ptr [ebp+10h]
8057b1bc ff750c       push    dword ptr [ebp+0Ch]
8057b1bf ff7508       push    dword ptr [ebp+8]
8057b1c2 e873c7ffff   call    nt!IoCreateFile (8057793a)
8057b1c7 5d           pop     ebp
8057b1c8 c21800       ret     18h
8057b1cb cc           int     3
8057b1cc cc           int     3
8057b1cd cc           int     3
8057b1ce cc           int     3
8057b1cf cc           int     3

        在这种情况下进行Near Jmp的Inline Hook正好,三条指令,5个字节长度。但也有例外情况。 

        如Windows XP SP3中的 NtOpenEvent:

    nt!NtOpenEvent:
806101e0 6a18           push    18h
806101e2 68a0df4d80     push    offset nt!ExTraceAllTables+0x1b (804ddfa0)
806101e7 e854cbf2ff     call    nt!_SEH_prolog (8053cd40)
806101ec 64a124010000   mov     eax, dword ptr fs:[00000124h]
806101f2 8a9840010000   mov     bl, byte ptr [eax+140h]
806101f8 885ddc         mov     byte ptr [ebp-24h], bl
806101fb 84db           test    bl, bl
806101fd 743c           je      nt!NtOpenEvent+0x5b (8061023b)
806101ff 8365fc00       and     dword ptr [ebp-4], 0
80610203 8b7508         mov     esi, dword ptr [ebp+8]
80610206 a134315680     mov     eax, dword ptr [nt!MmUserProbeAddress (80563134)]
8061020b 3bf0           cmp     esi, eax
8061020d 7206           jb      nt!NtOpenEvent+0x35 (80610215)
8061020f c70000000000   mov     dword ptr [eax], 0
80610215 8b06           mov     eax, dword ptr [esi]
80610217 8906           mov     dword ptr [esi], eax
80610219 834dfcff       or      dword ptr [ebp-4], 0FFFFFFFFh
8061021d eb1f           jmp     nt!NtOpenEvent+0x5e (8061023e)
8061021f 8b45ec         mov     eax, dword ptr [ebp-14h]
80610222 8b00           mov     eax, dword ptr [eax]
80610224 8b00           mov     eax, dword ptr [eax]
80610226 8945e0         mov     dword ptr [ebp-20h], eax
80610229 e8c0400000     call    nt!ExSystemExceptionFilter (806142ee)
8061022e c3             ret     
......

         发现第一条指令2字节,第二条指令5字节,对于使用Near Jmp的5字节来说,正好落在第2条指令中间,也就是说把一整条指令打断了,这样运行肯定会出问题。

        所以需要一个计算每条指令长度的功能,来获取大于等于我们需要hook长度的最少完整指令长度,而 Hook Api lib 0.4 for C 这篇文章就提供了这个方法。

二、代码实现

        直接上代码:

        头文件

//
//deroko 的LDEX86的头文件定义
/*
       C_MODRM       for instructions that require MODRM
       C_PREFIX      for PREFIXES (SEG/REP)
       C_2BYTE       for instructions which opcode is 2 byte
*/
#define       C_SIZE1             0x01
#define       C_MODRM             0x02
#define       C_DATA8             0x04
#define       C_DATA16            0x08
#define       C_DATA32            0x10
#define       C_PREFIX            0x20
#define       C_2BYTE             0x40
#define       C_REL               0x80    //used to don't fuck up relative jmps with 67 prefix    
#define       C_66                0x66    //operand size prefix
#define       C_67                0x67    //address size prefix

#define       C_UNKNOWN           0x00

static BYTE table_1[256]={
/* 00 */  C_MODRM
/* 01 */, C_MODRM
/* 02 */, C_MODRM
/* 03 */, C_MODRM
/* 04 */, C_DATA8    // add al, ax, eax + 32imm  w not set imm size = 8
/* 05 */, C_DATA32   // add al, ax, eax + 32imm  w set imm size = 32
/* 06 */, C_SIZE1    //push es
/* 07 */, C_SIZE1    //pop es
/* 08 */, C_MODRM    //or w set
/* 09 */, C_MODRM    //or w not set :)
/* 0A */, C_MODRM
/* 0B */, C_MODRM
/* 0C */, C_DATA8    // or al/ax/eax shortcut
/* 0D */, C_DATA32   // or al/ax/eax shortcut
/* 0E */, C_SIZE1    // push cs
/* 0F */, C_2BYTE
/* 10 */, C_MODRM    //adc w/d set mod rm, next 4
/* 11 */, C_MODRM
/* 12 */, C_MODRM
/* 13 */, C_MODRM
/* 14 */, C_DATA8    //adc al, imm8
/* 15 */, C_DATA32   //adc al, imm32
/* 16 */, C_SIZE1    //push ss
/* 17 */, C_SIZE1    //pop ss
/* 18 */, C_MODRM    //sbb w set/not set
/* 19 */, C_MODRM
/* 1A */, C_MODRM    //sbb d/w combinations
/* 1B */, C_MODRM    //sbb d/w combinations
/* 1C */, C_DATA8    //sbb al, imm8
/* 1D */, C_DATA32   //sbb eax, imm32
/* 1E */, C_SIZE1    //push ds
/* 1F */, C_SIZE1    //pop ds
/* 20 */, C_MODRM    //and mod/rm d/w bit combinations = 4
/* 21 */, C_MODRM
/* 22 */, C_MODRM
/* 23 */, C_MODRM    //end and mod/rm d/w bit combinations
/* 24 */, C_DATA8    //and al, imm8
/* 25 */, C_DATA32   //and al, imm32
/* 26 */, C_PREFIX
/* 27 */, C_SIZE1    //daa
/* 28 */, C_MODRM    //sub w/d mixup
/* 29 */, C_MODRM    
/* 2A */, C_MODRM
/* 2B */, C_MODRM    //sub w/d mixup end
/* 2C */, C_DATA8    //sub al, ax ,eax imm8
/* 2D */, C_DATA32   //sub al, ax, eax imm8
/* 2E */, C_PREFIX
/* 2F */, C_SIZE1    //das
/* 30 */, C_MODRM    //xor next 4
/* 31 */, C_MODRM
/* 32 */, C_MODRM
/* 33 */, C_MODRM
/* 34 */, C_DATA8    //xor al, ax, eax imm 8 w not set (al)
/* 35 */, C_DATA32   //xor al, ax, eax imm 32 w set (eax)
/* 36 */, C_PREFIX
/* 37 */, C_SIZE1           //AAA
/* 38 */, C_MODRM           //cmp d/w set 4 combinations
/* 39 */, C_MODRM           //cmp
/* 3A */, C_MODRM           //cmp
/* 3B */, C_MODRM           //cmp
/* 3C */, C_DATA8           //cmp al, ax, eax imm 8
/* 3D */, C_DATA32          //cmp al, ax, eax imm 32
/* 3E */, C_PREFIX
/* 3F */, C_SIZE1           //AAS
/* 40 */, C_SIZE1           //inc reg (alternate encoding)
/* 41 */, C_SIZE1
/* 42 */, C_SIZE1
/* 43 */, C_SIZE1
/* 44 */, C_SIZE1
/* 45 */, C_SIZE1
/* 46 */, C_SIZE1
/* 47 */, C_SIZE1
/* 48 */, C_SIZE1           //dec reg (alternate encoding)
/* 49 */, C_SIZE1
/* 4A */, C_SIZE1
/* 4B */, C_SIZE1
/* 4C */, C_SIZE1
/* 4D */, C_SIZE1
/* 4E */, C_SIZE1
/* 4F */, C_SIZE1
/* 50 */, C_SIZE1
/* 51 */, C_SIZE1
/* 52 */, C_SIZE1
/* 53 */, C_SIZE1
/* 54 */, C_SIZE1
/* 55 */, C_SIZE1
/* 56 */, C_SIZE1
/* 57 */, C_SIZE1
/* 58 */, C_SIZE1    //pop reg
/* 59 */, C_SIZE1
/* 5A */, C_SIZE1
/* 5B */, C_SIZE1
/* 5C */, C_SIZE1
/* 5D */, C_SIZE1
/* 5E */, C_SIZE1
/* 5F */, C_SIZE1    //pop reg ends
/* 60 */, C_SIZE1    //pushad
/* 61 */, C_SIZE1    //popad
/* 62 */, C_MODRM    //bound
/* 63 */, C_MODRM    //arpl
/* 64 */, C_PREFIX
/* 65 */, C_PREFIX
/* 66 */, C_PREFIX
/* 67 */, C_PREFIX
/* 68 */, C_DATA32  //push immidiate 32
/* 69 */, C_MODRM + C_DATA32       //imul reg/reg imm32
/* 6A */, C_DATA8   //push imm 8
/* 6B */, C_MODRM + C_DATA8        //imul reg/reg imm8
/* 6C */, C_SIZE1   //ins w not set
/* 6D */, C_SIZE1   //ins w set
/* 6E */, C_SIZE1   //outs w not set
/* 6F */, C_SIZE1   //outs w set
/* 70 */, C_DATA8  + C_REL  //jcc 8 bit displacement start
/* 71 */, C_DATA8  + C_REL
/* 72 */, C_DATA8  + C_REL
/* 73 */, C_DATA8  + C_REL
/* 74 */, C_DATA8  + C_REL
/* 75 */, C_DATA8  + C_REL
/* 76 */, C_DATA8  + C_REL
/* 77 */, C_DATA8  + C_REL
/* 78 */, C_DATA8  + C_REL
/* 79 */, C_DATA8  + C_REL
/* 7A */, C_DATA8  + C_REL
/* 7B */, C_DATA8  + C_REL
/* 7C */, C_DATA8  + C_REL
/* 7D */, C_DATA8  + C_REL
/* 7E */, C_DATA8  + C_REL
/* 7F */, C_DATA8  + C_REL  //jcc 8 bit displacement ends
/* 80 */, C_MODRM + C_DATA8   //sub immidira/reg 32bit imm, also cmp modrm/imm32, also cmp
/* 81 */, C_MODRM + C_DATA32   //sub imidiate/reg 32bit imm, also cmp modrm/imm32, also cmp
/* 82 */, C_MODRM + C_DATA8    //sub or mod rm 8imm w not set, --||--      /imm8, also cmp
/* 83 */, C_MODRM + C_DATA8    //sub or mod rm 8imm w set set, --||--      /imm8, also cmp
/* 84 */, C_MODRM    //test w not set
/* 85 */, C_MODRM    //test w set
/* 86 */, C_MODRM    //xchg w not set
/* 87 */, C_MODRM    //xchg w set
/* 88 */, C_MODRM    //mov not set w
/* 89 */, C_MODRM    //mov set w
/* 8A */, C_MODRM    //mov d set/not
/* 8B */, C_MODRM
/* 8C */, C_MODRM    //mov reg/seg
/* 8D */, C_MODRM    //lea
/* 8E */, C_MODRM    //mov reg/seg I guess
/* 8F */, C_MODRM    //pop reg/memory
/* 90 */, C_SIZE1    //nop
/* 91 */, C_SIZE1    //xchg al, ax, eax   reg
/* 92 */, C_SIZE1
/* 93 */, C_SIZE1
/* 94 */, C_SIZE1
/* 95 */, C_SIZE1
/* 96 */, C_SIZE1
/* 97 */, C_SIZE1    //xchg al, ax, eax,  ret ends
/* 98 */, C_SIZE1    //cbw, cwde
/* 99 */, C_SIZE1    //cdq, cwd
/* 9A */, C_DATA32 + C_DATA16 //far call (call unsinged full offset,selector)
/* 9B */, C_SIZE1    //wait//fwait
/* 9C */, C_SIZE1           //pushfd
/* 9D */, C_SIZE1           //popfd
/* 9E */, C_SIZE1           //sahf
/* 9F */, C_SIZE1           //LAHF
/* A0 */, C_DATA32          //mov al, ax, eax,mem full_offset
/* A1 */, C_DATA32          //mov al, ax, eax, mem full_offset
/* A2 */, C_DATA32          //mov mem, al, ax, eax full_offset
/* A3 */, C_DATA32          //mov mem, al, ax, eax full_offset
/* A4 */, C_SIZE1           //movsb
/* A5 */, C_SIZE1           //movsd
/* A6 */, C_SIZE1    //cmpsb... 2 of them w bit set
/* A7 */, C_SIZE1    
/* A8 */, C_DATA8    //test al/ax/eax shortcut
/* A9 */, C_DATA32   //test al/ax/eax shortcut
/* AA */, C_SIZE1    //stosb
/* AB */, C_SIZE1    //stosd, or stosw + PREFIX 66
/* AC */, C_SIZE1    //lodsb
/* AD */, C_SIZE1    //lodsw + PREFIX 66 or lodsd
/* AE */, C_SIZE1    //scasb
/* AF */, C_SIZE1    //scasd
/* B0 */, C_DATA8    //mov reg, imm 8 alterante encoding
/* B1 */, C_DATA8
/* B2 */, C_DATA8
/* B3 */, C_DATA8
/* B4 */, C_DATA8
/* B5 */, C_DATA8
/* B6 */, C_DATA8
/* B7 */, C_DATA8
/* B8 */, C_DATA32   //mov immidiate to reg (alternate encoding)
/* B9 */, C_DATA32
/* BA */, C_DATA32
/* BB */, C_DATA32
/* BC */, C_DATA32
/* BD */, C_DATA32
/* BE */, C_DATA32
/* BF */, C_DATA32
/* C0 */, C_MODRM+C_DATA8 //rcl reg/mem by imm8 also rcr depends on opcode in modr/m field, also rol/ror
/* C1 */, C_MODRM+C_DATA8 //-----------||-----------
/* C2 */, C_DATA16
/* C3 */, C_SIZE1    //ret no args
/* C4 */, C_MODRM    //les
/* C5 */, C_MODRM    //lds
/* C6 */, C_MODRM+C_DATA8   // mov mem/imm
/* C7 */, C_MODRM+C_DATA32  //litle change (mov mem/imm)
/* C8 */, C_DATA8 + C_DATA16    //enter 16disp, 8bit level =4 size
/* C9 */, C_SIZE1
/* CA */, C_DATA16              //retf param
/* CB */, C_SIZE1               //retf no param
/* CC */, C_SIZE1
/* CD */, C_DATA8    //int, 8bit interupt number
/* CE */, C_SIZE1    //into 
/* CF */, C_SIZE1    //iret
/* D0 */, C_MODRM    //rcl reg/memory by 1 , also rcr, also ror/rol
/* D1 */, C_MODRM    //same with w bit set , -||-
/* D2 */, C_MODRM    //rcl register by cl  , -||-
/* D3 */, C_MODRM    //same with w bit set , -||- , also rol,ror
/* D4 */, C_DATA8    //aam 2 byte long but C_DATA8 is processed as 2 in my algo so this is ok
/* D5 */, C_DATA8    //aad 2 bytes long C_DATA8 is processed as 2 byte long 
/* D6 */, C_SIZE1    //salc
/* D7 */, C_SIZE1    //xlat
/* D8 */, C_MODRM    //all FPU are C_MODRM
/* D9 */, C_MODRM    
/* DA */, C_MODRM
/* DB */, C_MODRM
/* DC */, C_MODRM
/* DD */, C_MODRM
/* DE */, C_MODRM
/* DF */, C_MODRM    //end FPU instructions
/* E0 */, C_DATA8 + C_REL   //loonz 8bit
/* E1 */, C_DATA8 + C_REL   //loopz 8bit
/* E2 */, C_DATA8 + C_REL   //loop  8bit
/* E3 */, C_DATA8 + C_REL    //jecxz 8bit Address-size prefix indicates jcxz or jecxz
/* E4 */, C_DATA8    //in al, port
/* E5 */, C_DATA8    //in eax, port
/* E6 */, C_DATA8    //out port w not set (out 0, al)
/* E7 */, C_DATA8    //out port w set (out 0, eax)
/* E8 */, C_DATA32 + C_REL
/* E9 */, C_DATA32 + C_REL   //jmp full displacement
/* EA */, C_DATA32 + C_DATA16 //jmp far full offset, selector
/* EB */, C_DATA8     //jmp 8 bit displacement
/* EC */, C_SIZE1    //in
/* ED */, C_SIZE1    //in
/* EE */, C_SIZE1    //out
/* EF */, C_SIZE1    //out
/* F0 */, C_PREFIX
/* F1 */, C_SIZE1    //int1
/* F2 */, C_PREFIX
/* F3 */, C_PREFIX
/* F4 */, C_SIZE1    //hlt
/* F5 */, C_SIZE1    //cmc
/* F6 */, C_MODRM + C_DATA8 //not (w not set), neg depends on opcode field in modrm, it can be test imm
/* F7 */, C_MODRM + C_DATA32 //not (w set)    , neg depends on opcode field in modrm, it can be test imm
/* F8 */, C_SIZE1    //clc
/* F9 */, C_SIZE1    //stc
/* FA */, C_SIZE1    //cli
/* FB */, C_SIZE1    //sti
/* FC */, C_SIZE1    //cld
/* FD */, C_SIZE1    //std    
/* FE */, C_MODRM    //inc/dec w not set (modrm)
/* FF */, C_MODRM    //inc/dec w set     (modrm) //call also depends on reg/opcode field
};                   //also jmp (depends on reg/opcode) fild

static BYTE table_2[256]={
/* 00 */  C_MODRM           //lldt
/* 01 */, C_MODRM           //invlpg
/* 02 */, C_MODRM           //lar
/* 03 */, C_MODRM           //LSL
/* 04 */, 0
/* 05 */, 0
/* 06 */, C_SIZE1           //clts
/* 07 */, 0
/* 08 */, C_SIZE1           //invd
/* 09 */, C_SIZE1
/* 0A */, 0
/* 0B */, 0
/* 0C */, 0
/* 0D */, 0
/* 0E */, 0
/* 0F */, 0
/* 10 */, 0
/* 11 */, 0
/* 12 */, 0
/* 13 */, 0
/* 14 */, 0
/* 15 */, 0
/* 16 */, 0
/* 17 */, 0
/* 18 */, 0
/* 19 */, 0
/* 1A */, 0
/* 1B */, 0
/* 1C */, 0
/* 1D */, 0
/* 1E */, 0
/* 1F */, 0
/* 20 */, C_MODRM           //mov reg/crX
/* 21 */, C_MODRM           //mov drX/reg
/* 22 */, C_MODRM           //mov crX/reg and it foes all the way down
/* 23 */, C_MODRM           //mov reg/drX
/* 24 */, 0
/* 25 */, 0
/* 26 */, 0
/* 27 */, 0
/* 28 */, 0
/* 29 */, 0
/* 2A */, 0
/* 2B */, 0
/* 2C */, 0
/* 2D */, 0
/* 2E */, 0
/* 2F */, 0
/* 30 */, C_SIZE1
/* 31 */, C_SIZE1
/* 32 */, C_SIZE1
/* 33 */, C_SIZE1
/* 34 */, C_SIZE1
/* 35 */, 0
/* 36 */, 0
/* 37 */, 0
/* 38 */, 0
/* 39 */, 0
/* 3A */, 0
/* 3B */, 0
/* 3C */, 0
/* 3D */, 0
/* 3E */, 0
/* 3F */, 0
/* 40 */, C_MODRM           //conditional move
/* 41 */, C_MODRM
/* 42 */, C_MODRM
/* 43 */, C_MODRM
/* 44 */, C_MODRM
/* 45 */, C_MODRM
/* 46 */, C_MODRM
/* 47 */, C_MODRM
/* 48 */, C_MODRM
/* 49 */, C_MODRM
/* 4A */, C_MODRM
/* 4B */, C_MODRM
/* 4C */, C_MODRM
/* 4D */, C_MODRM
/* 4E */, C_MODRM
/* 4F */, C_MODRM           //end conditional move 
/* 50 */, 0
/* 51 */, 0
/* 52 */, 0
/* 53 */, 0
/* 54 */, 0
/* 55 */, 0
/* 56 */, 0
/* 57 */, 0
/* 58 */, 0
/* 59 */, 0
/* 5A */, 0
/* 5B */, 0
/* 5C */, 0
/* 5D */, 0
/* 5E */, 0
/* 5F */, 0
/* 60 */, 0
/* 61 */, 0
/* 62 */, 0
/* 63 */, 0
/* 64 */, 0
/* 65 */, 0
/* 66 */, 0
/* 67 */, 0
/* 68 */, 0
/* 69 */, 0
/* 6A */, 0
/* 6B */, 0
/* 6C */, 0
/* 6D */, 0
/* 6E */, 0
/* 6F */, 0
/* 70 */, 0
/* 71 */, 0
/* 72 */, 0
/* 73 */, 0
/* 74 */, 0
/* 75 */, 0
/* 76 */, 0
/* 77 */, 0
/* 78 */, 0
/* 79 */, 0
/* 7A */, 0
/* 7B */, 0
/* 7C */, 0
/* 7D */, 0
/* 7E */, 0
/* 7F */, 0
/* 80 */, C_DATA32   //jccs 2 byte long imm32
/* 81 */, C_DATA32
/* 82 */, C_DATA32
/* 83 */, C_DATA32
/* 84 */, C_DATA32
/* 85 */, C_DATA32
/* 86 */, C_DATA32
/* 87 */, C_DATA32
/* 88 */, C_DATA32
/* 89 */, C_DATA32
/* 8A */, C_DATA32
/* 8B */, C_DATA32
/* 8C */, C_DATA32
/* 8D */, C_DATA32
/* 8E */, C_DATA32
/* 8F */, C_DATA32   //jccs 2byte long ends imm32
/* 90 */, C_MODRM
/* 91 */, C_MODRM
/* 92 */, C_MODRM
/* 93 */, C_MODRM
/* 94 */, C_MODRM
/* 95 */, C_MODRM
/* 96 */, C_MODRM
/* 97 */, C_MODRM
/* 98 */, C_MODRM
/* 99 */, C_MODRM
/* 9A */, C_MODRM
/* 9B */, C_MODRM
/* 9C */, C_MODRM
/* 9D */, C_MODRM
/* 9E */, C_MODRM
/* 9F */, C_MODRM
/* A0 */, C_SIZE1            //push fs
/* A1 */, C_SIZE1           //pop fs
/* A2 */, C_SIZE1           //cpuid
/* A3 */, C_MODRM           //bt reg/mem
/* A4 */, C_MODRM + C_DATA8
/* A5 */, C_MODRM
/* A6 */, 0
/* A7 */, 0
/* A8 */, C_SIZE1           //push gs
/* A9 */, C_SIZE1           //pop gs
/* AA */, C_SIZE1
/* AB */, C_MODRM           //bts
/* AC */, C_MODRM + C_DATA8
/* AD */, C_MODRM
/* AE */, 0
/* AF */, C_MODRM           //imul reg/reg or reg/mem
/* B0 */, C_MODRM           //cmpxchg
/* B1 */, C_MODRM           //cmpxchg
/* B2 */, C_MODRM           //lss
/* B3 */, C_MODRM           //btr
/* B4 */, C_MODRM           //lfs
/* B5 */, C_MODRM           //lgs
/* B6 */, C_MODRM           //movzx
/* B7 */, C_MODRM           //movzx
/* B8 */, 0
/* B9 */, 0
/* BA */, C_MODRM + C_DATA8 //bt imm8
/* BB */, C_MODRM           //btc mod/rm
/* BC */, C_MODRM           //BSF
/* BD */, C_MODRM           //BSR
/* BE */, C_MODRM           //movsx
/* BF */, C_MODRM           //movsx
/* C0 */, C_MODRM           //xadd
/* C1 */, C_MODRM           //xadd
/* C2 */, 0
/* C3 */, 0
/* C4 */, 0
/* C5 */, 0
/* C6 */, 0
/* C7 */, 0
/* C8 */, C_SIZE1           //bswap eax
/* C9 */, C_SIZE1
/* CA */, C_SIZE1
/* CB */, C_SIZE1
/* CC */, C_SIZE1
/* CD */, C_SIZE1
/* CE */, C_SIZE1
/* CF */, C_SIZE1           //bswap reg ends
/* D0 */, 0
/* D1 */, 0
/* D2 */, 0
/* D3 */, 0
/* D4 */, 0
/* D5 */, 0
/* D6 */, 0
/* D7 */, 0
/* D8 */, 0
/* D9 */, 0
/* DA */, 0
/* DB */, 0
/* DC */, 0
/* DD */, 0
/* DE */, 0
/* DF */, 0
/* E0 */, 0
/* E1 */, 0
/* E2 */, 0
/* E3 */, 0
/* E4 */, 0
/* E5 */, 0
/* E6 */, 0
/* E7 */, 0
/* E8 */, 0
/* E9 */, 0
/* EA */, 0
/* EB */, 0
/* EC */, 0
/* ED */, 0
/* EE */, 0
/* EF */, 0
/* F0 */, 0
/* F1 */, 0
/* F2 */, 0
/* F3 */, 0
/* F4 */, 0
/* F5 */, 0
/* F6 */, 0
/* F7 */, 0
/* F8 */, 0
/* F9 */, 0
/* FA */, 0
/* FB */, 0
/* FC */, 0
/* FD */, 0
/* FE */, 0
/* FF */, 0
};

         CPP文件

int GetOpCodeSize(PVOID Start)
{
        BYTE opcode, * p, /*tempopcode,*/ instruction;
        int size;
        int opsizeprefix = 0, addressprefix = 0;
        size = 0;
        p = (PBYTE)Start;
        opcode = *p;
        //Proces PREFIXES!!! if any...
prefix_loop:
        if (table_1[opcode] == C_PREFIX) {
                if (opcode == C_66)
                        opsizeprefix = 1;
                if (opcode == C_67)
                        addressprefix = 1;
                size++;
                p++;
                opcode = *p;
                goto prefix_loop;
        }
        //check for test, stupid and fucking test
        instruction = table_1[opcode];
        if ((opcode == 0xF6) || (opcode == 0xF7)) {
                opcode = p[1];
                if ((opcode & 0x38) != 0)         //test or neg/not...
                        instruction = C_MODRM;

        }
        if (opsizeprefix)
                //where was 8 still is 8 //where was 32 now is 16
                if (instruction & C_DATA32) {
                        instruction &= ~(C_DATA32);
                        instruction |= C_DATA16;
                }
        //if not relative change 
        if (addressprefix && !(instruction & C_REL)) {
                instruction &= ~(C_DATA32);
                instruction &= ~(C_DATA8);
                instruction |= C_DATA16;
        }
        //clear relative flag
        if (instruction & C_REL)
                instruction &= ~(C_REL);
        //fill instruction with flags from table_2 and decode it in right way
        if (instruction == C_2BYTE) {
                size += 1;
                p++;
                instruction = table_2[*p];
                //if (instruction == C_DATA32)
                //   size += 5;
                //goto check_modrm;   
        }
        size += 1;                         //opcode len;     
//check_modrm:
        if (instruction & C_MODRM) {
                unsigned char modrm, sib;
                size += 1;
                p++;
                modrm = *p;
                if ((modrm >> 6) == 0 && (modrm & 0x07) == 0x05) //modrm is folowed by 32disp
                        size += 4;

                if ((modrm >> 6) != 3 && (modrm & 0x07) == 0x04) {   //sib
                        size++;
                        p++;
                        sib = *p;
                        if ((modrm >> 6) == 1 && (modrm & 0x07) == 0x04) //8bit disp after SIB(added to index)
                                size++;
                        if ((modrm >> 6) == 2 && (modrm & 0x07) == 0x04) //32bit displacement after sib(added to index)             
                                size += 4;
                        if ((modrm >> 6) == 0 && (sib & 0x07) == 0x05)
                                size += 4;
                } //SIB processing
                TEST CODE//
                if (modrm >= 0x40 && modrm <= 0x7f && (modrm & 0x07) != 0x04)
                        size += 1;
                if (modrm >= 0x80 && modrm <= 0xbf && (modrm & 0x07) != 0x04)
                        size += 4;
                ///TEST CODE/// 
        }
        if (instruction & C_DATA32)  //is this opcode opcode modrm immdata ???
                size += 4;
        if (instruction & C_DATA8)
                size++;
        if (instruction & C_DATA16)
                size += 2;
        if (instruction == C_UNKNOWN)
                size += 1;
        return size;
}

三、测试

         测试循环打印出 NtOpenProcess 前50行指令,环境为WinXP x86 SP3.。

1.代码

#if DBG
#define KDPRINT(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,  format, ##__VA_ARGS__ ) 
#else
#define KDPRINT(format, ...)
#endif


NTSTATUS  DriverEntry(PDRIVER_OBJECT pDriverObject,
        PUNICODE_STRING pRegistryPath)
{
        UNREFERENCED_PARAMETER(pDriverObject);
        NTSTATUS ntStatus = STATUS_SUCCESS;
        do
        {
                KDPRINT("【GetOpCodeX86】::【DriverEntry】DriverEntry! \n");

                KDPRINT("【GetOpCodeX86】::【DriverEntry】Hello Kernel World! CurrentProcessId:0x%p CurrentIRQL:0x%u\n",
                        PsGetCurrentProcessId(),
                        KeGetCurrentIrql());

                if (pRegistryPath != NULL)
                {
                        KDPRINT("【GetOpCodeX86】::【DriverEntry】RegistryPath:%wZ \n", pRegistryPath);
                }
                pDriverObject->DriverUnload = DriverUnload;

                PrintFunctionOpCode((PBYTE)NtOpenProcess);

        } while (false);

        return ntStatus;
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
        UNREFERENCED_PARAMETER(pDriverObject);
        KDPRINT("【GetOpCodeX86】::【DriverUnload】DriverUnload CurrentProcessId:0x%p CurrentIRQL:0x%u\n",
                PsGetCurrentProcessId(),
                KeGetCurrentIrql());
}

VOID PrintFunctionOpCode(PBYTE pAddress)
{
        ULONG ulGetOpCodeSingleSize = 0;
        ULONG ulGetOpCodeTotalSize = 0;
        ULONG nLines = 1;
        while (nLines <= 50)
        {
                ulGetOpCodeSingleSize = GetOpCodeSize(pAddress + ulGetOpCodeTotalSize);
                KDPRINT("【GetOpCodeX86】::【PrintFunctionOpCode】Line %03d, GetOpCodeSize:%d\r\n",
                        nLines, ulGetOpCodeSingleSize);
                ulGetOpCodeTotalSize += ulGetOpCodeSingleSize;
                nLines++;
        }
}

2.输出结果:

 3.Windbg反汇编结果

 4.结论

        通过对比可以看出前50条指令中每条指令长度都是正确计算出来的。

PS 附上库代码的CSDN下载链接

HookAPILib 0.4.raricon-default.png?t=LA23https://download.csdn.net/download/zhuting__xf/36512669

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值