反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("\r\n\r\n%S\r\n",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\r\n",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 \r\n");
                                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  \r\n");
                                        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 \r\n",dwHHash,dwFileHash);
                                if (dwHHash!= dwFileHash)
                                {
                                    printf("XXXXXXXXXXXX find inline hook **************** \r\n");
                                }

                                printf("Will WriteMemory Size %d \r\n",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\r\n");
                                }else
                                {
                                    printf(" WriteMemory Failed\r\n");
                                }
                                break;

                            }
                            
                        }
                        break;

                    }

                }
                //UnmapViewOfFile(lpBuffer);
            }
        }
        CloseHandle(hFile);
    }
}

 

posted @ 2017-03-19 10:23  m4sterx  阅读(405)  评论(0编辑  收藏  举报