信息来源:whitecell
文章作者:Polymorphours
---------------------

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
                 );
}


Whitecell Security Systems,一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
Whitecell Website:http://www.whitecell.org/
Whitecell Forum:http://www.whitecell.org/forum/