Code:
// GDIHook.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <tchar.h>
#include <stdio.h>
#include <Psapi.h>
HMODULE g_hMod;
FILE *fp;
enum statData
{
None = -1,
Players=0,
PlayerPos,
Win_Odds,
Pot_odds
};
bool bPlayer = false;
bool bPatchOn = true;
char g_szString[100] = {0};
class CData
{
public:
CData ()
{
strcpy(szPlayers, " ");
strcpy(szPlayerPos, " ");
strcpy(szWin_Odds, "0%");
strcpy(szPot_odds, "0%");
}
char szPlayers[10];
char szPlayerPos[10];
char szWin_Odds[10];
char szPot_odds[10];
char* GetString();
};
char* CData::GetString()
{
ZeroMemory(g_szString, 100);
if(bPlayer)
{
strcpy(g_szString, "F,");
}
else
{
strcpy(g_szString, "P,");
}
strcat(g_szString, szPlayers);
strcat(g_szString, ",");
strcat(g_szString, szPlayerPos);
strcat(g_szString, ",");
strcat(g_szString, szWin_Odds);
strcat(g_szString, ",");
strcat(g_szString, szPot_odds);
strcat(g_szString, ",\r\n");
return g_szString;
}
static CData g_Data;
///////////////////////////////////////////////////////////////////////
// PutOnClipboard
///////////////////////////////////////////////////////////////////////
BOOL WINAPI PutOnClipboard(char *data)
{
LPTSTR lptstrCopy;
HGLOBAL hglbCopy;
// Open the clipboard, and empty it.
if (!OpenClipboard(NULL))
return FALSE;
// If no data, return
if (strlen(data) == 0)
{
CloseClipboard(); // selection
return FALSE;
}
hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (strlen(data) + 1) * sizeof(TCHAR));
if (hglbCopy == NULL)
{
CloseClipboard();
return FALSE;
}
// Lock the handle and copy the text to the buffer.
lptstrCopy = (char *) GlobalLock(hglbCopy);
strcpy(lptstrCopy, data);
GlobalUnlock(hglbCopy);
// Place the handle on the clipboard.
EmptyClipboard();
SetClipboardData(CF_TEXT, hglbCopy);
CloseClipboard();
return TRUE;
}
///////////////////////////////////////////////////////////////////////
// FilterData
///////////////////////////////////////////////////////////////////////
int FilterData(int x, int y)
{
MessageBox(0, "Checking for info", 0, MB_OK);
if (x == 461 && y == 24)
{
// if(bPlayer)
return Players;
}
else if (x== 563 && y ==24)
{
// if(bPlayer)
return PlayerPos;
}
else if (x >= 440 && x<= 465 && y>60)
{
// if(bPlayer)
return Win_Odds;
}
else if (x >= 518 && x<= 570 && y>60)
{
// if(bPlayer)
return Pot_odds;
}
return None;
}
///////////////////////////////////////////////////////////////////////
// myTextOutW
///////////////////////////////////////////////////////////////////////
BOOL WINAPI myTextOutW(HDC hDC, int x, int y, LPCWSTR str, int len)
{
int iFilter = FilterData(x, y);
if(len >0)
{
char *pstr =(char *)LocalAlloc(LMEM_FIXED, len*2+1);
int len2 =WideCharToMultiByte(CP_ACP, 0, str, len, pstr, len*2, NULL, NULL);
pstr[len2] =0;
if (!strcmp(pstr,"Position:"))
bPlayer = true;
if (!strcmp(pstr,"Group:"))
{
bPlayer = false;
strcpy(g_Data.szPlayers, " ");
strcpy(g_Data.szPlayerPos, " ");
strcpy(g_Data.szPot_odds, "0%");
strcpy(g_Data.szWin_Odds, "0%");
}
switch(iFilter)
{
case Players:
{
strcpy(g_Data.szPlayers, pstr);
}
break;
case PlayerPos:
{
strcpy(g_Data.szPlayerPos, pstr);
}
break;
case Pot_odds:
{
strcpy(g_Data.szPot_odds, pstr);
}
break;
case Win_Odds:
{
strcpy(g_Data.szWin_Odds, pstr);
}
break;
default:;
// nothing
}
// fprintf(fp, "\nmyTextOutW X=%d, Y=%d, String = %s\n", x, y, pstr);
// fflush(fp);
char *szData = g_Data.GetString();
PutOnClipboard(szData);
fprintf(fp, szData);
fflush(fp);
LocalFree(pstr);
}
else
{
switch(iFilter)
{
case Players:
{
strcpy(g_Data.szPlayers, " ");
}
break;
case PlayerPos:
{
strcpy(g_Data.szPlayerPos, " ");
}
break;
case Pot_odds:
{
strcpy(g_Data.szPot_odds, "0%");
}
break;
case Win_Odds:
{
strcpy(g_Data.szWin_Odds, "0%");
}
break;
default:;
// nothing
}
}
return TextOutW(hDC, x, y, str, len);
}
///////////////////////////////////////////////////////////////////////
// patchEAT
///////////////////////////////////////////////////////////////////////
DWORD WINAPI patchEAT(HMODULE hMod, PROC origFunc, PROC newFunc)
{
PIMAGE_DOS_HEADER pDosH;
PIMAGE_NT_HEADERS pNTH;
PIMAGE_EXPORT_DIRECTORY pExportDir;
pDosH = (PIMAGE_DOS_HEADER) hMod;
pNTH = (PIMAGE_NT_HEADERS) ((DWORD) pDosH + (DWORD) pDosH->e_lfanew);
pExportDir = (PIMAGE_EXPORT_DIRECTORY) ((DWORD) pDosH +
(DWORD) (pNTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));
ULONG *arrSymbols = (ULONG *) ((DWORD) pDosH + pExportDir->AddressOfFunctions);
for(unsigned int i = 0; i < pExportDir->NumberOfFunctions; ++i)
{
DWORD *pFuncRVA = (DWORD *) &arrSymbols[i];
DWORD origRVA = (DWORD) origFunc - (DWORD) pDosH;
if(*pFuncRVA == origRVA)
{
MEMORY_BASIC_INFORMATION mbi;
DWORD oldProt;
VirtualQuery(pFuncRVA, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &oldProt);
*pFuncRVA = (DWORD) newFunc - (DWORD) pDosH;
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, oldProt, &oldProt);
break;
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////
// patchIAT
///////////////////////////////////////////////////////////////////////
DWORD WINAPI patchIAT(HMODULE hMod, PROC origFunc, PROC newFunc)
{
PIMAGE_DOS_HEADER pDosH;
PIMAGE_NT_HEADERS pNTH;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
PIMAGE_THUNK_DATA pThunk;
if(!newFunc || !hMod || hMod == g_hMod)
return 0;
// Verify that the newFunc is valid
if(IsBadCodePtr(newFunc))
return 0;
// Get DOS Header
pDosH = (PIMAGE_DOS_HEADER) hMod;
// Verify that the PE is valid by checking e_magic's value and DOS Header size
if(IsBadReadPtr(pDosH, sizeof(IMAGE_DOS_HEADER)))
return 0;
if(pDosH->e_magic != IMAGE_DOS_SIGNATURE)
return 0;
// Find the NT Header by using the offset of e_lfanew value from hMod
pNTH = (PIMAGE_NT_HEADERS) ((DWORD) pDosH + (DWORD) pDosH->e_lfanew);
// Verify that the NT Header is correct
if(IsBadReadPtr(pNTH, sizeof(IMAGE_NT_HEADERS)))
return 0;
if(pNTH->Signature != IMAGE_NT_SIGNATURE)
return 0;
// iat patching
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ((DWORD) pDosH +
(DWORD) (pNTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
if(pImportDesc == (PIMAGE_IMPORT_DESCRIPTOR) pNTH)
return 0;
while(pImportDesc->Name)
{
// pImportDesc->Name gives the name of the module, so we can find "gdi32.dll"
char *name = (char *) ((DWORD) pDosH + (DWORD) (pImportDesc->Name));
// stricmp returns 0 if strings are equal, case insensitive
if(name && _stricmp(name, "gdi32.dll") == 0)
{
pThunk = (PIMAGE_THUNK_DATA)((DWORD) pDosH + (DWORD) pImportDesc->FirstThunk);
while(pThunk && pThunk->u1.Function)
{
// get the pointer of the imported function and see if it matches up with the original
if((DWORD) pThunk->u1.Function == (DWORD) origFunc)
{
//Sleep(250);
MEMORY_BASIC_INFORMATION mbi;
DWORD oldProt;
VirtualQuery(&pThunk->u1.Function, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &oldProt);
//pThunk->u1.Function = (& DWORD) newFunc; //Note that this is the original line
pThunk->u1.Function = (DWORD *) newFunc;
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, oldProt, &oldProt);
break;
}
else
{
++pThunk;
}
}
}
// Sleep(250);
++pImportDesc;
}
return 0;
}
///////////////////////////////////////////////////////////////////////
// setHook
///////////////////////////////////////////////////////////////////////
PROC setHook()
{
fp = fopen("C:\\stats.txt", "w");
HMODULE gdi32 = LoadLibrary("gdi32.dll");
/* initialize all the original functions to be hooked */
FARPROC origTextOutW = GetProcAddress(gdi32, "TextOutW");
HMODULE hMods[1024];
DWORD cbNeeded;
HANDLE hProcess = GetCurrentProcess();
if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
patchEAT(gdi32, (PROC) origTextOutW, (PROC) myTextOutW);
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); ++i)
{
if(hMods[i] != g_hMod && i != 29)
{
patchIAT(hMods[i], (PROC) origTextOutW, (PROC) myTextOutW);
}
}
}
bPatchOn = false;
return 0;
}
///////////////////////////////////////////////////////////////////////
// DllMain
///////////////////////////////////////////////////////////////////////
extern "C" BOOL APIENTRY WINAPI DllMain( HANDLE hInst, DWORD reason, LPVOID lpReserved )
{
switch(reason)
{
case DLL_PROCESS_ATTACH:
{
g_hMod = (HMODULE) hInst;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) setHook, 0, 0, NULL);
}
break;
case DLL_PROCESS_DETACH:
{
fclose(fp);
}
break;
}
return TRUE;
}