diff options
Diffstat (limited to 'src/ldso')
-rw-r--r-- | src/ldso/pe_open_image_from_addr.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/src/ldso/pe_open_image_from_addr.c b/src/ldso/pe_open_image_from_addr.c index b8a1845..e241fac 100644 --- a/src/ldso/pe_open_image_from_addr.c +++ b/src/ldso/pe_open_image_from_addr.c @@ -9,11 +9,6 @@ #include <pemagine/pe_structs.h> #include "pe_os.h" -struct os_memory_section_name { - struct pe_unicode_str section_name; - wchar16_t section_name_buffer[]; -}; - pe_api int32_t pe_open_image_from_addr( __out void ** himage, __in void * addr, @@ -24,47 +19,61 @@ pe_api int32_t pe_open_image_from_addr( __in uint32_t share_access, __in uint32_t open_options) { - int32_t status; struct os_oa oa; struct os_iosb iosb; - struct os_memory_section_name * path; - uint32_t len; void * hntdll; - os_zw_query_virtual_memory * zw_query_virtual_memory; os_zw_open_file * zw_open_file; - + struct pe_unicode_str path; + struct pe_ldr_tbl_entry * lentry; + wchar16_t * name; + wchar16_t * cap; + wchar16_t * src; + wchar16_t * dst; + wchar16_t * mark; /* init */ - path = (struct os_memory_section_name *)buffer; - path->section_name.strlen = 0; - path->section_name.maxlen = (uint16_t)(bufsize - sizeof(struct pe_unicode_str)); - path->section_name.buffer = path->section_name_buffer; - if (!(hntdll = pe_get_ntdll_module_handle())) return OS_STATUS_INTERNAL_ERROR; - if (!(zw_query_virtual_memory = (os_zw_query_virtual_memory *)pe_get_procedure_address( - hntdll,"ZwQueryVirtualMemory"))) - return OS_STATUS_INTERNAL_ERROR; - if (!(zw_open_file = (os_zw_open_file *)pe_get_procedure_address( hntdll,"ZwOpenFile"))) return OS_STATUS_INTERNAL_ERROR; /* native path of image containing addr */ - if ((status = zw_query_virtual_memory( - OS_CURRENT_PROCESS_HANDLE, - addr, - OS_MEMORY_SECTION_NAME, - buffer, - bufsize, - &len))) - return status; + if (!(lentry = pe_get_ldr_entry_from_addr(addr))) + return OS_STATUS_INTERNAL_ERROR; + + if (bufsize - 4*sizeof(wchar16_t) < lentry->full_dll_name.strlen) + return OS_STATUS_BUFFER_TOO_SMALL; + + name = lentry->full_dll_name.buffer; + mark = (wchar16_t *)buffer; + dst = mark; + + if (name[1] == ':') { + *dst++ = '\\'; + *dst++ = '?'; + *dst++ = '?'; + *dst++ = '\\'; + } + + src = name; + dst = mark; + cap = &dst[lentry->full_dll_name.strlen / sizeof(wchar16_t)]; + + for (; dst<cap; ) + *dst++ = *src++; + + *dst = 0; + + path.strlen = sizeof(wchar16_t) * (cap - mark); + path.maxlen = 0; + path.buffer = mark; /* oa */ oa.len = sizeof(struct os_oa); oa.root_dir = 0; - oa.obj_name = &path->section_name; + oa.obj_name = &path; oa.obj_attr = oattr; oa.sec_desc = 0; oa.sec_qos = 0; |