能力值:
( LV12,RANK:760 )
|
-
-
26 楼
DbgPrint("PsGetCurrentProcessId is:%x\n",(PUCHAR)hMod + pAddressOfFunctions[index]);
pAddressOfFunctions[index] = ( PCHAR )MyPsGetCurrentProcessId - BaseAddress;
DbgPrint("g_OriginalPsGetCurrentProcessId is:%x\n",g_OriginalPsGetCurrentProcessId);
g_OriginalPsGetCurrentProcessId= (PUCHAR)hMod + pAddressOfFunctions[index] ;
要改成
g_OriginalPsGetCurrentProcessId= (PUCHAR)hMod + pAddressOfFunctions[index] ;
DbgPrint("PsGetCurrentProcessId is:%x\n",(PUCHAR)hMod + pAddressOfFunctions[index]);
pAddressOfFunctions[index] = ( PCHAR )MyPsGetCurrentProcessId - BaseAddress;
DbgPrint("g_OriginalPsGetCurrentProcessId is:%x\n",g_OriginalPsGetCurrentProcessId);
|
能力值:
( LV2,RANK:10 )
|
-
-
27 楼
对更改内核导出表的操作,代码略作修改,如下:
if(test==1)
{
g_OriginalPsGetCurrentProcessId=(ULONG)((PUCHAR)hMod + pAddressOfFunctions[index]);
DbgPrint("PsGetCurrentProcessId is:%x\n",g_OriginalPsGetCurrentProcessId);
_asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}
pAddressOfFunctions[index] = (PCHAR)MyPsGetCurrentProcessId - BaseAddress;
_asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}
DbgPrint("g_OriginalPsGetCurrentProcessId is:%x\n",g_OriginalPsGetCurrentProcessId);
}
否则容易蓝屏。
|
能力值:
( LV3,RANK:20 )
|
-
-
28 楼
PVOID GetModlueBaseAdress(char* ModlueName)
{
ULONG size,index;
PULONG buf;
NTSTATUS status;
PSYSTEM_MODULE_INFORMATION module;
PVOID driverAddress=0;
ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size);
if(NULL==(buf = (PULONG)ExAllocatePool(PagedPool, size)))
{
DbgPrint("failed alloc memory failed \n");
return 0;
}
status=ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0);
if(!NT_SUCCESS( status ))
{
DbgPrint("failed query\n");
return 0;
}
module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1);
for (index = 0; index < *buf; index++)
if (_stricmp(module[index].ImageName + module[index].ModuleNameOffset, ModlueName) == 0)
{
driverAddress = module[index].Base;
DbgPrint("Module found at:%x\n",driverAddress);
}
ExFreePool(buf);
return driverAddress;
}
哪位大哥告诉我下
(_stricmp(module[index].ImageName + module[index].ModuleNameOffset, ModlueName) == 0这句的module[index].ImageName + module[index].ModuleNameOffset是什么意思啊?弄不明白
|
能力值:
( LV2,RANK:10 )
|
-
-
29 楼
#include "ntddk.h"
#include "hookiat.h"
#pragma comment(lib,"ntdll.lib")
ULONG g_OriginalPsGetCurrentProcessId;
typedef HANDLE (*PSGETCURRENTPROCESSID)();
HANDLE
MyPsGetCurrentProcessId()
{
HANDLE handle;
DbgPrint("HOOK_PsGetCurrentProcessId called!\n");
handle =((PSGETCURRENTPROCESSID)(g_OriginalPsGetCurrentProcessId))();
return handle;
}
PVOID GetModlueBaseAdress(char* ModlueName)
{
ULONG size,index;
PULONG buf;
NTSTATUS status;
PSYSTEM_MODULE_INFORMATION module;
PVOID driverAddress=0;
ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size);
if(NULL==(buf = (PULONG)ExAllocatePool(PagedPool, size)))
{
DbgPrint("failed alloc memory failed \n");
return 0;
}
status=ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0);
if(!NT_SUCCESS( status ))
{
DbgPrint("failed query\n");
return 0;
}
module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1);
for (index = 0; index < *buf; index++)
if (_stricmp(module[index].ImageName + module[index].ModuleNameOffset, ModlueName) == 0)
{
driverAddress = module[index].Base;
DbgPrint("Module found at:%x\n",driverAddress);
}
ExFreePool(buf);
return driverAddress;
}
//StartHook_And_Unhook是安装钩子和卸载钩子,如果 test==1表示安装,否则表示卸载
VOID StartHook_And_Unhook(IN PCSTR funName, IN unsigned int test)
{
HANDLE hMod;//JK:不指向任何类型的指针
PUCHAR BaseAddress = NULL;//JK:这个变量保存了一个32BTI地址,而这个地址指向了一个内存单元的内容
IMAGE_DOS_HEADER * dosheader;//JK:DOS文件头指针
IMAGE_OPTIONAL_HEADER * opthdr;//JK:结构
PIMAGE_EXPORT_DIRECTORY exports;//JK:用于保存一个IMAGE_EXPORT_DIRECTORY结构地址的指针变量
USHORT index=0 ;
ULONG addr ,i;
PUCHAR pFuncName = NULL;
PULONG pAddressOfFunctions,pAddressOfNames;//这个变量保存了一个32BTI地址,而这个地址指向了四个内存单元的内容
PUSHORT pAddressOfNameOrdinals;//这个变量保存了一个32BTI地址,而这个地址指向了两个内存单元的内容
BaseAddress= GetModlueBaseAdress("ntoskrnl.exe");//JK:获取要HOOK模块的导入表的模块地址
DbgPrint("Map BaseAddress is:%x\n",BaseAddress);
hMod = BaseAddress;
dosheader = (IMAGE_DOS_HEADER *)hMod;//JK:dosheader保存了描述DOS头的结构变量的地址
opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);//JK:dosheader->e_lfanew会输出PE文件头的位置+24是因为IMAGE_FILE_HEADER结构占20个字节,而加4是因为Signature所占4个字节,这样就指向了IMAGE_OPTIONAL_HEADER的位置
exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader+ opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);//JK:exports保存了IMAGE_EXPORT_DIRECTORY结构变量的地址
pAddressOfFunctions=(ULONG*)((BYTE*)hMod+exports->AddressOfFunctions); //JK:获得EAT的入口地址,EAT又双字的数组组成
pAddressOfNames=(ULONG*)((BYTE*)hMod+exports->AddressOfNames);//JK:函数名字符串的地址表,根据这个地址表(由双字的数组组成)可获得函数名称的字符串
pAddressOfNameOrdinals=(USHORT*)((BYTE*)hMod+exports->AddressOfNameOrdinals); //JK:保存用于去pAddressOfFunctions指向的EAT中取函数地址的索引值(这个索引值还与函数名字符串的地址表对应,这样就可通过函数名称返回函数的地址了)
for (i = 0; i < exports->NumberOfNames; i++)
{
index=pAddressOfNameOrdinals[i];
pFuncName = (PUCHAR)( (BYTE*)hMod + pAddressOfNames[i]);
if (_stricmp( (char*)pFuncName,funName) == 0)
{
addr=pAddressOfFunctions[index];//JK:addr变量保存了PsGetCurrentProcessId函数的地址
break;
}
}
if(test==1) {
_asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}
//DbgPrint("PsGetCurrentProcessId is:%x\n",(ULONG)hMod + addr);//JK:输出PsGetCurrentProcessId这个函数的地址,基地址加RVA JK:用addr代替了pAddressOfFunctions[index]
g_OriginalPsGetCurrentProcessId= (ULONG)hMod + pAddressOfFunctions[index] ;//JK:g_OriginalPsGetCurrentProcessId保存了原先PsGetCurrentProcessId的地址
//DbgPrint("g_OriginalPsGetCurrentProcessId is:%x\n",g_OriginalPsGetCurrentProcessId);
pAddressOfFunctions[index] = ( PCHAR )MyPsGetCurrentProcessId - BaseAddress;//求出MyPsGetCurrentProcessId的RVA
_asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}
}
else
{
_asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}
pAddressOfFunctions[index] = ( PCHAR )g_OriginalPsGetCurrentProcessId - BaseAddress;//JK 恢复以前的PsGetCurrentProcessId的地址
_asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}
}
}
VOID Unload(PDRIVER_OBJECT DriverObject)
{
PCSTR myfunName="PsGetCurrentProcessId";
StartHook_And_Unhook(myfunName,0);
DbgPrint("Unload Callled\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str)
{
PCSTR myfunName="PsGetCurrentProcessId";
StartHook_And_Unhook(myfunName,1);
DriverObject->DriverUnload = Unload;
return STATUS_SUCCESS;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
30 楼
别做这傻事了,eat是危险的,因为call指令在作怪。call指令有长跳河短跳之分,系统函数中call指令一般都跳的距离不太远。
|
能力值:
( LV2,RANK:10 )
|
-
-
31 楼
别光顾着发帖,得试试你的方法可靠不?你的方法我可以是说不可靠,除非你的驱动基地址离系统基地址很近
|
能力值:
( LV2,RANK:10 )
|
-
-
32 楼
不是CALL的事,我调试时发现时进入了KeStackAttachProcess这个函数,好像是保护系统了。。。。 请高手指点,因为上面有贴图,所以我觉得是可行了。。。。。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
33 楼
怎么没人跟帖呢?
|
能力值:
( LV2,RANK:10 )
|
-
-
34 楼
好东西,才发现。膜拜
|
能力值:
( LV2,RANK:10 )
|
-
-
35 楼
应该多加学习学习
|
能力值:
( LV2,RANK:10 )
|
-
-
36 楼
侃侃 ,不懂
|
能力值:
( LV2,RANK:10 )
|
-
-
37 楼
这个能钩住用GetProcAddress得到的函数地址吗?我要钩的是普通DLL的函数,应该不会蓝吧!
|
能力值:
( LV2,RANK:10 )
|
-
-
38 楼
看看再说。。。
|
能力值:
( LV6,RANK:90 )
|
-
-
39 楼
两年之后 再看这个贴子 果然很强大 楼主太无敌了
|
能力值:
( LV2,RANK:10 )
|
-
-
40 楼
我搞定这个了,是因为没有正确返回基地址的问题。我用WINDBG一步步追踪发现问题存于此
BaseAddress= GetModlueBaseAdress("\\WINDOWS\\system32\\ntkrnlpa.exe");
。。。。
if (_stricmp( (char*)pFuncName,funName) == 0)
修改后的源码:
#include "ntddk.h"
#include "hookiat.h"
#pragma comment(lib,"ntdll.lib")
ULONG g_OriginalPsGetCurrentProcessId;
typedef HANDLE (*PSGETCURRENTPROCESSID)();
HANDLE
MyPsGetCurrentProcessId()
{
HANDLE handle=NULL;
DbgPrint("HOOK_PsGetCurrentProcessId called!\n");
// handle =((PSGETCURRENTPROCESSID)(g_OriginalPsGetCurrentProcessId))();
return handle;
}
PVOID GetModlueBaseAdress(char* ModlueName)
{
ULONG size,index;
PULONG buf;
NTSTATUS status;
PSYSTEM_MODULE_INFORMATION module;
PVOID driverAddress=0;
//利用ZwQuerySystemInformation依据SystemModuleInformation获取Ntoskerl.exe基址和镜像大小
ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size); //返回需要size大小
if(NULL==(buf = (PULONG)ExAllocatePool(PagedPool, size)))
{
DbgPrint("failed alloc memory failed \n");
return 0;
}
status=ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0);//系统模块信息存入buf
if(!NT_SUCCESS( status ))
{
DbgPrint("failed query\n");
return 0;
}
/*
typedef struct _SYSTEM_MODULE_INFORMATION {//Information Class 11
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
}SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;
*/
module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1);//+1代表加了4个字节,可能4个字节里存了MODULE的总数。通过下面的FOR循环中看出
for (index = 0; index < *buf; index++)
//if (_stricmp(module[index].ImageName + module[index].ModuleNameOffset, ModlueName) == 0)
if (_stricmp(module[index].ImageName, ModlueName) == 0)
{
driverAddress = module[index].Base;//找到模块的基地址
DbgPrint("Module found at:%x\n",driverAddress);
}
ExFreePool(buf);
return driverAddress;
}
//StartHook_And_Unhook是安装钩子和卸载钩子,如果 test==1表示安装,否则表示卸载
VOID StartHook_And_Unhook(IN PCSTR funName, IN unsigned int test)
{
HANDLE hMod;//JK:不指向任何类型的指针
PUCHAR BaseAddress = NULL;//JK:这个变量保存了一个32BTI地址,而这个地址指向了一个内存单元的内容
IMAGE_DOS_HEADER * dosheader;//JK:DOS文件头指针
IMAGE_OPTIONAL_HEADER * opthdr;//JK:结构
PIMAGE_EXPORT_DIRECTORY exports;//JK:用于保存一个IMAGE_EXPORT_DIRECTORY结构地址的指针变量
USHORT index=0 ;
ULONG addr ,i;
PUCHAR pFuncName = NULL;
PULONG pAddressOfFunctions,pAddressOfNames;//这个变量保存了一个32BTI地址,而这个地址指向了四个内存单元的内容
PUSHORT pAddressOfNameOrdinals;//这个变量保存了一个32BTI地址,而这个地址指向了两个内存单元的内容
BaseAddress= GetModlueBaseAdress("\\WINDOWS\\system32\\ntkrnlpa.exe");//JK:获取要HOOK模块的导入表的模块地址 ntoskrnl.exe
DbgPrint("Map BaseAddress is:%x\n",BaseAddress);
hMod = BaseAddress;
dosheader = (IMAGE_DOS_HEADER *)hMod;//JK:dosheader保存了描述DOS头的结构变量的地址
opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);//JK:dosheader->e_lfanew会输出PE文件头的位置+24是因为IMAGE_FILE_HEADER结构占20个字节,而加4是因为Signature所占4个字节,这样就指向了IMAGE_OPTIONAL_HEADER的位置
exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader+ opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);//JK:exports保存了IMAGE_EXPORT_DIRECTORY结构变量的地址
pAddressOfFunctions=(ULONG*)((BYTE*)hMod+exports->AddressOfFunctions/*指向了一个双字数组*/); //JK:获得EAT的入口地址,EAT又双字的数组组成
pAddressOfNames=(ULONG*)((BYTE*)hMod+exports->AddressOfNames);//JK:函数名字符串的地址表,根据这个地址表(由双字的数组组成)可获得函数名称的字符串
pAddressOfNameOrdinals=(USHORT*)((BYTE*)hMod+exports->AddressOfNameOrdinals); //JK:保存用于去pAddressOfFunctions指向的EAT中取函数地址的索引值(这个索引值还与函数名字符串的地址表对应,这样就可通过函数名称返回函数的地址了)
for (i = 0; i < exports->NumberOfNames; i++)
{
index=pAddressOfNameOrdinals[i];
pFuncName = (PUCHAR)( (BYTE*)hMod + pAddressOfNames[i]);
if (_stricmp( (char*)pFuncName,funName) == 0)
{
addr=pAddressOfFunctions[index];//JK:addr变量保存了PsGetCurrentProcessId函数的地址
DbgPrint("fount !! %x\n",addr);
break;
}
}
if(test==1) {
_asm
{
push eax
mov eax,CR0
and eax,0FFFEFFFFh
mov CR0,eax
pop eax
}
/*
//DbgPrint("PsGetCurrentProcessId is:%x\n",(ULONG)hMod + addr);//JK:输出PsGetCurrentProcessId这个函数的地址,基地址加RVA JK:用addr代替了pAddressOfFunctions[index]
g_OriginalPsGetCurrentProcessId= (ULONG)hMod + pAddressOfFunctions[index] ;//JK:g_OriginalPsGetCurrentProcessId保存了原先PsGetCurrentProcessId的地址
DbgPrint("original is:%x\n",(ULONG)hMod + pAddressOfFunctions[index]);
//DbgPrint("g_OriginalPsGetCurrentProcessId is:%x\n",g_OriginalPsGetCurrentProcessId);
pAddressOfFunctions[index] = ( PCHAR )MyPsGetCurrentProcessId;- BaseAddress;//求出MyPsGetCurrentProcessId的RVA
DbgPrint("Current is:%x\n",(ULONG)hMod + pAddressOfFunctions[index]);
*/
DbgPrint("hMod is:%x\n",(ULONG)hMod);
DbgPrint("pAddressOfFunctions[index] is:%x\n",pAddressOfFunctions[index]);
DbgPrint("PsGetCurrentProcessId is:%x\n",(ULONG)hMod + (ULONG)pAddressOfFunctions[index]);
DbgPrint("BaseAddress is:%x\n",(ULONG)BaseAddress);
DbgPrint("MyPsGetCurrentProcessId is:%x\n",(ULONG)MyPsGetCurrentProcessId);
pAddressOfFunctions[index] = ( PCHAR )MyPsGetCurrentProcessId - (PCHAR)BaseAddress;
DbgPrint("pAddressOfFunctions[index] is:%x\n",pAddressOfFunctions[index]);
g_OriginalPsGetCurrentProcessId= (ULONG)hMod + pAddressOfFunctions[index] ;
_asm
{
push eax
mov eax,CR0
or eax,NOT 0FFFEFFFFh
mov CR0,eax
pop eax
}
}
else
{
_asm
{
push eax
mov eax,CR0
and eax,0FFFEFFFFh
mov CR0,eax
pop eax
}
pAddressOfFunctions[index] = ( PCHAR )g_OriginalPsGetCurrentProcessId - BaseAddress;//JK 恢复以前的PsGetCurrentProcessId的地址
_asm
{
push eax
mov eax,CR0
or eax,NOT 0FFFEFFFFh
mov CR0,eax
pop eax
}
}
}
VOID Unload(PDRIVER_OBJECT DriverObject)
{
PCSTR myfunName="PsGetCurrentProcessId";
StartHook_And_Unhook(myfunName,0);
DbgPrint("Unload Callled\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str)
{
PCSTR myfunName="PsGetCurrentProcessId";
// MyPsGetCurrentProcessId();
DbgPrint("MyPsGetCurrentProcessId is:%x\n", MyPsGetCurrentProcessId);
DbgPrint("unmodify PsGetCurrentProcessId is:%x\n", PsGetCurrentProcessId);
DbgPrint("original is:%x\n", PsGetCurrentProcessId());
StartHook_And_Unhook(myfunName,1);
DbgPrint("Modify is:%x\n", PsGetCurrentProcessId());
DbgPrint("modify PsGetCurrentProcessId is:%x\n", PsGetCurrentProcessId);
//PsGetCurrentProcessId();
DriverObject->DriverUnload = Unload;
return STATUS_SUCCESS;
}
|
能力值:
( LV4,RANK:50 )
|
-
-
41 楼
来学习...看了...很不错...
|
能力值:
( LV2,RANK:10 )
|
-
-
42 楼
学习..........
|
能力值:
( LV17,RANK:797 )
|
-
-
43 楼
在修改之前加载的驱动不是没有效果了吗?
|
能力值:
( LV2,RANK:10 )
|
-
-
44 楼
mark了再看。。我还以为是应用层的hook
|
能力值:
( LV2,RANK:10 )
|
-
-
45 楼
mark
|
能力值:
( LV1,RANK:0 )
|
-
-
46 楼
这个也没法逃避eat 内核hook
|
|
|