Author:?? Polymorphours
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
??? );
}