1>正在编译...
1>event.c
1>正在编译资源...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>正在链接...
1>event.obj : error LNK2019: 无法解析的外部符号 __imp__NtWriteVirtualMemory@20,该符号在函数 _Hook@0 中被引用
1>d:\My Documents\Visual Studio 2008\Projects\event\check\event.sys : fatal error LNK1120: 1 个无法解析的外部命令
1>生成日志保存在“file://d:\My Documents\Visual Studio 2008\Projects\event\event\check\BuildLog.htm”
1>event - 2 个错误,0 个警告
========== 全部重新生成: 成功 0 个,失败 1 个,跳过 0 个 ==========
为什么会出错呢
以下是代码
#include<ntddk.h>
#define INITCODE code_seg("INIT") //入口函数
#pragma INITCODE
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; //由于KeServiceDescriptorTable只有一项,这里就简单点了
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;//KeServiceDescriptorTable为导出函数
/////////////////////////////////////原型
NTSYSAPI
NTSTATUS
NTAPI
NtWriteVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnLength OPTIONAL
);
VOID Hook();
VOID Unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);
//////////////////////////////////////
ULONG JmpAddress;//跳转到NtWriteVirtualMemory里的地址
ULONG OldServiceAddress;//原来NtWriteVirtualMemory的服务地址
//////////////////////////////////////
__declspec(naked) NTSTATUS __stdcall MyNtWriteVirtualMemory(PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId)
{
DbgPrint("NtWriteVirtualMemory() called");
__asm{
push 0155h
push 805b5394h //共十个字节
jmp [JmpAddress]
}
}
///////////////////////////////////////////////////
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = OnUnload;
DbgPrint("Unhooker load");
Hook();
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("Unhooker unload!");
Unhook();
}
/////////////////////////////////////////////////////
VOID Hook()
{
ULONG Address;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;//0x115为NtWriteVirtualMemory服务ID
DbgPrint("Address:0x%08X",Address);
OldServiceAddress = *(ULONG*)Address;//保存原来NtWriteVirtualMemory的地址
DbgPrint("OldServiceAddress:0x%08X",OldServiceAddress);
DbgPrint("MyNtWriteVirtualMemory:0x%08X",MyNtWriteVirtualMemory);
JmpAddress = (ULONG)NtWriteVirtualMemory + 10; //跳转到NtWriteVirtualMemory函数头+10的地方,这样在其前面写的JMP都失效了
DbgPrint("JmpAddress:0x%08X",JmpAddress);
__asm{//去掉内存保护
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*((ULONG*)Address) = (ULONG)MyNtWriteVirtualMemory;//HOOK SSDT
__asm{//恢复内存保护
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
//////////////////////////////////////////////////////
VOID Unhook()
{
ULONG Address;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;//查找SSDT
__asm{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*((ULONG*)Address) = (ULONG)OldServiceAddress;//还原SSDT
__asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
DbgPrint("Unhook");
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!