summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2017-12-11 16:22:13 +0000
committermidipix <writeonce@midipix.org>2017-12-11 16:10:29 -0500
commit1f892c11f4e92ea57654a5d70bd7fd5535e5a386 (patch)
treef3ca58cff65c08c3146f3cd6d9660462106b3dd1
parent8e91ccf95ec9e12b1743cf0746c53b93557cdd48 (diff)
downloadntapi-1f892c11f4e92ea57654a5d70bd7fd5535e5a386.tar.bz2
ntapi-1f892c11f4e92ea57654a5d70bd7fd5535e5a386.tar.xz
__ntapi_ldr_load_system_dll(): support 'downlevel' with greater compassion.
-rw-r--r--src/ldr/ntapi_ldr_load_system_dll.c94
1 files changed, 60 insertions, 34 deletions
diff --git a/src/ldr/ntapi_ldr_load_system_dll.c b/src/ldr/ntapi_ldr_load_system_dll.c
index 9106395..d0f3771 100644
--- a/src/ldr/ntapi_ldr_load_system_dll.c
+++ b/src/ldr/ntapi_ldr_load_system_dll.c
@@ -17,21 +17,23 @@ int32_t __stdcall __ntapi_ldr_load_system_dll(
__out void ** image_base)
{
int32_t status;
+ void * hkernel32;
wchar16_t * wch;
+ wchar16_t * cap;
wchar16_t * sysdir;
nt_unicode_string nt_sysdir;
nt_unicode_string nt_image_name;
- uintptr_t buffer[0x80];
+ size_t buffer[0x200/sizeof(size_t)];
+ void * (*load_library_ex_utf16)(
+ wchar16_t *,
+ void *,
+ uint32_t);
(void)image_flags;
- /* stack buffer */
- __ntapi->tt_aligned_block_memset(
- buffer,0,sizeof(buffer));
-
+ /* shell-style dos path */
sysdir = (wchar16_t *)buffer;
- /* shell-style dos path */
if ((status = __ntapi->tt_get_system_directory_dos_path(
hsysdir,
sysdir,sizeof(buffer),
@@ -45,40 +47,64 @@ int32_t __stdcall __ntapi_ldr_load_system_dll(
nt_image_name.maxlen = base_name_size;
nt_image_name.buffer = base_name;
+ /* the logical way */
status = __ntapi->ldr_load_dll(
sysdir,0,
&nt_image_name,
image_base);
- switch (status) {
- case NT_STATUS_DLL_NOT_FOUND:
- break;
+ /* eight point one big sigh support */
+ if (status) {
+ cap = &sysdir[sizeof(buffer)/sizeof(wchar16_t)];
+
+ for (wch=sysdir; *wch; wch++)
+ (void)0;
+
+ if (&wch[base_name_size/sizeof(wchar16_t)] >= cap)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ if (!(hkernel32 = pe_get_kernel32_module_handle()))
+ return NT_STATUS_INTERNAL_ERROR;
+
+ if (!(load_library_ex_utf16 = pe_get_procedure_address(
+ hkernel32,"LoadLibraryExW")))
+ return NT_STATUS_INTERNAL_ERROR;
+
+ __ntapi->tt_memcpy_utf16(
+ wch,base_name,
+ base_name_size);
+
+ wch[base_name_size/sizeof(wchar16_t)] = 0;
- default:
- return status;
+ if ((*image_base = load_library_ex_utf16(sysdir,0,0)))
+ status = NT_STATUS_SUCCESS;
}
- /* downlevel */
- for (wch=sysdir; *wch; wch++)
- (void)0;
-
- if (&wch[10] > &sysdir[sizeof(buffer)/sizeof(wchar16_t)])
- return NT_STATUS_BUFFER_TOO_SMALL;
-
- *wch++ = 'd';
- *wch++ = 'o';
- *wch++ = 'w';
- *wch++ = 'n';
- *wch++ = 'l';
- *wch++ = 'e';
- *wch++ = 'v';
- *wch++ = 'e';
- *wch++ = 'l';
- *wch++ = '\\';
- *wch++ = 0;
-
- return __ntapi->ldr_load_dll(
- sysdir,0,
- &nt_image_name,
- image_base);
+ /* downlevel... */
+ if (status) {
+ if (&wch[base_name_size/sizeof(wchar16_t)] >= &cap[-10])
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ *wch++ = 'd';
+ *wch++ = 'o';
+ *wch++ = 'w';
+ *wch++ = 'n';
+ *wch++ = 'l';
+ *wch++ = 'e';
+ *wch++ = 'v';
+ *wch++ = 'e';
+ *wch++ = 'l';
+ *wch++ = '\\';
+
+ __ntapi->tt_memcpy_utf16(
+ wch,base_name,
+ base_name_size);
+
+ wch[base_name_size/sizeof(wchar16_t)] = 0;
+
+ if ((*image_base = load_library_ex_utf16(sysdir,0,0)))
+ status = NT_STATUS_SUCCESS;
+ }
+
+ return status;
}