反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); } }
签名档:
从事网络安全和编程的我,很希望能找到志同道合的朋友交流。
欢迎cn博客的好友拍砖,留言。