boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
阅读:978回复:1

Hook程序中不确定错误!!

楼主#
更多 发布于:2007-09-11 16:30
__declspec(naked)
NTAPI
HOOKQueryValueKey(IN HANDLE  KeyHandle,
                  IN PUNICODE_STRING  ValueName,
                  IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
                  OUT PVOID  KeyValueInformation,
                  IN ULONG  Lenth,
                  OUT PULONG  ResultLength
                  )
{
    _asm
    {
        //first execulte overwrited 7BYTES
        //int 3;
        add esp, 12;
        pushfd;

        push ResultLength;
        push Lenth;
        push KeyValueInformation;
        push KeyValueInformationClass;
        push ValueName;
        push KeyHandle;
        jmp forwArd;

bAck:    //.........15bytes
        _emit 0xAA;//1
        _emit 0xAA;//2
        _emit 0xAA;//3
        _emit 0xAA;//4
        _emit 0xAA;//5
        _emit 0xAA;//6
        _emit 0xAA;//7
        _emit 0xAA;//8
        _emit 0xAA;//9
        _emit 0xAA;//10
        _emit 0xAA;//11
        _emit 0xAA;//12
        _emit 0xAA;//13
        _emit 0xAA;//14
        _emit 0xAA;//15
        //.........
        _emit 0xEA;
        _emit 0xAA;
        _emit 0xAA;
        _emit 0xAA;
        _emit 0xAA;
        _emit 0x08;
        _emit 0x00;
forwArd:
        call bAck;
    }
    //处理结果
    KdPrint(("%08x, %08x, %08x, %wZ\n", KeyHandle, Lenth, ResultLength, ValueName));
    _asm
    {
        popfd;
        mov esp, ebp;
        pop ebp;
        ret;
    }
}
我使用上面代码进行inline hook QueryValueKey的第15Bytes,为什么会出现不确定的错误?
Kd QueryValueKey显示
push  ebp
mov  ebp,esp
push ....
push ....
push ....

mov eax, fs:[000000??]   //RePlace with far Jump to HOOKQueryValueKey with 7Bytes
push eax

.....

我的确HOOK到了数据,好多,但是突然就会挂掉:-(大牛们解释一下
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2007-09-11 22:55
#include <ntddk.h>
#include "AsmCodeLen.h"
#include "main.h"

BYTE oldByte[9] = {0};
BYTE newcode[9] = {0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90, 0x90};

BYTE oldByte2[7] = {0};
BYTE newcode2[7] = {0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00};

PBYTE g_lpDeviceIoControlFile = NULL;
PBYTE g_lpQueryValueKey = NULL;

NTSTATUS
DriverEntry(
            IN PDRIVER_OBJECT DriverObject,
            IN PUNICODE_STRING RegistryPath)
{
    int i;
    PBYTE lpDeviceIoControlFile = (PBYTE)NtDeviceIoControlFile;
    PBYTE lpHookDeviceIoControlFile = (PBYTE)my_function_detour_ntdeviceiocontrolfile;

    PBYTE lpQueryValueKey = GetSSDTFunction((PBYTE)ZwQueryValueKey);
    PBYTE lpHookQueryValueKey = (PBYTE)HOOKQueryValueKey;
    
    g_lpDeviceIoControlFile = lpDeviceIoControlFile;
    g_lpQueryValueKey = lpQueryValueKey;

    //NtDeviceIoControlFile反汇编如下
    //55 PUSH EBP
    //8BEC MOV EBP, ESP
    //6A01 PUSH 01
    //FF752C PUSH DWORD PTR [EBP + 2C]
    //ff7528 push dword ptr [ebp+0x28]
    //ff7524 push dword ptr [ebp+0x24]
    //ff7520 push dword ptr [ebp+0x20]
    //...
    //Hook it At ff7528 - ff7520
    //with write 7 bytes [far jmp 0xAAAAAAAA:0800] + 2bytes nop
    *(PULONG)(newcode+1) = (ULONG)lpHookDeviceIoControlFile;
    *(PULONG)(newcode2+1) = (ULONG)lpHookQueryValueKey;
    //*(PULONG)(newcode2+1) = (ULONG)HOOKQueryValueKey;
    //重定位Hook中的0xAAAAAAAA
    for(i=0; i<256;i++)
    {
        if ((0xAA == lpHookDeviceIoControlFile) &&
            (0xAA == lpHookDeviceIoControlFile[i+1]) &&
            (0xAA == lpHookDeviceIoControlFile[i+2]) &&
            (0xAA == lpHookDeviceIoControlFile[i+3]))
        {
            *(PULONG)(lpHookDeviceIoControlFile + i) = (ULONG)lpDeviceIoControlFile + 8 + sizeof(newcode);
            break;
        }
    }
    
    for(i=0; i<256; i++)
    {
        if ((0xAA == lpHookQueryValueKey) &&
            (0xAA == lpHookQueryValueKey[i+1]) &&
            (0xAA == lpHookQueryValueKey[i+2]) &&
            (0xAA == lpHookQueryValueKey[i+3]))
        {
            //write 15 bytes
            RtlCopyBytes(lpHookQueryValueKey + i, lpQueryValueKey, 15);
            //注意EA占1Byte
            *(PULONG)(&lpHookQueryValueKey[i + 15 + 1]) = (ULONG)lpQueryValueKey + 15 + sizeof(newcode2);
            break;
        }
    }
    
    //hook
    _asm
    {
        CLI;                    //dissable interrupt
        MOV EAX, CR0;            //move CR0 register into EAX
        AND EAX, NOT 10000H;    //disable WP bit
        MOV CR0, EAX;            //write register back
    }

    RtlCopyBytes(oldByte, lpDeviceIoControlFile+8, sizeof(newcode));
    RtlCopyBytes(lpDeviceIoControlFile+8, newcode, sizeof(newcode));

    //HOOKQueryValueKey
    RtlCopyBytes(oldByte2, lpQueryValueKey+15, sizeof(newcode2));
    RtlCopyBytes(lpQueryValueKey+15, newcode2, sizeof(newcode2));
    
    _asm
    {
        MOV EAX, CR0;
        OR  EAX, 10000H;
        MOV CR0, EAX;
        STI;
        
    }
    KdPrint(("Success, %08x, %08x", lpHookQueryValueKey, lpHookDeviceIoControlFile));
    DriverObject->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}

VOID
DriverUnload (IN struct _DRIVER_OBJECT *DriverObject)
{
    //back up
    _asm
    {
        CLI;                    //dissable interrupt
        MOV EAX, CR0;            //move CR0 register into EAX
        AND EAX, NOT 10000H;    //disable WP bit
        MOV CR0, EAX;            //write register back
    }
    RtlCopyBytes(g_lpDeviceIoControlFile+8, oldByte, sizeof(newcode));
    RtlCopyBytes(g_lpQueryValueKey+15, oldByte2, sizeof(newcode2));
    _asm
    {
        MOV EAX, CR0;
        OR  EAX, 10000H;
        MOV CR0, EAX;
        STI;
    }
    KdPrint(("Unload"));
}

/*
 *    得到NT内核函数的实际执行地址
 */
PBYTE
GetSSDTFunction(PBYTE lpNtFunction)
{
    //返回指定函数的实际地址以便inline hook
    //MOV eax, FunID
    //LEA EDX, [esp+4]
    //INT 2E
    //RET
    //
    ULONG id = *(PULONG)(lpNtFunction + 1);
    return (PBYTE)(*((PULONG)KeServiceDescriptorTable->ServiceTableBase + id));
}
NTSTATUS CheckFunctionBytesNtDeviceIoControlFile()
{
    int i=0;
    char *p = (char *)NtDeviceIoControlFile;
    //The beginning of the NtDeviceIoControlFile function
    //should match:
    //55 PUSH EBP
    //8BEC MOV EBP, ESP
    //6A01 PUSH 01
    //FF752C PUSH DWORD PTR [EBP + 2C]
    //
    BYTE c[] = {0x55, 0x8B, 0xEC, 0x6A, 0x01, 0xFF, 0x75, 0x2C};
    while(i<8)
    {
        DbgPrint(" - 0x%02X ", (unsigned char)p);
        DbgPrint("\n");
        if(p != c)
        {
            return STATUS_UNSUCCESSFUL;
        }
        i++;
    }
    return STATUS_SUCCESS;
}

//--------------------------------------------------------------------
// naked functions have no prolog/epilog code - they are functionally like the
// target of a goto statement
//--------------------------------------------------------------------
__declspec(naked)
NTAPI
my_function_detour_ntdeviceiocontrolfile(IN HANDLE FileHandle,
                                         IN HANDLE Event OPTIONAL,
                                         IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
                                         IN PVOID ApcContext OPTIONAL,
                                         OUT PIO_STATUS_BLOCK IoStatusBlock,
                                         IN ULONG IoControlCode,
                                         IN PVOID InputBuffer OPTIONAL,
                                         IN ULONG InputBufferLength,
                                         OUT PVOID OutputBuffer OPTIONAL,
                                         IN ULONG OutputBufferLength
)
{
    //首先反向恢复堆栈
    //55 PUSH EBP
    //8BEC MOV EBP, ESP
    //6A01 PUSH 01
    //FF752C PUSH DWORD PTR [EBP + 2C]
    _asm
    {
        add esp, 8;
        //pushad;            //普通寄存器顺序入栈

        //执行原始NtDeviceIoControlFile函数
        push OutputBufferLength;
        push OutputBuffer;
        push InputBufferLength;
        push InputBuffer;
        push IoControlCode;
        push IoStatusBlock;
        push ApcContext;
        push ApcRoutine;
        push Event;
        push FileHandle;
        jmp forwArd;
bAck:    
        push ebp;
        mov ebp, esp
        push 0x01
        push dword ptr [ebp+0x2C];
        push dword ptr [ebp+0x28];
        push dword ptr [ebp+0x24];
        push dword ptr [ebp+0x20];
        _emit 0xEA;
        _emit 0xAA;
        _emit 0xAA;
        _emit 0xAA;
        _emit 0xAA;
        _emit 0x08;
        _emit 0x00;
forwArd:
        call bAck;
    }
    //ok!
    //过滤IP数据
    if (IOCTL_TCP_QUERY_INFORMATION_EX == IoControlCode)
    {
        //显示数据到调试
        DebugBuffer(InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength);
    }
    _asm
    {
        //popad;
        mov esp, ebp;
        pop ebp;
        ret;
    }
}

__declspec(naked)
NTAPI
HOOKQueryValueKey(IN HANDLE  KeyHandle,
                  IN PUNICODE_STRING  ValueName,
                  IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
                  OUT PVOID  KeyValueInformation,
                  IN ULONG  Lenth,
                  OUT PULONG  ResultLength
                  )
{
    _asm
    {
        //first execulte overwrited 7BYTES
        //int 3;
        add esp, 12;
        pushfd;

        push ResultLength;
        push Lenth;
        push KeyValueInformation;
        push KeyValueInformationClass;
        push ValueName;
        push KeyHandle;
        jmp forwArd;

bAck:    //.........15bytes
        _emit 0xAA;//1
        _emit 0xAA;//2
        _emit 0xAA;//3
        _emit 0xAA;//4
        _emit 0xAA;//5
        _emit 0xAA;//6
        _emit 0xAA;//7
        _emit 0xAA;//8
        _emit 0xAA;//9
        _emit 0xAA;//10
        _emit 0xAA;//11
        _emit 0xAA;//12
        _emit 0xAA;//13
        _emit 0xAA;//14
        _emit 0xAA;//15
        //.........
        _emit 0xEA;
        _emit 0xAA;
        _emit 0xAA;
        _emit 0xAA;
        _emit 0xAA;
        _emit 0x08;
        _emit 0x00;
forwArd:
        call bAck;
    }
    //处理结果
    KdPrint(("%08x, %08x, %08x, %wZ\n", KeyHandle, Lenth, ResultLength, ValueName));
    _asm
    {
        popfd;
        mov esp, ebp;
        pop ebp;
        ret;
    }
}

VOID
DebugBuffer(IN PVOID lpBuf,
            IN ULONG BufLen,
            IN PVOID lpOutBuf,
            IN ULONG OutBufLen)
{
    ULONG i;
    TDIObjectID *TdiObj = (PTDIObjectID)lpBuf;
    //KdPrint(("%08x,%08x,%08x,%08x,%08x", TdiObj->toi_type, TdiObj->toi_class, TdiObj->toi_id, BufLen, OutBufLen));
    if (0x102 == TdiObj->toi_id)
    {
        //ipconfig use it to get ip!
        //KdPrint(("OutBuf Len [%08x]", OutBufLen));
        for(i=0; i<OutBufLen-1; i+=4)
        {
            
            if (0x0201a8c0 == *(PULONG)((PBYTE)lpOutBuf + i))
            {
                *(PULONG)((PBYTE)lpOutBuf + i) = 0x0301a8c0;
            }
            //KdPrint(("[%d]%08x", i>>2, *(PULONG)((PBYTE)lpOutBuf + i)));
        }
    }
}
大牛们帮我调试一下哦:
游客

返回顶部