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 #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 }
通过对比可以看出前50条指令中每条指令长度都是正确计算出来的。
《HookAPILib0.4.rar》