/********************************************************/ /* ntapi: Native API core library */ /* Copyright (C) 2013--2017 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ /********************************************************/ #include #include #include #include #include "ntapi_impl.h" #if (__SIZEOF_POINTER__ == 4) static wchar16_t runtime_arg[12] = { ' ','-','r',' ', 'i','n','t','e','g','r','a','l'}; #elif (__SIZEOF_POINTER__ == 8) static wchar16_t runtime_arg[20] = { ' ','-','r',' ', 'i','n','t','e','g','r','a','l', '-','r','u','n','t','i','m','e'}; #endif int32_t __stdcall __ntapi_tt_get_runtime_data( __out nt_runtime_data ** rtdata, __in wchar16_t ** wargv) { int32_t status; nt_process_parameters * process_params; wchar16_t * addrarg; uintptr_t address; uintptr_t buffer; nt_runtime_data * prtdata; ntapi_internals * __internals; /* init */ __internals = __ntapi_internals(); /* once? */ if (__internals->rtdata) { *rtdata = __internals->rtdata; return NT_STATUS_SUCCESS; } if (!(wargv = wargv ? wargv : __internals->ntapi_img_sec_bss->argv_envp_array)) return NT_STATUS_INVALID_PARAMETER; if (!wargv[1] || !wargv[2]) return NT_STATUS_MORE_PROCESSING_REQUIRED; /* integral process? */ addrarg = ((wargv[1][0] == '-') && (wargv[1][1] == 'r') && (wargv[1][2] == 0)) ? wargv[2] : 0; /* top-level framework process? */ if (!addrarg || wargv[3]) return NT_STATUS_MORE_PROCESSING_REQUIRED; /* obtain pointer to data block */ if ((status = __ntapi->tt_hex_utf16_to_uintptr( addrarg,&address))) return status; /* invalid pointer? */ if (address & 0xFFF) return NT_STATUS_MORE_PROCESSING_REQUIRED; /* address is aligned at page boundary */ if ((status = __ntapi->zw_read_virtual_memory( NT_CURRENT_PROCESS_HANDLE, (void *)address, (char *)&buffer, sizeof(buffer), 0))) return status; /* abi */ prtdata = (nt_runtime_data *)address; if (__ntapi->tt_guid_compare(&prtdata->abi,&(nt_guid)NT_PROCESS_GUID_RTDATA)) return NT_STATUS_MORE_PROCESSING_REQUIRED; /* update state */ prtdata->flags |= NT_RUNTIME_DATA_INTEGRAL_PROCESS; /* avoid confusion :-) */ process_params = ((nt_peb *)pe_get_peb_address())->process_params; __ntapi->tt_memcpy_utf16( (wchar16_t *)pe_va_from_rva( process_params->command_line.buffer, process_params->command_line.strlen - sizeof(runtime_arg)), runtime_arg, sizeof(runtime_arg)); *rtdata = prtdata; return NT_STATUS_SUCCESS; }