• 反ring3 hook demo ,直接从dll文件修复 dll的code段,实现反hook


    // CounterHook.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    
    void showInfo(LPWSTR strInfo)
    {
    	OutputDebugStringW(strInfo);
    }
    
    typedef HANDLE (WINAPI* pfnCreateEvent)(
    	LPSECURITY_ATTRIBUTES lpEventAttributes,
    	BOOL bManualReset,
    	BOOL bInitialState,
    	LPWSTR lpName
    	);
    
    
    
    pfnCreateEvent lpFunCreateEvent ;
    
    
    HANDLE  __declspec(naked) WINAPI MyCreateEvent(
    	LPSECURITY_ATTRIBUTES lpEventAttributes,
    	BOOL bManualReset,
    	BOOL bInitialState,
    	LPWSTR lpName
    	)
    {
    	
    	
    	_asm  
    	{  
    		
    		
    		 mov         edi,edi  
    		 push        ebp  
    		 mov         ebp,esp  
    		 
    		 jmp		 lpFunCreateEvent
    		
    	}  
    	
    }
    
    typedef int (WINAPI* pfnMessageBoxW)(HWND hWnd,LPWSTR lpText,LPWSTR lpCaption,UINT uType);
    pfnMessageBoxW lpMessageBoxW ;
    
    int __declspec(naked) WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
    {
    	_asm{
    			mov         edi,edi  
    			push        ebp  
    			mov         ebp,esp  
    
    			jmp		 lpMessageBoxW
    	}
    }
    
    
    void HookCreateEventW()
    {
    	BYTE NewBytes[5] = {0xe9,0x0,0x0,0x0,0x0};
    	HMODULE h= LoadLibraryW(L"kernel32.dll");
    		
    	lpFunCreateEvent = (pfnCreateEvent) GetProcAddress(h,"CreateEventW");
    
        
    	*(DWORD*)(NewBytes + 1) = (DWORD)MyCreateEvent-(DWORD)lpFunCreateEvent-5;    
    	WriteProcessMemory(INVALID_HANDLE_VALUE,(LPVOID)lpFunCreateEvent,NewBytes,5,NULL);
    	lpFunCreateEvent = (pfnCreateEvent)((LPBYTE)lpFunCreateEvent +5 );
    
    
    }
    void HookMessageBoxW()
    {
    	BYTE NewBytes[5] = {0xe9,0x0,0x0,0x0,0x0};
    	HMODULE h= LoadLibraryW(L"user32.dll");
    
    	lpMessageBoxW = (pfnMessageBoxW) GetProcAddress(h,"MessageBoxW");
    
    
    	*(DWORD*)(NewBytes + 1) = (DWORD)MyMessageBox-(DWORD)lpMessageBoxW-5;    
    	WriteProcessMemory(INVALID_HANDLE_VALUE,(LPVOID)lpMessageBoxW,NewBytes,5,NULL);
    	lpMessageBoxW = (pfnMessageBoxW)((LPBYTE)lpMessageBoxW +5 );
    }
    void CounterHookdll(LPWSTR strDllName)
    {
    	WCHAR wszModuleName[MAX_PATH];
    	DWORD dwZeroMem[64];
    	DWORD dwFileSizeH;
    	DWORD dwFileSizeL;
    	IMAGE_DOS_HEADER* dosHead;
    	IMAGE_NT_HEADERS* peHead;
    	IMAGE_SECTION_HEADER* sections;
    	int sectionCount ;
    	HMODULE h = LoadLibraryW(strDllName);
    	GetModuleFileName(h,wszModuleName,MAX_PATH);
    
    	ZeroMemory(dwZeroMem,sizeof(dwZeroMem));
    
    	HANDLE hFile = CreateFile(wszModuleName,GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_SYSTEM, NULL);
    	DWORD dwError = GetLastError();
    	if (hFile != INVALID_HANDLE_VALUE)
    	{
    		dwFileSizeL = GetFileSize(hFile,&dwFileSizeH);
    
    
    		HANDLE hMap = CreateFileMappingW(hFile,NULL,PAGE_READONLY|SEC_IMAGE,dwFileSizeH,dwFileSizeL,NULL);
    
    		DWORD dwError = GetLastError();
    		if (hMap!= NULL)
    		{
    			LPVOID lpBuffer =MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
    
    			//lpBuffer = h ;
    			
    			
    			if ((*(LPWORD)lpBuffer) == 0x5a4d/* && ((LPBYTE)lpBuffer+ (*(LPDWORD)((LPBYTE)lpBuffer+0x3c))==0x4550*/)
    			{
    				// 				DWORD dwOffset = *(LPDWORD)((LPBYTE)lpBuffer+0x3c);
    				// 				if (*(LPWORD)((LPBYTE)lpBuffer+dwOffset) == 0x4550)
    				// 				{
    				// 					
    				// 				}
    				dosHead = (IMAGE_DOS_HEADER*)lpBuffer;
    				peHead = (IMAGE_NT_HEADERS*)((LPBYTE)lpBuffer+dosHead->e_lfanew);
    
    				sectionCount = peHead->FileHeader.NumberOfSections;
    				sections = (IMAGE_SECTION_HEADER*)((LPBYTE)peHead+sizeof(IMAGE_NT_HEADERS));
    				for (int i=0;i<sectionCount;i++)
    				{
    					//printf((char*)((sections+i)->Name));
    
    					if ((sections+i)->Name[1]=='t')
    					{
    						DWORD dwWriteStart ,dwWriteEnd ;
    						DWORD dwCodeSize = (sections+i)->SizeOfRawData ;
    						DWORD dwVirtualAddress =  (sections+i)->VirtualAddress ;
    
    						LPBYTE lpCodeAddr = (LPBYTE)lpBuffer+dwVirtualAddress ;
    						int j = 0;
    						for ( ;j<dwCodeSize;j++)
    						{
    							// find first WINAPI 
    							if(*(LPDWORD)(lpCodeAddr+j) ==0x8b55ff8b)
    							{
    								
    								dwWriteStart = j ;
    
    								for(int e=dwWriteStart;e<dwCodeSize;e++ )
    								{
    // 									if (*(LPDWORD)(lpCodeAddr+e) == 0 && *(LPDWORD)(lpCodeAddr+e+16)==0)
    // 									{
    // 										dwWriteEnd = e ;
    // 									}
    									if (memcmp(lpCodeAddr+e,dwZeroMem,sizeof(dwZeroMem))==0)
    									{
    										dwWriteEnd = e ;
    										break;
    									}
    								}
    								//dwCodeSize +=5;
    								DWORD dwOldAtr=0;
    								DWORD dwMem,dwMem2 ;
    								dwMem = (DWORD)h+dwVirtualAddress+dwWriteStart;
    								dwMem2 = (DWORD)((LPBYTE)lpCodeAddr+dwWriteStart );
    					
    								if(WriteProcessMemory(INVALID_HANDLE_VALUE,(LPVOID)dwMem,(LPVOID)dwMem2,dwWriteEnd-dwWriteStart,NULL))
    								{
    									printf(" WriteMemory OK");
    								}else
    								{
    									printf(" WriteMemory Failed");
    								}
    								return ;
    
    							}
    						}
    
    
    					}
    
    				}
    
    			}
    		}
    
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HANDLE hEvent ;
    	HookCreateEventW();
    	CounterHookdll(L"kernel32.dll");
    	hEvent = CreateEventW(NULL,FALSE,FALSE,L"Good");
    	printf("hEvent= 0x%08x",hEvent);
    	HookMessageBoxW();
    	CounterHookdll(L"user32.dll");
    	MessageBoxW(NULL,L"GOOD",L"Good",0);
    	getchar();
    	return 0;
    }
    

      

    今天对CounterHookdll 进行了兼容性改进:

    1. 对写入地址end的获取进行了优化改进

    2. 增加hash计算,判断写入是否成功

    3. 发现被inlinehook的dll

    增加些打印信息

    void CounterHookdll(LPWSTR strDllName)
    {
        WCHAR wszModuleName[MAX_PATH];
        
        DWORD dwZeroMem[4];
        DWORD dwFileSizeH;
        DWORD dwFileSizeL;
        IMAGE_DOS_HEADER* dosHead;
        IMAGE_NT_HEADERS* peHead;
        IMAGE_SECTION_HEADER* sections;
        int sectionCount ;
        HMODULE h = LoadLibraryW(strDllName);
        if (h == INVALID_HANDLE_VALUE)
        {
            return ;
        }
        GetModuleFileName(h,wszModuleName,MAX_PATH);
        printf("
    
    %S
    ",wszModuleName);
        ZeroMemory(dwZeroMem,sizeof(dwZeroMem));
    
        HANDLE hFile = CreateFile(wszModuleName,GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_SYSTEM, NULL);
        DWORD dwError = GetLastError();
        if (hFile != INVALID_HANDLE_VALUE)
        {
            dwFileSizeL = GetFileSize(hFile,&dwFileSizeH);
    
            wsprintf(wszModuleName,L"names%d",rand());
            printf("map-name %S
    ",wszModuleName);
            HANDLE hMap = CreateFileMappingW(hFile,NULL,PAGE_READONLY|SEC_IMAGE,dwFileSizeH,dwFileSizeL,wszModuleName);
    
            DWORD dwError = GetLastError();
            if (hMap!= NULL)
            {
                LPVOID lpBuffer =MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
    
                //lpBuffer = h ;
                
                
                if ((*(LPWORD)lpBuffer) == 0x5a4d/* && ((LPBYTE)lpBuffer+ (*(LPDWORD)((LPBYTE)lpBuffer+0x3c))==0x4550*/)
                {
                    //                 DWORD dwOffset = *(LPDWORD)((LPBYTE)lpBuffer+0x3c);
                    //                 if (*(LPWORD)((LPBYTE)lpBuffer+dwOffset) == 0x4550)
                    //                 {
                    //                     
                    //                 }
                    dosHead = (IMAGE_DOS_HEADER*)lpBuffer;
                    peHead = (IMAGE_NT_HEADERS*)((LPBYTE)lpBuffer+dosHead->e_lfanew);
    
                    sectionCount = peHead->FileHeader.NumberOfSections;
                    sections = (IMAGE_SECTION_HEADER*)((LPBYTE)peHead+sizeof(IMAGE_NT_HEADERS));
                    for (int i=0;i<sectionCount;i++)
                    {
                        printf((char*)((sections+i)->Name));
    
                        if ((sections+i)->Name[1]=='t')
                        {
                            DWORD dwWriteStart ,dwWriteEnd ;
                            DWORD dwCodeSize = (sections+i)->SizeOfRawData ;
                            DWORD dwVirtualAddress =  (sections+i)->VirtualAddress ;
    
                            LPBYTE lpCodeAddr = (LPBYTE)lpBuffer+dwVirtualAddress ;
                            int j = 0;
                            for ( ;j<dwCodeSize;j++)
                            {
                                // find first WINAPI 
                                if(*(LPDWORD)(lpCodeAddr+j) ==0x8b55ff8b)
                                {
                                    printf("find first WINAPI 
    ");
                                    dwWriteStart = j ;
    
                                    for(int e=dwCodeSize;e > dwWriteStart; )
                                    {
    //                                     if (*(LPDWORD)(lpCodeAddr+e) == 0 && *(LPDWORD)(lpCodeAddr+e+16)==0)
    //                                     {
    //                                         dwWriteEnd = e ;
    //                                     }
                                        if (!IsBadReadPtr( lpCodeAddr+e,sizeof(dwZeroMem)) && memcmp(lpCodeAddr+e,dwZeroMem,sizeof(dwZeroMem))==0)
                                        {
                                            printf("find End  
    ");
                                            dwWriteEnd = e ;
                                            break;
                                        }
    
                                        e-=sizeof(dwZeroMem);
                                    }
    
    
                                    //dwCodeSize +=5;
                                    DWORD dwOldAtr=0;
                                    DWORD dwMem,dwMem2,dwHHash,dwFileHash ,dwMemSize;
                                    dwMem = (DWORD)h+dwVirtualAddress+dwWriteStart;
                                    dwMem2 = (DWORD)((LPBYTE)lpCodeAddr+dwWriteStart );
    
                                    dwMemSize = dwWriteEnd-dwWriteStart;
    
                                    dwHHash = CalcHash((LPBYTE)dwMem,dwMemSize);
                                    dwFileHash = CalcHash((LPBYTE)dwMem2,dwMemSize);
                                    printf("MODULE hash %d  FILE hash %d 
    ",dwHHash,dwFileHash);
                                    if (dwHHash!= dwFileHash)
                                    {
                                        printf("XXXXXXXXXXXX find inline hook **************** 
    ");
                                    }
    
                                    printf("Will WriteMemory Size %d 
    ",dwMemSize);
    
                                    if(WriteProcessMemory(INVALID_HANDLE_VALUE,(LPVOID)dwMem,(LPVOID)dwMem2,dwWriteEnd-dwWriteStart,NULL))
                                    {
                                        dwHHash = CalcHash((LPBYTE)dwMem,dwMemSize);
                                        if (dwHHash != dwFileHash)
                                        {
                                            printf("WriteMemory OK but hash is incorrect!");
                                        }
                                        printf(" WriteMemory OK
    ");
                                    }else
                                    {
                                        printf(" WriteMemory Failed
    ");
                                    }
                                    break;
    
                                }
                                
                            }
                            break;
    
                        }
    
                    }
                    //UnmapViewOfFile(lpBuffer);
                }
            }
            CloseHandle(hFile);
        }
    }
  • 相关阅读:
    javaee后台适合用的编辑器插件
    昨天做了一个使用javamail发送文件的demo
    jsp页面可以巧用模态框
    jQuery 表单验证插件——Validation(基础)
    jsp引入struts标签,引入自己写的jquery需要注意的问题
    LeetCode的神坑
    Java函数结束时的内存回收坑
    递归与回溯1
    由树的定义和递归想到的
    复杂一点的二叉树递归
  • 原文地址:https://www.cnblogs.com/M4ster/p/counter_hook.html
Copyright © 2020-2023  润新知