Sucsor
驱动牛犊
驱动牛犊
  • 注册日期2005-02-05
  • 最后登录2007-03-27
  • 粉丝0
  • 关注0
  • 积分253分
  • 威望26点
  • 贡献值0点
  • 好评度25点
  • 原创分2分
  • 专家分0分
阅读:5859回复:14

[原创](AVP)卡巴驱动程序载入分析随记

楼主#
更多 发布于:2007-02-02 09:44
  (AVP)卡巴驱动程序载入分析随记 by Sucsor/RCT
    忘记是什么原因了,去年曾经跟踪过AVP的驱动程序,发现kl1.sys的驱动程序中多出了几个设备对象,
但是代码中又没有找到创建设备对象相应的代码.后来发现在是在别的驱动里创建的,但是在KD时,
又没有发现其模块,很纳闷,后来发现Kl1.sys中果然是将几个*.sys载入了几个驱动,并执行了这些驱动的代码.
    最近突发奇想,想要做个驱动的壳,而AVP有那么点儿意思,让一个驱动程序做Loader,然后在这个Loader里
处理其他代码,我想应该可以按这个思路做个小壳.........
    声明,只是爱好和学习,没有其他目的.本文初发布于http://www.debugman.com,后来看到XIkug的文件来到这里,
所以也来热闹一下,希望本文能起抛砖引玉的作用.

致谢:fly,xikug,winroot,throb,lemon...

以下流程都是在kl1.sys 中执行的,其文件版本是:6.0.15.229,文章写的比较仓促,再加上实在不太会写文章,失误之处请指正

1,HOOK SSDT NtOpenFile,将自己的NtOpenFile替换系统的,在做完自己的处理后再传递给系统
.text:000112E9 83 C4 0C                          add     esp, 0Ch        ; 下面是HookZwOpenFile
.text:000112EC 0F 20 C3                          mov     ebx, cr0
.text:000112EF 53                                push    ebx
.text:000112F0 81 E3 FF FF FE FF                 and     ebx, 0FFFEFFFFh  ;取消页保护 16bit of Cr0
.text:000112F6 0F 22 C3                          mov     cr0, ebx
.text:000112F9 B8 34 1A 01 00                    mov     eax, offset ZwOpenFile(x,x,x,x,x,x)
.text:000112FE 33 C9                             xor     ecx, ecx
.text:00011300 8B 40 02                          mov     eax, [eax+2]
.text:00011303 8B 00                             mov     eax, [eax]
.text:00011305 80 38 B8                          cmp     byte ptr [eax], 0B8h ;目前2000-2003的首字节都是B8
.text:00011308 75 04                             jnz     short loc_1130E
.text:00011308
                                                 ;得到服务号
.text:0001130A 0F B6 48 01                       movzx   ecx, byte ptr [eax+1]
.text:0001130A
.text:0001130E
.text:0001130E                   loc_1130E:                              ; CODE XREF: DriverEntry(x,x)+FBj
.text:0001130E A1 C8 02 01 00                    mov     eax, ds:__imp__KeServiceDescriptorTable
.text:00011313 C1 E1 02                          shl     ecx, 2
.text:00011316 8B 10                             mov     edx, [eax]
.text:00011318 8B 14 0A                          mov     edx, [edx+ecx] ;计算SSDT项
.text:0001131B 89 15 0C 1C 01 00                 mov     long (*r_ZwOpenFile)(void * *,ulong,_OBJECT_ATTRIBUTES *,_IO_STATUS_BLOCK *,ulong,ulong), edx
.text:00011321 8B 00                             mov     eax, [eax];修改SSDT项
.text:00011323 C7 04 08 28 10 01+                mov     dword ptr [eax+ecx], offset hZwOpenFile(void * *,ulong,_OBJECT_ATTRIBUTES *,_IO_STATUS_BLOCK *,ulong,ulong)
.text:0001132A 5B                                pop     ebx
.text:0001132B 0F 22 C3                          mov     cr0, ebx ;还原Cr0
.text:0001132E 33 C0                             xor     eax, eax

2,AVP的NtOpenFile被调用时,都会判断IsHook变量是否为TRUE和文件路径是否是包含"\\SystemRoot\\System32\\DRIVERS\\",
  根据我的理解,这个判断是为了确认OS是否已经支持访问这个路径了。
3,如果包括有"\\SystemRoot\\System32\\DRIVERS\\"路径并IsHook为FALSE,则执行载入自己驱动的操作,在执行成功后设置
  IsHook为TRUE.  
4,AVP的载入驱动的函数是从MyLoad开始的,MyLoad做了两件事,1是从
  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\kl1\Parameters中取出各个需要启动的驱动的路径,
  以备后面打开文件;2,调用Load函数处理文件的载入操作
5,Load函数首先初始了Module对像(参见附录的对象关系),构造函数的第一个参数是要载入驱动的名字,在这个构造
  函数返回的对象中包含了载入的驱动的入口地址(具体见对象关系);然后,Load调用Module::Begin开始执行被载入
  驱动的代码.
6,Module::Module函数的工作流程:
  6.1 从文件名的全路径中得到*.sys名字,与"\\SystemRoot\\System32\\DRIVERS\\%s"接合,
  6,2 打开文件,查询文件大小,分配内存,将整个文件读到内存,调用函数分别是:
      ZwCreateFile,ZwQueryInformationFile,ExAllocatePoolWithTag和ZwReadFile
  6.3 初始了Module2对象,该对象偏移8处保存了被读入文件的缓冲区地址,
      并将对象保存到Module对象成员中,调用Module::Init函数(),该函数分配了一个结构,
      该结构中最重的是一个成员保存了被载入驱动的入口函数地址.
  6.4 调用Module2::Mark2,该函数对驱动文件进行了Mapping,处理了重定位表,处理了IAT
      ,然后将驱动的入口函数地址保存到结构里
以下是从Module2::Mark2截取的代码:
这段代码新开缓冲区,准备进行Mapping
.text:00011683 55                                push    ebp
.text:00011684 8B EC                             mov     ebp, esp
.text:00011686 83 EC 20                          sub     esp, 20h
.text:00011689 8B 45 08                          mov     eax, [ebp+Offset2c]
.text:0001168C 53                                push    ebx
.text:0001168D 8B D9                             mov     ebx, ecx   ==>Ecx是Module2对象,+8处保存了文件缓冲区地址
.text:0001168F 56                                push    esi
.text:00011690 83 20 00                          and     dword ptr [eax], 0
.text:00011693 57                                push    edi
.text:00011694 8B 43 08                          mov     eax, [ebx+8] ;取文件缓冲区地址
.text:00011697 68 47 65 4E 2D                    push    '-NeG'          ; Tag
.text:0001169C 89 45 F4                          mov     [ebp+OffsetOfBaseAddress], eax
.text:0001169F 8B 48 3C                          mov     ecx, [eax+3Ch]  ; IMAGE_NT_HEADERS的偏移
.text:000116A2 FF 74 08 50                       push    dword ptr [eax+ecx+50h] ; NumberOfBytes ==>SizeOfImage
.text:000116A6 8D 34 08                          lea     esi, [eax+ecx]
.text:000116A9 89 75 FC                          mov     [ebp+pImageNtHeader], esi
.text:000116AC 6A 00                             push    0               ; PoolType
.text:000116AE FF 15 04 03 01 00                 call    ds:ExAllocatePoolWithTag(x,x,x) ; 又分配是一个缓冲区用于以Image的方式Mapping文件
.text:000116B4 89 43 0C                          mov     [ebx+0Ch], eax ;将缓冲区保存的0xc 处
.text:000116B7 8B 4E 54                          mov     ecx, [esi+_IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeaders] ; SizeOfHeaders
.text:000116BA 8B 73 08                          mov     esi, [ebx+8]
.text:000116BD 8B F8                             mov     edi, eax
.text:000116BF 8B C1                             mov     eax, ecx
.text:000116C1 C1 E9 02                          shr     ecx, 2
.text:000116C4 F3 A5                             rep movsd               ; 将Headers传到新分析的缓冲区里
.text:000116C6 8B C8                             mov     ecx, eax
.text:000116C8 8B 45 F4                          mov     eax, [ebp+OffsetOfBaseAddress]
.text:000116CB 83 E1 03                          and     ecx, 3
.text:000116CE F3 A4                             rep movsb               ; 将边界剩下的传送
.text:000116D0 33 C9                             xor     ecx, ecx

以下代码处理Section的影射,特别之处主要是对于SectionAlignment的处理(注:这里变量多个含义,名字起的不一定准确)
这段将每个段进行了影射,除了Reloc段

.text:000116D0 33 C9                             xor     ecx, ecx
.text:000116D2 66 81 38 4D 5A                    cmp     word ptr [eax], 'ZM'    
.text:000116D7 89 4D F0                          mov     [ebp+NextSectionOffset], ecx
.text:000116DA 0F 85 97 00 00 00                 jnz     loc_11777
.text:000116DA
.text:000116E0 39 48 3C                          cmp     [eax+IMAGE_DOS_HEADER.e_lfanew], ecx
.text:000116E3 0F 84 8E 00 00 00                 jz      loc_11777
.text:000116E3
.text:000116E9 8B 55 FC                          mov     edx, [ebp+pImageNtHeader]
.text:000116EC 89 4D F4                          mov     [ebp+OffsetOfBaseAddress], ecx
.text:000116EF 66 39 4A 06                       cmp     [edx+_IMAGE_NT_HEADERS.FileHeader.NumberOfSections], cx
.text:000116F3 0F 86 81 00 00 00                 jbe     loc_1177A       ; Image Buffer
.text:000116F3
.text:000116F9 8D B2 08 01 00 00                 lea     esi, [edx+108h]
.text:000116FF 89 75 F8                          mov     [ebp+pSizeOfRawData], esi
.text:000116FF
.text:00011702
.text:00011702                   loc_11702:                              ; CODE XREF: Module2::Mark2(void * *)+F2j
.text:00011702 F6 46 14 60                       test    byte ptr [esi+14h], 60h ; Characteristics ==> READ | Execute
.text:00011706 74 2D                             jz      short loc_11735
.text:00011706
.text:00011708 8B 46 F8                          mov     eax, [esi-8]    ; VirtualSize
.text:0001170B 8B 0E                             mov     ecx, [esi]      ; SizeOfRawData
.text:0001170D 3B C1                             cmp     eax, ecx
.text:0001170F 77 02                             ja      short loc_11713
.text:0001170F
.text:00011711 8B C8                             mov     ecx, eax        ; 取大
.text:00011711
.text:00011713
.text:00011713                   loc_11713:                              ; CODE XREF: Module2::Mark2(void * *)+8Cj
.text:00011713 8B 45 F8                          mov     eax, [ebp+pSizeOfRawData]
.text:00011716 8B 76 04                          mov     esi, [esi+4]    ; PointerToRawData
.text:00011719 03 73 08                          add     esi, [ebx+8]    ; 指向原代码的Raw位置
.text:0001171C 8B 78 FC                          mov     edi, [eax-4]    ; VirtualAddress
.text:0001171F 8B C1                             mov     eax, ecx
.text:00011721 03 7B 0C                          add     edi, [ebx+0Ch]  ; 求目标[虚拟]地址
.text:00011724 C1 E9 02                          shr     ecx, 2
.text:00011727 F3 A5                             rep movsd               ; Copy Code
.text:00011729 8B C8                             mov     ecx, eax        ;
.text:0001172B 83 E1 03                          and     ecx, 3
.text:0001172E F3 A4                             rep movsb
.text:00011730 8B 75 F8                          mov     esi, [ebp+pSizeOfRawData]
.text:00011733 EB 19                             jmp     short loc_1174E ; 处理SectionAlignment
.text:00011733
.text:00011735                   ; ---------------------------------------------------------------------------
.text:00011735
.text:00011735                   loc_11735:                              ; CODE XREF: Module2::Mark2(void * *)+83j
.text:00011735 8B 4E F8                          mov     ecx, [esi-8]
.text:00011738 8B 7E FC                          mov     edi, [esi-4]    ; VirtualAddress
.text:0001173B 03 7B 08                          add     edi, [ebx+8]    ; 计算目标的虚拟地址
.text:0001173E 8B D1                             mov     edx, ecx
.text:00011740 33 C0                             xor     eax, eax
.text:00011742 C1 E9 02                          shr     ecx, 2
.text:00011745 F3 AB                             rep stosd
.text:00011747 8B CA                             mov     ecx, edx
.text:00011749 83 E1 03                          and     ecx, 3
.text:0001174C F3 AA                             rep stosb
.text:0001174C
.text:0001174E
.text:0001174E                   loc_1174E:                              ; CODE XREF: Module2::Mark2(void * *)+B0j
.text:0001174E 8B 7D FC                          mov     edi, [ebp+pImageNtHeader] ; 处理SectionAlignment
.text:00011751 8B 46 F8                          mov     eax, [esi-8]
.text:00011754 33 D2                             xor     edx, edx
.text:00011756 83 C6 28                          add     esi, 28h        ; esi==> SizeOfRawData
.text:00011759 8B 4F 38                          mov     ecx, [edi+38h]  ; SectionAlignment
.text:0001175C 89 75 F8                          mov     [ebp+pSizeOfRawData], esi
.text:0001175F 8D 44 08 FF                       lea     eax, [eax+ecx-1] ; 对齐到SectionAlignemnt
.text:00011763 F7 F1                             div     ecx
.text:00011765 0F AF C1                          imul    eax, ecx
.text:00011768 01 45 F0                          add     [ebp+NextSectionOffset], eax
.text:0001176B FF 45 F4                          inc     [ebp+OffsetOfBaseAddress]
.text:0001176E 0F B7 47 06                       movzx   eax, word ptr [edi+6] ; NumerOfSections
.text:00011772 39 45 F4                          cmp     [ebp+OffsetOfBaseAddress], eax    ;
.text:00011775 72 8B                             jb      short loc_11702 ; Characteristics ==> READ | Execute

以下代码处理重定位表,貌似跟流出来的Win2k的代码中处理重定位表的代码相似
.text:00011777 8B 55 FC                          mov     edx, [ebp+pImageNtHeader] ; int
.text:00011777
.text:0001177A
.text:0001177A                   loc_1177A:                              ; CODE XREF: Module2::Mark2(void * *)+70j
.text:0001177A 8B 4B 0C                          mov     ecx, [ebx+0Ch]  ; Image Buffer
.text:0001177D 8B 82 A0 00 00 00                 mov     eax, [edx+0A0h] ; ==>IMAGE_DIRECTORY_ENTRY_BASERELOC 重定位表的VirtualAddress
.text:00011783 8B B2 A4 00 00 00                 mov     esi, [edx+0A4h] ; 重定位表的大小
.text:00011789 8B F9                             mov     edi, ecx
.text:0001178B 2B 7A 34                          sub     edi, [edx+_IMAGE_NT_HEADERS.OptionalHeader.ImageBase] ; ImageBase
.text:0001178E 03 C1                             add     eax, ecx
.text:00011790 85 F6                             test    esi, esi
.text:00011792 89 75 F4                          mov     [ebp+OffsetOfBaseAddress], esi
.text:00011795 74 52                             jz      short loc_117E9 ;
.text:00011795
.text:00011797
.text:00011797                   b_processReloc:                         ; CODE XREF: Module2::Mark2(void * *)+164j
.text:00011797 8B 48 04                          mov     ecx, [eax+IMAGE_BASE_RELOCATION.SizeOfBlock]
.text:0001179A 8D 70 08                          lea     esi, [eax+8]
.text:0001179D 29 4D F4                          sub     [ebp+OffsetOfBaseAddress], ecx
.text:000117A0 8B 00                             mov     eax, [eax]
.text:000117A2 03 43 0C                          add     eax, [ebx+0Ch]
.text:000117A5 83 C1 F8                          add     ecx, -8
.text:000117A8 D1 E9                             shr     ecx, 1
.text:000117AA 89 75 F8                          mov     [ebp+pSizeOfRawData], esi
.text:000117AD 8B F1                             mov     esi, ecx
.text:000117AF 49                                dec     ecx
.text:000117B0 85 F6                             test    esi, esi
.text:000117B2 74 2C                             jz      short loc_117E0
.text:000117B2
.text:000117B4 41                                inc     ecx
.text:000117B5 89 4D F0                          mov     [ebp+NextSectionOffset], ecx
.text:000117B5
.text:000117B8

.text:000117B8                   loc_117B8:                              ; CODE XREF: Module2::Mark2(void * *)+15Bj
.text:000117B8 8B 4D F8                          mov     ecx, [ebp+pSizeOfRawData]
.text:000117BB 0F B7 09                          movzx   ecx, word ptr [ecx]
.text:000117BE 8B F1                             mov     esi, ecx        ; 处理重定位表 见附录
.text:000117C0 66 81 E1 00 F0                    and     cx, 0F000h      ;
.text:000117C5 81 E6 FF 0F 00 00                 and     esi, 0FFFh
.text:000117CB 03 F0                             add     esi, eax
.text:000117CD 81 F9 00 30 00 00                 cmp     ecx, 3000h
.text:000117D3 75 02                             jnz     short loc_117D7
.text:000117D3
.text:000117D5 01 3E                             add     [esi], edi
.text:000117D5
.text:000117D7
.text:000117D7                   loc_117D7:                              ; CODE XREF: Module2::Mark2(void * *)+150j
.text:000117D7 83 45 F8 02                       add     [ebp+pSizeOfRawData], 2
.text:000117DB FF 4D F0                          dec     [ebp+NextSectionOffset]
.text:000117DE 75 D8                             jnz     short loc_117B8
.text:000117DE
.text:000117E0
.text:000117E0                   loc_117E0:                              ; CODE XREF: Module2::Mark2(void * *)+12Fj
.text:000117E0 83 7D F4 00                       cmp     [ebp+OffsetOfBaseAddress], 0
.text:000117E4 8B 45 F8                          mov     eax, [ebp+pSizeOfRawData]
.text:000117E7 75 AE                             jnz     short b_processReloc

以下是处理导入表的代码,相信这个大家都比较了解了
.text:000117E9 8B 82 80 00 00 00                 mov     eax, [edx+80h]  ; 导入表的VirtualAddress
.text:000117EF 85 C0                             test    eax, eax
.text:000117F1 0F 84 B1 00 00 00                 jz      loc_118A8
.text:000117F1
.text:000117F7 8B 7B 0C                          mov     edi, [ebx+0Ch]
.text:000117FA 03 F8                             add     edi, eax        ; edi指向 IMAGE_IMPORT_DESCRIPTOR
.text:000117FA
.text:000117FC
.text:000117FC                   loc_117FC:                              ; CODE XREF: Module2::Mark2(void * *)+220j
.text:000117FC 8B 4F 0C                          mov     ecx, [edi+IMAGE_IMPORT_DESCRIPTOR.Name]
.text:000117FF 85 C9                             test    ecx, ecx
.text:00011801 0F 84 A1 00 00 00                 jz      loc_118A8
.text:00011801
.text:00011807 8B 43 0C                          mov     eax, [ebx+0Ch]
.text:0001180A 03 C8                             add     ecx, eax
.text:0001180C 89 4D F4                          mov     [ebp+OffsetOfBaseAddress], ecx
.text:0001180F 8B 4F 10                          mov     ecx, [edi+IMAGE_IMPORT_DESCRIPTOR.FirstThunk]
.text:00011812 8D 34 01                          lea     esi, [ecx+eax]
.text:00011815 8B 0F                             mov     ecx, [edi]
.text:00011817 85 C9                             test    ecx, ecx
.text:00011819 74 07                             jz      short loc_11822
.text:00011819
.text:0001181B 03 C8                             add     ecx, eax
.text:0001181D 89 4D F8                          mov     [ebp+pSizeOfRawData], ecx
.text:00011820 EB 03                             jmp     short loc_11825
计算驱动入口地址
.text:000118A8 8B 42 28                          mov     eax, [edx+_IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint]
.text:000118AB 8B 4D 08                          mov     ecx, [ebp+Offset2c]
.text:000118AE 03 43 0C                          add     eax, [ebx+0Ch]
.text:000118B1 5F                                pop     edi
.text:000118B2 5E                                pop     esi
.text:000118B3 5B                                pop     ebx
.text:000118B4 89 01                             mov     [ecx], eax

7,在得到Entry后,Module::Module就结束了,返回到Load函数,Load函数调用Module::Begin执行被载入的驱动代码
.text:000109D4 8B F1                             mov     esi, ecx ==>指向Module对象,
.text:000109D6 8B 46 10                          mov     eax, [esi+10h]
.text:000109D9 85 C0                             test    eax, eax
.text:000109DB 74 5E                             jz      short loc_10A3B
.text:000109DB
.text:000109DD 8B 0D 00 1C 01 00                 mov     ecx, _NT_CONTEXT * myctx ;见附录结构
.text:000109E3 53                                push    ebx
.text:000109E4 83 C1 04                          add     ecx, 4
.text:000109E7 51                                push    ecx
.text:000109E8 50                                push    eax
.text:000109E9 FF 50 2C                          call    dword ptr [eax+2Ch] ; 调用入口 [ecx+10h]=xxBuffer 其偏移 0x2c处是驱动的入口地址


附录:

Module::Module
[ecx]=vptable
[ecx+8]=FileBuffer Same As 0x1c
[ecx+10h]=xxBuffer 其偏移 0x2c处是驱动的入口地址
[ecx+0x14]=="un"
[ecx+18h]==FileName
[ecx+1Ch]==FileBuffer
[ecx+0x20]=Module2

Module2:Module2
ecx+8==FileBuffer
ecx+c==用户Mapping驱动文件的Buffer


_NT_CONTEXT
[myctx+0]=DriverObject
[myctx+4]=RegistryPath         \
[myctx+8]=RegistryPath->Buffer /
//
// Based relocation format.
//

typedef struct _IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;
    DWORD   SizeOfBlock;
//  WORD    TypeOffset[1]; 解释见下面注释
} IMAGE_BASE_RELOCATION;

typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;

4 bits    Type    Stored in the high 4 bits of the WORD, a value that indicates the type of base relocation to be applied.
                For more information, see section 6.6.2, “Base Relocation Types.”
12 bits    Offset    Stored in the remaining 12 bits of the WORD, an offset from the starting address that was specified in
                the Page RVA field for the block. This offset specifies where the base relocation is to be applied.

下面是从Win2k源码里找到的,处理重定位表的

PIMAGE_BASE_RELOCATION NTAPI
LdrProcessRelocationBlock(IN ULONG_PTR Address,
              IN ULONG Count,
              IN PUSHORT TypeOffset,
              IN LONG_PTR Delta)
{
  SHORT Offset;
  USHORT Type;
  USHORT i;
  PUSHORT ShortPtr;
  PULONG LongPtr;

  for (i = 0; i < Count; i++)
    {
      Offset = *TypeOffset & 0xFFF;
      Type = *TypeOffset >> 12;

      switch (Type)
        {
          case IMAGE_REL_BASED_ABSOLUTE:
            break;

          case IMAGE_REL_BASED_HIGH:
            ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset);
            *ShortPtr += HIWORD(Delta);
            break;

          case IMAGE_REL_BASED_LOW:
            ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset);
            *ShortPtr += LOWORD(Delta);
            break;

          case IMAGE_REL_BASED_HIGHLOW:
            LongPtr = (PULONG)((ULONG_PTR)Address + Offset);
            *LongPtr += Delta;
            break;

          case IMAGE_REL_BASED_HIGHADJ:
          case IMAGE_REL_BASED_MIPS_JMPADDR:
          default:
            DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
            return NULL;
        }

      TypeOffset++;
    }

  return (PIMAGE_BASE_RELOCATION)TypeOffset;
}

/**********************************************************************
 * NAME                                                         LOCAL
 *      LdrPerformRelocations
 *
 * DESCRIPTION
 *      Relocate a DLL's memory image.
 *
 * ARGUMENTS
 *
 * RETURN VALUE
 *
 * REVISIONS
 *
 * NOTE
 *
 */
static NTSTATUS
LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
                      PVOID ImageBase)
{
  PIMAGE_DATA_DIRECTORY RelocationDDir;
  PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
  ULONG Count, ProtectSize, OldProtect, OldProtect2;
  PVOID Page, ProtectPage, ProtectPage2;
  PUSHORT TypeOffset;
  ULONG_PTR Delta;
  NTSTATUS Status;

  if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
    {
      return STATUS_UNSUCCESSFUL;
    }

  RelocationDDir =
    &NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];

  if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0)
    {
      return STATUS_SUCCESS;
    }

  ProtectSize = PAGE_SIZE;
  Delta = (ULONG_PTR)ImageBase - NTHeaders->OptionalHeader.ImageBase;
  RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase +
                  RelocationDDir->VirtualAddress);
  RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase +
                  RelocationDDir->VirtualAddress + RelocationDDir->Size);

  while (RelocationDir < RelocationEnd &&
         RelocationDir->SizeOfBlock > 0)
    {
      Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) /
              sizeof(USHORT);
      Page = (PVOID)((ULONG_PTR)ImageBase + (ULONG_PTR)RelocationDir->VirtualAddress);
      TypeOffset = (PUSHORT)(RelocationDir + 1);

      /* Unprotect the page(s) we're about to relocate. */
      ProtectPage = Page;
      Status = NtProtectVirtualMemory(NtCurrentProcess(),
                                      &ProtectPage,
                                      &ProtectSize,
                                      PAGE_READWRITE,
                                      &OldProtect);
      if (!NT_SUCCESS(Status))
        {
          DPRINT1("Failed to unprotect relocation target.\n");
          return Status;
        }

      if (RelocationDir->VirtualAddress + PAGE_SIZE <
          NTHeaders->OptionalHeader.SizeOfImage)
        {
          ProtectPage2 = (PVOID)((ULONG_PTR)ProtectPage + PAGE_SIZE);
          Status = NtProtectVirtualMemory(NtCurrentProcess(),
                                          &ProtectPage2,
                                          &ProtectSize,
                                          PAGE_READWRITE,
                                          &OldProtect2);
          if (!NT_SUCCESS(Status))
            {
              DPRINT1("Failed to unprotect relocation target (2).\n");
              NtProtectVirtualMemory(NtCurrentProcess(),
                                     &ProtectPage,
                                     &ProtectSize,
                                     OldProtect,
                                     &OldProtect);
              return Status;
            }
        }
      else
        {
          ProtectPage2 = NULL;
        }

      RelocationDir = LdrProcessRelocationBlock((ULONG_PTR)Page,
                                                Count,
                                                TypeOffset,
                                                Delta);
      if (RelocationDir == NULL)
        return STATUS_UNSUCCESSFUL;

      /* Restore old page protection. */
      NtProtectVirtualMemory(NtCurrentProcess(),
                             &ProtectPage,
                             &ProtectSize,
                             OldProtect,
                             &OldProtect);

      if (ProtectPage2 != NULL)
        {
          NtProtectVirtualMemory(NtCurrentProcess(),
                                 &ProtectPage2,
                                 &ProtectSize,
                                 OldProtect2,
                                 &OldProtect2);
        }
    }

  return STATUS_SUCCESS;
}

最新喜欢:

zhczfzhczf
xikug
驱动小牛
驱动小牛
  • 注册日期2001-09-25
  • 最后登录2013-09-27
  • 粉丝1
  • 关注0
  • 积分1001分
  • 威望169点
  • 贡献值0点
  • 好评度168点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2007-02-02 10:11
原来卡吧是这样加载驱动的。。。学习了。。。
http://www.debugman.com
Sucsor
驱动牛犊
驱动牛犊
  • 注册日期2005-02-05
  • 最后登录2007-03-27
  • 粉丝0
  • 关注0
  • 积分253分
  • 威望26点
  • 贡献值0点
  • 好评度25点
  • 原创分2分
  • 专家分0分
板凳#
发布于:2007-02-02 10:14
我被托了,赫赫
doskey
论坛版主
论坛版主
  • 注册日期2004-12-08
  • 最后登录2016-04-05
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望302点
  • 贡献值0点
  • 好评度300点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-02-03 10:58
 呵呵。支持呀~
qiweixue
驱动小牛
驱动小牛
  • 注册日期2004-07-21
  • 最后登录2011-12-19
  • 粉丝0
  • 关注0
  • 积分1006分
  • 威望274点
  • 贡献值0点
  • 好评度268点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2007-02-03 13:03
呵呵,支持...
感谢fly ,xikug,winroot,doskey    
CFC4N
驱动牛犊
驱动牛犊
  • 注册日期2006-09-20
  • 最后登录2007-03-23
  • 粉丝0
  • 关注0
  • 积分55分
  • 威望10点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-02-13 15:34
感谢CCTV.???V  
行尸走肉的生活实在毫无意义
flyfox
驱动中牛
驱动中牛
  • 注册日期2001-04-05
  • 最后登录2012-08-03
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望22点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-03-27 19:28
good
一剑西来,天外飞仙
wu1239
驱动牛犊
驱动牛犊
  • 注册日期2005-10-16
  • 最后登录2012-11-19
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-03-28 20:28
Thanks.
gleon
驱动牛犊
驱动牛犊
  • 注册日期2005-11-21
  • 最后登录2009-06-23
  • 粉丝0
  • 关注0
  • 积分666分
  • 威望71点
  • 贡献值0点
  • 好评度69点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-04-12 22:29
Very GOod!!
laoye360
驱动牛犊
驱动牛犊
  • 注册日期2006-07-04
  • 最后登录2020-12-03
  • 粉丝0
  • 关注0
  • 积分615分
  • 威望127点
  • 贡献值0点
  • 好评度62点
  • 原创分0分
  • 专家分0分
  • 社区居民
9楼#
发布于:2007-12-30 10:57
poize
驱动牛犊
驱动牛犊
  • 注册日期2005-08-17
  • 最后登录2013-09-13
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望32点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2008-01-03 11:10
我估计很多人已经对卡巴了解很深了
hongfu830202
驱动牛犊
驱动牛犊
  • 注册日期2007-10-22
  • 最后登录2016-01-09
  • 粉丝1
  • 关注0
  • 积分17分
  • 威望200点
  • 贡献值0点
  • 好评度57点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2008-03-08 12:38
回头写篇破文,小弟系菜鸟,大家多多帮助啊
yangxb771224
驱动牛犊
驱动牛犊
  • 注册日期2005-05-28
  • 最后登录2008-08-26
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望6点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2008-08-26 19:49
thanks
zyanswer@21cn.c
驱动牛犊
驱动牛犊
  • 注册日期2008-02-15
  • 最后登录2010-06-26
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望94点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2008-12-19 12:03
lunlun
驱动牛犊
驱动牛犊
  • 注册日期2007-03-04
  • 最后登录2009-11-14
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望33点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2009-05-05 16:33
回 楼主
谢谢啦,我遇到问题。 卡巴和自己过滤驱动蓝屏,原来卡巴这样加载,但是有没有好方式处理他所造成蓝屏呢?
游客

返回顶部