punkbuster blackscreenshot!
Hey all,
Punkbuster have changed their screenshot routine a few months back (I think), they are no longer using GetForegroundWindow() so the older methods don't work. To fix this, I hook the api function GetWindowThreadProcessId by modifing the IAT of the PBCL module and redirecting the function to our own. Then, we return null to get a blank. Tested on COD2/COD4, worked fine. Code below:
Code:
#include <windows.h>
#include <stdio.h>
// credits to osGB writers / temp2 for highlighting the func
DWORD xx IATHook(charxx DllWhichImports, charxx DllImportsFrom, charxx OldFunctionName)
{
DWORD dwIndex;
DWORD dwOffset;
HMODULE hDllWhichImports;
PIMAGE_DATA_DIRECTORY pDataDirectory;
PIMAGE_DOS_HEADER pDosHeader;
PDWORD pdwIAT;
PDWORD pdwINT;
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor;
PIMAGE_IMPORT_BY_NAME pImportName;
PIMAGE_OPTIONAL_HEADER pOptionalHeader;
PIMAGE_NT_HEADERS pPeHeader;
PSTR strCurrent;
hDllWhichImports = GetModuleHandleA(DllWhichImports);
if(!hDllWhichImports) return NULL;
pDosHeader = PIMAGE_DOS_HEADER(hDllWhichImports);
dwOffset = pDosHeader->e_lfanew;
pPeHeader = PIMAGE_NT_HEADERS(long(hDllWhichImports) + dwOffset);
pOptionalHeader = &pPeHeader->OptionalHeader;
pDataDirectory = pOptionalHeader->DataDirectory;
dwOffset = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
pImportDescriptor = PIMAGE_IMPORT_DESCRIPTOR(long(hDllWhichImports) + dwOffset);
for(dwIndex = 0; true; dwIndex++)
{
dwOffset = pImportDescriptor[dwIndex].Name;
if (!dwOffset) return NULL;
strCurrent = PSTR(long(hDllWhichImports) + dwOffset);
if(stricmp(strCurrent, DllImportsFrom) == 0) break;
}
dwOffset = pImportDescriptor[dwIndex].FirstThunk;
pdwIAT = PDWORD(long(hDllWhichImports) + dwOffset);
dwOffset = pImportDescriptor[dwIndex].OriginalFirstThunk;
pdwINT = PDWORD(long(hDllWhichImports) + dwOffset);
for(dwIndex = 0; true; dwIndex++)
{
dwOffset = pdwINT[dwIndex];
if (!dwOffset) return NULL;
pImportName = PIMAGE_IMPORT_BY_NAME(long(hDllWhichImports) + dwOffset);
strCurrent = PSTR(pImportName->Name);
if(stricmp(strCurrent, OldFunctionName) == 0)
{
return &pdwIAT[dwIndex];
}
}
return NULL;
}
/xx Our cloned func, we direct the calls to this and return null for blankies xx/
DWORD MyGetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId)
{
return NULL;
}
/xx DLL Main, Hook is performed here... xx/
BOOL APIENTRY DllMain(HMODULE hDll, DWORD dwReason, PVOID lpReserved)
{
if(dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hDll);
DWORD dwBackup;
DWORD dwOffset;
DWORD xxdwAddress = IATHook("pbcl.dll", "user32.dll", "GetWindowThreadProcessId");
if (dwAddress)
{
VirtualProtect(dwAddress, sizeof(DWORD), PAGE_READWRITE, &dwBackup);
xxdwAddress = PtrToUlong((DWORD)&MyGetWindowThreadProcessId);
VirtualProtect(dwAddress, sizeof(DWORD), dwBackup, &dwOffset);
dwAddress = NULL;
}
}
return 0x1;
}
Mine works too.
Did it a bit differently.. i dont really wanna post the source for it.. kinda working on a full-on Bonafide PB Bypass.
I'll probably make my Bypass Public when im finished..
What i did in mine, is basically just NOP'd the screenshot process.
But Great post, and thank's for sharing.
Edit: I'm also quite fond of just Hooking the process.
hey people could you please teach me how to use that code?
idk where to put it please
Look At The Date Guy ^^^^