|
#include <ntddk.h>
#include "ntimage.h"
#include <windef.h>
#include "LDasm.h"
typedef NTSTATUS (*OBOPENOBJECTBYPOINTER)
(
IN PVOID Object,
IN ULONG HandleAttributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
OUT PHANDLE Handle
);
PEPROCESS MyProcess=(PEPROCESS)0x80fefa98;//我们要保护的进程对象 自行修改
OBOPENOBJECTBYPOINTER pObOpenObjectByPointer=NULL;
PVOID pNtOpenProcess=NULL;
ULONG GetFuncAddr(PWCHAR funcname)
{
UNICODE_STRING uniFuncName;
RtlInitUnicodeString(&uniFuncName,funcname);
return (ULONG)MmGetSystemRoutineAddress(&uniFuncName);
}
void MemOpen()
{
__asm {
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
}
void MemClose()
{
__asm {
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
// 从StartAddr地址 开始找OldAddr 替换为NewAddr地址 长度是 SIZE
BOOL CallAddrHook(PVOID StartAddr,PVOID OldAddr,PVOID NewAddr,ULONG Size)
{
PUCHAR cPtr, pOpcode;
ULONG Length,Tmp;
for (cPtr=StartAddr;(ULONG)cPtr<(ULONG)StartAddr+Size;cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);//计算当前指令长度
if (!Length) break;
if (Length ==5 && *cPtr==0xE8)// 当前长度5 且第一字节为E8
{//因为CALL用的是相对偏移 所以我们还需要进行计算相对偏移
if ( (ULONG)OldAddr-(ULONG)cPtr-5 == *(PULONG)(cPtr+1)) //判断当前是否为OldAddr的CALL相对地址
{
DbgPrint("ULONG cPtr=%x",(ULONG)cPtr);
Tmp=(ULONG)NewAddr-(ULONG)cPtr-5;//我们的CALL地址相对偏移
MemOpen();
*(PULONG)(cPtr+1)=Tmp;//直接替换为我们的FAKE函数地址
MemClose();
return TRUE;
}
}
}
return FALSE;
}
//NtOpenProcess
NTSTATUS MyObOpenObjectByPointer_forProcess(IN PVOID Object,
IN ULONG HandleAttributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
OUT PHANDLE Handle)
{
if (Object==MyProcess)
{
return STATUS_ACCESS_DENIED;
}
else
{
return pObOpenObjectByPointer (Object, HandleAttributes,PassedAccessState,DesiredAccess,ObjectType,AccessMode,Handle);
}
}
VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
CallAddrHook(pNtOpenProcess,MyObOpenObjectByPointer_forProcess,pObOpenObjectByPointer,PAGE_SIZE);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
//查找地址
pObOpenObjectByPointer=(OBOPENOBJECTBYPOINTER)GetFuncAddr(L"ObOpenObjectByPointer");//
DbgPrint("pObOpenObjectByPointer=%x",pObOpenObjectByPointer);
pNtOpenProcess=(PVOID)GetFuncAddr(L"NtOpenProcess");
DbgPrint("pNtOpenProcess=%x",pNtOpenProcess);
CallAddrHook(pNtOpenProcess,pObOpenObjectByPointer,MyObOpenObjectByPointer_forProcess,PAGE_SIZE);
DriverObject->DriverUnload = Unload;
return STATUS_SUCCESS;
} |
|