Author: Polymorphours
Email: Polymorphours@whitecell.org
Homepage:http://www.whitecell.org
Date: 2005-11-17
Email: Polymorphours@whitecell.org
Homepage:http://www.whitecell.org
Date: 2005-11-17
/*++ Author: Polymorphours Date: 2005/1/10 通过对 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 ); } |