系统相关
首页 > 系统相关> > Windows驱动开发学习记录- x86 InlineHook字节数计算(使用Hook Api lib 0.4 for C)

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为例,其反汇编如下:

 1 0: kd> u nt!NtOpenFile nt!NtQueryEaFile-1
 2 nt!NtOpenFile:
 3 8057b1a0 8bff            mov     edi,edi
 4 8057b1a2 55              push    ebp
 5 8057b1a3 8bec            mov     ebp,esp
 6 8057b1a5 33c0            xor     eax,eax
 7 8057b1a7 50              push    eax
 8 8057b1a8 50              push    eax
 9 8057b1a9 50              push    eax
10 8057b1aa 50              push    eax
11 8057b1ab 50              push    eax
12 8057b1ac ff751c          push    dword ptr [ebp+1Ch]
13 8057b1af 6a01            push    1
14 8057b1b1 ff7518          push    dword ptr [ebp+18h]
15 8057b1b4 50              push    eax
16 8057b1b5 50              push    eax
17 8057b1b6 ff7514          push    dword ptr [ebp+14h]
18 8057b1b9 ff7510          push    dword ptr [ebp+10h]
19 8057b1bc ff750c          push    dword ptr [ebp+0Ch]
20 8057b1bf ff7508          push    dword ptr [ebp+8]
21 8057b1c2 e873c7ffff      call    nt!IoCreateFile (8057793a)
22 8057b1c7 5d              pop     ebp
23 8057b1c8 c21800          ret     18h
24 8057b1cb cc              int     3
25 8057b1cc cc              int     3
26 8057b1cd cc              int     3
27 8057b1ce cc              int     3
28 8057b1cf cc              int     3

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

        如Windows XP SP3中的 NtOpenEvent:

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

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

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

 

二、代码实现

        直接上代码:

   头文件

  1 //
  2 //deroko 的LDEX86的头文件定义
  3 /*
  4        C_MODRM       for instructions that require MODRM
  5        C_PREFIX      for PREFIXES (SEG/REP)
  6        C_2BYTE       for instructions which opcode is 2 byte
  7 */
  8 #define       C_SIZE1             0x01
  9 #define       C_MODRM             0x02
 10 #define       C_DATA8             0x04
 11 #define       C_DATA16            0x08
 12 #define       C_DATA32            0x10
 13 #define       C_PREFIX            0x20
 14 #define       C_2BYTE             0x40
 15 #define       C_REL               0x80    //used to don't fuck up relative jmps with 67 prefix    
 16 #define       C_66                0x66    //operand size prefix
 17 #define       C_67                0x67    //address size prefix
 18  
 19 #define       C_UNKNOWN           0x00
 20  
 21 static BYTE table_1[256]={
 22 /* 00 */  C_MODRM
 23 /* 01 */, C_MODRM
 24 /* 02 */, C_MODRM
 25 /* 03 */, C_MODRM
 26 /* 04 */, C_DATA8    // add al, ax, eax + 32imm  w not set imm size = 8
 27 /* 05 */, C_DATA32   // add al, ax, eax + 32imm  w set imm size = 32
 28 /* 06 */, C_SIZE1    //push es
 29 /* 07 */, C_SIZE1    //pop es
 30 /* 08 */, C_MODRM    //or w set
 31 /* 09 */, C_MODRM    //or w not set :)
 32 /* 0A */, C_MODRM
 33 /* 0B */, C_MODRM
 34 /* 0C */, C_DATA8    // or al/ax/eax shortcut
 35 /* 0D */, C_DATA32   // or al/ax/eax shortcut
 36 /* 0E */, C_SIZE1    // push cs
 37 /* 0F */, C_2BYTE
 38 /* 10 */, C_MODRM    //adc w/d set mod rm, next 4
 39 /* 11 */, C_MODRM
 40 /* 12 */, C_MODRM
 41 /* 13 */, C_MODRM
 42 /* 14 */, C_DATA8    //adc al, imm8
 43 /* 15 */, C_DATA32   //adc al, imm32
 44 /* 16 */, C_SIZE1    //push ss
 45 /* 17 */, C_SIZE1    //pop ss
 46 /* 18 */, C_MODRM    //sbb w set/not set
 47 /* 19 */, C_MODRM
 48 /* 1A */, C_MODRM    //sbb d/w combinations
 49 /* 1B */, C_MODRM    //sbb d/w combinations
 50 /* 1C */, C_DATA8    //sbb al, imm8
 51 /* 1D */, C_DATA32   //sbb eax, imm32
 52 /* 1E */, C_SIZE1    //push ds
 53 /* 1F */, C_SIZE1    //pop ds
 54 /* 20 */, C_MODRM    //and mod/rm d/w bit combinations = 4
 55 /* 21 */, C_MODRM
 56 /* 22 */, C_MODRM
 57 /* 23 */, C_MODRM    //end and mod/rm d/w bit combinations
 58 /* 24 */, C_DATA8    //and al, imm8
 59 /* 25 */, C_DATA32   //and al, imm32
 60 /* 26 */, C_PREFIX
 61 /* 27 */, C_SIZE1    //daa
 62 /* 28 */, C_MODRM    //sub w/d mixup
 63 /* 29 */, C_MODRM    
 64 /* 2A */, C_MODRM
 65 /* 2B */, C_MODRM    //sub w/d mixup end
 66 /* 2C */, C_DATA8    //sub al, ax ,eax imm8
 67 /* 2D */, C_DATA32   //sub al, ax, eax imm8
 68 /* 2E */, C_PREFIX
 69 /* 2F */, C_SIZE1    //das
 70 /* 30 */, C_MODRM    //xor next 4
 71 /* 31 */, C_MODRM
 72 /* 32 */, C_MODRM
 73 /* 33 */, C_MODRM
 74 /* 34 */, C_DATA8    //xor al, ax, eax imm 8 w not set (al)
 75 /* 35 */, C_DATA32   //xor al, ax, eax imm 32 w set (eax)
 76 /* 36 */, C_PREFIX
 77 /* 37 */, C_SIZE1           //AAA
 78 /* 38 */, C_MODRM           //cmp d/w set 4 combinations
 79 /* 39 */, C_MODRM           //cmp
 80 /* 3A */, C_MODRM           //cmp
 81 /* 3B */, C_MODRM           //cmp
 82 /* 3C */, C_DATA8           //cmp al, ax, eax imm 8
 83 /* 3D */, C_DATA32          //cmp al, ax, eax imm 32
 84 /* 3E */, C_PREFIX
 85 /* 3F */, C_SIZE1           //AAS
 86 /* 40 */, C_SIZE1           //inc reg (alternate encoding)
 87 /* 41 */, C_SIZE1
 88 /* 42 */, C_SIZE1
 89 /* 43 */, C_SIZE1
 90 /* 44 */, C_SIZE1
 91 /* 45 */, C_SIZE1
 92 /* 46 */, C_SIZE1
 93 /* 47 */, C_SIZE1
 94 /* 48 */, C_SIZE1           //dec reg (alternate encoding)
 95 /* 49 */, C_SIZE1
 96 /* 4A */, C_SIZE1
 97 /* 4B */, C_SIZE1
 98 /* 4C */, C_SIZE1
 99 /* 4D */, C_SIZE1
100 /* 4E */, C_SIZE1
101 /* 4F */, C_SIZE1
102 /* 50 */, C_SIZE1
103 /* 51 */, C_SIZE1
104 /* 52 */, C_SIZE1
105 /* 53 */, C_SIZE1
106 /* 54 */, C_SIZE1
107 /* 55 */, C_SIZE1
108 /* 56 */, C_SIZE1
109 /* 57 */, C_SIZE1
110 /* 58 */, C_SIZE1    //pop reg
111 /* 59 */, C_SIZE1
112 /* 5A */, C_SIZE1
113 /* 5B */, C_SIZE1
114 /* 5C */, C_SIZE1
115 /* 5D */, C_SIZE1
116 /* 5E */, C_SIZE1
117 /* 5F */, C_SIZE1    //pop reg ends
118 /* 60 */, C_SIZE1    //pushad
119 /* 61 */, C_SIZE1    //popad
120 /* 62 */, C_MODRM    //bound
121 /* 63 */, C_MODRM    //arpl
122 /* 64 */, C_PREFIX
123 /* 65 */, C_PREFIX
124 /* 66 */, C_PREFIX
125 /* 67 */, C_PREFIX
126 /* 68 */, C_DATA32  //push immidiate 32
127 /* 69 */, C_MODRM + C_DATA32       //imul reg/reg imm32
128 /* 6A */, C_DATA8   //push imm 8
129 /* 6B */, C_MODRM + C_DATA8        //imul reg/reg imm8
130 /* 6C */, C_SIZE1   //ins w not set
131 /* 6D */, C_SIZE1   //ins w set
132 /* 6E */, C_SIZE1   //outs w not set
133 /* 6F */, C_SIZE1   //outs w set
134 /* 70 */, C_DATA8  + C_REL  //jcc 8 bit displacement start
135 /* 71 */, C_DATA8  + C_REL
136 /* 72 */, C_DATA8  + C_REL
137 /* 73 */, C_DATA8  + C_REL
138 /* 74 */, C_DATA8  + C_REL
139 /* 75 */, C_DATA8  + C_REL
140 /* 76 */, C_DATA8  + C_REL
141 /* 77 */, C_DATA8  + C_REL
142 /* 78 */, C_DATA8  + C_REL
143 /* 79 */, C_DATA8  + C_REL
144 /* 7A */, C_DATA8  + C_REL
145 /* 7B */, C_DATA8  + C_REL
146 /* 7C */, C_DATA8  + C_REL
147 /* 7D */, C_DATA8  + C_REL
148 /* 7E */, C_DATA8  + C_REL
149 /* 7F */, C_DATA8  + C_REL  //jcc 8 bit displacement ends
150 /* 80 */, C_MODRM + C_DATA8   //sub immidira/reg 32bit imm, also cmp modrm/imm32, also cmp
151 /* 81 */, C_MODRM + C_DATA32   //sub imidiate/reg 32bit imm, also cmp modrm/imm32, also cmp
152 /* 82 */, C_MODRM + C_DATA8    //sub or mod rm 8imm w not set, --||--      /imm8, also cmp
153 /* 83 */, C_MODRM + C_DATA8    //sub or mod rm 8imm w set set, --||--      /imm8, also cmp
154 /* 84 */, C_MODRM    //test w not set
155 /* 85 */, C_MODRM    //test w set
156 /* 86 */, C_MODRM    //xchg w not set
157 /* 87 */, C_MODRM    //xchg w set
158 /* 88 */, C_MODRM    //mov not set w
159 /* 89 */, C_MODRM    //mov set w
160 /* 8A */, C_MODRM    //mov d set/not
161 /* 8B */, C_MODRM
162 /* 8C */, C_MODRM    //mov reg/seg
163 /* 8D */, C_MODRM    //lea
164 /* 8E */, C_MODRM    //mov reg/seg I guess
165 /* 8F */, C_MODRM    //pop reg/memory
166 /* 90 */, C_SIZE1    //nop
167 /* 91 */, C_SIZE1    //xchg al, ax, eax   reg
168 /* 92 */, C_SIZE1
169 /* 93 */, C_SIZE1
170 /* 94 */, C_SIZE1
171 /* 95 */, C_SIZE1
172 /* 96 */, C_SIZE1
173 /* 97 */, C_SIZE1    //xchg al, ax, eax,  ret ends
174 /* 98 */, C_SIZE1    //cbw, cwde
175 /* 99 */, C_SIZE1    //cdq, cwd
176 /* 9A */, C_DATA32 + C_DATA16 //far call (call unsinged full offset,selector)
177 /* 9B */, C_SIZE1    //wait//fwait
178 /* 9C */, C_SIZE1           //pushfd
179 /* 9D */, C_SIZE1           //popfd
180 /* 9E */, C_SIZE1           //sahf
181 /* 9F */, C_SIZE1           //LAHF
182 /* A0 */, C_DATA32          //mov al, ax, eax,mem full_offset
183 /* A1 */, C_DATA32          //mov al, ax, eax, mem full_offset
184 /* A2 */, C_DATA32          //mov mem, al, ax, eax full_offset
185 /* A3 */, C_DATA32          //mov mem, al, ax, eax full_offset
186 /* A4 */, C_SIZE1           //movsb
187 /* A5 */, C_SIZE1           //movsd
188 /* A6 */, C_SIZE1    //cmpsb... 2 of them w bit set
189 /* A7 */, C_SIZE1    
190 /* A8 */, C_DATA8    //test al/ax/eax shortcut
191 /* A9 */, C_DATA32   //test al/ax/eax shortcut
192 /* AA */, C_SIZE1    //stosb
193 /* AB */, C_SIZE1    //stosd, or stosw + PREFIX 66
194 /* AC */, C_SIZE1    //lodsb
195 /* AD */, C_SIZE1    //lodsw + PREFIX 66 or lodsd
196 /* AE */, C_SIZE1    //scasb
197 /* AF */, C_SIZE1    //scasd
198 /* B0 */, C_DATA8    //mov reg, imm 8 alterante encoding
199 /* B1 */, C_DATA8
200 /* B2 */, C_DATA8
201 /* B3 */, C_DATA8
202 /* B4 */, C_DATA8
203 /* B5 */, C_DATA8
204 /* B6 */, C_DATA8
205 /* B7 */, C_DATA8
206 /* B8 */, C_DATA32   //mov immidiate to reg (alternate encoding)
207 /* B9 */, C_DATA32
208 /* BA */, C_DATA32
209 /* BB */, C_DATA32
210 /* BC */, C_DATA32
211 /* BD */, C_DATA32
212 /* BE */, C_DATA32
213 /* BF */, C_DATA32
214 /* C0 */, C_MODRM+C_DATA8 //rcl reg/mem by imm8 also rcr depends on opcode in modr/m field, also rol/ror
215 /* C1 */, C_MODRM+C_DATA8 //-----------||-----------
216 /* C2 */, C_DATA16
217 /* C3 */, C_SIZE1    //ret no args
218 /* C4 */, C_MODRM    //les
219 /* C5 */, C_MODRM    //lds
220 /* C6 */, C_MODRM+C_DATA8   // mov mem/imm
221 /* C7 */, C_MODRM+C_DATA32  //litle change (mov mem/imm)
222 /* C8 */, C_DATA8 + C_DATA16    //enter 16disp, 8bit level =4 size
223 /* C9 */, C_SIZE1
224 /* CA */, C_DATA16              //retf param
225 /* CB */, C_SIZE1               //retf no param
226 /* CC */, C_SIZE1
227 /* CD */, C_DATA8    //int, 8bit interupt number
228 /* CE */, C_SIZE1    //into 
229 /* CF */, C_SIZE1    //iret
230 /* D0 */, C_MODRM    //rcl reg/memory by 1 , also rcr, also ror/rol
231 /* D1 */, C_MODRM    //same with w bit set , -||-
232 /* D2 */, C_MODRM    //rcl register by cl  , -||-
233 /* D3 */, C_MODRM    //same with w bit set , -||- , also rol,ror
234 /* D4 */, C_DATA8    //aam 2 byte long but C_DATA8 is processed as 2 in my algo so this is ok
235 /* D5 */, C_DATA8    //aad 2 bytes long C_DATA8 is processed as 2 byte long 
236 /* D6 */, C_SIZE1    //salc
237 /* D7 */, C_SIZE1    //xlat
238 /* D8 */, C_MODRM    //all FPU are C_MODRM
239 /* D9 */, C_MODRM    
240 /* DA */, C_MODRM
241 /* DB */, C_MODRM
242 /* DC */, C_MODRM
243 /* DD */, C_MODRM
244 /* DE */, C_MODRM
245 /* DF */, C_MODRM    //end FPU instructions
246 /* E0 */, C_DATA8 + C_REL   //loonz 8bit
247 /* E1 */, C_DATA8 + C_REL   //loopz 8bit
248 /* E2 */, C_DATA8 + C_REL   //loop  8bit
249 /* E3 */, C_DATA8 + C_REL    //jecxz 8bit Address-size prefix indicates jcxz or jecxz
250 /* E4 */, C_DATA8    //in al, port
251 /* E5 */, C_DATA8    //in eax, port
252 /* E6 */, C_DATA8    //out port w not set (out 0, al)
253 /* E7 */, C_DATA8    //out port w set (out 0, eax)
254 /* E8 */, C_DATA32 + C_REL
255 /* E9 */, C_DATA32 + C_REL   //jmp full displacement
256 /* EA */, C_DATA32 + C_DATA16 //jmp far full offset, selector
257 /* EB */, C_DATA8     //jmp 8 bit displacement
258 /* EC */, C_SIZE1    //in
259 /* ED */, C_SIZE1    //in
260 /* EE */, C_SIZE1    //out
261 /* EF */, C_SIZE1    //out
262 /* F0 */, C_PREFIX
263 /* F1 */, C_SIZE1    //int1
264 /* F2 */, C_PREFIX
265 /* F3 */, C_PREFIX
266 /* F4 */, C_SIZE1    //hlt
267 /* F5 */, C_SIZE1    //cmc
268 /* F6 */, C_MODRM + C_DATA8 //not (w not set), neg depends on opcode field in modrm, it can be test imm
269 /* F7 */, C_MODRM + C_DATA32 //not (w set)    , neg depends on opcode field in modrm, it can be test imm
270 /* F8 */, C_SIZE1    //clc
271 /* F9 */, C_SIZE1    //stc
272 /* FA */, C_SIZE1    //cli
273 /* FB */, C_SIZE1    //sti
274 /* FC */, C_SIZE1    //cld
275 /* FD */, C_SIZE1    //std    
276 /* FE */, C_MODRM    //inc/dec w not set (modrm)
277 /* FF */, C_MODRM    //inc/dec w set     (modrm) //call also depends on reg/opcode field
278 };                   //also jmp (depends on reg/opcode) fild
279  
280 static BYTE table_2[256]={
281 /* 00 */  C_MODRM           //lldt
282 /* 01 */, C_MODRM           //invlpg
283 /* 02 */, C_MODRM           //lar
284 /* 03 */, C_MODRM           //LSL
285 /* 04 */, 0
286 /* 05 */, 0
287 /* 06 */, C_SIZE1           //clts
288 /* 07 */, 0
289 /* 08 */, C_SIZE1           //invd
290 /* 09 */, C_SIZE1
291 /* 0A */, 0
292 /* 0B */, 0
293 /* 0C */, 0
294 /* 0D */, 0
295 /* 0E */, 0
296 /* 0F */, 0
297 /* 10 */, 0
298 /* 11 */, 0
299 /* 12 */, 0
300 /* 13 */, 0
301 /* 14 */, 0
302 /* 15 */, 0
303 /* 16 */, 0
304 /* 17 */, 0
305 /* 18 */, 0
306 /* 19 */, 0
307 /* 1A */, 0
308 /* 1B */, 0
309 /* 1C */, 0
310 /* 1D */, 0
311 /* 1E */, 0
312 /* 1F */, 0
313 /* 20 */, C_MODRM           //mov reg/crX
314 /* 21 */, C_MODRM           //mov drX/reg
315 /* 22 */, C_MODRM           //mov crX/reg and it foes all the way down
316 /* 23 */, C_MODRM           //mov reg/drX
317 /* 24 */, 0
318 /* 25 */, 0
319 /* 26 */, 0
320 /* 27 */, 0
321 /* 28 */, 0
322 /* 29 */, 0
323 /* 2A */, 0
324 /* 2B */, 0
325 /* 2C */, 0
326 /* 2D */, 0
327 /* 2E */, 0
328 /* 2F */, 0
329 /* 30 */, C_SIZE1
330 /* 31 */, C_SIZE1
331 /* 32 */, C_SIZE1
332 /* 33 */, C_SIZE1
333 /* 34 */, C_SIZE1
334 /* 35 */, 0
335 /* 36 */, 0
336 /* 37 */, 0
337 /* 38 */, 0
338 /* 39 */, 0
339 /* 3A */, 0
340 /* 3B */, 0
341 /* 3C */, 0
342 /* 3D */, 0
343 /* 3E */, 0
344 /* 3F */, 0
345 /* 40 */, C_MODRM           //conditional move
346 /* 41 */, C_MODRM
347 /* 42 */, C_MODRM
348 /* 43 */, C_MODRM
349 /* 44 */, C_MODRM
350 /* 45 */, C_MODRM
351 /* 46 */, C_MODRM
352 /* 47 */, C_MODRM
353 /* 48 */, C_MODRM
354 /* 49 */, C_MODRM
355 /* 4A */, C_MODRM
356 /* 4B */, C_MODRM
357 /* 4C */, C_MODRM
358 /* 4D */, C_MODRM
359 /* 4E */, C_MODRM
360 /* 4F */, C_MODRM           //end conditional move 
361 /* 50 */, 0
362 /* 51 */, 0
363 /* 52 */, 0
364 /* 53 */, 0
365 /* 54 */, 0
366 /* 55 */, 0
367 /* 56 */, 0
368 /* 57 */, 0
369 /* 58 */, 0
370 /* 59 */, 0
371 /* 5A */, 0
372 /* 5B */, 0
373 /* 5C */, 0
374 /* 5D */, 0
375 /* 5E */, 0
376 /* 5F */, 0
377 /* 60 */, 0
378 /* 61 */, 0
379 /* 62 */, 0
380 /* 63 */, 0
381 /* 64 */, 0
382 /* 65 */, 0
383 /* 66 */, 0
384 /* 67 */, 0
385 /* 68 */, 0
386 /* 69 */, 0
387 /* 6A */, 0
388 /* 6B */, 0
389 /* 6C */, 0
390 /* 6D */, 0
391 /* 6E */, 0
392 /* 6F */, 0
393 /* 70 */, 0
394 /* 71 */, 0
395 /* 72 */, 0
396 /* 73 */, 0
397 /* 74 */, 0
398 /* 75 */, 0
399 /* 76 */, 0
400 /* 77 */, 0
401 /* 78 */, 0
402 /* 79 */, 0
403 /* 7A */, 0
404 /* 7B */, 0
405 /* 7C */, 0
406 /* 7D */, 0
407 /* 7E */, 0
408 /* 7F */, 0
409 /* 80 */, C_DATA32   //jccs 2 byte long imm32
410 /* 81 */, C_DATA32
411 /* 82 */, C_DATA32
412 /* 83 */, C_DATA32
413 /* 84 */, C_DATA32
414 /* 85 */, C_DATA32
415 /* 86 */, C_DATA32
416 /* 87 */, C_DATA32
417 /* 88 */, C_DATA32
418 /* 89 */, C_DATA32
419 /* 8A */, C_DATA32
420 /* 8B */, C_DATA32
421 /* 8C */, C_DATA32
422 /* 8D */, C_DATA32
423 /* 8E */, C_DATA32
424 /* 8F */, C_DATA32   //jccs 2byte long ends imm32
425 /* 90 */, C_MODRM
426 /* 91 */, C_MODRM
427 /* 92 */, C_MODRM
428 /* 93 */, C_MODRM
429 /* 94 */, C_MODRM
430 /* 95 */, C_MODRM
431 /* 96 */, C_MODRM
432 /* 97 */, C_MODRM
433 /* 98 */, C_MODRM
434 /* 99 */, C_MODRM
435 /* 9A */, C_MODRM
436 /* 9B */, C_MODRM
437 /* 9C */, C_MODRM
438 /* 9D */, C_MODRM
439 /* 9E */, C_MODRM
440 /* 9F */, C_MODRM
441 /* A0 */, C_SIZE1            //push fs
442 /* A1 */, C_SIZE1           //pop fs
443 /* A2 */, C_SIZE1           //cpuid
444 /* A3 */, C_MODRM           //bt reg/mem
445 /* A4 */, C_MODRM + C_DATA8
446 /* A5 */, C_MODRM
447 /* A6 */, 0
448 /* A7 */, 0
449 /* A8 */, C_SIZE1           //push gs
450 /* A9 */, C_SIZE1           //pop gs
451 /* AA */, C_SIZE1
452 /* AB */, C_MODRM           //bts
453 /* AC */, C_MODRM + C_DATA8
454 /* AD */, C_MODRM
455 /* AE */, 0
456 /* AF */, C_MODRM           //imul reg/reg or reg/mem
457 /* B0 */, C_MODRM           //cmpxchg
458 /* B1 */, C_MODRM           //cmpxchg
459 /* B2 */, C_MODRM           //lss
460 /* B3 */, C_MODRM           //btr
461 /* B4 */, C_MODRM           //lfs
462 /* B5 */, C_MODRM           //lgs
463 /* B6 */, C_MODRM           //movzx
464 /* B7 */, C_MODRM           //movzx
465 /* B8 */, 0
466 /* B9 */, 0
467 /* BA */, C_MODRM + C_DATA8 //bt imm8
468 /* BB */, C_MODRM           //btc mod/rm
469 /* BC */, C_MODRM           //BSF
470 /* BD */, C_MODRM           //BSR
471 /* BE */, C_MODRM           //movsx
472 /* BF */, C_MODRM           //movsx
473 /* C0 */, C_MODRM           //xadd
474 /* C1 */, C_MODRM           //xadd
475 /* C2 */, 0
476 /* C3 */, 0
477 /* C4 */, 0
478 /* C5 */, 0
479 /* C6 */, 0
480 /* C7 */, 0
481 /* C8 */, C_SIZE1           //bswap eax
482 /* C9 */, C_SIZE1
483 /* CA */, C_SIZE1
484 /* CB */, C_SIZE1
485 /* CC */, C_SIZE1
486 /* CD */, C_SIZE1
487 /* CE */, C_SIZE1
488 /* CF */, C_SIZE1           //bswap reg ends
489 /* D0 */, 0
490 /* D1 */, 0
491 /* D2 */, 0
492 /* D3 */, 0
493 /* D4 */, 0
494 /* D5 */, 0
495 /* D6 */, 0
496 /* D7 */, 0
497 /* D8 */, 0
498 /* D9 */, 0
499 /* DA */, 0
500 /* DB */, 0
501 /* DC */, 0
502 /* DD */, 0
503 /* DE */, 0
504 /* DF */, 0
505 /* E0 */, 0
506 /* E1 */, 0
507 /* E2 */, 0
508 /* E3 */, 0
509 /* E4 */, 0
510 /* E5 */, 0
511 /* E6 */, 0
512 /* E7 */, 0
513 /* E8 */, 0
514 /* E9 */, 0
515 /* EA */, 0
516 /* EB */, 0
517 /* EC */, 0
518 /* ED */, 0
519 /* EE */, 0
520 /* EF */, 0
521 /* F0 */, 0
522 /* F1 */, 0
523 /* F2 */, 0
524 /* F3 */, 0
525 /* F4 */, 0
526 /* F5 */, 0
527 /* F6 */, 0
528 /* F7 */, 0
529 /* F8 */, 0
530 /* F9 */, 0
531 /* FA */, 0
532 /* FB */, 0
533 /* FC */, 0
534 /* FD */, 0
535 /* FE */, 0
536 /* FF */, 0
537 };

  CPP文件

 1 int GetOpCodeSize(PVOID Start)
 2 {
 3         BYTE opcode, * p, /*tempopcode,*/ instruction;
 4         int size;
 5         int opsizeprefix = 0, addressprefix = 0;
 6         size = 0;
 7         p = (PBYTE)Start;
 8         opcode = *p;
 9         //Proces PREFIXES!!! if any...
10 prefix_loop:
11         if (table_1[opcode] == C_PREFIX) {
12                 if (opcode == C_66)
13                         opsizeprefix = 1;
14                 if (opcode == C_67)
15                         addressprefix = 1;
16                 size++;
17                 p++;
18                 opcode = *p;
19                 goto prefix_loop;
20         }
21         //check for test, stupid and fucking test
22         instruction = table_1[opcode];
23         if ((opcode == 0xF6) || (opcode == 0xF7)) {
24                 opcode = p[1];
25                 if ((opcode & 0x38) != 0)         //test or neg/not...
26                         instruction = C_MODRM;
27  
28         }
29         if (opsizeprefix)
30                 //where was 8 still is 8 //where was 32 now is 16
31                 if (instruction & C_DATA32) {
32                         instruction &= ~(C_DATA32);
33                         instruction |= C_DATA16;
34                 }
35         //if not relative change 
36         if (addressprefix && !(instruction & C_REL)) {
37                 instruction &= ~(C_DATA32);
38                 instruction &= ~(C_DATA8);
39                 instruction |= C_DATA16;
40         }
41         //clear relative flag
42         if (instruction & C_REL)
43                 instruction &= ~(C_REL);
44         //fill instruction with flags from table_2 and decode it in right way
45         if (instruction == C_2BYTE) {
46                 size += 1;
47                 p++;
48                 instruction = table_2[*p];
49                 //if (instruction == C_DATA32)
50                 //   size += 5;
51                 //goto check_modrm;   
52         }
53         size += 1;                         //opcode len;     
54 //check_modrm:
55         if (instruction & C_MODRM) {
56                 unsigned char modrm, sib;
57                 size += 1;
58                 p++;
59                 modrm = *p;
60                 if ((modrm >> 6) == 0 && (modrm & 0x07) == 0x05) //modrm is folowed by 32disp
61                         size += 4;
62  
63                 if ((modrm >> 6) != 3 && (modrm & 0x07) == 0x04) {   //sib
64                         size++;
65                         p++;
66                         sib = *p;
67                         if ((modrm >> 6) == 1 && (modrm & 0x07) == 0x04) //8bit disp after SIB(added to index)
68                                 size++;
69                         if ((modrm >> 6) == 2 && (modrm & 0x07) == 0x04) //32bit displacement after sib(added to index)             
70                                 size += 4;
71                         if ((modrm >> 6) == 0 && (sib & 0x07) == 0x05)
72                                 size += 4;
73                 } //SIB processing
74                 TEST CODE//
75                 if (modrm >= 0x40 && modrm <= 0x7f && (modrm & 0x07) != 0x04)
76                         size += 1;
77                 if (modrm >= 0x80 && modrm <= 0xbf && (modrm & 0x07) != 0x04)
78                         size += 4;
79                 ///TEST CODE/// 
80         }
81         if (instruction & C_DATA32)  //is this opcode opcode modrm immdata ???
82                 size += 4;
83         if (instruction & C_DATA8)
84                 size++;
85         if (instruction & C_DATA16)
86                 size += 2;
87         if (instruction == C_UNKNOWN)
88                 size += 1;
89         return size;
90 }

 

 

三、测试

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

  1.代码

 1 #if DBG
 2 #define KDPRINT(projectName, format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,    projectName "::【" __FUNCTION__  "】" ##format,  ##__VA_ARGS__ )
 3 #else
 4 #define KDPRINT(format, ...)
 5 #endif
 6 
 7 
 8 NTSTATUS  DriverEntry(
 9         PDRIVER_OBJECT pDriverObject,
10         PUNICODE_STRING pRegistryPath)
11 {
12         UNREFERENCED_PARAMETER(pDriverObject);
13         NTSTATUS ntStatus = STATUS_SUCCESS;
14         do
15         {
16                 KDPRINT("【GetOpCodeX86】","DriverEntry! \n");
17 
18                 KDPRINT("【GetOpCodeX86】","Hello Kernel World! CurrentProcessId:0x%p CurrentIRQL:0x%u\n",
19                         PsGetCurrentProcessId(),
20                         KeGetCurrentIrql());
21 
22                 if (pRegistryPath != NULL)
23                 {
24                         KDPRINT("【GetOpCodeX86】","RegistryPath:%wZ \n", pRegistryPath);
25                 }
26                 pDriverObject->DriverUnload = DriverUnload;
27 
28                 PrintFunctionOpCode((PBYTE)NtOpenProcess);
29 
30         } while (false);
31 
32         return ntStatus;
33 }
34 
35 VOID DriverUnload(
36         PDRIVER_OBJECT pDriverObject)
37 {
38         UNREFERENCED_PARAMETER(pDriverObject);
39         KDPRINT("【GetOpCodeX86】"," CurrentProcessId:0x%p CurrentIRQL:0x%u\n",
40                 PsGetCurrentProcessId(),
41                 KeGetCurrentIrql());
42 }
43 
44 VOID PrintFunctionOpCode(PBYTE pAddress)
45 {
46         ULONG ulGetOpCodeSingleSize = 0;
47         ULONG ulGetOpCodeTotalSize = 0;
48         ULONG nLines = 1;
49         while (nLines <= 50)
50         {
51                 ulGetOpCodeSingleSize = GetOpCodeSize(pAddress + ulGetOpCodeTotalSize);
52                 KDPRINT("【GetOpCodeX86】","Line %03d, GetOpCodeSize:%d\r\n",
53                         nLines, ulGetOpCodeSingleSize);
54                 ulGetOpCodeTotalSize += ulGetOpCodeSingleSize;
55                 nLines++;
56         }
57 }

 

  

  2.输出结果(WinXP SP3):

 

 

   3.Windbg反汇编结果

 

 

  4.结论

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

 

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

  《HookAPILib0.4.rar》

标签:set,x86,字节数,DATA32,eax,DATA8,lib,MODRM,SIZE1
来源: https://www.cnblogs.com/ImprisonedSoul/p/15603730.html