UCRT64 ~/Desktop $ cat delay_user32.d cat: delay_user32.d: No such file or directory
UCRT64 ~/Desktop $ cat delay_user32.def LIBRARY "USER32.DLL" EXPORTS MessageBoxW UCRT64 ~/Desktop $ cat test.c #include <stdio.h> #include <windows.h> extern void** __imp_MessageBoxW; int main(void) { fprintf(stderr, "main 1: __imp_MessageBoxW = %p\n", *__imp_MessageBoxW); MessageBoxW(NULL, L"test message", NULL, MB_ICONINFORMATION | MB_YESNO); fprintf(stderr, "main 2: __imp_MessageBoxW = %p\n", *__imp_MessageBoxW); } UCRT64 ~/Desktop $ dlltool -d delay_user32.def -y delay_user32.dll.a UCRT64 ~/Desktop $ gcc -Wall -Wextra test.c delay_user32.dll.a UCRT64 ~/Desktop $ ./a.exe main 1: __imp_MessageBoxW = E900008F0B058D48 main 2: __imp_MessageBoxW = 44DB334538EC8348 -- Best regards, LIU Hao
From e6fdf91f3d965ccd7491a02db929a1def4f5c0a8 Mon Sep 17 00:00:00 2001 From: LIU Hao <lh_mo...@126.com> Date: Tue, 11 Feb 2025 10:34:14 +0800 Subject: [PATCH] crt/delayimp: Make IAT temporarily writeable before modifying it Since Binutils 2.44, the import address table (abbr. IAT) is now read-only, in alignment with Microsoft LINK and LLD. It is now required to make the IAT writeable before modifying it. Similar code exists in Microsoft delayhlp.cpp. Reference: https://devblogs.microsoft.com/oldnewthing/20221006-07/?p=107257 Reference: https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=db00f6c3aceabbf03acdb69e74b59b2d2b043cd7 Reference: https://bugs.winehq.org/show_bug.cgi?id=57819 Reference: https://sourceware.org/bugzilla/show_bug.cgi?id=32675 Signed-off-by: LIU Hao <lh_mo...@126.com> --- mingw-w64-crt/misc/delayimp.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/mingw-w64-crt/misc/delayimp.c b/mingw-w64-crt/misc/delayimp.c index caa6166f0..6ced2d327 100644 --- a/mingw-w64-crt/misc/delayimp.c +++ b/mingw-w64-crt/misc/delayimp.c @@ -131,6 +131,9 @@ static int WINAPI FLoadedAtPreferredAddress(PIMAGE_NT_HEADERS pinh,HMODULE hmod) /*typedef unsigned long *PULONG_PTR;*/ #endif +/* Ideally this should be an SRWLOCK, but it would require Vista. */ +static volatile LONG gDelayLoadLock = 0; + FARPROC WINAPI __delayLoadHelper2(PCImgDelayDescr pidd,FARPROC *ppfnIATEntry); FARPROC WINAPI __delayLoadHelper2(PCImgDelayDescr pidd,FARPROC *ppfnIATEntry) @@ -147,7 +150,9 @@ FARPROC WINAPI __delayLoadHelper2(PCImgDelayDescr pidd,FARPROC *ppfnIATEntry) unsigned iIAT, iINT; PCImgThunkData pitd; FARPROC pfnRet; - + DWORD dwOldProtect; + WINBOOL bUnprotected; + if(!(idd.grAttrs & dlattrRva)) { PDelayLoadInfo rgpdli[1] = { &dli}; RaiseException(VcppException(ERROR_SEVERITY_ERROR,ERROR_INVALID_PARAMETER),0,1,(PULONG_PTR)(rgpdli)); @@ -217,7 +222,13 @@ FARPROC WINAPI __delayLoadHelper2(PCImgDelayDescr pidd,FARPROC *ppfnIATEntry) } } SetEntryHookBypass: + while(InterlockedExchange(&gDelayLoadLock, 1) != 0) + Sleep(100); + bUnprotected = VirtualProtect(ppfnIATEntry, sizeof(FARPROC), PAGE_READWRITE, &dwOldProtect); *ppfnIATEntry = pfnRet; + if(bUnprotected && dwOldProtect != PAGE_READWRITE) + VirtualProtect(ppfnIATEntry, sizeof(FARPROC), dwOldProtect, &dwOldProtect); + InterlockedExchange(&gDelayLoadLock, 0); HookBypass: if(__pfnDliNotifyHook2) { dli.dwLastError = 0; -- 2.48.1
OpenPGP_signature.asc
Description: OpenPGP digital signature
_______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public