diff options
Diffstat (limited to 'src/process')
-rw-r--r-- | src/process/ntapi_tt_spawn_native_process.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/process/ntapi_tt_spawn_native_process.c b/src/process/ntapi_tt_spawn_native_process.c index 8e0623a..3417e0d 100644 --- a/src/process/ntapi_tt_spawn_native_process.c +++ b/src/process/ntapi_tt_spawn_native_process.c @@ -63,6 +63,11 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar char * patharg; void * hat; void * hfile; + char * src; + char * dst; + int envc; + char ** penv; + char ** pref; char ** parg; char ** rargv; char ** renvp; @@ -74,6 +79,8 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar uint32_t fsuspended; size_t buflen; size_t written; + size_t needed; + uintptr_t addr; char * raddr; size_t rsize; @@ -230,6 +237,49 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar wch += written/sizeof(wchar16_t); buflen -= written; + /* w32 environment */ + if (rtctx->w32_envp) { + addr = (uintptr_t)wch; + addr += sizeof(uintptr_t) - 1; + addr /= sizeof(uintptr_t); + addr *= sizeof(uintptr_t); + + penv = rtctx->w32_envp; + needed = sizeof(char *); + + for (envc=0; *penv; envc++) { + needed += sizeof(char *); + needed += __ntapi->tt_string_null_offset_multibyte(*penv); + penv++; + } + + needed += sizeof(uintptr_t) - 1; + needed /= sizeof(uintptr_t); + needed *= sizeof(uintptr_t); + + if (buflen < needed) + return __tt_spawn_return( + &rtblock,0,0,NT_STATUS_BUFFER_TOO_SMALL); + + rdata->w32_envp = (char **)(addr - (uintptr_t)rtblock.addr); + + pref = (char **)addr; + dst = (char *)&pref[++envc]; + + + for (penv=rtctx->w32_envp; *penv; penv++) { + *pref++ = dst - (uintptr_t)rtblock.addr; + + for (src=*penv; *src; src++,dst++) + *dst = *src; + + *dst++ = 0; + } + + wch += needed / sizeof(wchar16_t); + buflen -= needed; + } + if (buflen < 0x10000) return __tt_spawn_return( &rtblock,0,0,NT_STATUS_BUFFER_TOO_SMALL); |