/********************************************************/ /* ntapi: Native API core library */ /* Copyright (C) 2013--2017 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ /********************************************************/ #include #include #include #include "ntapi_impl.h" int32_t __stdcall __ntapi_ldr_load_system_dll( __in void * hsysdir __optional, __in wchar16_t * base_name, __in uint16_t base_name_size, __in uint32_t * image_flags __optional, __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; size_t buffer[0x200/sizeof(size_t)]; void * (*load_library_ex_utf16)( wchar16_t *, void *, uint32_t); (void)image_flags; /* shell-style dos path */ sysdir = (wchar16_t *)buffer; if ((status = __ntapi->tt_get_system_directory_dos_path( hsysdir, sysdir,sizeof(buffer), 0,0,&nt_sysdir))) return status; sysdir = &sysdir[4]; /* image */ nt_image_name.strlen = base_name_size; 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); /* 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; if ((*image_base = load_library_ex_utf16(sysdir,0,0))) status = NT_STATUS_SUCCESS; } /* 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; }