📄 process.c
字号:
if (ksrc != src) kfree(ksrc); return ret;}static int copy_env_dfl(struct nls_table *nls, PWSTR *pwcs, char *src, int len){ char *ksrc, *p; PWSTR wcs = *pwcs; wchar_t *wc; int ret = -ENOMEM; int i = 0; if (wcs) return -EINVAL; ksrc = kmalloc(len + 1, GFP_KERNEL); if (!ksrc) return ret; ret = -EFAULT; if (copy_from_user(ksrc, src, len)) goto out_free_src; ksrc[len++] = 0; wcs = kmalloc(len * sizeof(wchar_t), GFP_KERNEL); ret = -ENOMEM; if (!wcs) goto out_free_src; ret = -EINVAL; p = ksrc; wc = wcs; while (p < ksrc + len) { i = nls->char2uni(p, sizeof(wchar_t), wc++); if (i < 0) goto out_free_wcs; p += i; } ret = (char *)wc - (char *)wcs; *pwcs = wcs; goto out_free_src;out_free_wcs: kfree(wcs);out_free_src: kfree(ksrc); return ret;}long wcslen_user(const wchar_t *s){ long res = 0; wchar_t c; for (;;) { if (get_user(c, s)) return 0; if (!c) return res + sizeof(wchar_t); res += sizeof(wchar_t); s++; }}static int copy_env(PWSTR *pwcs, PWSTR src){ int len; PWSTR dst = *pwcs; if (dst) return -EINVAL; len = wcslen_user(src); dst = kmalloc(len, GFP_KERNEL); if (copy_from_user(dst, src, len)) return -EFAULT; *pwcs = dst; return len;}/* create ppb */NTSTATUScreate_ppb(PRTL_USER_PROCESS_PARAMETERS *ppb_res, struct eprocess *process, struct linux_binprm *bprm, char *image_name, char *dll_path, char *current_dir, PWSTR environ, char *window_title, char *desktop_info, char *shell_info, char *rt_info){ PRTL_USER_PROCESS_PARAMETERS ppb = NULL; HANDLE current_dir_handle; HANDLE console_handle; int i, env_size, len, brk_size; int ret = -EINVAL; unsigned long console_flags; unsigned long addr; unsigned long pos = bprm->p; unsigned long argv_start, envp_start; unsigned long brk_res; char **argv, **envp; char *cmd_line; void *ptr; UNICODE_STRING dll_path_uni; UNICODE_STRING current_dir_uni; UNICODE_STRING window_title_uni; UNICODE_STRING desktop_info_uni; UNICODE_STRING shell_info_uni; UNICODE_STRING rt_info_uni; UNICODE_STRING image_name_uni; UNICODE_STRING cmd_line_uni; PWSTR kenv = NULL; struct nls_table *nls = process->ep_nls; ktrace("create_ppb\n"); argv = (char **)kmalloc(bprm->argc * sizeof(char *), GFP_KERNEL); envp = (char **)kmalloc(bprm->envc * sizeof(char *), GFP_KERNEL); argv_start = pos; for (i = 0; i < bprm->argc; i++) { argv[i] = (char *)pos; pos += strlen_user(argv[i]); *((char *)(pos - 1)) = ' '; } *((char *)(pos - 1)) = '\0'; cmd_line = (char *)argv_start; ktrace("cmd_line %s\n", cmd_line); kfree(argv); envp_start = pos; for (i = 0; i < bprm->envc; i++) { envp[i] = (char *)pos; pos += strlen_user(envp[i]); } /* copy environment from user to kernel */ if (environ) env_size = copy_env(&kenv, environ); else env_size = copy_env_dfl(nls, &kenv, (char *)envp_start, pos - envp_start); ktrace("envsize %d %d\n", pos - envp_start, env_size); if (!dll_path) { for (i = 0; i < bprm->envc; i++) { if (!strncmp(envp[i], "DLLPATH", strlen("DLLPATH"))) { char *p = envp[i]; while (*p && *p != '=') p++; if (*p) dll_path = p + 1; } } } if (str2unistr(nls, &dll_path_uni, dll_path)) goto out_free_envp; if (!current_dir) { for (i = 0; i < bprm->envc; i++) { if (!strncmp(envp[i], "PWD", strlen("PWD"))) { char *p = envp[i]; while (*p && *p != '=') p++; if (*p) current_dir = p + 1; } } } if (str2unistr(nls, ¤t_dir_uni, current_dir)) goto out_free_dll; if (str2unistr(nls, &image_name_uni, image_name)) goto out_free_cwd; if (str2unistr(nls, &cmd_line_uni, cmd_line)) goto out_free_image; if (str2unistr(nls, &window_title_uni, window_title)) goto out_free_cmd; if (str2unistr(nls, &desktop_info_uni, desktop_info)) goto out_free_title; if (str2unistr(nls, &shell_info_uni, shell_info)) goto out_free_desktop; if (str2unistr(nls, &rt_info_uni, rt_info)) goto out_free_shell; current_dir_handle = NULL; console_handle = NULL; console_flags = 0;#define AAA(uni) AAA(current_dir_uni); AAA(dll_path_uni); AAA(image_name_uni); AAA(cmd_line_uni); AAA(window_title_uni); AAA(desktop_info_uni); AAA(shell_info_uni); AAA(rt_info_uni);#undef AAA len = sizeof(RTL_USER_PROCESS_PARAMETERS) /* size of process parameter block */ + MAX_PATH * sizeof(wchar_t) /* size of current directory buffer */ + ALIGN_TO_LONG(dll_path_uni.MaximumLength) + ALIGN_TO_LONG(image_name_uni.MaximumLength) + ALIGN_TO_LONG(cmd_line_uni.MaximumLength) + ALIGN_TO_LONG(window_title_uni.MaximumLength) + ALIGN_TO_LONG(desktop_info_uni.MaximumLength) + ALIGN_TO_LONG(shell_info_uni.MaximumLength) + ALIGN_TO_LONG(rt_info_uni.MaximumLength) + ALIGN_TO_LONG(env_size); /* Calculate the required block size */ brk_size = ALIGN(len, PAGE_SIZE); ktrace("brk_size %d\n", brk_size); addr = 0x80000000UL; down_write(¤t->mm->mmap_sem); brk_res = do_brk(addr, brk_size); up_write(¤t->mm->mmap_sem); ktrace("brk_res 0x%x\n", brk_res); if (brk_res != addr) goto out_free_rt; ppb = (PRTL_USER_PROCESS_PARAMETERS)addr; ktrace("ppb 0x%x\n", ppb); ppb->AllocationSize = brk_size; ppb->Size = len; ppb->Flags = PPF_NORMALIZED; ppb->CurrentDirectoryHandle = current_dir_handle; ppb->hConsole = console_handle; ppb->ProcessGroup = console_flags; ptr = (void *)(ppb + 1); ktrace("ptr 0x%x\n", ptr); /* copy current directory */ ret = copy_param_str(ptr, &ppb->CurrentDirectoryName, ¤t_dir_uni); if (ret < 0) goto out_free_rt; /* copy dll path */ ptr += ret; ret = copy_param_str(ptr, &ppb->DllPath, &dll_path_uni); if (ret < 0) goto out_free_rt; /* copy image path name */ ptr += ret; ret = copy_param_str(ptr, &ppb->ImagePathName, &image_name_uni); if (ret < 0) goto out_free_rt; /* copy command line */ ptr += ret; ret = copy_param_str(ptr, &ppb->CommandLine, &cmd_line_uni); ktrace("command line %p\n",&ppb->CommandLine.Buffer); if (ret < 0) goto out_free_rt; /* copy title */ ptr += ret; ret = copy_param_str(ptr, &ppb->WindowTitle, &window_title_uni); if (ret < 0) goto out_free_rt; /* copy desktop */ ptr += ret; ret = copy_param_str(ptr, &ppb->DesktopInfo, &desktop_info_uni); if (ret < 0) goto out_free_rt; /* copy shell info */ ptr += ret; ret = copy_param_str(ptr, &ppb->ShellInfo, &shell_info_uni); if (ret < 0) goto out_free_rt; /* copy runtime info */ ptr += ret; ret = copy_param_str(ptr, &ppb->RuntimeInfo, &rt_info_uni); if (ret < 0) goto out_free_rt; /* copy Environment */ ptr += ret; ret = copy_to_user(ppb->Environment = ptr, kenv, env_size); if (ret) goto out_free_rt;#define AAA(fld) AAA(DllPath); AAA(ImagePathName); AAA(CommandLine); AAA(WindowTitle); AAA(DesktopInfo); AAA(ShellInfo); AAA(RuntimeInfo); ktrace("sizeof(RTL_USER_PROCESS_PARAMETERS) %d\n", sizeof(RTL_USER_PROCESS_PARAMETERS)); /* FIXME: DENORMALIZE_PARAMS(ppb); */ AAA(DllPath); AAA(ImagePathName); AAA(CommandLine); AAA(WindowTitle); AAA(DesktopInfo); AAA(ShellInfo); AAA(RuntimeInfo);#undef AAA *ppb_res = ppb; ret = STATUS_SUCCESS;out_free_rt: FREE_UNI(rt_info_uni);out_free_shell: FREE_UNI(shell_info_uni);out_free_desktop: FREE_UNI(desktop_info_uni);out_free_title: FREE_UNI(window_title_uni);out_free_cmd: FREE_UNI(cmd_line_uni);out_free_image: FREE_UNI(image_name_uni);out_free_dll: FREE_UNI(dll_path_uni);out_free_cwd: FREE_UNI(current_dir_uni);out_free_envp: kfree(envp); return ret;}void ExitProcessThreads(struct ethread *thread, NTSTATUS exit_code){ /* TODO */}void ExitCurrentThread(task_t *tsk, NTSTATUS exit_code){ ktrace("ExitCurrentThread\n"); if(current==tsk) do_exit(exit_code); else do_exit_task(tsk, exit_code);}/* * terminate all the threads of the process, * then terminate the process */NTSTATUSSTDCALLNtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL, IN NTSTATUS ExitStatus){ struct ethread *thread; struct eprocess *process; struct mm_struct *mm; struct win32_object *obj; ktrace("NtTerminateProcess: handle %d, status %ld\n", ProcessHandle, ExitStatus); if (!(thread = thread_find())) return -EINVAL; if (!ProcessHandle || ProcessHandle == NtCurrentProcess()) process = thread->threads_process; else { obj = GetObject(thread, ProcessHandle, &process_objclass); if (!obj) return -EINVAL; process = (struct eprocess *)obj->o_private; } mm = current->mm; /* * kill ourselves right now, * the process will be run down when the last thread terminates */ ExitCurrentThread(get_first_thread(process)->et_task, ExitStatus); ktrace("terminate child\n"); /* we should never reach this point! */ return(STATUS_SUCCESS);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -