[半原创]六一儿童节礼物:恢复Kernel Inline Hook(第一季)
有不少儿童被Inline Hook弄得很不爽,又不懂得如何恢复。于是我特地写了个DLL和SYS,用来恢复任意Inline Hook(给出地址就行)。
有重定位代码,不用担心出错。里面的DLL和SYS暂不开源,可直接IDA+F5。
======
遇到什么问题请回帖,我考完试去旅游前会统一作答。 沙发自己占。 全被你抢去了,断人活路啊 很神奇的东西。。 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指教啊。 回复 10# 本网站最菜的人
回拜 unhook.sys没有什么技术含量,copymemory而已。
dll.dll才是精髓,逆了一下,dll函数的原型应该是:
Decl ...
乔丹二世 发表于 2010-5-28 23:32 http://www.m5home.com/bbs/images/common/back.gif
逆向得很正确,不愧是学校研发中心的人。
顺便说一下,ReInlineInit在Form_Load中调用一次就可以了,不能多次调用,否则适得其反。 既然都被人逆向出来了,那我就公布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
好人做到底,连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;
}
好人做到底,连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);
回复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。 回复 18# 本网站最菜的人
Inline Hook IoCreateFile。 回复Tesla.Angela
我是指对某种INLINE HOOK 方式无效
本网站最菜的人 发表于 2010-6-5 20:22 http://www.m5home.com/bbs/images/common/back.gif
刚才没看到“方式”二字。
以前好像听谁说过,某种Inline Hook,一恢复就会把函数完全搞乱。 膜拜一下......完全看不懂@_@ 本帖最后由 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修改内核数据的方法。 感謝大牛分享@@ 木有那么多钱 楼上没钱!?! 回来看看
HD还是这么猛 OK大哥,很久不见了!
听说你最近学汇编去了? 下载回来看看,谢谢分享。。。 回复 29# bigwahaha
读取内核文件原始数据的方式不底层,很容易被bypass。 多重跳hook也行? Inline有几个我都不知道。‘ms太可恶了,有一大打不开源 膜拜下!~······· 没钱,下不了。。我表示很无奈..!
页:
[1]
2