diff --git a/src/process/ntapi_tt_spawn_native_process.c b/src/process/ntapi_tt_spawn_native_process.c index ae62d35..120cbbd 100644 --- a/src/process/ntapi_tt_spawn_native_process.c +++ b/src/process/ntapi_tt_spawn_native_process.c @@ -65,9 +65,10 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar wchar16_t ** pwarg; wchar16_t * wch; void * hchild[2]; - uint32_t written; wchar16_t * imgbuf; uint32_t fsuspended; + size_t buflen; + size_t written; /* rtctx (convenience) */ rtctx = sparams->rtctx; @@ -106,7 +107,7 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar /* rtblock, rdata */ rtblock.addr = 0; - rtblock.size = 0x20000; + rtblock.size = 0x40000; rtblock.remote_addr = 0; rtblock.remote_size = 0; rtblock.flags = 0; @@ -135,7 +136,7 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar /* imgbuf */ imgbuf = (wchar16_t *)rtblock.addr; - imgbuf += 0x10000 / sizeof(*imgbuf); + imgbuf += 0x30000 / sizeof(*imgbuf); /* hfile */ if (sparams->himage) @@ -149,13 +150,17 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar if ((status = __ntapi->zw_query_object( hfile, NT_OBJECT_NAME_INFORMATION, - imgbuf,0x10000,&written))) + imgbuf,0x10000, + &(uint32_t){0}))) return __tt_spawn_return( &rtblock,0,0,status); imgname = (nt_unicode_string *)imgbuf; /* argv, envp */ + buflen = rtblock.size; + buflen -= sizeof(*rdata); + if ((status = __ntapi->tt_array_copy_utf8( &rdata->argc, (const char **)sparams->argv, @@ -165,16 +170,16 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar sparams->optarg, rtblock.addr, rdata->buffer, - rtblock.size - sizeof(*rdata), - &rtblock.remote_size))) + buflen,&written))) return __tt_spawn_return( &rtblock,0,0,status); - rdata->argv = (char **)&((nt_runtime_data *)0)->buffer; - rdata->envp = rdata->argv + rdata->argc + 1; + rdata->argv = (char **)&((nt_runtime_data *)0)->buffer; + rdata->envp = rdata->argv + rdata->argc + 1; - rdata->wargv = (wchar16_t **)(rdata->buffer + (rtblock.remote_size / sizeof(uintptr_t)) + 1); - rdata->wenvp = rdata->wargv + rdata->argc + 1; + rdata->wargv = (wchar16_t **)rdata->buffer; + rdata->wargv += written / sizeof(wchar16_t **) + 1; + rdata->wenvp = rdata->wargv + rdata->argc + 1; rargv = rdata->argv + ((uintptr_t)rtblock.addr / sizeof(char *)); renvp = rdata->envp + ((uintptr_t)rtblock.addr / sizeof(char *)); @@ -183,33 +188,44 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar rdata->envc++; pwarg = rdata->wenvp + rdata->envc + 1; - wch = (wchar16_t *)pwarg; + wch = (wchar16_t *)pwarg; + + if ((written == (uintptr_t)wch - (uintptr_t)rdata) > rtblock.size) + return __tt_spawn_return( + &rtblock,0,0,NT_STATUS_BUFFER_TOO_SMALL); + + buflen = rtblock.size; + buflen -= written; if ((status = __ntapi->tt_array_convert_utf8_to_utf16( rargv, rdata->wargv, - rdata, - wch, - rtblock.size - sizeof(wchar16_t)*(wch-(wchar16_t *)rdata->buffer), - &rtblock.remote_size))) + rdata,wch, + buflen,&written))) return __tt_spawn_return( &rtblock,0,0,status); - wch += rtblock.remote_size/sizeof(wchar16_t); + wch += written/sizeof(wchar16_t); + buflen -= written; if ((status = __ntapi->tt_array_convert_utf8_to_utf16( renvp, rdata->wenvp, - rdata, - wch, - rtblock.size - sizeof(wchar16_t)*(wch-(wchar16_t *)rdata->buffer), - &rtblock.remote_size))) + rdata,wch, + buflen,&written))) return __tt_spawn_return( &rtblock,0,0,status); rdata->wargv -= (uintptr_t)rtblock.addr / sizeof(wchar16_t *); rdata->wenvp -= (uintptr_t)rtblock.addr / sizeof(wchar16_t *); + wch += written/sizeof(wchar16_t); + buflen -= written; + + if (buflen < 0x10000) + return __tt_spawn_return( + &rtblock,0,0,NT_STATUS_BUFFER_TOO_SMALL); + /* session */ if (sparams->hready) { if ((status = __ntapi->zw_duplicate_object( @@ -248,8 +264,11 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar cparams.creation_flags_process = NT_PROCESS_CREATE_FLAGS_INHERIT_HANDLES; cparams.creation_flags_thread = NT_PROCESS_CREATE_FLAGS_CREATE_THREAD_SUSPENDED; - crtblock.size = 0x10000; - cparams.rtblock = &crtblock; + crtblock.size = (size_t)wch - (size_t)rdata; + crtblock.size += 0xFFFF; + crtblock.size |= 0xFFFF; + crtblock.size ^= 0xFFFF; + cparams.rtblock = &crtblock; /* hoppla */ if ((status = __ntapi->tt_create_native_process(&cparams)))