|
|
6d58d9 |
/*****************************************************************************/
|
|
|
6d58d9 |
/* pemagination: a (virtual) tour into portable bits and executable bytes */
|
|
|
6d58d9 |
/* Copyright (C) 2013--2017 Z. Gilboa */
|
|
|
6d58d9 |
/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */
|
|
|
6d58d9 |
/*****************************************************************************/
|
|
|
6d58d9 |
|
|
|
6d58d9 |
#include <psxtypes/psxtypes.h>
|
|
|
6d58d9 |
#include <pemagine/pemagine.h>
|
|
|
6d58d9 |
#include <pemagine/pe_structs.h>
|
|
|
6d58d9 |
#include "pe_os.h"
|
|
|
6d58d9 |
|
|
|
6d58d9 |
pe_api int32_t pe_open_image_from_addr(
|
|
|
6d58d9 |
__out void ** himage,
|
|
|
6d58d9 |
__in void * addr,
|
|
|
6d58d9 |
__out uintptr_t * buffer,
|
|
|
29ad40 |
__in size_t bufsize,
|
|
|
9d2131 |
__in uint32_t oattr,
|
|
|
6d58d9 |
__in uint32_t desired_access,
|
|
|
9d2131 |
__in uint32_t share_access,
|
|
|
6d58d9 |
__in uint32_t open_options)
|
|
|
6d58d9 |
{
|
|
|
6d58d9 |
struct os_oa oa;
|
|
|
6d58d9 |
struct os_iosb iosb;
|
|
|
6d58d9 |
void * hntdll;
|
|
|
6d58d9 |
os_zw_open_file * zw_open_file;
|
|
|
0cc26d |
struct pe_unicode_str path;
|
|
|
0cc26d |
struct pe_ldr_tbl_entry * lentry;
|
|
|
0cc26d |
wchar16_t * name;
|
|
|
0cc26d |
wchar16_t * cap;
|
|
|
0cc26d |
wchar16_t * src;
|
|
|
0cc26d |
wchar16_t * dst;
|
|
|
0cc26d |
wchar16_t * mark;
|
|
|
6d58d9 |
|
|
|
6d58d9 |
/* init */
|
|
|
6d58d9 |
if (!(hntdll = pe_get_ntdll_module_handle()))
|
|
|
6d58d9 |
return OS_STATUS_INTERNAL_ERROR;
|
|
|
6d58d9 |
|
|
|
6d58d9 |
if (!(zw_open_file = (os_zw_open_file *)pe_get_procedure_address(
|
|
|
6d58d9 |
hntdll,"ZwOpenFile")))
|
|
|
6d58d9 |
return OS_STATUS_INTERNAL_ERROR;
|
|
|
6d58d9 |
|
|
|
6d58d9 |
/* native path of image containing addr */
|
|
|
0cc26d |
if (!(lentry = pe_get_ldr_entry_from_addr(addr)))
|
|
|
0cc26d |
return OS_STATUS_INTERNAL_ERROR;
|
|
|
0cc26d |
|
|
|
0cc26d |
if (bufsize - 4*sizeof(wchar16_t) < lentry->full_dll_name.strlen)
|
|
|
0cc26d |
return OS_STATUS_BUFFER_TOO_SMALL;
|
|
|
0cc26d |
|
|
|
0cc26d |
name = lentry->full_dll_name.buffer;
|
|
|
0cc26d |
mark = (wchar16_t *)buffer;
|
|
|
0cc26d |
dst = mark;
|
|
|
0cc26d |
|
|
|
0cc26d |
if (name[1] == ':') {
|
|
|
0cc26d |
*dst++ = '\\';
|
|
|
0cc26d |
*dst++ = '?';
|
|
|
0cc26d |
*dst++ = '?';
|
|
|
0cc26d |
*dst++ = '\\';
|
|
|
0cc26d |
}
|
|
|
0cc26d |
|
|
|
0cc26d |
src = name;
|
|
|
0cc26d |
cap = &dst[lentry->full_dll_name.strlen / sizeof(wchar16_t)];
|
|
|
0cc26d |
|
|
|
0cc26d |
for (; dst
|
|
|
0cc26d |
*dst++ = *src++;
|
|
|
0cc26d |
|
|
|
0cc26d |
*dst = 0;
|
|
|
0cc26d |
|
|
|
0cc26d |
path.strlen = sizeof(wchar16_t) * (cap - mark);
|
|
|
0cc26d |
path.maxlen = 0;
|
|
|
0cc26d |
path.buffer = mark;
|
|
|
6d58d9 |
|
|
|
6d58d9 |
/* oa */
|
|
|
6d58d9 |
oa.len = sizeof(struct os_oa);
|
|
|
6d58d9 |
oa.root_dir = 0;
|
|
|
0cc26d |
oa.obj_name = &pat;;
|
|
|
9d2131 |
oa.obj_attr = oattr;
|
|
|
6d58d9 |
oa.sec_desc = 0;
|
|
|
6d58d9 |
oa.sec_qos = 0;
|
|
|
6d58d9 |
|
|
|
6d58d9 |
/* default access */
|
|
|
6d58d9 |
desired_access = desired_access
|
|
|
6d58d9 |
? desired_access
|
|
|
6d58d9 |
: OS_SEC_SYNCHRONIZE | OS_FILE_READ_ATTRIBUTES | OS_FILE_READ_ACCESS;
|
|
|
6d58d9 |
|
|
|
6d58d9 |
/* open image */
|
|
|
6d58d9 |
return zw_open_file(
|
|
|
6d58d9 |
himage,
|
|
|
6d58d9 |
desired_access,
|
|
|
9d2131 |
&oa,&iosb,
|
|
|
9d2131 |
share_access,
|
|
|
6d58d9 |
open_options | OS_FILE_NON_DIRECTORY_FILE);
|
|
|
6d58d9 |
}
|