Tesla.Angela 发表于 2010-5-24 17:05:26

[半原创]六一儿童节礼物:恢复Kernel Inline Hook(第一季)

有不少儿童被Inline Hook弄得很不爽,又不懂得如何恢复。
于是我特地写了个DLL和SYS,用来恢复任意Inline Hook(给出地址就行)。
有重定位代码,不用担心出错。里面的DLL和SYS暂不开源,可直接IDA+F5。
======
遇到什么问题请回帖,我考完试去旅游前会统一作答。

Tesla.Angela 发表于 2010-5-24 17:05:51

沙发自己占。

9908006 发表于 2010-5-24 22:17:14

全被你抢去了,断人活路啊

oopww 发表于 2010-5-25 22:30:53

很神奇的东西。。

本网站最菜的人 发表于 2010-5-28 22:21:11

本网站最菜的人 发表于 2010-5-28 22:51:09

乔丹二世 发表于 2010-5-28 23:32:12

unhook.sys没有什么技术含量,copymemory而已。
dll.dll才是精髓,逆了一下,dll函数的原型应该是:
Declare Sub ReInlineInit Lib "dll.dll" Alias "#2" ()
Declare Sub GetByte Lib "dll.dll" Alias "#1" (ByVal 目标地址 As Long, ByRef 返回的字节 As Byte)
如果说错了,还请HD指教啊。

本网站最菜的人 发表于 2010-5-29 22:20:54

乔丹二世 发表于 2010-5-30 20:09:15

回复 10# 本网站最菜的人


回拜

Tesla.Angela 发表于 2010-6-5 15:11:25

unhook.sys没有什么技术含量,copymemory而已。
dll.dll才是精髓,逆了一下,dll函数的原型应该是:
Decl ...
乔丹二世 发表于 2010-5-28 23:32 http://www.m5home.com/bbs/images/common/back.gif

逆向得很正确,不愧是学校研发中心的人。
顺便说一下,ReInlineInit在Form_Load中调用一次就可以了,不能多次调用,否则适得其反。

Tesla.Angela 发表于 2010-6-5 15:31:17

既然都被人逆向出来了,那我就公布vb部分的源码吧:
Option Explicit

Private Declare Sub ReInlineInit Lib "dll.dll" Alias "#2" ()
Private Declare Sub GetByte Lib "dll.dll" Alias "#1" (ByVal TargetAddr As Long, ByRef rtb As Byte)
Private DrvController As New cls_Driver

Private Type stUNHOOK
    TarAddr As Long
    Length As Long
    OrigiData(260) As Byte
End Type

Private Sub Command1_Click() '得到内核函数机器码
    On Error Resume Next '需要ulong,但是vb没有ulong,所以会出现dll调用约定错误,不过无所谓
    'get bytes
    Dim kfb As Byte, i As Long
    Dim TarAdr As Long: TarAdr = Val("&H" & Text1.Text)
    List1.Clear
    For i = 0 To CLng(Text2.Text) - 1
      Call GetByte(TarAdr + i, kfb)
      List1.AddItem String(2 - Len(Hex(kfb)), "0") & Hex(kfb)
    Next
    'restore
    Dim xx As stUNHOOK
    xx.Length = CLng(Text2.Text)
    xx.TarAddr = Val("&H" & Text1.Text)
    For i = 0 To xx.Length - 1
      xx.OrigiData(i) = Val("&H" & List1.List(i))
    Next
    With DrvController
      .IoControl .CTL_CODE_GEN(&H801), VarPtr(xx), Len(xx), 0, 0
    End With
End Sub

Private Sub Form_Load() '初始化
    ReInlineInit '重定位
    With DrvController '加驱动
      .szDrvFilePath = Replace(App.Path & "\UNHOOK.sys", "\\", "\")
      .szDrvLinkName = "UNHOOK"
      .szDrvDisplayName = "UNHOOK"
      .szDrvSvcName = "UNHOOK"
      .InstDrv
      .StartDrv
      .OpenDrv
    End With
    If DrvController.OpenDrv = False Then MsgBox "驱动加载失败", 64, "": End
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    With DrvController
      .StopDrv
      .DelDrv
    End With
End Sub

Tesla.Angela 发表于 2010-6-5 15:41:40

好人做到底,连dll的代码一起公布了吧。

dll.cpp:

#include "stdafx.h"
#include "dll.h"
#include "ntdll.h"
typedef struct _MODULES
{
   ULONG    NumberOfModules; //模块个数
   SYSTEM_MODULEModules;//偷懒
} MODULES, *PMODULES;
HMODULE hKernel;
ULONG KernelBase;
BOOLEAN bInit=FALSE;

ULONG Reloc(ULONG lpBase, ULONG VirtualAddress )
{
PIMAGE_DOS_HEADERpDosHeader;
PIMAGE_NT_HEADERSpNtHeader;
PIMAGE_BASE_RELOCATION pRelocTable;
ULONG i,dwOldProtect;
pDosHeader = (PIMAGE_DOS_HEADER)lpBase;
if ( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )
return 0;
pNtHeader =(PIMAGE_NT_HEADERS)( (ULONG)lpBase + pDosHeader->e_lfanew );//厉行检查
if (pNtHeader->OptionalHeader.DataDirectory.Size)//是否存在重定位表
{
pRelocTable=(PIMAGE_BASE_RELOCATION)((ULONG)lpBase + pNtHeader->OptionalHeader.DataDirectory.VirtualAddress);
do
{
   ULONG numofReloc=(pRelocTable->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2;
   SHORT minioffset=0;
   PUSHORT pRelocData=(PUSHORT)((ULONG)pRelocTable+sizeof(IMAGE_BASE_RELOCATION));
   for (i=0;i<numofReloc;i++)//循环,或直接判断*pData是否为0也可以作为结束标记
   {
    PULONG RelocAddress;//需要重定位的地址
    //重定位的高4位是重定位类型,
    if (((*pRelocData)>>12)==IMAGE_REL_BASED_HIGHLOW)//判断重定位类型是否为IMAGE_REL_BASED_HIGHLOW
    {
   //计算需要进行重定位的地址
   //重定位数据的低12位再加上本重定位块头的RAV即真正需要重定位的数据的RAV
   minioffset=(*pRelocData)&0xFFF;//小偏移
   //模块基址+重定位基址+每个数据表示的小偏移量
   RelocAddress=(PULONG)(lpBase+pRelocTable->VirtualAddress+minioffset);

   //直接在RING3修改:原始数据+基址-IMAGE_OPTINAL_HEADER中的基址
   VirtualProtect((PVOID)RelocAddress, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect);//因为是R3直接LOAD的 所以要修改一下内存权限
   *RelocAddress=*RelocAddress+VirtualAddress-pNtHeader->OptionalHeader.ImageBase;
   VirtualProtect((PVOID)RelocAddress, 4, dwOldProtect, NULL);
    }
    //下一个重定位数据
    pRelocData++;
   }
   //下一个重定位块
   pRelocTable=(PIMAGE_BASE_RELOCATION)((ULONG)pRelocTable+pRelocTable->SizeOfBlock);
}while (pRelocTable->VirtualAddress);
return TRUE;
}
return FALSE;
}

ULONG GetKernelPath(char * Kernel)
{
MODULES Drivers;
ULONG Count;
NTSTATUS status=NtQuerySystemInformation(SystemModuleInformation,&Drivers,sizeof(Drivers),&Count);
if (NT_SUCCESS(status))
{
if (Kernel)
{
   lstrcpyA(Kernel,Drivers.Modules.ImageName+Drivers.Modules.ModuleNameOffset );
}
return (ULONG)Drivers.Modules.Base;
}
return FALSE;
}

BOOL Init()
{
CHAR szKernelName;
KernelBase=GetKernelPath(szKernelName);
if (KernelBase)
{
hKernel=LoadLibraryExA(szKernelName, 0, DONT_RESOLVE_DLL_REFERENCES);
if (hKernel)
{
   Reloc((ULONG)hKernel,KernelBase);//重定位
   return TRUE;
}
}
return FALSE;
}

ULONG   htoi(char   *str)   
{   
ULONG   i=0,   j,   dec=0,   t;   
j=strlen(str);   
if(*str=='0')   i=2;   
while(i<j)   
{   
dec<<=4;   
t=*(str+i++);   
if(t<58)   t-=48;   
if(t>64&&t<71)   t-=55;   
if(t>96&&t<103)   t-=87;   
dec|=t;   
}   
return   dec;   
}   

DLL_API VOID ReInlineInit()
{
if(bInit==FALSE)
{
Init();
bInit=TRUE;
}
}

DLL_API VOID GetByte(ULONG TarAddr, PBYTE rtb)
{
ULONG tmpaddr=TarAddr-KernelBase+(ULONG)hKernel;
*rtb=*(PBYTE)tmpaddr;
}

Tesla.Angela 发表于 2010-6-5 15:42:38

好人做到底,连dll的代码一起公布了吧。

dll.h:

#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
DLL_API VOID ReInlineInit();
DLL_API VOID GetByte(ULONG TarAddr, PBYTE rtb);

本网站最菜的人 发表于 2010-6-5 19:13:02

Tesla.Angela 发表于 2010-6-5 20:08:22

回复Tesla.Angela

学习 + 膜拜
PS1:重定位的代码........
PS2:对某种WS的HOOK无效
本网站最菜的人 发表于 2010-6-5 19:13 http://www.m5home.com/bbs/images/common/back.gif

PS1:这个是拼凑的,算是半原创吧。
PS2:SSDT HOOK ZwCreateFile。

本网站最菜的人 发表于 2010-6-5 20:22:49

Tesla.Angela 发表于 2010-6-5 20:23:39

回复 18# 本网站最菜的人

Inline Hook IoCreateFile。

Tesla.Angela 发表于 2010-6-5 20:26:06

回复Tesla.Angela
我是指对某种INLINE HOOK 方式无效
本网站最菜的人 发表于 2010-6-5 20:22 http://www.m5home.com/bbs/images/common/back.gif


刚才没看到“方式”二字。
以前好像听谁说过,某种Inline Hook,一恢复就会把函数完全搞乱。

马大哈 发表于 2010-6-5 21:41:34

膜拜一下......完全看不懂@_@

Tesla.Angela 发表于 2010-6-5 23:18:32

本帖最后由 Tesla.Angela 于 2010-6-5 23:20 编辑

还有驱动的源码:
#include <NTDDK.H>
#include <windef.h>

#define NT_DEVICE_NAME            L"\\Device\\UnHook"
#define DOS_DEVICE_NAME             L"\\DosDevices\\UnHook"
#define IOCTL_UnHook                              CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _Unhook {
   ULONG      TarAddr; //目标地址
   ULONG      Length;      //需要覆盖的长度
   BYTE                OrigiData;//原始数据
} UNHOOK, *PUNHOOK;

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject );


void MemOpen()
{
      __asm {   
                cli
                        moveax,cr0
                        andeax,not 10000h
                        movcr0,eax
      }
}


void MemClose()
{
      __asm {   
                moveax,cr0
                        or   eax,10000h
                        movcr0,eax
                        sti
      }
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{

      UNICODE_STRING   uniDeviceName;
      UNICODE_STRING   uniSymLink;
      NTSTATUS         ntStatus;
      PDEVICE_OBJECT   deviceObject = NULL;

      RtlInitUnicodeString(&uniDeviceName, NT_DEVICE_NAME);
      RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);

      DriverObject->MajorFunction =
                DriverObject->MajorFunction = DispatchCreateClose;
      DriverObject->MajorFunction = DispatchIoctl;
      DriverObject->DriverUnload = UnloadDriver;

      ntStatus = IoCreateDevice(DriverObject, 0,&uniDeviceName,FILE_DEVICE_UNKNOWN,
                                                                FILE_DEVICE_SECURE_OPEN, FALSE,&deviceObject);

      if (!NT_SUCCESS(ntStatus)) return ntStatus;

    ntStatus = IoCreateSymbolicLink(&uniSymLink, &uniDeviceName);

      if (!NT_SUCCESS(ntStatus))
      {
                IoDeleteDevice(deviceObject);
                return ntStatus;
      }

      //DbgPrint("driver loaded!\n");
    return STATUS_SUCCESS;
}


NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
      pIrp->IoStatus.Information = 0;
      pIrp->IoStatus.Status = STATUS_SUCCESS;
      IoCompleteRequest(pIrp, IO_NO_INCREMENT);
      return STATUS_SUCCESS;
}


NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT pDevObj,INPIRP pIrp)
{
      
      NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;//STATUS_UNSUCCESSFUL;//
      PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
      ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
      ULONG inBufLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
      ULONG outBufLength =pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
               
      PVOID OutputBuffer = pIrp->UserBuffer;
      PVOID InputBuffer= pIrp->AssociatedIrp.SystemBuffer;

      switch(uIoControlCode)
      {
                case IOCTL_UnHook:
                        {
                              UNHOOK UnHook={0};

                              memcpy(&UnHook,InputBuffer,sizeof(UNHOOK));

                              MemOpen();
                              memcpy((PVOID)UnHook.TarAddr,UnHook.OrigiData,UnHook.Length);
                              MemClose();
                              ntStatus = STATUS_SUCCESS;
                              break;
                        }
      }

      pIrp->IoStatus.Status = ntStatus;
      //pIrp->IoStatus.Information = outBufLength;
      IoCompleteRequest(pIrp, IO_NO_INCREMENT);
      return ntStatus;
}


VOID UnloadDriver( IN PDRIVER_OBJECT DriverObject )
{
      PDEVICE_OBJECT    deviceObject = DriverObject->DeviceObject;
      UNICODE_STRING    uniSymLink;

      RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);
      
      //DbgPrint("driver unloaded.\n");
      IoDeleteSymbolicLink(&uniSymLink);
      IoDeleteDevice(deviceObject);
}

需要说的是,这样子修改内核数据蓝屏的可能性很大,建议大家参考MySystemDebugControl修改内核数据的方法。

vip235689 发表于 2010-6-7 22:01:58

感謝大牛分享@@

9908006 发表于 2010-6-8 20:59:38

木有那么多钱

oopww 发表于 2010-6-10 14:02:52

楼上没钱!?!

ok100fen 发表于 2010-6-16 16:17:11

回来看看
HD还是这么猛

HoviDelphic 发表于 2010-6-16 19:27:48

OK大哥,很久不见了!
听说你最近学汇编去了?

本网站最菜的人 发表于 2010-6-16 20:22:25

bigwahaha 发表于 2010-7-19 15:17:49

下载回来看看,谢谢分享。。。

Tesla.Angela 发表于 2010-7-19 19:28:04

回复 29# bigwahaha


读取内核文件原始数据的方式不底层,很容易被bypass。

pe1011 发表于 2010-7-23 21:32:52

多重跳hook也行?

eaaca123 发表于 2010-7-31 12:48:44

Inline有几个我都不知道。‘ms太可恶了,有一大打不开源

8013 发表于 2010-8-4 07:57:01

膜拜下!~·······

a2010xxb 发表于 2010-9-7 02:20:32

没钱,下不了。。我表示很无奈..!
页: [1] 2
查看完整版本: [半原创]六一儿童节礼物:恢复Kernel Inline Hook(第一季)