pid_t fork(void) { NTSTATUS nErrCode; CONTEXT ctxThreadContext; HANDLE hProcess; HANDLE hThread; INITIAL_TEB itInitialTeb; CLIENT_ID ciClientId; MEMORY_BASIC_INFORMATION mbiStackInfo; THREAD_BASIC_INFORMATION tbiThreadInfo; struct __tagcsrmsg{ PORT_MESSAGE PortMessage; struct CSRSS_MESSAGE CsrssMessage; PROCESS_INFORMATION ProcessInformation; CLIENT_ID Debugger; ULONG CreationFlags; ULONG VdmInfo[2]; } csrmsg; /* STEP 1: Duplicate current process */ nErrCode = NtCreateProcess ( &hProcess, PROCESS_ALL_ACCESS, NULL, NtCurrentProcess(), TRUE, 0, 0, 0 ); /* failure */ if(!NT_SUCCESS(nErrCode)) { ERR("NtCreateProcess() failed with status 0x%08X\n", nErrCode); goto fail; } /* STEP 2: Duplicate current thread */ /* 2.1: duplicate registers */ ctxThreadContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS | CONTEXT_FLOATING_POINT; /* get the current thread's registers */ nErrCode = NtGetContextThread(NtCurrentThread(), &ctxThreadContext); /* failure */ if(!NT_SUCCESS(nErrCode)) { ERR("NtGetContextThread() failed with status 0x%08X\n", nErrCode); goto cleanup_and_fail; } /* redirect the child process to the child_branch label (see 4.3 below) */ ctxThreadContext.Eip = (ULONG)&&child_branch; /* 2.2: duplicate stack */ /* get stack base and size */ nErrCode = NtQueryVirtualMemory ( NtCurrentProcess(), (PVOID)ctxThreadContext.Esp, MemoryBasicInformation, &mbiStackInfo, sizeof(mbiStackInfo), 0 ); /* failure */ if(!NT_SUCCESS(nErrCode)) { ERR("NtQueryVirtualMemory() failed with status 0x%08X\n", nErrCode); goto cleanup_and_fail; } itInitialTeb.StackCommit = 0; itInitialTeb.StackReserve = 0; itInitialTeb.StackBase = (PVOID)((ULONG)(mbiStackInfo.BaseAddress) + mbiStackInfo.RegionSize); itInitialTeb.StackLimit = mbiStackInfo.BaseAddress; itInitialTeb.StackAllocate = mbiStackInfo.AllocationBase; /* 2.3: create duplicate thread */ nErrCode = NtCreateThread ( &hThread, THREAD_ALL_ACCESS, NULL, hProcess, (CLIENT_ID *)&ciClientId, &ctxThreadContext, &itInitialTeb, TRUE ); /* failure */ if(!NT_SUCCESS(nErrCode)) { ERR("NtCreateThread() failed with status 0x%08X\n", nErrCode); goto cleanup_and_fail; } /* 2.4: duplicate the TEB */ /* store the client id in the child thread's stack (see 4.3b) */ nErrCode = NtWriteVirtualMemory ( hProcess, &ciClientId, &ciClientId, sizeof(ciClientId), 0 ); /* failure */ if(!NT_SUCCESS(nErrCode)) { ERR("NtWriteVirtualMemory() failed with status 0x%08X\n", nErrCode); goto cleanup_and_fail; } /* get the child thread's TEB base */ nErrCode = NtQueryInformationThread ( hThread, ThreadBasicInformation, &tbiThreadInfo, sizeof(tbiThreadInfo), 0 ); /* failure */ if(!NT_SUCCESS(nErrCode)) { ERR("NtQueryInformationThread() failed with status 0x%08X\n", nErrCode); goto cleanup_and_fail; } /* copy the TEB */ nErrCode = NtWriteVirtualMemory ( hProcess, tbiThreadInfo.TebBaseAddress, NtCurrentTeb(), sizeof(TEB), 0 ); /* failure */ if(!NT_SUCCESS(nErrCode)) { ERR("NtWriteVirtualMemory() failed with status 0x%08X\n", nErrCode); goto cleanup_and_fail; } /* STEP 3: Call Win32 subsystem */ memset(&csrmsg, 0, sizeof(csrmsg)); csrmsg.ProcessInformation.hProcess = hProcess; csrmsg.ProcessInformation.hThread = hThread; csrmsg.ProcessInformation.dwProcessId = (DWORD)ciClientId.UniqueProcess; csrmsg.ProcessInformation.dwThreadId = (DWORD)ciClientId.UniqueThread; nErrCode = CsrClientCallServer(&csrmsg, 0, 0x10000, 0x24); /* failure */ if(!NT_SUCCESS(nErrCode)) { ERR("CsrClientCallServer() failed with status 0x%08X\n", nErrCode); goto cleanup_and_fail; } /* STEP 4: Finalization */ /* 4.1: resume thread */ nErrCode = NtResumeThread(hThread, 0); /* 4.2: close superfluous handles */ NtClose(hProcess); NtClose(hThread); /* 4.3: (parent) return the child process id */ return ((pid_t)(ciClientId.UniqueProcess)); /* 4.3b: (child) cleanup and return 0 */ child_branch: /* restore the thread and process id in the TEB */ memcpy(&NtCurrentTeb()->Cid, &ciClientId, sizeof(ciClientId)); /* return 0 */ return (0); cleanup_and_fail: NtTerminateProcess(hProcess, nErrCode); fail: errno = __status_to_errno(nErrCode); return (-1); }
/* * @implemented */ VOID WINAPI ExitProcess(UINT uExitCode) { // CSR_API_MESSAGE CsrRequest; // ULONG Request; NTSTATUS Status; /* kill sibling threads ... we want to be alone at this point */ NtTerminateProcess(NULL, 0); /* unload all dll's */ LdrShutdownProcess(); /* notify csrss of process termination */ // Request = TERMINATE_PROCESS; // Status = CsrClientCallServer(&CsrRequest, // NULL, // MAKE_CSR_API(Request, CSR_NATIVE), // sizeof(CSR_API_MESSAGE)); // if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status)) // { // DPRINT("Failed to tell csrss about terminating process\n"); // } NtTerminateProcess(NtCurrentProcess (), uExitCode); /* should never get here */ ASSERT(0); while(1); }
Int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWChar lpCmdLine, Int nCmdShow) { Int Result; UNREFERENCED_PARAMETER(hInstance); UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(nCmdShow); g_HeapHandle = RtlCreateHeap(0, NULL, 0, 0, NULL, NULL); // MyLib_Initialize(); /* WChar end; lpCmdLine = GetCommandLineW(); end = *lpCmdLine++ == '\"' ? '\"' : ' '; while (*lpCmdLine && *lpCmdLine != end) ++lpCmdLine; if (*++lpCmdLine) { while (*lpCmdLine == ' ' || *lpCmdLine == '\t') ++lpCmdLine; } */ Result = WinMain2(/*GetModuleHandleW*/(NULL), 0, lpCmdLine, SW_SHOWDEFAULT); RtlDestroyHeap(g_HeapHandle); // MyLib_UnInitialize(); NtTerminateProcess(NtCurrentProcess(), Result); }
NTSTATUS NTAPI SmpTerminate(IN PULONG_PTR Parameters, IN ULONG ParameterMask, IN ULONG ParameterCount) { NTSTATUS Status; BOOLEAN Old; ULONG Response; /* Give the shutdown privilege to the thread */ if (RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, TRUE, &Old) == STATUS_NO_TOKEN) { /* Thread doesn't have a token, give it to the entire process */ RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &Old); } /* Take down the process/machine with a hard error */ Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, ParameterCount, ParameterMask, Parameters, OptionShutdownSystem, &Response); /* Terminate the process if the hard error didn't already */ return NtTerminateProcess(NtCurrentProcess(), Status); }
/* * ucmLoadCallback * * Purpose: * * Image load notify callback, when kernel32 available - acquire import and run target application. * */ VOID NTAPI ucmLoadCallback( PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved ) { BOOL bReadSuccess, bIsLocalSystem = FALSE; PWSTR lpParameter = NULL; ULONG cbParameter = 0L; UNREFERENCED_PARAMETER(DllSize); UNREFERENCED_PARAMETER(Reserved); if (DllName == NULL) { return; } if (_strcmpi(DllName, L"kernel32.dll") == 0) { g_pvKernel32 = DllBase; } if (_strcmpi(DllName, L"user32.dll") == 0) { if (g_pvKernel32) { pCreateProcessW = ucmLdrGetProcAddress( (PCHAR)g_pvKernel32, "CreateProcessW"); if (pCreateProcessW != NULL) { ucmIsLocalSystem(&bIsLocalSystem); bReadSuccess = ucmReadParameters( &lpParameter, &cbParameter, NULL, NULL, bIsLocalSystem); ucmLaunchPayloadEx( pCreateProcessW, lpParameter, cbParameter); if ((bReadSuccess) && (lpParameter != NULL)) { RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, lpParameter); } NtTerminateProcess(NtCurrentProcess(), STATUS_SUCCESS); } } } }
_Check_return_ BOOLEAN ProcessHackerShutdown( VOID ) { HWND WindowHandle; WindowHandle = FindWindow(L"ProcessHacker", NULL); if (WindowHandle) { HANDLE processHandle; ULONG processID = 0; ULONG threadID = GetWindowThreadProcessId(WindowHandle, &processID); SendMessageTimeout(WindowHandle, WM_QUIT, 0, 0, SMTO_ABORTIFHUNG | SMTO_BLOCK, 5000, NULL); if (NT_SUCCESS(PhOpenProcess(&processHandle, SYNCHRONIZE | PROCESS_TERMINATE, ULongToHandle(processID)))) { //PostMessage(WindowHandle, WM_QUIT, 0, 0); // Wait on the process handle, if we timeout, kill it. //if (WaitForSingleObject(processHandle, 10000) != WAIT_OBJECT_0) NtTerminateProcess(processHandle, 1); NtClose(processHandle); } } return FALSE; }
static BOOLEAN NTAPI PhpPreviousInstancesCallback( _In_ PPH_STRINGREF Name, _In_ PPH_STRINGREF TypeName, _In_opt_ PVOID Context ) { ULONG64 processId64; PH_STRINGREF firstPart; PH_STRINGREF secondPart; if ( PhStartsWithStringRef2(Name, L"PhMutant_", TRUE) && PhSplitStringRefAtChar(Name, L'_', &firstPart, &secondPart) && PhStringToInteger64(&secondPart, 10, &processId64) ) { HANDLE processHandle; if (NT_SUCCESS(PhOpenProcess( &processHandle, SYNCHRONIZE | PROCESS_TERMINATE, ULongToHandle((ULONG)processId64) ))) { NtTerminateProcess(processHandle, 1); NtClose(processHandle); } } return TRUE; }
NTSTATUS __cdecl _main(int argc, char *argv[], char *envp[], ULONG DebugFlag) { NTSTATUS Status = STATUS_SUCCESS; PROCESS_BASIC_INFORMATION PBI = {0}; /* Lookup yourself */ Status = NtQueryInformationProcess (NtCurrentProcess(), ProcessBasicInformation, & PBI, sizeof PBI, NULL); if(NT_SUCCESS(Status)) { SmSsProcessId = (ULONG) PBI.UniqueProcessId; } /* Initialize the system */ Status = InitSessionManager(); /* Watch required subsystems TODO */ #if 0 if (!NT_SUCCESS(Status)) { int i; for (i=0; i < (sizeof Children / sizeof Children[0]); i++) { if (Children[i]) { NtTerminateProcess(Children[i],0); } } DPRINT1("SM: Initialization failed!\n"); goto ByeBye; } Status = NtWaitForMultipleObjects(((LONG) sizeof(Children) / sizeof(HANDLE)), Children, WaitAny, TRUE, /* alertable */ NULL); /* NULL for infinite */ if (!NT_SUCCESS(Status)) { DPRINT1("SM: NtWaitForMultipleObjects failed! (Status=0x%08lx)\n", Status); } else { DPRINT1("SM: Process terminated!\n"); } ByeBye: /* Raise a hard error (crash the system/BSOD) */ NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0,0,0,0,0); // NtTerminateProcess(NtCurrentProcess(), 0); #endif return NtTerminateThread(NtCurrentThread(), Status); }
NTSTATUS log_fini(void) { dprintf("%lu failed, %lu passed\n", fail_count, pass_count); NtClose( slot ); NtClose( event ); return NtTerminateProcess( NtCurrentProcess(), fail_count ? 1 : 0 ); }
DECLSPEC_NORETURN // __attribute((noreturn)) void exit(int exitcode) { // DbgBreakPoint(); NtTerminateProcess(NtCurrentProcess(), exitcode); /* Should never get here */ while(1); }
int _cdecl _main(int argc, char *argv[], char *envp[], int DebugFlag) { KPRIORITY BasePriority = (8 + 1) + 4; NTSTATUS Status; //ULONG Response; // see the #if 0 UNREFERENCED_PARAMETER(envp); UNREFERENCED_PARAMETER(DebugFlag); /* Set the Priority */ NtSetInformationProcess(NtCurrentProcess(), ProcessBasePriority, &BasePriority, sizeof(KPRIORITY)); /* Give us IOPL so that we can access the VGA registers */ Status = NtSetInformationProcess(NtCurrentProcess(), ProcessUserModeIOPL, NULL, 0); if (!NT_SUCCESS(Status)) { /* Raise a hard error */ DPRINT1("CSRSS: Could not raise IOPL, Status: 0x%08lx\n", Status); #if 0 Status = NtRaiseHardError(STATUS_IO_PRIVILEGE_FAILED, 0, 0, NULL, OptionOk, &Response); #endif } /* Initialize CSR through CSRSRV */ Status = CsrServerInitialization(argc, argv); if (!NT_SUCCESS(Status)) { /* Kill us */ DPRINT1("CSRSS: Unable to initialize server, Status: 0x%08lx\n", Status); NtTerminateProcess(NtCurrentProcess(), Status); } /* Disable errors */ CsrpSetDefaultProcessHardErrorMode(); /* If this is Session 0, make sure killing us bugchecks the system */ if (NtCurrentPeb()->SessionId == 0) RtlSetProcessIsCritical(TRUE, NULL, FALSE); /* Kill this thread. CSRSRV keeps us going */ NtTerminateThread(NtCurrentThread(), Status); return 0; }
NTSTATUS kuhl_m_process_genericOperation(int argc, wchar_t * argv[], KUHL_M_PROCESS_GENERICOPERATION operation) { HANDLE hProcess; NTSTATUS status = STATUS_NOT_FOUND; DWORD pid = 0, access; PCWCHAR szPid, szText; switch(operation) { case KUHL_M_PROCESS_GENERICOPERATION_TERMINATE: access = PROCESS_TERMINATE; szText = L"NtTerminateProcess"; break; case KUHL_M_PROCESS_GENERICOPERATION_SUSPEND: access = PROCESS_SUSPEND_RESUME; szText = L"NtSuspendProcess"; break; case KUHL_M_PROCESS_GENERICOPERATION_RESUME: access = PROCESS_SUSPEND_RESUME; szText = L"NtResumeProcess"; break; default: return status; } if(kull_m_string_args_byName(argc, argv, L"pid", &szPid, NULL)) pid = wcstoul(szPid, NULL, 0); if(pid) { if(hProcess = OpenProcess(access, FALSE, pid)) { switch(operation) { case KUHL_M_PROCESS_GENERICOPERATION_TERMINATE: status = NtTerminateProcess(hProcess, STATUS_SUCCESS); break; case KUHL_M_PROCESS_GENERICOPERATION_SUSPEND: status = NtSuspendProcess(hProcess); break; case KUHL_M_PROCESS_GENERICOPERATION_RESUME: status = NtResumeProcess(hProcess); break; } if(NT_SUCCESS(status)) kprintf(L"%s of %u PID : OK !\n", szText, pid); else PRINT_ERROR(L"%s 0x%08x\n", szText, status); CloseHandle(hProcess); } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR(L"pid (/pid:123) is missing"); return status; }
int main() { int round; int t; GET_NTDLL(NtTerminateProcess, (IN HANDLE ProcessHandle OPTIONAL, IN NTSTATUS ExitStatus)); INIT(); for (round = 0; round < ROUNDS; round++) { #ifdef VERBOSE print("round %d\n", round); #endif if (round > 0) { /* clean up first */ NtTerminateProcess(0 /* everyone but me */, 666); #ifdef VERBOSE print("all alone again %d\n", round); #endif VERBOSE } global_started = 0; global_finished = 0; for (t = 0; t < TOTAL_THREADS; t++) { thread[t] = (HANDLE)create_thread(executor); if (thread[t] == NULL) print("GLE: %d\n", GetLastError()); assert(thread[t] != NULL); } #ifdef VERBOSE print("started %d threads\n", TOTAL_THREADS); #else print("started some threads\n"); #endif /* wait for some to start */ while (global_started < WAIT_TO_START) YIELD(); /* wait for some work to get done */ while (global_finished < WAIT_TO_FINISH) YIELD(); #ifdef VERBOSE print("some %d work, done %d\n", global_started, global_finished); #endif } print("done\n"); return 0; }
/** * @brief Terminates the calling native process. * @details This routine releases all resources * used by zenwinx library before the process termination. * @param[in] exit_code the exit status. */ void winx_exit(int exit_code) { NTSTATUS Status; kb_close(); winx_flush_dbg_log(0); Status = NtTerminateProcess(NtCurrentProcess(),exit_code); if(!NT_SUCCESS(Status)){ print_post_scriptum("winx_exit: cannot terminate process",Status); } }
BOOL WowExitTask( PCSR_THREAD pcsrt) { HANDLE ahandle[2]; USERTHREAD_WOW_INFORMATION WowInfo; NTSTATUS Status; ahandle[1] = heventCancel; /* * Query task id and exit function. */ LeaveCrit(); Status = NtUserQueryInformationThread(pcsrt->ThreadHandle, UserThreadWOWInformation, &WowInfo, sizeof(WowInfo), NULL); EnterCrit(); if (!NT_SUCCESS(Status)) return FALSE; /* * If no task id was returned, it is not a WOW task */ if (WowInfo.hTaskWow == 0) return FALSE; /* * The created thread needs to be able to reenter user because this * call will grab the CSR critical section and whoever has that * may need to grab the USER critical section before it can * release it. */ LeaveCrit(); /* * Try to make it exit itself. This will work most of the time. * If this doesn't work, terminate this process. */ ahandle[0] = InternalCreateCallbackThread(pcsrt->Process->ProcessHandle, (DWORD)WowInfo.lpfnWowExitTask, (DWORD)WowInfo.hTaskWow); if (ahandle[0] == NULL) { NtTerminateProcess(pcsrt->Process->ProcessHandle, 0); pcsrt->Process->Flags |= CSR_PROCESS_TERMINATED; goto Exit; } WaitForMultipleObjects(2, ahandle, FALSE, INFINITE); NtClose(ahandle[0]); Exit: EnterCrit(); return TRUE; }
void mydie(NTSTATUS status, NTSTATUS fatalStatus){ printf_s("\nAn error occurred. NTSTATUS: %lX", status); if (fatalStatus){ printf_s("\nWhile handling this error, a fatal error occurred."); printf_s("\nProgram termination due to NTSTATUS 0x%lX.", fatalStatus); fflush(stdin); _getch(); NtTerminateProcess(INVALID_HANDLE_VALUE, status); } fflush(stdin); _getch(); }
/******************************************************************* * EXC_DefaultHandling * * Default handling for exceptions. Called when we didn't find a suitable handler. */ static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context ) { if (send_debug_event( rec, FALSE, context ) == DBG_CONTINUE) return; /* continue execution */ if (rec->ExceptionFlags & EH_STACK_INVALID) ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); else if (rec->ExceptionCode == EXCEPTION_NONCONTINUABLE_EXCEPTION) ERR("Process attempted to continue execution after noncontinuable exception.\n"); else ERR("Unhandled exception code %lx flags %lx addr %p\n", rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); NtTerminateProcess( NtCurrentProcess(), 1 ); }
void test_terminate_process( void ) { PROCESS_BASIC_INFORMATION info; NTSTATUS r; r = NtTerminateProcess( 0, STATUS_UNSUCCESSFUL ); ok( r == STATUS_SUCCESS, "wrong return %08lx\n", r ); r = NtQueryInformationProcess( NtCurrentProcess(), ProcessBasicInformation, &info, sizeof info, 0); ok( r == STATUS_SUCCESS, "wrong return %08lx\n", r ); ok( info.ExitStatus == STATUS_PENDING, "Exit code wrong %08lx\n", info.ExitStatus ); }
static NTSTATUS NTAPI TerminatorTP1( _In_ HANDLE ProcessId ) { NTSTATUS status; HANDLE processHandle; if (NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_TERMINATE, ProcessId ))) { // Don't use KPH. status = NtTerminateProcess(processHandle, STATUS_SUCCESS); NtClose(processHandle); } return status; }
/* * @implemented */ BOOL WINAPI TerminateProcess(HANDLE hProcess, UINT uExitCode) { NTSTATUS Status; if (hProcess == NULL) { return FALSE; } Status = NtTerminateProcess(hProcess, uExitCode); if (NT_SUCCESS(Status)) { return TRUE; } SetLastErrorByStatus(Status); return FALSE; }
BOOL CProcessTool::TerminateProcess(DWORD dwPid) { BOOL bSucceed = FALSE; if(NtTerminateProcess) { HANDLE hProcess; hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid); if(hProcess) { if(NtTerminateProcess(hProcess,1)==0) { bSucceed = TRUE; } else { LOG::printError(TEXT("NtTerminateProcess")); } } } return bSucceed; }
main( int argc, char *argv[], char *envp[] ) { HANDLE CurrentProcessHandle; NTSTATUS Status; ULONG i; VOID SeMain(); CurrentProcessHandle = NtCurrentProcess(); Status = STATUS_SUCCESS; DbgPrint( "Entering User Mode Test Program\n" ); DbgPrint( "argc: %ld\n", argc ); if (argv != NULL) { for (i=0; i<argc; i++) { DbgPrint( "argv[ %ld ]: %s\n", i, argv[ i ] ); } } if (envp != NULL) { i = 0; while (*envp) { DbgPrint( "envp[ %02ld ]: %s\n", i++, *envp++ ); } } SeMain(); DbgPrint( "Exiting User Mode Test Program with Status = %lx\n", Status ); NtTerminateProcess( CurrentProcessHandle, Status ); }
NTSTATUS ModifySelfSizeOfImage(LPWSTR ExeFullPath, LPWSTR CommandLine, ULONG SizeOfImage) { BOOL Result; ULONG Length; PVOID FakeCPInfoBuffer; WCHAR CmdFullPath[MAX_NTPATH]; PWCHAR CmdLineBuffer; NTSTATUS Status; PLDR_MODULE LdrModule; PIMAGE_DOS_HEADER DosHeader; PIMAGE_NT_HEADERS NtHeader; PIMAGE_SECTION_HEADER SectionHeader; FAKE_CREATE_PROCESS_INFO *fcpi; PROCESS_INFORMATION ProcessInformation; CONTEXT Context; NtFileDisk file; UNICODE_STRING ExeNtPath, *ProcessCommandLine; UNREFERENCED_PARAMETER(CommandLine); LdrModule = Nt_FindLdrModuleByName(NULL); DosHeader = (PIMAGE_DOS_HEADER)&__ImageBase; NtHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew); fcpi = (FAKE_CREATE_PROCESS_INFO *)AllocStack(0x2000); fcpi->PeHeaderSize = (ULONG_PTR)(IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections) - (ULONG_PTR)DosHeader; Status = file.Open(LdrModule->FullDllName.Buffer); if (!NT_SUCCESS(Status)) return Status; Status = file.Read(fcpi->PeHeader, fcpi->PeHeaderSize); if (!NT_SUCCESS(Status)) return Status; CmdLineBuffer = (PWCHAR)((ULONG_PTR)fcpi->PeHeader + fcpi->PeHeaderSize); fcpi->CommandLine.Buffer = CmdLineBuffer; fcpi->CommandLine.Length = (USHORT)(StrLengthW(ExeFullPath) * sizeof(WCHAR)); ProcessCommandLine = &Nt_CurrentPeb()->ProcessParameters->CommandLine; CopyMemory(CmdLineBuffer, ProcessCommandLine->Buffer, ProcessCommandLine->Length); *(PULONG_PTR)&CmdLineBuffer += ProcessCommandLine->Length; CmdLineBuffer[0] = 0; fcpi->CommandLine.Length = ProcessCommandLine->Length; fcpi->CommandLine.MaximumLength = fcpi->CommandLine.Length + sizeof(WCHAR); ++CmdLineBuffer; CmdLineBuffer = (PWCHAR)ROUND_UP((ULONG_PTR)CmdLineBuffer, 16); RtlDosPathNameToNtPathName_U(LdrModule->FullDllName.Buffer, &ExeNtPath, NULL, NULL); fcpi->ExeNtPath.Buffer = CmdLineBuffer; CopyMemory(CmdLineBuffer, ExeNtPath.Buffer, ExeNtPath.Length); *(PULONG_PTR)&CmdLineBuffer += ExeNtPath.Length; CmdLineBuffer[0] = 0; fcpi->ExeNtPath.Length = ExeNtPath.Length; fcpi->ExeNtPath.MaximumLength = fcpi->ExeNtPath.Length + sizeof(WCHAR); *CmdLineBuffer++ = 0; RtlFreeUnicodeString(&ExeNtPath); DosHeader = (PIMAGE_DOS_HEADER)fcpi->PeHeader; NtHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew); SectionHeader = IMAGE_FIRST_SECTION(NtHeader); SectionHeader += NtHeader->FileHeader.NumberOfSections - 1; SizeOfImage -= LdrModule->SizeOfImage; SizeOfImage = ROUND_UP(SizeOfImage, MEMORY_PAGE_SIZE); SectionHeader->Misc.VirtualSize = ROUND_UP(SectionHeader->Misc.VirtualSize, MEMORY_PAGE_SIZE) + SizeOfImage; if (NtHeader->FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage)) NtHeader->OptionalHeader.SizeOfImage += SizeOfImage; Length = Nt_GetSystemDirectory(CmdFullPath, countof(CmdFullPath)); StrCopyW(CmdFullPath + Length, L"cmd.exe"); ProcessInformation.hProcess = NtCurrentProcess(); ProcessInformation.hThread = NtCurrentThread(); #if 1 Result = Nt_CreateProcess(NULL, CmdFullPath, NULL, CREATE_SUSPENDED, NULL, &ProcessInformation); if (!Result) return STATUS_UNSUCCESSFUL; #endif FakeCPInfoBuffer = NULL; LOOP_ONCE { ULONG_PTR Offset; Status = NtDuplicateObject( NtCurrentProcess(), NtCurrentProcess(), ProcessInformation.hProcess, &fcpi->ProcessHandle, 0, 0, DUPLICATE_SAME_ACCESS ); if (!NT_SUCCESS(Status)) break; /* Status = NtDuplicateObject( NtCurrentProcess(), file, ProcessInformation.hProcess, &fcpi->FileHandle, 0, 0, DUPLICATE_SAME_ACCESS ); if (!NT_SUCCESS(Status)) break; */ Status = Nt_AllocateMemory(ProcessInformation.hProcess, &FakeCPInfoBuffer, MEMORY_PAGE_SIZE); if (!NT_SUCCESS(Status)) break; fcpi->CreateProcessInternalW = CreateProcessInternalW; fcpi->NtTerminateProcess = NtTerminateProcess; fcpi->LdrShutdownProcess = LdrShutdownProcess; fcpi->NtCreateFile = NtCreateFile; fcpi->NtWriteFile = NtWriteFile; fcpi->NtClose = NtClose; fcpi->NtWaitForSingleObject = NtWaitForSingleObject; fcpi->InitialDirectory.Buffer = NULL; Offset = (ULONG_PTR)FakeCPInfoBuffer - (ULONG_PTR)fcpi; *(PULONG_PTR)&fcpi->CommandLine.Buffer += Offset; *(PULONG_PTR)&fcpi->ExeNtPath.Buffer += Offset; Status = Nt_WriteMemory( ProcessInformation.hProcess, FakeCPInfoBuffer, fcpi, (ULONG_PTR)CmdLineBuffer - (ULONG_PTR)fcpi, &Length ); if (!NT_SUCCESS(Status)) break; Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; Status = NtGetContextThread(ProcessInformation.hThread, &Context); if (!NT_SUCCESS(Status)) break; Context.Eip = (ULONG_PTR)FakeCPInfoBuffer + Length; Context.Eip = ROUND_UP(Context.Eip, 16); Context.Ecx = (ULONG_PTR)FakeCPInfoBuffer; Status = Nt_WriteMemory( ProcessInformation.hProcess, (PVOID)Context.Eip, ModifySizeOfImage, (ULONG_PTR)ModifySizeOfImageEnd - (ULONG_PTR)ModifySizeOfImage, &Length ); if (!NT_SUCCESS(Status)) break; #if 1 Status = NtSetContextThread(ProcessInformation.hThread, &Context); if (!NT_SUCCESS(Status)) break; Status = NtResumeThread(ProcessInformation.hThread, NULL); #else INLINE_ASM jmp Context.Eip; #endif } if (!NT_SUCCESS(Status)) { if (FakeCPInfoBuffer != NULL) Nt_FreeMemory(ProcessInformation.hProcess, FakeCPInfoBuffer); NtTerminateProcess(ProcessInformation.hProcess, 0); } NtClose(ProcessInformation.hProcess); NtClose(ProcessInformation.hThread); return Status; }
NTSTATUS NTAPI SmpExecuteImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, IN ULONG Flags, IN PRTL_USER_PROCESS_INFORMATION ProcessInformation) { PRTL_USER_PROCESS_INFORMATION ProcessInfo; NTSTATUS Status; RTL_USER_PROCESS_INFORMATION LocalProcessInfo; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; /* Use the input process information if we have it, otherwise use local */ ProcessInfo = ProcessInformation; if (!ProcessInfo) ProcessInfo = &LocalProcessInfo; /* Create parameters for the target process */ Status = RtlCreateProcessParameters(&ProcessParameters, FileName, SmpDefaultLibPath.Length ? &SmpDefaultLibPath : NULL, Directory, CommandLine, SmpDefaultEnvironment, NULL, NULL, NULL, 0); if (!NT_SUCCESS(Status)) { /* This is a pretty bad failure. ASSERT on checked builds and exit */ ASSERTMSG("RtlCreateProcessParameters", NT_SUCCESS(Status)); DPRINT1("SMSS: RtlCreateProcessParameters failed for %wZ - Status == %lx\n", FileName, Status); return Status; } /* Set the size field as required */ ProcessInfo->Size = sizeof(RTL_USER_PROCESS_INFORMATION); /* Check if the debug flag was requested */ if (Flags & SMP_DEBUG_FLAG) { /* Write it in the process parameters */ ProcessParameters->DebugFlags = 1; } else { /* Otherwise inherit the flag that was passed to SMSS itself */ ProcessParameters->DebugFlags = SmpDebug; } /* Subsystems get the first 1MB of memory reserved for DOS/IVT purposes */ if (Flags & SMP_SUBSYSTEM_FLAG) { ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB; } /* And always force NX for anything that SMSS launches */ ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_NX; /* Now create the process */ Status = RtlCreateUserProcess(FileName, OBJ_CASE_INSENSITIVE, ProcessParameters, NULL, NULL, NULL, FALSE, NULL, NULL, ProcessInfo); RtlDestroyProcessParameters(ProcessParameters); if (!NT_SUCCESS(Status)) { /* If we couldn't create it, fail back to the caller */ DPRINT1("SMSS: Failed load of %wZ - Status == %lx\n", FileName, Status); return Status; } /* Associate a session with this process */ Status = SmpSetProcessMuSessionId(ProcessInfo->ProcessHandle, MuSessionId); /* If the application is deferred (suspended), there's nothing to do */ if (Flags & SMP_DEFERRED_FLAG) return Status; /* Otherwise, get ready to start it, but make sure it's a native app */ if (ProcessInfo->ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE) { /* Resume it */ NtResumeThread(ProcessInfo->ThreadHandle, NULL); if (!(Flags & SMP_ASYNC_FLAG)) { /* Block on it unless Async was requested */ NtWaitForSingleObject(ProcessInfo->ThreadHandle, FALSE, NULL); } /* It's up and running now, close our handles */ NtClose(ProcessInfo->ThreadHandle); NtClose(ProcessInfo->ProcessHandle); } else { /* This image is invalid, so kill it, close our handles, and fail */ Status = STATUS_INVALID_IMAGE_FORMAT; NtTerminateProcess(ProcessInfo->ProcessHandle, Status); NtWaitForSingleObject(ProcessInfo->ThreadHandle, 0, 0); NtClose(ProcessInfo->ThreadHandle); NtClose(ProcessInfo->ProcessHandle); DPRINT1("SMSS: Not an NT image - %wZ\n", FileName); } /* Return the outcome of the process create */ return Status; }
NTSTATUS NTAPI SmpExecuteInitialCommand(IN ULONG MuSessionId, IN PUNICODE_STRING InitialCommand, IN HANDLE InitialCommandProcess, OUT PHANDLE ReturnPid) { NTSTATUS Status; RTL_USER_PROCESS_INFORMATION ProcessInfo; UNICODE_STRING Arguments, ImageFileDirectory, ImageFileName; ULONG Flags = 0; /* Check if we haven't yet connected to ourselves */ if (!SmApiPort) { /* Connect to ourselves, as a client */ Status = SmConnectToSm(0, 0, 0, &SmApiPort); if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status); return Status; } } /* Parse the initial command line */ Status = SmpParseCommandLine(InitialCommand, &Flags, &ImageFileName, &ImageFileDirectory, &Arguments); if (Flags & SMP_INVALID_PATH) { /* Fail if it doesn't exist */ DPRINT1("SMSS: Initial command image (%wZ) not found\n", &ImageFileName); if (ImageFileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer); return STATUS_OBJECT_NAME_NOT_FOUND; } /* And fail if any other reason is also true */ if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: SmpParseCommandLine( %wZ ) failed - Status == %lx\n", InitialCommand, Status); return Status; } /* Execute the initial command -- but defer its full execution */ Status = SmpExecuteImage(&ImageFileName, &ImageFileDirectory, InitialCommand, MuSessionId, SMP_DEFERRED_FLAG, &ProcessInfo); /* Free any buffers we had lying around */ if (ImageFileName.Buffer) { RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer); } if (ImageFileDirectory.Buffer) { RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileDirectory.Buffer); } if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer); /* Bail out if we couldn't execute the initial command */ if (!NT_SUCCESS(Status)) return Status; /* Now duplicate the handle to this process */ Status = NtDuplicateObject(NtCurrentProcess(), ProcessInfo.ProcessHandle, NtCurrentProcess(), InitialCommandProcess, PROCESS_ALL_ACCESS, 0, 0); if (!NT_SUCCESS(Status)) { /* Kill it utterly if duplication failed */ DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status); NtTerminateProcess(ProcessInfo.ProcessHandle, Status); NtResumeThread(ProcessInfo.ThreadHandle, NULL); NtClose(ProcessInfo.ThreadHandle); NtClose(ProcessInfo.ProcessHandle); return Status; } /* Return PID to the caller, and set this as the initial command PID */ if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess; if (!MuSessionId) SmpInitialCommandProcessId = ProcessInfo.ClientId.UniqueProcess; /* Now call our server execution function to wrap up its initialization */ Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE); if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == %lx\n", Status); return Status; }
BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { NTSTATUS Status; BASESRV_API_CONNECTINFO ConnectInfo; ULONG ConnectInfoSize = sizeof(ConnectInfo); WCHAR SessionDir[256]; DPRINT("DllMain(hInst %p, dwReason %lu)\n", hDll, dwReason); Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString; /* Cache the PEB and Session ID */ Peb = NtCurrentPeb(); SessionId = Peb->SessionId; switch (dwReason) { case DLL_PROCESS_ATTACH: { /* Set no filter initially */ GlobalTopLevelExceptionFilter = RtlEncodePointer(NULL); /* Enable the Rtl thread pool and timer queue to use proper Win32 thread */ RtlSetThreadPoolStartFunc(BaseCreateThreadPoolThread, BaseExitThreadPoolThread); /* Register the manifest prober routine */ LdrSetDllManifestProber(BasepProbeForDllManifest); /* Don't bother us for each thread */ LdrDisableThreadCalloutsForDll((PVOID)hDll); /* Initialize default path to NULL */ RtlInitUnicodeString(&BaseDefaultPath, NULL); /* Setup the Object Directory path */ if (!SessionId) { /* Use the raw path */ wcscpy(SessionDir, WIN_OBJ_DIR); } else { /* Use the session path */ swprintf(SessionDir, L"%ws\\%ld%ws", SESSION_DIR, SessionId, WIN_OBJ_DIR); } /* Connect to the Base Server */ Status = CsrClientConnectToServer(SessionDir, BASESRV_SERVERDLL_INDEX, &ConnectInfo, &ConnectInfoSize, &BaseRunningInServerProcess); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to connect to CSR (Status %lx)\n", Status); NtTerminateProcess(NtCurrentProcess(), Status); return FALSE; } /* Get the server data */ ASSERT(Peb->ReadOnlyStaticServerData); BaseStaticServerData = Peb->ReadOnlyStaticServerData[BASESRV_SERVERDLL_INDEX]; ASSERT(BaseStaticServerData); /* Check if we are running a CSR Server */ if (!BaseRunningInServerProcess) { /* Set the termination port for the thread */ DPRINT("Creating new thread for CSR\n"); CsrNewThread(); } /* Initialize heap handle table */ BaseDllInitializeMemoryManager(); /* Set HMODULE for our DLL */ kernel32_handle = hCurrentModule = hDll; /* Set the directories */ BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory; BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory; /* Construct the default path (using the static buffer) */ _snwprintf(BaseDefaultPathBuffer, sizeof(BaseDefaultPathBuffer) / sizeof(WCHAR), L".;%wZ;%wZ\\system;%wZ;", &BaseWindowsSystemDirectory, &BaseWindowsDirectory, &BaseWindowsDirectory); BaseDefaultPath.Buffer = BaseDefaultPathBuffer; BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR); BaseDefaultPath.MaximumLength = sizeof(BaseDefaultPathBuffer); /* Use remaining part of the default path buffer for the append path */ BaseDefaultPathAppend.Buffer = (PWSTR)((ULONG_PTR)BaseDefaultPathBuffer + BaseDefaultPath.Length); BaseDefaultPathAppend.Length = 0; BaseDefaultPathAppend.MaximumLength = BaseDefaultPath.MaximumLength - BaseDefaultPath.Length; /* Initialize command line */ InitCommandLines(); /* Initialize the DLL critical section */ RtlInitializeCriticalSection(&BaseDllDirectoryLock); /* Initialize the National Language Support routines */ if (!NlsInit()) { DPRINT1("NLS Init failed\n"); return FALSE; } /* Initialize Console Support */ if (!ConDllInitialize(dwReason, SessionDir)) { DPRINT1("Failed to set up console\n"); return FALSE; } /* Initialize application certification globals */ InitializeListHead(&BasepAppCertDllsList); RtlInitializeCriticalSection(&gcsAppCert); /* Insert more dll attach stuff here! */ DllInitialized = TRUE; break; } case DLL_PROCESS_DETACH: { if (DllInitialized != FALSE) { /* Uninitialize console support */ ConDllInitialize(dwReason, NULL); /* Insert more dll detach stuff here! */ NlsUninit(); /* Delete DLL critical section */ RtlDeleteCriticalSection(&BaseDllDirectoryLock); } break; } case DLL_THREAD_ATTACH: { /* ConDllInitialize sets the current console locale for the new thread */ return ConDllInitialize(dwReason, NULL); } default: break; } return TRUE; }
VOID TestParent( VOID ) { NTSTATUS Status; STRING DirectoryName; STRING LinkName; STRING LinkTarget; STRING SectionName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE DirectoryHandle, LinkHandle, SectionHandle; ULONG ReturnedLength; CHAR ObjectInfoBuffer[ 512 ]; OBJECT_BASIC_INFORMATION ObjectBasicInfo; POBJECT_NAME_INFORMATION ObjectNameInfo; POBJECT_TYPE_INFORMATION ObjectTypeInfo; LARGE_INTEGER SectionSize; Status = STATUS_SUCCESS; DbgPrint( "Entering Object Manager User Mode Test Program\n" ); RtlInitString( &SectionName, "\\A:\\OSO001.MSG" ); InitializeObjectAttributes( &ObjectAttributes, &SectionName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, NULL ); SectionSize.LowPart = 0x1000; SectiinSize.HighPart = 0; Status = NtCreateSection( &SectionHandle, GENERIC_READ, &ObjectAttributes, &SectionSize, PAGE_READONLY, SEC_RESERVE, NULL ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to create %Z section object (%X) [OK]\n", &SectionName, Status ); } RtlInitString( &DirectoryName, "\\Drives" ); InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, (PSECURITY_DESCRIPTOR)1 ); ObjectAttributes.Length = 0; Status = NtCreateDirectoryObject( &DirectoryHandle, -1, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to create %Z directory object (%X) [OK]\n", &DirectoryName, Status ); } RtlInitString( &DirectoryName, "\\Drives" ); InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, (PSECURITY_DESCRIPTOR)1 ); ObjectAttributes.Length = 0; Status = NtCreateDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to create %Z directory object (%X) [OK]\n", &DirectoryName, Status ); } InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, -1, NULL, (PSECURITY_DESCRIPTOR)1 ); Status = NtCreateDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to create %Z directory object (%X) [OK]\n", &DirectoryName, Status ); } InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, (PSECURITY_DESCRIPTOR)1 ); Status = NtCreateDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to create %Z directory object (%X) [OK]\n", &DirectoryName, Status ); } InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL ); Status = NtCreateDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to create %Z directory object (%X)\n", &DirectoryName, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } Status = NtClose( DirectoryHandle ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to close %Z directory object handle - %lx (%X)\n", &DirectoryName, DirectoryHandle, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = NtOpenDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to open %Z directory object (%X)\n", &DirectoryName, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } Status = NtQueryObject( DirectoryHandle, ObjectBasicInformation, &ObjectBasicInfo, sizeof( ObjectBasicInfo ), &ReturnedLength ); if (!NT_SUCCESS( Status )) { DbgPrint( "NtQueryObject( %lx, ObjectBasicInfo ) failed - Status == %X\n", DirectoryHandle, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } DbgPrint( "NtQueryObject( %lx, ObjectBasicInfo ) returned %lx bytes\n", DirectoryHandle, ReturnedLength ); DbgPrint( " Attributes = %lx\n", ObjectBasicInfo.Attributes ); DbgPrint( " GrantedAccess = %lx\n", ObjectBasicInfo.GrantedAccess ); DbgPrint( " HandleCount = %lx\n", ObjectBasicInfo.HandleCount ); DbgPrint( " PointerCount = %lx\n", ObjectBasicInfo.PointerCount ); DbgPrint( " PagedPoolCharge = %lx\n", ObjectBasicInfo.PagedPoolCharge ); DbgPrint( " NonPagedPoolCharge = %lx\n", ObjectBasicInfo.NonPagedPoolCharge ); DbgPrint( " NameInfoSize = %lx\n", ObjectBasicInfo.NameInfoSize ); DbgPrint( " TypeInfoSize = %lx\n", ObjectBasicInfo.TypeInfoSize ); DbgPrint( " SecurityDescriptorSize = %lx\n", ObjectBasicInfo.SecurityDescriptorSize ); ObjectNameInfo = (POBJECT_NAME_INFORMATION)ObjectInfoBuffer; Status = NtQueryObject( DirectoryHandle, ObjectNameInformation, ObjectNameInfo, sizeof( ObjectInfoBuffer ), &ReturnedLength ); if (!NT_SUCCESS( Status )) { DbgPrint( "NtQueryObject( %lx, ObjectNameInfo ) failed - Status == %X\n", DirectoryHandle, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } DbgPrint( "NtQueryObject( %lx, ObjectNameInfo ) returned %lx bytes\n", DirectoryHandle, ReturnedLength ); DbgPrint( " Name = (%ld,%ld) '%Z'\n", ObjectNameInfo->Name.MaximumLength, ObjectNameInfo->Name.Length, &ObjectNameInfo->Name ); ObjectTypeInfo = (POBJECT_TYPE_INFORMATION)ObjectInfoBuffer; Status = NtQueryObject( DirectoryHandle, ObjectTypeInformation, ObjectTypeInfo, sizeof( ObjectInfoBuffer ), &ReturnedLength ); if (!NT_SUCCESS( Status )) { DbgPrint( "NtQueryObject( %lx, ObjectTypeInfo ) failed - Status == %X\n", DirectoryHandle, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } DbgPrint( "NtQueryObject( %lx, ObjectTypeInfo ) returned %lx bytes\n", DirectoryHandle, ReturnedLength ); DbgPrint( " TypeName = (%ld,%ld) '%Z'\n", ObjectTypeInfo->TypeName.MaximumLength, ObjectTypeInfo->TypeName.Length, &ObjectTypeInfo->TypeName ); RtlInitString( &LinkName, "TestSymbolicLink" ); InitializeObjectAttributes( &ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObjectAttributes.RootDirectory = DirectoryHandle; RtlInitString( &LinkTarget, "\\Device\\FileSystem" ); Status = NtCreateSymbolicLinkObject( &LinkHandle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes, &LinkTarget ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to create %Z => %Z symbolic link object (%X)\n", &LinkName, &LinkTarget, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } Status = NtClose( DirectoryHandle ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to close %Z directory object handle - %lx (%X)\n", &DirectoryName, DirectoryHandle, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } RtlInitString( &DirTypeName, "Directory" ); RtlInitString( &LinkTypeName, "SymbolicLink" ); DumpObjectDirs( "\\", 0 ); RtlInitString( &LinkName, "TestSymbolicLink" ); InitializeObjectAttributes( &ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObjectAttributes.RootDirectory = LinkHandle; Status = NtOpenDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to open %Z directory object (%X) [OK]\n", &DirectoryName, Status ); } Status = NtClose( LinkHandle ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to close %Z symbolic link handle - %lx (%X)\n", &LinkName, LinkHandle, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = NtOpenDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to open %Z directory object (%X)\n", &DirectoryName, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } Status = NtMakeTemporaryObject( DirectoryHandle ); if (!NT_SUCCESS( Status )) { DbgPrint( "NtMakeTemporaryObject( %lx ) failed - Status == %X\n", DirectoryHandle, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } Status = NtClose( DirectoryHandle ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to close %Z directory object handle - %lx (%X)\n", &DirectoryName, DirectoryHandle, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = NtOpenDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to open %Z directory object (%X) [OK]\n", &DirectoryName, Status ); } RtlInitString( &DirectoryName, "\\ExclusiveDir" ); InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE | OBJ_EXCLUSIVE, NULL, NULL ); Status = NtCreateDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to create %Z directory object (%X)\n", &DirectoryName, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE | OBJ_EXCLUSIVE, NULL, NULL ); Status = NtOpenDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to open %Z directory object (%X)\n", &DirectoryName, Status ); NtTerminateProcess( NtCurrentProcess(), Status ); } InitializeObjectAttributes( &ObjectAttributes, &DirectoryName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = NtOpenDirectoryObject( &DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { DbgPrint( "Unable to open %Z directory object (%X) [OK]\n", &DirectoryName, Status ); } DbgPrint( "Exiting Object Manager User Mode Test Program with Status = %X\n", Status ); }
NTSTATUS PhCommandModeStart( VOID ) { static PH_COMMAND_LINE_OPTION options[] = { { PH_COMMAND_OPTION_HWND, L"hwnd", MandatoryArgumentType } }; NTSTATUS status; PPH_STRING commandLine; if (!NT_SUCCESS(status = PhGetProcessCommandLine(NtCurrentProcess(), &commandLine))) return status; PhParseCommandLine( &commandLine->sr, options, sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION), PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS, PhpCommandModeOptionCallback, NULL ); PhDereferenceObject(commandLine); if (PhEqualString2(PhStartupParameters.CommandType, L"process", TRUE)) { SIZE_T i; SIZE_T processIdLength; HANDLE processId; HANDLE processHandle; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; processIdLength = PhStartupParameters.CommandObject->Length / 2; for (i = 0; i < processIdLength; i++) { if (!PhIsDigitCharacter(PhStartupParameters.CommandObject->Buffer[i])) break; } if (i == processIdLength) { ULONG64 processId64; if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &processId64)) return STATUS_INVALID_PARAMETER; processId = (HANDLE)processId64; } else { PVOID processes; PSYSTEM_PROCESS_INFORMATION process; if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; if (!(process = PhFindProcessInformationByImageName(processes, &PhStartupParameters.CommandObject->sr))) { PhFree(processes); return STATUS_NOT_FOUND; } processId = process->UniqueProcessId; PhFree(processes); } if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_TERMINATE, processId))) { status = NtTerminateProcess(processHandle, STATUS_SUCCESS); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId))) { status = NtSuspendProcess(processHandle); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId))) { status = NtResumeProcess(processHandle); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"priority", TRUE)) { UCHAR priority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandValue, L"idle", TRUE)) priority = PROCESS_PRIORITY_CLASS_IDLE; else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE)) priority = PROCESS_PRIORITY_CLASS_NORMAL; else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE)) priority = PROCESS_PRIORITY_CLASS_HIGH; else if (PhEqualString2(PhStartupParameters.CommandValue, L"realtime", TRUE)) priority = PROCESS_PRIORITY_CLASS_REALTIME; else if (PhEqualString2(PhStartupParameters.CommandValue, L"abovenormal", TRUE)) priority = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; else if (PhEqualString2(PhStartupParameters.CommandValue, L"belownormal", TRUE)) priority = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; else return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { PROCESS_PRIORITY_CLASS priorityClass; priorityClass.Foreground = FALSE; priorityClass.PriorityClass = priority; status = NtSetInformationProcess(processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS)); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"iopriority", TRUE)) { ULONG ioPriority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandValue, L"verylow", TRUE)) ioPriority = 0; else if (PhEqualString2(PhStartupParameters.CommandValue, L"low", TRUE)) ioPriority = 1; else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE)) ioPriority = 2; else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE)) ioPriority = 3; else return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { status = PhSetProcessIoPriority(processHandle, ioPriority); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"pagepriority", TRUE)) { ULONG64 pagePriority64; ULONG pagePriority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; PhStringToInteger64(&PhStartupParameters.CommandValue->sr, 10, &pagePriority64); pagePriority = (ULONG)pagePriority64; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { status = NtSetInformationProcess( processHandle, ProcessPagePriority, &pagePriority, sizeof(ULONG) ); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"injectdll", TRUE)) { if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic( &processHandle, ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, processId ))) { LARGE_INTEGER timeout; timeout.QuadPart = -5 * PH_TIMEOUT_SEC; status = PhInjectDllProcess( processHandle, PhStartupParameters.CommandValue->Buffer, &timeout ); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"unloaddll", TRUE)) { if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic( &processHandle, ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, processId ))) { PVOID baseAddress; if (NT_SUCCESS(status = PhpGetDllBaseRemote( processHandle, &PhStartupParameters.CommandValue->sr, &baseAddress ))) { LARGE_INTEGER timeout; timeout.QuadPart = -5 * PH_TIMEOUT_SEC; status = PhUnloadDllProcess( processHandle, baseAddress, &timeout ); } NtClose(processHandle); } } } else if (PhEqualString2(PhStartupParameters.CommandType, L"service", TRUE)) { SC_HANDLE serviceHandle; SERVICE_STATUS serviceStatus; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandAction, L"start", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_START ))) return PhGetLastWin32ErrorAsNtStatus(); if (!StartService(serviceHandle, 0, NULL)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"continue", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_PAUSE_CONTINUE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_CONTINUE, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"pause", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_PAUSE_CONTINUE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_PAUSE, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"stop", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_STOP ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"delete", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, DELETE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!DeleteService(serviceHandle)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } } else if (PhEqualString2(PhStartupParameters.CommandType, L"thread", TRUE)) { ULONG64 threadId64; HANDLE threadId; HANDLE threadHandle; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &threadId64)) return STATUS_INVALID_PARAMETER; threadId = (HANDLE)threadId64; if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_TERMINATE, threadId))) { status = NtTerminateThread(threadHandle, STATUS_SUCCESS); NtClose(threadHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId))) { status = NtSuspendThread(threadHandle, NULL); NtClose(threadHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId))) { status = NtResumeThread(threadHandle, NULL); NtClose(threadHandle); } } } return status; }
ForceInline VOID main2(Int argc, WChar **argv) { NTSTATUS Status; WCHAR *pExePath, szDllPath[MAX_NTPATH], FullExePath[MAX_NTPATH]; STARTUPINFOW si; PROCESS_INFORMATION pi; #if 0 PVOID buf; // CNtFileDisk file; UNICODE_STRING str; // file.Open((FIELD_BASE(FindLdrModuleByName(NULL)->InLoadOrderModuleList.Flink, LDR_MODULE, InLoadOrderModuleList))->FullDllName.Buffer); // buf = AllocateMemory(file.GetSize32()); // file.Read(buf); // file.Close(); RTL_CONST_STRING(str, L"OllyDbg.exe"); LoadDllFromMemory(GetNtdllHandle(), -1, &str, NULL, LMD_MAPPED_DLL); PrintConsoleW( L"%s handle = %08X\n" L"%s.NtSetEvent = %08X\n", str.Buffer, GetModuleHandleW(str.Buffer), str.Buffer, Nt_GetProcAddress(GetModuleHandleW(str.Buffer), "NtSetEvent") ); getch(); FreeMemory(buf); return; #endif #if 1 if (argc == 1) return; RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, (PBOOLEAN)&Status); while (--argc) { pExePath = findextw(*++argv); if (CHAR_UPPER4W(*(PULONG64)pExePath) == CHAR_UPPER4W(TAG4W('.LNK'))) { if (FAILED(GetPathFromLinkFile(*argv, FullExePath, countof(FullExePath)))) { pExePath = *argv; } else { pExePath = FullExePath; } } else { pExePath = *argv; } RtlGetFullPathName_U(pExePath, sizeof(szDllPath), szDllPath, NULL); #if 0 Status = FakeCreateProcess(szDllPath, NULL); if (!NT_SUCCESS(Status)) #else rmnamew(szDllPath); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); Status = CreateProcessInternalW( NULL, pExePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, *szDllPath == 0 ? NULL : szDllPath, &si, &pi, NULL); if (!Status) #endif { PrintConsoleW(L"%s: CreateProcess() failed\n", pExePath); continue; } ULONG Length; UNICODE_STRING DllFullPath; Length = Nt_GetExeDirectory(szDllPath, countof(szDllPath)); CopyStruct(szDllPath + Length, L"XP3Viewer.dll", sizeof(L"XP3Viewer.dll")); DllFullPath.Buffer = szDllPath; DllFullPath.Length = (USHORT)(Length + CONST_STRLEN(L"XP3Viewer.dll")); DllFullPath.Length *= sizeof(WCHAR); DllFullPath.MaximumLength = DllFullPath.Length; Status = InjectDllToRemoteProcess(pi.hProcess, pi.hThread, &DllFullPath, FALSE); if (!NT_SUCCESS(Status)) { // PrintError(GetLastError()); NtTerminateProcess(pi.hProcess, 0); } NtClose(pi.hProcess); NtClose(pi.hThread); } #endif }
/** * @brief Aborts the application in the out of memory condition case * when no custom killer is set by the winx_set_killer routine. */ int default_killer(size_t n) { /* terminate process with exit code 3 */ NtTerminateProcess(NtCurrentProcess(),3); return 0; }