/trunk/main.c |
---|
118,6 → 118,21 |
return xstrlen(out); |
} |
void CALLBACK FakeRundll32(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { |
char* tmp; |
simplealert(TEXT("You tried to execute this method with RunDLL32. This is a Photoshop plugin!")); |
tmp = (char*)malloc(512); |
if (tmp != 0) { |
sprintf(tmp, "hwnd: %p\nhinst: %p\nlpszCmdLine: %s\nCmdShow: %d", (void*)(hwnd), (void*)(hinst), lpszCmdLine, nCmdShow); |
MessageBoxA(0, tmp, 0, 0); |
free(tmp); |
} |
return; |
} |
DLLEXPORT MACPASCAL |
void ENTRYPOINT(short selector, FilterRecordPtr pb, intptr_t *data, short *result){ |
static Boolean wantdialog = false; |
142,13 → 157,18 |
EnterCodeResource(); |
#ifdef WIN_ENV |
// The first 64KB of address space is always invalid |
if ((intptr_t)result <= 0xffff) { |
if ((intptr_t)result == SW_SHOWDEFAULT) { |
// When the 8BF file is analyzed with VirusTotal.com, it will invoke each |
// exported function by calling |
// C:\Windows\System32\rundll32.exe rundll32.exe FilterFoundry.8bf,PluginMain |
// loaddll64.exe 'C:\Users\user\Desktop\attachment.dll' |
// ==> rundll32.exe C:\Users\user\Desktop\attachment.dll,PluginMain |
// ==> C:\Windows\system32\WerFault.exe -u -p 6612 -s 480 |
// |
// But RunDLL32 requires following signature: |
// void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow); |
// void __stdcall EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow); |
// Our signature is: |
// void PluginMain(short selector, FilterRecordPtr pb, intptr_t *data, short *result); |
// |
// Obviously, this will cause an Exception. (It crashes at *result=e because result is 0xA) |
// Here is the problem: The crash will be handled by WerFault.exe inside the |
// VirusTotal virtual machine. WerFault connects to various servers (9 DNS resolutions!) and does |
159,11 → 179,12 |
// actions, although they have nothing to do with us! |
// See https://www.virustotal.com/gui/file/1f1012c567208186be455b81afc1ee407ae6476c197d633c70cc70929113223a/behavior |
// |
// TODO: Not 100% sure if the calling convention is correct... |
// are we corrupting the stack? At least WER isn't triggered... |
// Commented out DM 27.12.2021: For Win32s at Win3.1, the variable IS less than 0xFFFF ?! |
// TODO: Do we have another way to detect rundll32 abuse? |
// return; |
// TODO: Usually, The first 64KB of address space are always invalid. However, in Win32s (Windows 3.11), the |
// variable "result" is <=0xFFFF ! Let's just hope that it is never 0x000A (SW_SHOWDEFAULT), |
// otherwise we have a problem here! |
// I don't understand why this works! Aren't we __cdecl and rundll expected __stdcall? But why is the parameter order correct and not reversed? |
FakeRundll32((HWND)selector, (HINSTANCE)pb, (LPSTR)data, (int)(intptr_t)result); |
return; |
} |
#endif |
/trunk/slider_win.c |
---|
101,6 → 101,28 |
return DefWindowProc(hwnd, uMsg, wParam, lParam); |
} |
void Win32sFixSuperclassing(HWND hDlg, int destItem, int sourceItem) { |
// Win32s (Win3.11) compatibility fix: Since GetClassInfo(WC_BUTTON) and GetClassInfo(WC_STATIC) won't work, |
// we had replaced the WndProc by a dummy. Now, we find out the real Button and Static WndProcs and give them |
// to our classes, making them the intended superclasses. Messages which have been sent in between were lost, |
// though... |
WNDPROC wndProc; |
#ifdef _WIN64 |
wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, destItem), GWLP_WNDPROC); |
if (wndProc == DummyWndProc) { |
wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, sourceItem), GWLP_WNDPROC); |
SetWindowLongPtr(GetDlgItem(hDlg, destItem), GWLP_WNDPROC, (LONG_PTR)wndProc); |
} |
#else |
wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, destItem), GWL_WNDPROC); |
if (wndProc == DummyWndProc) { |
wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, sourceItem), GWL_WNDPROC); |
SetWindowLongPtr(GetDlgItem(hDlg, destItem), GWL_WNDPROC, (LONG_PTR)wndProc); |
} |
#endif |
} |
Boolean MakeSimpleSubclass(LPCTSTR targetClass, LPCTSTR sourceClass) { |
WNDCLASS clx; |
/trunk/slider_win.h |
---|
34,6 → 34,7 |
// Misc utilities |
Boolean MakeSimpleSubclass(LPCTSTR targetClass, LPCTSTR sourceClass); |
void Win32sFixSuperclassing(HWND hDlg, int destItem, int sourceItem); |
// Init and uninit |
void Slider_Uninit_PluginDll(); |
/trunk/ui_win.c |
---|
232,8 → 232,6 |
extern Boolean doupdates; |
extern Handle preview_handle; |
WNDPROC wndProcStatic, wndProcButton; |
if ((gdata->pluginDllSliderMessageId != 0) && (wMsg == gdata->pluginDllSliderMessageId)) { |
// This is for the PLUGIN.DLL sliders only |
if (doupdates) { |
324,20 → 322,10 |
maindlginit(hDlg); |
// Win32s (Win3.11) compatibility fix: Since GetClassInfo("Button") and GetClassInfo("Static") won't work, |
// we had replaced the WndProc by a dummy. Now, we find out the real Button and Static WndProcs and give them |
// to our classes, making them the intended superclasses. Messages which have been sent in between were lost, |
// though... |
// Win32s (Windows 3.11) compatibility |
Win32sFixSuperclassing(hDlg, PREVIEWITEM, FIRSTCTLLABELITEM); |
for (i=0; i<4; i++) Win32sFixSuperclassing(hDlg, FIRSTICONITEM + i, OPENITEM); |
wndProcStatic = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, FIRSTCTLLABELITEM), GWLP_WNDPROC); |
SetWindowLongPtr(GetDlgItem(hDlg, PREVIEWITEM), GWLP_WNDPROC, (LONG)wndProcStatic); |
wndProcButton = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, OPENITEM), GWLP_WNDPROC); |
SetWindowLongPtr(GetDlgItem(hDlg, FIRSTICONITEM), GWLP_WNDPROC, (LONG)wndProcButton); |
SetWindowLongPtr(GetDlgItem(hDlg, FIRSTICONITEM + 1), GWLP_WNDPROC, (LONG)wndProcButton); |
SetWindowLongPtr(GetDlgItem(hDlg, FIRSTICONITEM + 2), GWLP_WNDPROC, (LONG)wndProcButton); |
SetWindowLongPtr(GetDlgItem(hDlg, FIRSTICONITEM + 3), GWLP_WNDPROC, (LONG)wndProcButton); |
// Some versions of Windows (NT 3.x) won't show the preview if it is calculated here. |
// So we need to put it in a timer. |
// Note that 1 millisecond is enough, even if the window needs longer than 1 millisecond to load. |