- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
是依据10年的进程保护修改的,这次是 内核里面替换函数地址,也就是 传说中的SSDT hook 。具体是 替换 NtReadVirtualMemory的函数地址。。。。
----------------------------------------------------------------
#include <ntddk.h>
typedef struct _SystemServiceDescriptorTable
{
PVOID ServiceTableBase; //SSDT表的基地址
PULONG ServiceCounterTableBase; //指向另一个索引表,该表包含了每个服务表项被调用的次数
ULONG NumberOfService; //当前系统所支持的服务个数
ULONG ParamTableBase; //包含了每个服务所需的参数字节数
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;
extern PSystemServiceDescriptorTable KeServiceDescriptorTable; //导出函数,DDK的头文件中并未声明
//内核函数声明
typedef NTSTATUS (*NtREADVIRTUALMEMORY)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnLength OPTIONAL);
//定义一个内核函数的数据类型
NtREADVIRTUALMEMORY pRealAddr;//用 NtREADVIRTUALMEMORY 定义 一个 真的 函数类型
ULONG RealServiceAddress; //接受被hook的函数地址
CHAR *TerminateName = "Form1.exe"; //这里就是我们的记事本进程名
UCHAR* PsGetProcessImageFileName( IN PEPROCESS Process );
BOOLEAN IsProtect(CHAR *temp) //判断正在结束的进程是否是我们要保护的魔兽进程
{
ULONG len = strcmp(TerminateName, temp);
if(!len)
return TRUE;
return FALSE;
}
NTSTATUS MyNtReadVirtualMemory(IN HANDLE ProcessHandle,IN PVOID BaseAddress,OUT PVOID Buffer,IN ULONG BufferLength,OUT PULONG ReturnLength OPTIONAL)//ReturnLength 是参数
{
PEPROCESS process; //接受通过ProcessHandle返回的进程
NTSTATUS status;
CHAR *pName; //接受进程的进程名
status = ObReferenceObjectByHandle(ProcessHandle, FILE_READ_DATA,0, KernelMode,&process,NULL); //获取进程
if(!NT_SUCCESS(status))//如果不是我们要保护的进程就放过它,让他正常访问内存
{
return (NTSTATUS)(NtREADVIRTUALMEMORY)pRealAddr(ProcessHandle, BaseAddress,Buffer,BufferLength,ReturnLength);
}
pName = (CHAR*)PsGetProcessImageFileName(process);
//获取进程名。内核中居然可以这样依据 进程结构 获取进程名,很好,很方面
if(IsProtect(pName)) //判断是否是我们要保护的进程,是则返回权限不足
{
DbgPrint(" 有进程正在访问 %s的内存,我让它访问不了! \n",pName); //嘿嘿,
return STATUS_ACCESS_DENIED;//返回为STATUS_ACCESS_DENIED CE就无法访问内存了
}
return (NTSTATUS)(NtREADVIRTUALMEMORY)pRealAddr(ProcessHandle, BaseAddress,Buffer,BufferLength,ReturnLength);
}
NTSTATUS Hook()
{
ULONG Address;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 277 * 4;
//可以用 xuetr查看。 win7上 序号为 277 xp上位186
RealServiceAddress = *(ULONG*)Address;
pRealAddr = (NtREADVIRTUALMEMORY)RealServiceAddress;
//开启SSDT 表为可写
_asm
{
cli;
mov eax, cr0;
and eax, not 10000h;
mov cr0, eax;
}
*((ULONG*)Address) = (ULONG)MyNtReadVirtualMemory; //替换为我们自己的NtTerminateProcess函数
DbgPrint("完成HOOK内核函数");
//设置SSDT表位只读
_asm
{
mov eax, cr0;
or eax, 10000h;
mov cr0, eax;
sti;
}
}
VOID UnHook()//把SSDT中的NtReadVirtualMemory函数还原
{
ULONG Address;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase +277 * 4;
//可以用 xuetr查看。 win7上 序号为277 xp上位 186
__asm
{
cli
mov eax, cr0;
and eax, not 10000h ;
mov cr0, eax ;
}
*((ULONG*)Address) = (ULONG)RealServiceAddress;
__asm
{
mov eax, cr0 ;
or eax, 10000h ;
mov cr0, eax ;
sti ;
}
}
VOID Unload(PDRIVER_OBJECT driver)
{
UNREFERENCED_PARAMETER(driver);
UnHook();
DbgPrint("卸载驱动完成...");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING str)
{
NTSTATUS status;
UNREFERENCED_PARAMETER(str);
driver->DriverUnload = Unload;
DbgPrint("驱动加载完成");
status = Hook();
return STATUS_SUCCESS;
}
两个版本全部搞定,xp和win7 32 位,果断分享。
http://pan.baidu.com/share/link?shareid=520327&uk=3895950538 |
|