📄 regmon.c
字号:
#include <ntddk.h>
#include "Reg.h"
#include <windef.h>
#include <stdio.h>
UNICODE_STRING DeviceNameString;
UNICODE_STRING LinkDeviceNameString;
/////////////////变量定义////////////////////////////
BYTE g_HookCode[5] = { 0xE9,0x00,0x00,0x00,0x00 }; //定义原始代码
BYTE g_OrigCode[5] = { 0x8B,0xFF,0x55,0x8B,0xEC };
BYTE jmp_orig_code[7] = { 0xEA,0x00,0x00,0x00,0x00,0x08,0x00 };
ULONG Addr_ObReferenceObjectByHandle = 0;
PVOID pRootControlBlock = 0;
POBJECT_TYPE CmpKeyObjectType; //注册表类型的数据
//////////////////////////////////////////////////////
//====================================================
NTSTATUS DetourFunctionHook_ObOpenObjectByHandle(IN ULONG FunAddr)
{
KIRQL oldIrql;
PMDL g_pmdlFunc = NULL;
PMDL g_pmdlReold = NULL;
PVOID *MappedPointer_OldFuc = NULL;
PVOID *MappedPointer_ToOld = NULL;
PUCHAR ori_Function = NULL;
PUCHAR re_Function = NULL;
PUCHAR inlineAdd = NULL;
ULONG Offset = 0;
ULONG ulDetourAddress = 0;
ULONG ulReEntryAddress = 0;
ori_Function = (PUCHAR)FunAddr;
re_Function = (PUCHAR)Re_Old_Function;
ulDetourAddress = (ULONG)Proxy_Function;
ulReEntryAddress = FunAddr + 5;
//初始化全局变量:
*( (PULONG)(g_HookCode+1) ) = (ULONG)Proxy_Function - FunAddr - 5;
*( (PULONG)(jmp_orig_code+1) ) = ulReEntryAddress;
//(1)映射内存,填写Re_Ori_NTFuntion函数机器码
g_pmdlReold = MmCreateMdl(NULL,re_Function,20);
if( !g_pmdlReold )
{
return STATUS_UNSUCCESSFUL;
}
MmBuildMdlForNonPagedPool(g_pmdlReold);
g_pmdlReold->MdlFlags = g_pmdlReold->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
MappedPointer_ToOld = MmMapLockedPages(g_pmdlReold, KernelMode);
inlineAdd = (PUCHAR)MappedPointer_ToOld;
RtlCopyMemory ( inlineAdd,g_OrigCode,5 ); //头五字节,补全原函数机器码(标准堆栈帧)
RtlCopyMemory ( (PUCHAR)inlineAdd + 5, jmp_orig_code, 7); //后七字节jmp_orig_code[7] (跳转回原函数)
MmUnmapLockedPages(MappedPointer_ToOld,g_pmdlReold);
IoFreeMdl(g_pmdlReold);
//(2)映射内存,对内核中原始函数打Detour补丁:
g_pmdlFunc = MmCreateMdl(NULL,ori_Function,10);
if(!g_pmdlFunc)
{
return STATUS_UNSUCCESSFUL;
}
MmBuildMdlForNonPagedPool(g_pmdlFunc);
g_pmdlFunc->MdlFlags = g_pmdlFunc->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
MappedPointer_OldFuc= MmMapLockedPages(g_pmdlFunc,KernelMode);
ori_Function = (PUCHAR)MappedPointer_OldFuc;
//对所要inline hook的函数头填充跳转指令,即打Detour补丁
KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
RtlCopyMemory ( ori_Function,g_HookCode,5 );
KeLowerIrql(oldIrql);
MmUnmapLockedPages(MappedPointer_OldFuc,g_pmdlReold);
IoFreeMdl(g_pmdlReold);
return STATUS_SUCCESS;
}
VOID UnHook_Function(IN ULONG FunAddr)
{
KIRQL oldIrql;
PUCHAR ori_Function = NULL;
PMDL g_pmdlPointer = NULL;
PVOID *MappedPointer = NULL;
__try
{
ori_Function = (PUCHAR)FunAddr;
g_pmdlPointer = MmCreateMdl(NULL,ori_Function,10);
if(!g_pmdlPointer)
{
return;
}
MmBuildMdlForNonPagedPool(g_pmdlPointer);
g_pmdlPointer->MdlFlags = g_pmdlPointer->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
MappedPointer= MmMapLockedPages(g_pmdlPointer, KernelMode);
ori_Function=(PUCHAR)MappedPointer;
KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
RtlCopyMemory ( ori_Function, g_OrigCode, 5 );
KeLowerIrql(oldIrql);
MmUnmapLockedPages(MappedPointer,g_pmdlPointer);
IoFreeMdl(g_pmdlPointer);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("UnHook Unsuccessful!\n");
}
}
ULONG GetFunctionAddr(IN PCWSTR FunctionName)
{
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,IN PUNICODE_STRING theRegistryPath)
{
NTSTATUS status;
PFILE_OBJECT FileObject;
UNICODE_STRING FilePath;
UNICODE_STRING DosName;
NTSTATUS Status;
STRING AnsiString;
theDriverObject->DriverUnload = UnloadDriver;
DbgPrint("Driver Loaded!");
Addr_ObReferenceObjectByHandle = (ULONG)GetFunctionAddr(L"ObReferenceObjectByHandle");
DbgPrint("ObReferenceObjectByHandle Address 0x%0.8X",Addr_ObReferenceObjectByHandle);
if( Addr_ObReferenceObjectByHandle == 0 )
return STATUS_UNSUCCESSFUL;
status = GetCmpKeyObjectTypeByInstance();
if( !NT_SUCCESS(status)||CmpKeyObjectType==0 )
return STATUS_UNSUCCESSFUL;
DbgPrint("CmpKeyObjectType 0x%0.8X",CmpKeyObjectType);
DetourFunctionHook_ObOpenObjectByHandle(Addr_ObReferenceObjectByHandle);
return STATUS_SUCCESS;
}
VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject)
{
UnHook_Function(Addr_ObReferenceObjectByHandle);
DbgPrint("\nDriver Unload OK!\n");
}
__declspec(naked)
BOOLEAN
Proxy_Function()
{
_asm{
push ebp
mov ebp,esp //构建标准堆栈帧
pushad
pushfd //保护现场
push [ebp+0x1C]
push [ebp+0x18]
push [ebp+0x14]
push [ebp+0x10]
push [ebp+0x0C]
push [ebp+0x08]
call Check_Parameter
cmp eax,1
je DenyRunning //返回值为1,运行DenyRunning
popfd
popad //恢复现场
mov esp,ebp
pop ebp //恢复原本堆栈帧
jmp Re_Old_Function
DenyRunning:
popfd
popad
mov eax,0xC0000022
mov esp,ebp
pop ebp
ret 18h
}
}
int __stdcall
Check_Parameter(
__in HANDLE Handle,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__out PVOID *Object,
__out_opt POBJECT_HANDLE_INFORMATION HandleInformation)
{
NTSTATUS status;
PEPROCESS Caller;
PCM_KEY_BODY KeyBody;
char CallerName[20] = {0};
char keyname[256];
Caller = PsGetThreadProcess( PsGetCurrentThread() );
//监控注册表
if( CmpKeyObjectType == ObjectType )
{
status = Re_Old_Function(Handle,DesiredAccess,ObjectType,
AccessMode,&KeyBody,NULL);
if( !NT_SUCCESS(status) )
return 1;
memcpy(CallerName,PsGetProcessImageFileName(Caller),16);
if( _stricmp(CallerName,"regedit.exe")==0 )
{
switch(DesiredAccess)
{
case KEY_QUERY_VALUE:
DbgPrint("KEY_QUERY_VALUE 0x%0.8X",DesiredAccess);break;
case KEY_SET_VALUE:
DbgPrint("KEY_SET_VALUE 0x%0.8X",DesiredAccess);break;
case KEY_CREATE_SUB_KEY:
DbgPrint("KEY_CREATE_SUB_KEY 0x%0.8X",DesiredAccess);break;
case KEY_ENUMERATE_SUB_KEYS:
DbgPrint("KEY_ENUMERATE_SUB_KEYS 0x%0.8X",DesiredAccess);break;
case KEY_ALL_ACCESS:
DbgPrint("KEY_ALL_ACCESS 0x%0.8X",DesiredAccess);break;
case DELETE:
DbgPrint("DELETE 0x%0.8X",DesiredAccess);break;
default:
DbgPrint("UnKnown 0x%0.8X",DesiredAccess);break;
}
DbgPrint("[Reg Called] %s ",PsGetProcessImageFileName(Caller));
memset(keyname,'\0',256);
GetRegNameByKeyObject(KeyBody,keyname);
DbgPrint("%s\n\n",keyname);
ObDereferenceObject(KeyBody);
if( _stricmp(keyname,"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run")==0 )
return 1; //与指定键值相等时进行筛出
}
}
return 0;
}
//Re_Old_NTFuntion跳转回原函数
__declspec(naked)
BOOLEAN
Re_Old_Function(
__in HANDLE Handle,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__out PVOID *Object,
__out_opt POBJECT_HANDLE_INFORMATION HandleInformation)
{
__asm {
_emit 0x90 //头五字节,补全原函数机器码(g_OrigCode[5])
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90 //后七字节,jmp_orig_code[7]
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90 // jmp 0008:ulReEntryAddress
}
}
NTSTATUS
GetRegNameByKeyObject(PCM_KEY_BODY pKeyObject,PCHAR RegKeyName)
{
char KeyName[256] = {0};
char KeyTmp[256] = {0};
PVOID pControlBlock = 0;
PVOID pParentControlBlock = 0;
PCM_NAME_CONTROL_BLOCK pNameControlBlock;
ULONG strLength;
if( !MmIsAddressValid(pKeyObject) ||
!MmIsAddressValid( (PULONG)((ULONG)pKeyObject->KeyControlBlock+NameBlock) ) )
{
return STATUS_ACCESS_DENIED;
}
pControlBlock = (PULONG)pKeyObject->KeyControlBlock;
for( pParentControlBlock = GetNextRegNameByControlBlock(pControlBlock,KeyTmp);
pParentControlBlock != 0;
pParentControlBlock = GetNextRegNameByControlBlock(pParentControlBlock,KeyTmp) )
{
strcat(KeyName,"\\");
strcat(KeyName,KeyTmp);
}
GetTheOriName(KeyName,KeyTmp);//逆序转为顺序的模块
pNameControlBlock = *(PCM_NAME_CONTROL_BLOCK *)((ULONG)pRootControlBlock+NameBlock);
strcat(RegKeyName,"\\");
memcpy(RegKeyName+1,pNameControlBlock->Name,pNameControlBlock->NameLength);
strLength = strlen(RegKeyName) + strlen(KeyTmp);
if( strLength < 256 )
{
strcat(RegKeyName,KeyTmp);
RegKeyName[strLength] = 0;
}
if( strLength >=256 )
{
memcpy(RegKeyName+1+pNameControlBlock->NameLength,KeyTmp,256-1-pNameControlBlock->NameLength);
*(RegKeyName+255) = 0;
}
return STATUS_SUCCESS;
}
void GetTheOriName(PCHAR inName,PCHAR outName)
{
ULONG length = 0;
ULONG iCnt = 0;
ULONG iTmp = 0;
length = strlen(inName);
for( iCnt=0;iCnt<length;iCnt++ )
{
if( *(inName+iCnt)==0x5c||*(inName+iCnt)==0x00 )
{
for(iTmp=1;iTmp<length;iTmp++)
{
if( *(inName+iCnt+iTmp)==0x5c||*(inName+iCnt+iTmp)==0x00 )
{
memcpy(outName+length-iTmp-iCnt,inName+iCnt,iTmp);
break;
}
}
}
}
}
PVOID
GetNextRegNameByControlBlock(PVOID pControlBlock,char* Name)
{
PVOID pParentControlBlock;
PCM_NAME_CONTROL_BLOCK pNameControlBlock;
if(pControlBlock ==0 || !MmIsAddressValid(pControlBlock) )
return 0;
pParentControlBlock = *(PVOID *)((ULONG)pControlBlock+ParentKcb);
pNameControlBlock =
*(PCM_NAME_CONTROL_BLOCK *)((ULONG)pControlBlock+NameBlock);
memcpy(Name,pNameControlBlock->Name,pNameControlBlock->NameLength);
Name[pNameControlBlock->NameLength]=0;
if( pParentControlBlock ==0 )
pRootControlBlock = pControlBlock;
return pParentControlBlock;
}
NTSTATUS
GetCmpKeyObjectTypeByInstance()
{
NTSTATUS ntStatus;
UNICODE_STRING keyName;
OBJECT_ATTRIBUTES objAttr;
HANDLE hKey;
PCM_KEY_BODY KeyBody;
char Type[30] = {0};
CmpKeyObjectType = 0;
RtlInitUnicodeString(&keyName,L"\\Registry\\Machine");
InitializeObjectAttributes(&objAttr,&keyName,
OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL);
ntStatus = ZwOpenKey(&hKey,KEY_READ,&objAttr);
if(! NT_SUCCESS(ntStatus))
{ DbgPrint("OpenKey Unsuccessful");
return STATUS_UNSUCCESSFUL; }
ntStatus = ObReferenceObjectByHandle(hKey,KEY_READ,NULL,KernelMode,&KeyBody,NULL);
if(! NT_SUCCESS(ntStatus))
{
DbgPrint("Object Initial Unsuccessful");
ZwClose(hKey);
return STATUS_UNSUCCESSFUL;
}
//验证KeyType的UNICODE_STRING是否为Key
ntStatus = GetObjectType(KeyBody,Type);
if( !NT_SUCCESS(ntStatus) )
return STATUS_UNSUCCESSFUL;
if( _stricmp(Type,"Key")==0 )
CmpKeyObjectType = OBJECT_TO_OBJECT_HEADER(KeyBody)->Type;
return STATUS_SUCCESS;
}
NTSTATUS
GetObjectType(PVOID Object,PUCHAR TypeName)
{
ANSI_STRING ANSI_TypeName;
PUNICODE_STRING pUNI_String;
*TypeName = 0;
pUNI_String = (PUNICODE_STRING)((ULONG)OBJECT_TO_OBJECT_HEADER(Object)->Type+type_Name);
if( !MmIsAddressValid(pUNI_String) )
return STATUS_ACCESS_DENIED;
if( !MmIsAddressValid(pUNI_String->Buffer) )
return STATUS_ACCESS_DENIED;
RtlUnicodeStringToAnsiString(&ANSI_TypeName,pUNI_String,TRUE);
memcpy(TypeName,ANSI_TypeName.Buffer,ANSI_TypeName.Length);
TypeName[ANSI_TypeName.Length] = 0;
RtlFreeAnsiString(&ANSI_TypeName);
return STATUS_SUCCESS;
}
BOOL IceSleep(int time)
{
LARGE_INTEGER Interval;
NTSTATUS status;
Interval.QuadPart = -10000 * time;
status=KeDelayExecutionThread(0, 0, &Interval);
return NT_SUCCESS(status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -