我尝试使用ZwCreateProcess
. 当我使用一些简单的测试程序时,它似乎可以工作。但是当我尝试CreateProcess
在分叉的子进程中使用 API 创建一个新进程时。子进程暂停了一段时间(父进程也是如此)然后崩溃。你能给我一些提示吗?
以下是测试代码和fork参考实现代码:
/*****************************************************/
Test program code fragment:
if ((pid = fork()) < 0) {
printf("fork error");
return -1;
}
if (pid == 0) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof(pi) );
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
//Child process will pause here for a while and then crash.
if(CreateProcess(_T("C:\\Windows\\notepad.exe"), NULL, NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi))
{
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}else{
// fputs("cann't create process", fp2);
}
}else{
//Parent code
}
/*****************************************************************************************************/
以下是我使用来自互联网的参考 fork 实现代码:
int win32_fork()
{
HANDLE hProcess = 0;
HANDLE hThread = 0;
BOOL bReturn;
InheritAll();
OBJECT_ATTRIBUTES oa = {sizeof oa};
ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, &oa,
0, 0, NULL, NULL, NULL);
CONTEXT context = {CONTEXT_FULL
| CONTEXT_DEBUG_REGISTERS
| CONTEXT_FLOATING_POINT};
ZwGetContextThread(NtCurrentThread(), &context);
context.Eip = ULONG(child);
MEMORY_BASIC_INFORMATION mbi;
ZeroMemory( &mbi, sizeof( mbi ) );
ZwQueryVirtualMemory(NtCurrentProcess(), PVOID(context.Esp),
MemoryBasicInformation, &mbi, sizeof mbi,
0);
USER_STACK stack = {0, 0, PCHAR(mbi.BaseAddress) + mbi.RegionSize,
mbi.BaseAddress, mbi.AllocationBase};
CLIENT_ID cid;
ZwCreateThread(&hThread, THREAD_ALL_ACCESS, &oa,
hProcess, &cid, &context, &stack, TRUE);
THREAD_BASIC_INFORMATION tbi;
ZeroMemory( &tbi, sizeof( tbi ) );
ZwQueryInformationThread(NtCurrentThread(),
ThreadBasicInformation,
&tbi, sizeof tbi, 0);
PNT_TIB tib = (PNT_TIB)tbi.TebBaseAddress;
ZwQueryInformationThread(hThread, ThreadBasicInformation,
&tbi, sizeof tbi, 0);
ZwWriteVirtualMemory(hProcess, tbi.TebBaseAddress,
&tib->ExceptionList, sizeof tib->ExceptionList,
0);
InformCsrss(hProcess, hThread,
ULONG(cid.UniqueProcess), ULONG(cid.UniqueThread));
ZwResumeThread(hThread, 0);
ZwClose(hThread);
ZwClose(hProcess);
return int(cid.UniqueProcess);
}