| |
| |
| |
| |
| |
| |
| #include <psxtypes/psxtypes.h> |
| #include <ntapi/nt_memory.h> |
| #include <ntapi/nt_process.h> |
| #include <ntapi/ntapi.h> |
| #include "ntapi_impl.h" |
| |
| typedef struct _nt_process_basic_information nt_pbi; |
| |
| int32_t __stdcall __ntapi_tt_create_remote_runtime_data( |
| __in void * hprocess, |
| __in_out nt_runtime_data_block * rtblock) |
| { |
| int32_t status; |
| |
| size_t bytes_written; |
| nt_pbi rpbi; |
| nt_process_parameters * rprocess_params; |
| nt_unicode_string rcmd_line; |
| uint32_t runtime_arg_hash; |
| nt_runtime_data * rtdata; |
| void * hserver; |
| |
| #if (__SIZEOF_POINTER__ == 4) |
| wchar16_t runtime_arg[8] = { |
| 'i','n','t','e','g','r','a','l'}; |
| #elif (__SIZEOF_POINTER__ == 8) |
| wchar16_t runtime_arg[16] = { |
| 'i','n','t','e','g','r','a','l', |
| '-','r','u','n','t','i','m','e'}; |
| #endif |
| |
| |
| if (!hprocess) |
| return NT_STATUS_INVALID_PARAMETER_1; |
| else if (!rtblock) |
| return NT_STATUS_INVALID_PARAMETER_2; |
| else if (!rtblock->addr) |
| return NT_STATUS_INVALID_PARAMETER_2; |
| else if (!rtblock->size) |
| return NT_STATUS_INVALID_PARAMETER_2; |
| |
| runtime_arg_hash = __ntapi->tt_buffer_crc32( |
| 0, |
| (char *)runtime_arg, |
| sizeof(runtime_arg)); |
| |
| |
| if ((status = __ntapi->zw_query_information_process( |
| hprocess, |
| NT_PROCESS_BASIC_INFORMATION, |
| (void *)&rpbi, |
| sizeof(nt_process_basic_information), |
| 0))) |
| return status; |
| |
| if ((status = __ntapi->zw_read_virtual_memory( |
| hprocess, |
| pe_va_from_rva( |
| rpbi.peb_base_address, |
| (uintptr_t)&(((nt_peb *)0)->process_params)), |
| (char *)&rprocess_params, |
| sizeof(uintptr_t), |
| &bytes_written))) |
| return status; |
| |
| if ((status = __ntapi->zw_read_virtual_memory( |
| hprocess, |
| &rprocess_params->command_line, |
| (char *)&rcmd_line, |
| sizeof(nt_unicode_string), |
| &bytes_written))) |
| return status; |
| |
| if (rcmd_line.buffer == 0) |
| return NT_STATUS_BUFFER_TOO_SMALL; |
| |
| if (rcmd_line.strlen < sizeof(runtime_arg) + 4*sizeof(wchar16_t)) |
| return NT_STATUS_INVALID_USER_BUFFER; |
| |
| if ((status = __ntapi->zw_read_virtual_memory( |
| hprocess, |
| pe_va_from_rva( |
| rcmd_line.buffer, |
| rcmd_line.strlen - sizeof(runtime_arg)), |
| (char *)&runtime_arg, |
| sizeof(runtime_arg), |
| &bytes_written))) |
| return status; |
| |
| |
| runtime_arg_hash ^= __ntapi->tt_buffer_crc32( |
| 0,(char *)runtime_arg, |
| sizeof(runtime_arg)); |
| |
| if (runtime_arg_hash) |
| return NT_STATUS_INVALID_SIGNATURE; |
| |
| |
| rtblock->remote_size = rtblock->size; |
| |
| if ((status = __ntapi->zw_allocate_virtual_memory( |
| hprocess, |
| &rtblock->remote_addr, |
| 0, |
| &rtblock->remote_size, |
| NT_MEM_RESERVE | NT_MEM_COMMIT, |
| NT_PAGE_READWRITE))) |
| return status; |
| |
| |
| rtdata = 0; |
| hserver = 0; |
| |
| if (rtblock->flags & NT_RUNTIME_DATA_DUPLICATE_SESSION_HANDLES) { |
| rtdata = (nt_runtime_data *)rtblock->addr; |
| hserver = rtdata->hserver; |
| |
| if ((status = __ntapi->zw_duplicate_object( |
| NT_CURRENT_PROCESS_HANDLE, |
| hserver, |
| hprocess, |
| &rtdata->hserver, |
| 0,0, |
| NT_DUPLICATE_SAME_ATTRIBUTES |
| |NT_DUPLICATE_SAME_ACCESS))) |
| return status; |
| } |
| |
| |
| status = __ntapi->zw_write_virtual_memory( |
| hprocess, |
| rtblock->remote_addr, |
| (char *)rtblock->addr, |
| rtblock->size, |
| &bytes_written); |
| |
| |
| if (rtdata) |
| rtdata->hserver = hserver; |
| |
| |
| if (status) |
| return status; |
| |
| |
| __ntapi->tt_uintptr_to_hex_utf16( |
| (uintptr_t)rtblock->remote_addr, |
| runtime_arg); |
| |
| |
| status = __ntapi->zw_write_virtual_memory( |
| hprocess, |
| pe_va_from_rva( |
| rcmd_line.buffer, |
| rcmd_line.strlen - sizeof(runtime_arg)), |
| (char *)&runtime_arg, |
| sizeof(runtime_arg), |
| &bytes_written); |
| |
| if (status) |
| __ntapi->zw_free_virtual_memory( |
| hprocess, |
| &rtblock->remote_addr, |
| &rtblock->remote_size, |
| NT_MEM_RELEASE); |
| |
| return status; |
| } |