diff options
author | midipix <writeonce@midipix.org> | 2017-12-11 16:22:13 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2017-12-11 16:10:29 -0500 |
commit | 1f892c11f4e92ea57654a5d70bd7fd5535e5a386 (patch) | |
tree | f3ca58cff65c08c3146f3cd6d9660462106b3dd1 | |
parent | 8e91ccf95ec9e12b1743cf0746c53b93557cdd48 (diff) | |
download | ntapi-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.c | 94 |
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; } |