大神进

yiyefangzhou24 2011-03-05 04:34:35
贴一个以前贴过的代码段,SSDT HOOK,我的程序为什么一旦启动就会死机?请大神看看我错在哪?
#include <ntddk.h> 

typedef struct _ServiceDescriptorEnty
{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;

typedef NTSTATUS (__stdcall *NTOPENPROCESS)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK AccessMask,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId);

NTOPENPROCESS RealNtOpenProcess;

extern PServiceDescriptorTableEntry KeServiceDescriptorTable;



NTSTATUS MyNtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);


VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("succeed!");
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
ULONG Address;
PULONG RealOPServiceAddress;
_asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
RealOPServiceAddress = *(ULONG*)Address;
RealNtOpenProcess = (NTOPENPROCESS)RealOPServiceAddress;
Address=(ULONG)KeServiceDescriptorTable->ServiceTableBase+0x7A*4;
*((ULONG*)Address)=(ULONG)MyNtOpenProcess;
_asm
{
cli
mov eax,cr0
and eax,10000h
mov cr0,eax
sti
}

DriverObject->DriverUnload=DriverUnload;
return STATUS_SUCCESS;
}


NTSTATUS MyNtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
{
NTSTATUS rc=NULL;
ULONG dwPID;
//rc=(NTSTATUS)(REALZWOPENPROCESS)RealZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
if(ClientId!=NULL)
{
dwPID=(ULONG)ClientId->UniqueProcess;
if(dwPID==2344)
{
DbgPrint("PID 2344 has been accessed,need forbidden");
ProcessHandle=0;
rc=STATUS_ACCESS_DENIED;
}
}
else
rc=(NTSTATUS)(NTOPENPROCESS)RealNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId );
return rc;
}
...全文
209 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiyefangzhou24 2011-03-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lactoferrin 的回复:]
关写保护
_asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*Address=MyNtOpenProcess;
开写保护
_asm
{
mov eax,cr0
or eax,10000h这里要用or才能把保护位置1
mov cr0,eax
sti……
[/Quote]这位果真是大神,拜读,我跨进内核程序设计遇上的第一个好心人,我先来看看我的错误啊,分嫌少另外给你加
Defonds 2011-03-06
  • 打赏
  • 举报
回复
不错,代码都有了
Lactoferrin 2011-03-06
  • 打赏
  • 举报
回复
关写保护
_asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*Address=MyNtOpenProcess;
开写保护
_asm
{
mov eax,cr0
or eax,10000h这里要用or才能把保护位置1
mov cr0,eax
sti
}
你在变量类型上有点乱,和指针一样大的整数应该用ULONG_PTR

MyNtOpenProcess中的判断没那么麻烦

你的DriverEntry中 RealOPServiceAddress = *(ULONG*)Address; 应该放在 Address=(ULONG)KeServiceDescriptorTable->ServiceTableBase+0x7A*4;之后

extern PServiceDescriptorTableEntry KeServiceDescriptorTable;
这样用得到的KeServiceDescriptorTable是指向那个描述符表指针的指针,所以要extern PServiceDescriptorTableEntry*KeServiceDescriptorTable; 后面就(*KeServiceDescriptorTable)->

如果这样_declspec(dllimport) extern PServiceDescriptorTableEntry KeServiceDescriptorTable;
KeServiceDescriptorTable就是指向那个描述符表的指针,可以直接用

不过我喜欢用MmGetSystemRoutineAddress得到地址

如果使用修改cr0的方法关保护,会使得虚拟存储器失效,如果中间存取了在页面文件中的数据就会出错,而且可能和其它cpu不协调,所以我用mdl的方式修改

使用硬编码NtOpenProcess的服务号无兼容性,不知道你有没有确定0x7A就是你的操作系统中的NtOpenProcess的服务号,从ZwOpenProcess的代码得到服务号更好
yiyefangzhou24 2011-03-06
  • 打赏
  • 举报
回复
一楼的大神,辛苦您了,但是小弟刚刚入门,不想抄网上的代码,请您看看我的到底错在哪 ?我觉得没有问题啊,非常感谢
Lactoferrin 2011-03-06
  • 打赏
  • 举报
回复
先给你的联系方式
yiyefangzhou24 2011-03-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 lactoferrin 的回复:]
ULONG 是unsigned long,在32位系统中能装下地址,但是在64位系统就装不下了
ULONG_PTR会根据实际编译时的宏定义成unsigned long或unsigned __int64,能够保证装得下地址

你的第二个__asm中不用再cli,因为前面已经把中断关了,两个_asm中的代码最好尽量少,只需要把*((ULONG*)Address)=(ULONG)MyNtOpenP……
[/Quote]学习了,哥么,能给个联系方式吗?你经常看邮件否,
if(answer==yes)
{
send to me ;
}
Lactoferrin 2011-03-06
  • 打赏
  • 举报
回复
extern PServiceDescriptorTableEntry KeServiceDescriptorTable;这个是我看错了
Lactoferrin 2011-03-06
  • 打赏
  • 举报
回复
前面的unsigned int *ServiceTableBase;应该改成void**ServiceTableBase;毕竟函数指针类型是void*比较好。
不过不改也行,因为只能在32位windows中ssdt hook
Lactoferrin 2011-03-06
  • 打赏
  • 举报
回复
ULONG 是unsigned long,在32位系统中能装下地址,但是在64位系统就装不下了
ULONG_PTR会根据实际编译时的宏定义成unsigned long或unsigned __int64,能够保证装得下地址

你的第二个__asm中不用再cli,因为前面已经把中断关了,两个_asm中的代码最好尽量少,只需要把*((ULONG*)Address)=(ULONG)MyNtOpenProcess;放在两个_asm之间即可
yiyefangzhou24 2011-03-06
  • 打赏
  • 举报
回复
首先,修改通过了,我非常高兴。

其次,来说说您的观点
1,开关写保护的地方我写的是错的,确实没有考虑到这个问题。
2,指针类型上,因为我看到Address既然是指向ULONG的指针,所以我将它定义为PLONG,编译的时候没有报错,我想请问一下为什么,因为初学驱动程序设计,对里面的变量类型不是完全了解ULONG_PTR是什么类型?
3“你的DriverEntry中 RealOPServiceAddress = *(ULONG*)Address; 应该放在 Address=(ULONG)KeServiceDescriptorTable->ServiceTableBase+0x7A*4;之后,“这个我认为是主要问题,当时这个地方出错我就反复修改,本来是对的,后来改着改着那一句就跑到下面去了,没查出来,这个是严重的逻辑错误。
4extern PServiceDescriptorTableEntry KeServiceDescriptorTable;问题,我认为是您看错了因为我在结构体中定义的是*KeServiceDescriptorTable。
5,mdl的方式修改比寄存器修改更为复杂,为了简单化毕竟我是经验有限,就用暴力修改寄存器的方法了
修改后的代码如下:(虽然稳定性有待考证)
#include <ntddk.h> 

typedef struct _ServiceDescriptorEnty
{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;

typedef NTSTATUS (__stdcall *NTOPENPROCESS)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK AccessMask,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId);

NTOPENPROCESS RealNtOpenProcess;

extern PServiceDescriptorTableEntry KeServiceDescriptorTable;


NTSTATUS MyNtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);


VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("succeed!");
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
ULONG Address;
ULONG_PTR RealOPServiceAddress;
_asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
Address=(ULONG)KeServiceDescriptorTable->ServiceTableBase+0x7A*4;
*((ULONG*)Address)=(ULONG)MyNtOpenProcess;
RealOPServiceAddress = *(ULONG*)Address;
RealNtOpenProcess = (NTOPENPROCESS)RealOPServiceAddress;

_asm
{
cli
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}

DriverObject->DriverUnload=DriverUnload;
return STATUS_SUCCESS;
}


NTSTATUS MyNtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
{
NTSTATUS rc=NULL;
ULONG dwPID;
//rc=(NTSTATUS)(REALZWOPENPROCESS)RealZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
if(ClientId!=NULL)
{
dwPID=(ULONG)ClientId->UniqueProcess;
if(dwPID==1884)
{
DbgPrint("PID 1884 has been accessed,need forbidden");
ProcessHandle=0;
rc=STATUS_ACCESS_DENIED;
}
}
else
rc=(NTSTATUS)(NTOPENPROCESS)RealNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId );
return rc;
}
Lactoferrin 2011-03-05
  • 打赏
  • 举报
回复
是不是一直没人回?
试这个

#include <ntddk.h>

typedef struct _ServiceDescriptorEnty
{
void**ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;

typedef NTSTATUS (__stdcall *NTOPENPROCESS)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK AccessMask,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId);

NTOPENPROCESS RealNtOpenProcess;PMDL mdl;void**mdladdr;

NTSTATUS __stdcall MyNtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);


VOID __stdcall DriverUnload(PDRIVER_OBJECT DriverObject)
{
*mdladdr=RealNtOpenProcess;
MmUnmapLockedPages(mdladdr,mdl);
IoFreeMdl(mdl);
}


NTSTATUS __stdcall DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
void**Address;static UNICODE_STRING Str1={26,26,L"ZwOpenProcess"},Str2={48,48,L"KeServiceDescriptorTable"};
PServiceDescriptorTableEntry KeServiceDescriptorTable;NTOPENPROCESS _ZwOpenProcess;
KeServiceDescriptorTable=MmGetSystemRoutineAddress(&Str2);
_ZwOpenProcess=MmGetSystemRoutineAddress(&Str1);
Address=(void**)&KeServiceDescriptorTable->ServiceTableBase[*(unsigned short*)((ULONG_PTR)_ZwOpenProcess+1)];
RealNtOpenProcess=*(NTOPENPROCESS*)Address;
mdl=IoAllocateMdl(Address,sizeof(void*),0,0,0);
MmBuildMdlForNonPagedPool(mdl);
mdladdr=(void**)MmMapLockedPagesSpecifyCache(mdl,KernelMode,MmNonCached,0,0,NormalPagePriority);
*mdladdr=MyNtOpenProcess;
DriverObject->DriverUnload=DriverUnload;

return 0;
}


NTSTATUS __stdcall MyNtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
{
if(ClientId)
{
if(((ULONG_PTR)ClientId->UniqueProcess&~3)==1940)return 0xC0000022;
}
return RealNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
}

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧