From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/ntdll/loader.c | 8 +++++++- dlls/ntdll/tests/rtl.c | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index df8324e0b6b..a3de8791498 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1066,6 +1066,7 @@ void * WINAPI RtlFindExportedRoutineByName( HMODULE module, const char *name ) const DWORD *functions; DWORD exp_size; int ordinal; + void *proc;
exports = RtlImageDirectoryEntryToData( module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size ); if (!exports || exp_size < sizeof(*exports)) return NULL; @@ -1074,7 +1075,12 @@ void * WINAPI RtlFindExportedRoutineByName( HMODULE module, const char *name ) if (ordinal >= exports->NumberOfFunctions) return NULL; functions = get_rva( module, exports->AddressOfFunctions ); if (!functions[ordinal]) return NULL; - return get_rva( module, functions[ordinal] ); + proc = get_rva( module, functions[ordinal] ); + /* if the address falls into the export dir, it's a forward */ + if (((const char *)proc >= (const char *)exports) && + ((const char *)proc < (const char *)exports + exp_size)) + return NULL; + return proc; }
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 88f62b0b588..442ad729540 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -95,6 +95,7 @@ static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExW)(PCWSTR, struct in6_addr *, static BOOL (WINAPI *pRtlIsCriticalSectionLocked)(CRITICAL_SECTION *); static BOOL (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION *); static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, ULONG, ULONG); +static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char *); static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *); static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **); static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *); @@ -137,6 +138,7 @@ static void InitFunctionPtrs(void) pRtlIsCriticalSectionLocked = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLocked"); pRtlIsCriticalSectionLockedByThread = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLockedByThread"); pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx"); + pRtlFindExportedRoutineByName = (void *)GetProcAddress(hntdll, "RtlFindExportedRoutineByName"); pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules"); pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification"); pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification"); @@ -3651,6 +3653,21 @@ static void test_RtlValidSecurityDescriptor(void) free(sd); }
+static void test_RtlFindExportedRoutineByName(void) +{ + void *proc; + + if (!pRtlFindExportedRoutineByName) + { + win_skip( "RtlFindExportedRoutineByName is not present\n" ); + return; + } + proc = pRtlFindExportedRoutineByName( GetModuleHandleW( L"kernelbase" ), "CtrlRoutine" ); + ok( proc != NULL, "Expected non NULL address\n" ); + proc = pRtlFindExportedRoutineByName( GetModuleHandleW( L"kernel32" ), "CtrlRoutine" ); + ok( proc == NULL, "Shouldn't find forwarded function\n" ); +} + START_TEST(rtl) { InitFunctionPtrs(); @@ -3697,4 +3714,5 @@ START_TEST(rtl) test_RtlFirstFreeAce(); test_RtlInitializeSid(); test_RtlValidSecurityDescriptor(); + test_RtlFindExportedRoutineByName(); }