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