在HS下可读写内存的驱动
#include<ntddk.h>/*
初学驱动 参读堕落天才ssdt hook 对抗inline hook
哪里有错或者有比这个还简单的方法还请大神指点一下 好让我从中得到启发 thx
By Bleach=darkmax
*/
typedef unsigned char BYTE;
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG reserved;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName;
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; // ZwQuerySystemInformation需要的数据结构
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
ULONG num,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
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为导出函数
/////////////////////////////////////
VOID Hook();
VOID Unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);
//////////////////////////////////////
ULONG JmpAddress;//跳转到NtOpenProcess里的地址
ULONG JmpAddress1;
ULONG JmpAddress2;
ULONG OldServiceAddress;//原来NtOpenProcess的服务地址
ULONG OldServiceAddress1;
ULONG OldServiceAddress2;
BYTE dthq={0};
BYTE hqdt={0};
BYTE dthq1={0};
BYTE hqdt1={0};
BYTE dthq2={0};
BYTE hqdt2={0};
PVOID newop=0;
PVOID newop1=0;
PVOID newop2=0;
PVOID newop3=0;
PVOID newop4=0;
PVOID newop5=0;
ULONG getid=0;
PVOID GetFuncAddress()
{
ULONG size,index;
PULONG buf;
ULONG i;
PSYSTEM_MODULE_INFORMATION module;
PVOID driverAddress = 0;
ULONG ntosknlBase;
ULONG ntosknlEnd;
ULONG curAddr;
NTSTATUS status;
ULONG k;
ULONG retAddr;
ULONG code_1 = 0x00a16480, code_2 = 0x50000000, code_3 = 0x1024448b,
code_4 = 0x10246c89; //定义特征码,通过Windbg的dd来找
ZwQuerySystemInformation(11,&size,0,&size); // 第一个参数其实是个enum,11 - SystemModuleInformation,为了保持简洁,我可耻的没放出定义。
buf = (PULONG) ExAllocatePool(PagedPool,size);
if(buf == NULL)
return NULL;
status = ZwQuerySystemInformation(11,buf,size,0); // 上一次调用得到大小,此次得到数据。
if(!NT_SUCCESS(status))
{
return NULL;
}
module = (PSYSTEM_MODULE_INFORMATION)((PULONG)buf + 1);
ntosknlEnd = (ULONG)module->Base + (ULONG)module->Size;
ntosknlBase = (ULONG)module->Base; //ntosknl的基地址
curAddr = ntosknlBase;
ExFreePool(buf);
for(i = curAddr; i<=ntosknlEnd; i++) //从头开始搜,当然,如果知道未导出函数前一个函数和后一个函数的信息,就可以减小范围,详见pediy的sysnap的方法。
{
if( (*((ULONG*)i)) == code_1 &&
(*((ULONG*)(i+4)) == code_2) &&
(*((ULONG*)(i+8)) == code_3) &&
(*((ULONG*)(i+12)) == code_4) )
{
retAddr = i;
//DbgPrint("Target Found! Address: 0x%08x\n",retAddr);
return retAddr;
}
}
}
//////////////////////////////////////
__declspec(naked) NTSTATUS __stdcall MyNtOpenProcess(PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId)
{
// DbgPrint("NtOpenProcess() called");
__asm
{
push
push
call
jmp
}
}
///////////////////////////////////////////////////
__declspec(naked) NTSTATUS __stdcall MyNtReadVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesReaded OPTIONAL)
{
__asm{
push
push
call
jmp
}
}
//===================================================
__declspec(naked) NTSTATUS __stdcall MyNtWriteVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnLength OPTIONAL)
{
__asm{
push
push
call
jmp
}
}
//////////////////////////////////////////////
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,Address1,Address2;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;//0x7A为NtOpenProcess服务ID
Address1 = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xBA * 4;
Address2 = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;
DbgPrint("Address:0x%08X",Address);
OldServiceAddress = *(ULONG*)Address;//保存原来NtOpenProcess的地址
OldServiceAddress1 = *(ULONG*)Address1;//保存原来NtOpenProcess的地址
OldServiceAddress2 = *(ULONG*)Address2;//保存原来NtOpenProcess的地址
newop=(ULONG)NtOpenProcess+1;
newop1=(ULONG)NtOpenProcess+6;
newop2=OldServiceAddress1+1;
newop3=OldServiceAddress1+3;
newop4=OldServiceAddress2+1;
newop5=OldServiceAddress2+3;
memcpy(dthq,newop,sizeof(dthq));
memcpy(hqdt,newop1,sizeof(hqdt));
memcpy(dthq1,newop2,sizeof(dthq1));
memcpy(hqdt1,newop3,sizeof(hqdt1));
memcpy(dthq2,newop4,sizeof(dthq2));
memcpy(hqdt2,newop5,sizeof(hqdt2));
getid=(ULONG)GetFuncAddress()-4;
JmpAddress = (ULONG)NtOpenProcess + 15; //跳转到NtOpenProcess函数头+15的地方,这样在其前面写的JMP都失效了
JmpAddress1 = OldServiceAddress1 + 12; //跳转到NtOpenProcess函数头+15的地方,这样在其前面写的JMP都失效了
JmpAddress2 = OldServiceAddress2 + 12; //跳转到NtOpenProcess函数头+15的地方,这样在其前面写的JMP都失效了
DbgPrint("JmpAddress:0x%08X",JmpAddress);
__asm{//去掉内存保护
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*((ULONG*)Address) = (ULONG)MyNtOpenProcess;//HOOK SSDT
*((ULONG*)Address1) = (ULONG)MyNtReadVirtualMemory;//HOOK SSDT
*((ULONG*)Address2) = (ULONG)MyNtWriteVirtualMemory;
__asm{//恢复内存保护
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
//////////////////////////////////////////////////////
VOID Unhook()
{
ULONG Address,Address1,Address2;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;
Address1 = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xBA * 4;
Address2 = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;
__asm{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*((ULONG*)Address) = (ULONG)OldServiceAddress;//还原SSDT
*((ULONG*)Address1) = (ULONG)OldServiceAddress1;
*((ULONG*)Address2) = (ULONG)OldServiceAddress2;
__asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
DbgPrint("Unhook");
}
锄禾日当午,发帖真辛苦。谁知坛中餐,帖帖皆辛苦! 顶,楼主v5 谢谢楼主分享,支持 海论坛 必须顶一个啊 顶顶顶顶大大的等等等等等等等等等等等等 {:lol:}{:lol:}{:lol:}{:lol:}{:lol:} 学习{:lol:}{:lol:}
页:
[1]