Example #1
0
VOID SetupParseCommandLine(
    VOID
    )
{
    static PH_COMMAND_LINE_OPTION options[] =
    {
        { SETUP_COMMAND_INSTALL, L"install", NoArgumentType },
        { SETUP_COMMAND_UNINSTALL, L"uninstall", NoArgumentType },
        { SETUP_COMMAND_UPDATE, L"update", NoArgumentType },
        { SETUP_COMMAND_REPAIR, L"repair", NoArgumentType },
        { SETUP_COMMAND_SILENTINSTALL, L"silent", NoArgumentType },
    };
    PPH_STRING commandLine;

    if (NT_SUCCESS(PhGetProcessCommandLine(NtCurrentProcess(), &commandLine)))
    {
        PhParseCommandLine(
            &commandLine->sr,
            options,
            ARRAYSIZE(options),
            PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS | PH_COMMAND_LINE_IGNORE_FIRST_PART,
            MainPropSheetCommandLineCallback,
            NULL
            );

        PhDereferenceObject(commandLine);
    }
}
Example #2
0
INT WINAPI WinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPSTR lpCmdLine,
    _In_ INT nCmdShow
    )
{
    PH_STRINGREF commandLine;

    BeInstanceHandle = hInstance;

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    PhInitializePhLibEx(PHLIB_INIT_MODULE_FILE_STREAM, 512 * 1024, 16 * 1024);

    PhApplicationName = L"Backup Explorer";

    PhUnicodeStringToStringRef(&NtCurrentPeb()->ProcessParameters->CommandLine, &commandLine);
    PhParseCommandLine(
        &commandLine,
        NULL,
        0,
        PH_COMMAND_LINE_IGNORE_FIRST_PART,
        BeCommandLineCallback,
        NULL
        );

    PhGuiSupportInitialization();
    PhTreeNewInitialization();

    BeWindowHandle = CreateDialog(
        hInstance,
        MAKEINTRESOURCE(IDD_EXPLORER),
        NULL,
        BeExplorerDlgProc
        );
    BeRegisterDialog(BeWindowHandle);
    ShowWindow(BeWindowHandle, SW_SHOW);

    return BeMessageLoop();
}
VOID PhpProcessStartupParameters(
    VOID
)
{
    static PH_COMMAND_LINE_OPTION options[] =
    {
        { PH_ARG_SETTINGS, L"settings", MandatoryArgumentType },
        { PH_ARG_NOSETTINGS, L"nosettings", NoArgumentType },
        { PH_ARG_SHOWVISIBLE, L"v", NoArgumentType },
        { PH_ARG_SHOWHIDDEN, L"hide", NoArgumentType },
        { PH_ARG_COMMANDMODE, L"c", NoArgumentType },
        { PH_ARG_COMMANDTYPE, L"ctype", MandatoryArgumentType },
        { PH_ARG_COMMANDOBJECT, L"cobject", MandatoryArgumentType },
        { PH_ARG_COMMANDACTION, L"caction", MandatoryArgumentType },
        { PH_ARG_COMMANDVALUE, L"cvalue", MandatoryArgumentType },
        { PH_ARG_RUNASSERVICEMODE, L"ras", MandatoryArgumentType },
        { PH_ARG_NOKPH, L"nokph", NoArgumentType },
        { PH_ARG_INSTALLKPH, L"installkph", NoArgumentType },
        { PH_ARG_UNINSTALLKPH, L"uninstallkph", NoArgumentType },
        { PH_ARG_DEBUG, L"debug", NoArgumentType },
        { PH_ARG_HWND, L"hwnd", MandatoryArgumentType },
        { PH_ARG_POINT, L"point", MandatoryArgumentType },
        { PH_ARG_SHOWOPTIONS, L"showoptions", NoArgumentType },
        { PH_ARG_PHSVC, L"phsvc", NoArgumentType },
        { PH_ARG_NOPLUGINS, L"noplugins", NoArgumentType },
        { PH_ARG_NEWINSTANCE, L"newinstance", NoArgumentType },
        { PH_ARG_ELEVATE, L"elevate", NoArgumentType },
        { PH_ARG_SILENT, L"s", NoArgumentType },
        { PH_ARG_HELP, L"help", NoArgumentType },
        { PH_ARG_SELECTPID, L"selectpid", MandatoryArgumentType },
        { PH_ARG_PRIORITY, L"priority", MandatoryArgumentType },
        { PH_ARG_PLUGIN, L"plugin", MandatoryArgumentType },
        { PH_ARG_SELECTTAB, L"selecttab", MandatoryArgumentType }
    };
    PH_STRINGREF commandLine;

    PhUnicodeStringToStringRef(&NtCurrentPeb()->ProcessParameters->CommandLine, &commandLine);

    memset(&PhStartupParameters, 0, sizeof(PH_STARTUP_PARAMETERS));

    if (!PhParseCommandLine(
                &commandLine,
                options,
                sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
                PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS | PH_COMMAND_LINE_IGNORE_FIRST_PART,
                PhpCommandLineOptionCallback,
                NULL
            ) || PhStartupParameters.Help)
    {
        PhShowInformation(
            NULL,
            L"Command line options:\n\n"
            L"-c\n"
            L"-ctype command-type\n"
            L"-cobject command-object\n"
            L"-caction command-action\n"
            L"-cvalue command-value\n"
            L"-debug\n"
            L"-elevate\n"
            L"-help\n"
            L"-hide\n"
            L"-installkph\n"
            L"-newinstance\n"
            L"-nokph\n"
            L"-noplugins\n"
            L"-nosettings\n"
            L"-plugin pluginname:value\n"
            L"-priority r|h|n|l\n"
            L"-s\n"
            L"-selectpid pid-to-select\n"
            L"-selecttab name-of-tab-to-select\n"
            L"-settings filename\n"
            L"-uninstallkph\n"
            L"-v\n"
        );

        if (PhStartupParameters.Help)
            RtlExitUserProcess(STATUS_SUCCESS);
    }

    if (PhStartupParameters.InstallKph)
    {
        NTSTATUS status;
        PPH_STRING kprocesshackerFileName;
        KPH_PARAMETERS parameters;

        kprocesshackerFileName = PhConcatStrings2(PhApplicationDirectory->Buffer, L"\\kprocesshacker.sys");

        parameters.SecurityLevel = KphSecurityNone;
        parameters.CreateDynamicConfiguration = TRUE;

        status = KphInstallEx(L"KProcessHacker2", kprocesshackerFileName->Buffer, &parameters);

        if (!NT_SUCCESS(status) && !PhStartupParameters.Silent)
            PhShowStatus(NULL, L"Unable to install KProcessHacker", status, 0);

        RtlExitUserProcess(status);
    }

    if (PhStartupParameters.UninstallKph)
    {
        NTSTATUS status;

        status = KphUninstall(L"KProcessHacker2");

        if (!NT_SUCCESS(status) && !PhStartupParameters.Silent)
            PhShowStatus(NULL, L"Unable to uninstall KProcessHacker", status, 0);

        RtlExitUserProcess(status);
    }

    if (PhStartupParameters.Elevate && !PhElevated)
    {
        PhShellProcessHacker(
            NULL,
            NULL,
            SW_SHOW,
            PH_SHELL_EXECUTE_ADMIN,
            PH_SHELL_APP_PROPAGATE_PARAMETERS | PH_SHELL_APP_PROPAGATE_PARAMETERS_FORCE_SETTINGS,
            0,
            NULL
        );
        RtlExitUserProcess(STATUS_SUCCESS);
    }

    if (PhStartupParameters.Debug)
    {
        // The symbol provider won't work if this is chosen.
        PhShowDebugConsole();
    }
}
NTSTATUS PhCommandModeStart(
    VOID
    )
{
    static PH_COMMAND_LINE_OPTION options[] =
    {
        { PH_COMMAND_OPTION_HWND, L"hwnd", MandatoryArgumentType }
    };
    NTSTATUS status;
    PPH_STRING commandLine;

    if (!NT_SUCCESS(status = PhGetProcessCommandLine(NtCurrentProcess(), &commandLine)))
        return status;

    PhParseCommandLine(
        &commandLine->sr,
        options,
        sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
        PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS,
        PhpCommandModeOptionCallback,
        NULL
        );
    PhDereferenceObject(commandLine);

    if (PhEqualString2(PhStartupParameters.CommandType, L"process", TRUE))
    {
        SIZE_T i;
        SIZE_T processIdLength;
        HANDLE processId;
        HANDLE processHandle;

        if (!PhStartupParameters.CommandObject)
            return STATUS_INVALID_PARAMETER;

        processIdLength = PhStartupParameters.CommandObject->Length / 2;

        for (i = 0; i < processIdLength; i++)
        {
            if (!PhIsDigitCharacter(PhStartupParameters.CommandObject->Buffer[i]))
                break;
        }

        if (i == processIdLength)
        {
            ULONG64 processId64;

            if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &processId64))
                return STATUS_INVALID_PARAMETER;

            processId = (HANDLE)processId64;
        }
        else
        {
            PVOID processes;
            PSYSTEM_PROCESS_INFORMATION process;

            if (!NT_SUCCESS(status = PhEnumProcesses(&processes)))
                return status;

            if (!(process = PhFindProcessInformationByImageName(processes, &PhStartupParameters.CommandObject->sr)))
            {
                PhFree(processes);
                return STATUS_NOT_FOUND;
            }

            processId = process->UniqueProcessId;
            PhFree(processes);
        }

        if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_TERMINATE, processId)))
            {
                status = NtTerminateProcess(processHandle, STATUS_SUCCESS);
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId)))
            {
                status = NtSuspendProcess(processHandle);
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId)))
            {
                status = NtResumeProcess(processHandle);
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"priority", TRUE))
        {
            UCHAR priority;

            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            if (PhEqualString2(PhStartupParameters.CommandValue, L"idle", TRUE))
                priority = PROCESS_PRIORITY_CLASS_IDLE;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE))
                priority = PROCESS_PRIORITY_CLASS_NORMAL;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE))
                priority = PROCESS_PRIORITY_CLASS_HIGH;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"realtime", TRUE))
                priority = PROCESS_PRIORITY_CLASS_REALTIME;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"abovenormal", TRUE))
                priority = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"belownormal", TRUE))
                priority = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
            else
                return STATUS_INVALID_PARAMETER;

            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId)))
            {
                PROCESS_PRIORITY_CLASS priorityClass;
                priorityClass.Foreground = FALSE;
                priorityClass.PriorityClass = priority;
                status = NtSetInformationProcess(processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS));
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"iopriority", TRUE))
        {
            ULONG ioPriority;

            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            if (PhEqualString2(PhStartupParameters.CommandValue, L"verylow", TRUE))
                ioPriority = 0;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"low", TRUE))
                ioPriority = 1;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE))
                ioPriority = 2;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE))
                ioPriority = 3;
            else
                return STATUS_INVALID_PARAMETER;

            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId)))
            {
                status = PhSetProcessIoPriority(processHandle, ioPriority);
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"pagepriority", TRUE))
        {
            ULONG64 pagePriority64;
            ULONG pagePriority;

            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            PhStringToInteger64(&PhStartupParameters.CommandValue->sr, 10, &pagePriority64);
            pagePriority = (ULONG)pagePriority64;

            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId)))
            {
                status = NtSetInformationProcess(
                    processHandle,
                    ProcessPagePriority,
                    &pagePriority,
                    sizeof(ULONG)
                    );
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"injectdll", TRUE))
        {
            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            if (NT_SUCCESS(status = PhOpenProcessPublic(
                &processHandle,
                ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
                processId
                )))
            {
                LARGE_INTEGER timeout;

                timeout.QuadPart = -5 * PH_TIMEOUT_SEC;
                status = PhInjectDllProcess(
                    processHandle,
                    PhStartupParameters.CommandValue->Buffer,
                    &timeout
                    );
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"unloaddll", TRUE))
        {
            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            if (NT_SUCCESS(status = PhOpenProcessPublic(
                &processHandle,
                ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
                processId
                )))
            {
                PVOID baseAddress;

                if (NT_SUCCESS(status = PhpGetDllBaseRemote(
                    processHandle,
                    &PhStartupParameters.CommandValue->sr,
                    &baseAddress
                    )))
                {
                    LARGE_INTEGER timeout;

                    timeout.QuadPart = -5 * PH_TIMEOUT_SEC;
                    status = PhUnloadDllProcess(
                        processHandle,
                        baseAddress,
                        &timeout
                        );
                }

                NtClose(processHandle);
            }
        }
    }
    else if (PhEqualString2(PhStartupParameters.CommandType, L"service", TRUE))
    {
        SC_HANDLE serviceHandle;
        SERVICE_STATUS serviceStatus;

        if (!PhStartupParameters.CommandObject)
            return STATUS_INVALID_PARAMETER;

        if (PhEqualString2(PhStartupParameters.CommandAction, L"start", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                SERVICE_START
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!StartService(serviceHandle, 0, NULL))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"continue", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                SERVICE_PAUSE_CONTINUE
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!ControlService(serviceHandle, SERVICE_CONTROL_CONTINUE, &serviceStatus))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"pause", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                SERVICE_PAUSE_CONTINUE
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!ControlService(serviceHandle, SERVICE_CONTROL_PAUSE, &serviceStatus))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"stop", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                SERVICE_STOP
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"delete", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                DELETE
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!DeleteService(serviceHandle))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
    }
    else if (PhEqualString2(PhStartupParameters.CommandType, L"thread", TRUE))
    {
        ULONG64 threadId64;
        HANDLE threadId;
        HANDLE threadHandle;

        if (!PhStartupParameters.CommandObject)
            return STATUS_INVALID_PARAMETER;

        if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &threadId64))
            return STATUS_INVALID_PARAMETER;

        threadId = (HANDLE)threadId64;

        if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_TERMINATE, threadId)))
            {
                status = NtTerminateThread(threadHandle, STATUS_SUCCESS);
                NtClose(threadHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId)))
            {
                status = NtSuspendThread(threadHandle, NULL);
                NtClose(threadHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId)))
            {
                status = NtResumeThread(threadHandle, NULL);
                NtClose(threadHandle);
            }
        }
    }

    return status;
}
Example #5
0
BOOLEAN PhaGetProcessKnownCommandLine(
    __in PPH_STRING CommandLine,
    __in PH_KNOWN_PROCESS_TYPE KnownProcessType,
    __out PPH_KNOWN_PROCESS_COMMAND_LINE KnownCommandLine
    )
{
    switch (KnownProcessType & KnownProcessTypeMask)
    {
    case ServiceHostProcessType:
        {
            // svchost.exe -k <GroupName>

            static PH_COMMAND_LINE_OPTION options[] =
            {
                { 1, L"k", MandatoryArgumentType }
            };

            KnownCommandLine->ServiceHost.GroupName = NULL;

            PhParseCommandLine(
                &CommandLine->sr,
                options,
                sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
                PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS,
                PhpSvchostCommandLineCallback,
                KnownCommandLine
                );

            if (KnownCommandLine->ServiceHost.GroupName)
            {
                PhaDereferenceObject(KnownCommandLine->ServiceHost.GroupName);
                return TRUE;
            }
            else
            {
                return FALSE;
            }
        }
        break;
    case RunDllAsAppProcessType:
        {
            // rundll32.exe <DllName>,<ProcedureName> ...

            SIZE_T i;
            ULONG_PTR lastIndexOfComma;
            PPH_STRING dllName;
            PPH_STRING procedureName;

            i = 0;

            // Get the rundll32.exe part.

            dllName = PhParseCommandLinePart(&CommandLine->sr, &i);

            if (!dllName)
                return FALSE;

            PhDereferenceObject(dllName);

            // Get the DLL name part.

            while (i < CommandLine->Length / 2 && CommandLine->Buffer[i] == ' ')
                i++;

            dllName = PhParseCommandLinePart(&CommandLine->sr, &i);

            if (!dllName)
                return FALSE;

            PhaDereferenceObject(dllName);

            // The procedure name begins after the last comma.

            lastIndexOfComma = PhFindLastCharInString(dllName, 0, ',');

            if (lastIndexOfComma == -1)
                return FALSE;

            procedureName = PhaSubstring(
                dllName,
                lastIndexOfComma + 1,
                dllName->Length / 2 - lastIndexOfComma - 1
                );
            dllName = PhaSubstring(dllName, 0, lastIndexOfComma);

            // If the DLL name isn't an absolute path, assume it's in system32.
            // TODO: Use a proper search function.

            if (RtlDetermineDosPathNameType_U(dllName->Buffer) == RtlPathTypeRelative)
            {
                dllName = PhaConcatStrings(
                    3,
                    ((PPH_STRING)PHA_DEREFERENCE(PhGetSystemDirectory()))->Buffer,
                    L"\\",
                    dllName->Buffer
                    );
            }

            KnownCommandLine->RunDllAsApp.FileName = dllName;
            KnownCommandLine->RunDllAsApp.ProcedureName = procedureName;
        }
        break;
    case ComSurrogateProcessType:
        {
            // dllhost.exe /processid:<Guid>

            static PH_STRINGREF inprocServer32Name = PH_STRINGREF_INIT(L"InprocServer32");

            SIZE_T i;
            ULONG_PTR indexOfProcessId;
            PPH_STRING argPart;
            PPH_STRING guidString;
            UNICODE_STRING guidStringUs;
            GUID guid;
            HANDLE clsidKeyHandle;
            HANDLE inprocServer32KeyHandle;
            PPH_STRING fileName;

            i = 0;

            // Get the dllhost.exe part.

            argPart = PhParseCommandLinePart(&CommandLine->sr, &i);

            if (!argPart)
                return FALSE;

            PhDereferenceObject(argPart);

            // Get the argument part.

            while (i < (ULONG)CommandLine->Length / 2 && CommandLine->Buffer[i] == ' ')
                i++;

            argPart = PhParseCommandLinePart(&CommandLine->sr, &i);

            if (!argPart)
                return FALSE;

            PhaDereferenceObject(argPart);

            // Find "/processid:"; the GUID is just after that.

            PhUpperString(argPart);
            indexOfProcessId = PhFindStringInString(argPart, 0, L"/PROCESSID:");

            if (indexOfProcessId == -1)
                return FALSE;

            guidString = PhaSubstring(
                argPart,
                indexOfProcessId + 11,
                (ULONG)argPart->Length / 2 - indexOfProcessId - 11
                );
            PhStringRefToUnicodeString(&guidString->sr, &guidStringUs);

            if (!NT_SUCCESS(RtlGUIDFromString(
                &guidStringUs,
                &guid
                )))
                return FALSE;

            KnownCommandLine->ComSurrogate.Guid = guid;
            KnownCommandLine->ComSurrogate.Name = NULL;
            KnownCommandLine->ComSurrogate.FileName = NULL;

            // Lookup the GUID in the registry to determine the name and file name.

            if (NT_SUCCESS(PhOpenKey(
                &clsidKeyHandle,
                KEY_READ,
                PH_KEY_CLASSES_ROOT,
                &PhaConcatStrings2(L"CLSID\\", guidString->Buffer)->sr,
                0
                )))
            {
                KnownCommandLine->ComSurrogate.Name =
                    PHA_DEREFERENCE(PhQueryRegistryString(clsidKeyHandle, NULL));

                if (NT_SUCCESS(PhOpenKey(
                    &inprocServer32KeyHandle,
                    KEY_READ,
                    clsidKeyHandle,
                    &inprocServer32Name,
                    0
                    )))
                {
                    KnownCommandLine->ComSurrogate.FileName =
                        PHA_DEREFERENCE(PhQueryRegistryString(inprocServer32KeyHandle, NULL));

                    if (fileName = PHA_DEREFERENCE(PhExpandEnvironmentStrings(
                        &KnownCommandLine->ComSurrogate.FileName->sr
                        )))
                    {
                        KnownCommandLine->ComSurrogate.FileName = fileName;
                    }

                    NtClose(inprocServer32KeyHandle);
                }

                NtClose(clsidKeyHandle);
            }
        }
        break;
    default:
        return FALSE;
    }

    return TRUE;
}
Example #6
0
int __cdecl main(int argc, char *argv[])
{
    static PH_COMMAND_LINE_OPTION options[] =
    {
        { FI_ARG_HELP, L"h", NoArgumentType },
        { FI_ARG_ACTION, L"a", MandatoryArgumentType },
        { FI_ARG_NATIVE, L"N", NoArgumentType },
        { FI_ARG_PATTERN, L"p", MandatoryArgumentType },
        { FI_ARG_CASESENSITIVE, L"C", NoArgumentType },
        { FI_ARG_OUTPUT, L"o", MandatoryArgumentType },
        { FI_ARG_FORCE, L"f", NoArgumentType },
        { FI_ARG_LENGTH, L"L", MandatoryArgumentType }
    };
    PH_STRINGREF commandLine;
    NTSTATUS status = STATUS_SUCCESS;

    if (!NT_SUCCESS(PhInitializePhLibEx(0, 0, 0)))
        return 1;

    PhUnicodeStringToStringRef(&NtCurrentPeb()->ProcessParameters->CommandLine, &commandLine);

    if (!PhParseCommandLine(
        &commandLine,
        options,
        sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
        PH_COMMAND_LINE_IGNORE_FIRST_PART,
        FiCommandLineCallback,
        NULL
        ) || FiArgHelp)
    {
        FiPrintHelp();
        return 0;
    }

    if (!FiArgFileName && (
        FiArgAction &&
        PhEqualString2(FiArgAction, L"dir", TRUE)
        ))
    {
        FiArgFileName = PhCreateStringFromUnicodeString(&NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath);
    }

    if (!FiArgAction)
    {
        FiPrintHelp();
        return 1;
    }
    else if (PhEqualString2(FiArgAction, L"map", TRUE))
    {
        WCHAR deviceNameBuffer[7] = L"\\??\\ :";
        ULONG i;
        WCHAR targetNameBuffer[0x100];
        UNICODE_STRING targetName;

        targetName.Buffer = targetNameBuffer;
        targetName.MaximumLength = sizeof(targetNameBuffer);

        for (i = 0; i < 26; i++)
        {
            HANDLE linkHandle;
            OBJECT_ATTRIBUTES oa;
            UNICODE_STRING deviceName;

            deviceNameBuffer[4] = (WCHAR)('A' + i);
            deviceName.Buffer = deviceNameBuffer;
            deviceName.Length = 6 * sizeof(WCHAR);

            InitializeObjectAttributes(
                &oa,
                &deviceName,
                OBJ_CASE_INSENSITIVE,
                NULL,
                NULL
                );

            if (NT_SUCCESS(NtOpenSymbolicLinkObject(
                &linkHandle,
                SYMBOLIC_LINK_QUERY,
                &oa
                )))
            {
                if (NT_SUCCESS(NtQuerySymbolicLinkObject(
                    linkHandle,
                    &targetName,
                    NULL
                    )))
                {
                    wprintf(L"%c: %.*s\n", 'A' + i, targetName.Length / 2, targetName.Buffer);
                }

                NtClose(linkHandle);
            }
        }
    }
    else if (!FiArgFileName)
    {
        wprintf(L"Error: file name missing.\n");
        FiPrintHelp();
        return 1;
    }
    else if (PhEqualString2(FiArgAction, L"hash", TRUE))
    {
        HANDLE fileHandle;
        LARGE_INTEGER fileSize;
        IO_STATUS_BLOCK isb;
        ULONG mode;

        if (!FiArgOutput)
            mode = HASH_MD5;
        else if (PhEqualString2(FiArgOutput, L"md5", TRUE))
            mode = HASH_MD5;
        else if (PhEqualString2(FiArgOutput, L"sha1", TRUE))
            mode = HASH_SHA1;
        else if (PhEqualString2(FiArgOutput, L"crc32", TRUE))
            mode = HASH_CRC32;
        else
        {
            wprintf(L"Invalid hash algorithm. Possibilities: md5, sha1, crc32\n");
            return 1;
        }

        if (FiCreateFile(
            &fileHandle,
            FILE_GENERIC_READ,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY
            ))
        {
            if (NT_SUCCESS(status = PhGetFileSize(fileHandle, &fileSize)))
            {
                MD5_CTX md5Context;
                A_SHA_CTX shaContext;
                ULONG crc;
                UCHAR buffer[PAGE_SIZE * 4];
                ULONG64 bytesRemaining;

                bytesRemaining = fileSize.QuadPart;

                switch (mode)
                {
                case HASH_MD5:
                    MD5Init(&md5Context);
                    break;
                case HASH_SHA1:
                    A_SHAInit(&shaContext);
                    break;
                case HASH_CRC32:
                    crc = 0;
                    break;
                }

                while (bytesRemaining)
                {
                    status = NtReadFile(
                        fileHandle,
                        NULL,
                        NULL,
                        NULL,
                        &isb,
                        buffer,
                        sizeof(buffer),
                        NULL,
                        NULL
                        );

                    if (!NT_SUCCESS(status))
                        break;

                    switch (mode)
                    {
                    case HASH_MD5:
                        MD5Update(&md5Context, buffer, (ULONG)isb.Information);
                        break;
                    case HASH_SHA1:
                        A_SHAUpdate(&shaContext, buffer, (ULONG)isb.Information);
                        break;
                    case HASH_CRC32:
                        crc = PhCrc32(crc, buffer, isb.Information);
                        break;
                    }

                    bytesRemaining -= (ULONG)isb.Information;
                }

                if (status == STATUS_END_OF_FILE)
                    status = STATUS_SUCCESS;

                switch (mode)
                {
                case HASH_MD5:
                    {
                        MD5Final(&md5Context);
                        wprintf(L"%s", PhBufferToHexString(md5Context.digest, 16)->Buffer);
                    }
                    break;
                case HASH_SHA1:
                    {
                        UCHAR hash[20];

                        A_SHAFinal(&shaContext, hash);
                        wprintf(L"%s", PhBufferToHexString(hash, 20)->Buffer);
                    }
                    break;
                case HASH_CRC32:
                    {
                        wprintf(L"%08x", crc);
                    }
                    break;
                }

                if (!NT_SUCCESS(status))
                    wprintf(L"Warning: I/O error encountered: %s\n", PhGetNtMessage(status)->Buffer);
            }

            NtClose(fileHandle);
        }

        if (!NT_SUCCESS(status))
        {
            wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer);
            return 1;
        }
    }
    else if (PhEqualString2(FiArgAction, L"execute", TRUE))
    {
        if (FiArgNative)
        {
            if (!NT_SUCCESS(status = PhCreateProcess(
                FiFormatFileName(FiArgFileName)->Buffer,
                FiArgOutput ? &FiArgOutput->sr : NULL,
                NULL,
                NULL,
                NULL,
                0,
                NULL,
                NULL,
                NULL,
                NULL
                )))
            {
                wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer);
                return 1;
            }
        }
        else
        {
            if (!NT_SUCCESS(status = PhCreateProcessWin32(
                FiArgFileName->Buffer,
                PhGetString(FiArgOutput),
                NULL,
                NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer,
                PH_CREATE_PROCESS_NEW_CONSOLE,
                NULL,
                NULL,
                NULL
                )))
            {
                wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer);
                return 1;
            }
        }
    }
    else if (PhEqualString2(FiArgAction, L"del", TRUE))
    {
        HANDLE fileHandle;

        if (FiCreateFile(
            &fileHandle,
            DELETE | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            FILE_DISPOSITION_INFORMATION dispositionInfo;
            IO_STATUS_BLOCK isb;

            dispositionInfo.DeleteFile = TRUE;
            if (!NT_SUCCESS(status = NtSetInformationFile(fileHandle, &isb, &dispositionInfo,
                sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation)))
            {
                wprintf(L"Error deleting file: %s\n", PhGetNtMessage(status)->Buffer);
            }

            NtClose(fileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"touch", TRUE))
    {
        HANDLE fileHandle;

        if (FiCreateFile(
            &fileHandle,
            FILE_READ_ATTRIBUTES | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN_IF,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            NtClose(fileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"mkdir", TRUE))
    {
        HANDLE fileHandle;

        if (FiCreateFile(
            &fileHandle,
            FILE_READ_ATTRIBUTES | SYNCHRONIZE,
            FiArgFileName,
            FILE_ATTRIBUTE_DIRECTORY,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_CREATE,
            FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            NtClose(fileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"rename", TRUE))
    {
        HANDLE fileHandle;
        PPH_STRING newFileName;

        if (!FiArgOutput)
        {
            wprintf(L"Error: new file name missing.\n");
            FiPrintHelp();
            return 1;
        }

        newFileName = FiFormatFileName(FiArgOutput);

        if (FiCreateFile(
            &fileHandle,
            DELETE | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            PFILE_RENAME_INFORMATION renameInfo;
            ULONG renameInfoSize;
            IO_STATUS_BLOCK isb;

            renameInfoSize = FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName) + (ULONG)newFileName->Length;
            renameInfo = PhAllocate(renameInfoSize);
            renameInfo->ReplaceIfExists = FiArgForce;
            renameInfo->RootDirectory = NULL;
            renameInfo->FileNameLength = (ULONG)newFileName->Length;
            memcpy(renameInfo->FileName, newFileName->Buffer, newFileName->Length);

            status = NtSetInformationFile(fileHandle, &isb, renameInfo, renameInfoSize, FileRenameInformation);
            PhFree(renameInfo);

            if (!NT_SUCCESS(status))
            {
                wprintf(L"Error renaming file: %s\n", PhGetNtMessage(status)->Buffer);
            }

            NtClose(fileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"copy", TRUE))
    {
        HANDLE fileHandle;
        HANDLE outFileHandle;
        LARGE_INTEGER fileSize;
        FILE_BASIC_INFORMATION basicInfo;

        if (!FiArgOutput)
        {
            wprintf(L"Error: output file name missing.\n");
            FiPrintHelp();
            return 1;
        }

        if (FiCreateFile(
            &fileHandle,
            FILE_READ_ATTRIBUTES | FILE_READ_DATA | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT
            ) && FiCreateFile(
            &outFileHandle,
            FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | SYNCHRONIZE,
            FiArgOutput,
            0,
            FILE_SHARE_READ | FILE_SHARE_DELETE,
            !FiArgForce ? FILE_CREATE : FILE_OVERWRITE_IF,
            FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
#define COPY_BUFFER_SIZE 0x10000
            IO_STATUS_BLOCK isb;
            PVOID buffer;
            ULONG64 bytesToCopy = FiArgLength;

            if (NT_SUCCESS(PhGetFileSize(fileHandle, &fileSize)))
            {
                PhSetFileSize(outFileHandle, &fileSize);
            }

            buffer = PhAllocatePage(COPY_BUFFER_SIZE, NULL);

            if (!buffer)
            {
                wprintf(L"Error allocating buffer.\n");
                return 1;
            }

            while (bytesToCopy)
            {
                status = NtReadFile(
                    fileHandle,
                    NULL,
                    NULL,
                    NULL,
                    &isb,
                    buffer,
                    bytesToCopy >= COPY_BUFFER_SIZE ? COPY_BUFFER_SIZE : (ULONG)bytesToCopy,
                    NULL,
                    NULL
                    );

                if (status == STATUS_END_OF_FILE)
                {
                    break;
                }
                else if (!NT_SUCCESS(status))
                {
                    wprintf(L"Error reading from file: %s\n", PhGetNtMessage(status)->Buffer);
                    break;
                }

                status = NtWriteFile(
                    outFileHandle,
                    NULL,
                    NULL,
                    NULL,
                    &isb,
                    buffer,
                    (ULONG)isb.Information, // number of bytes read
                    NULL,
                    NULL
                    );

                if (!NT_SUCCESS(status))
                {
                    wprintf(L"Error writing to output file: %s\n", PhGetNtMessage(status)->Buffer);
                    break;
                }

                bytesToCopy -= (ULONG)isb.Information;
            }

            PhFreePage(buffer);

            // Copy basic attributes over.
            if (NT_SUCCESS(NtQueryInformationFile(
                fileHandle,
                &isb,
                &basicInfo,
                sizeof(FILE_BASIC_INFORMATION),
                FileBasicInformation
                )))
            {
                NtSetInformationFile(
                    outFileHandle,
                    &isb,
                    &basicInfo,
                    sizeof(FILE_BASIC_INFORMATION),
                    FileBasicInformation
                    );
            }

            NtClose(fileHandle);
            NtClose(outFileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"dir", TRUE))
    {
        HANDLE fileHandle;
        UNICODE_STRING pattern;
        PPH_STRING totalSize, totalAllocSize;

        if (FiCreateFile(
            &fileHandle,
            FILE_LIST_DIRECTORY | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            FipDirFileCount = 0;
            FipDirDirCount = 0;
            FipDirTotalSize = 0;
            FipDirTotalAllocSize = 0;

            if (FiArgPattern)
                PhStringRefToUnicodeString(&FiArgPattern->sr, &pattern);

            PhEnumDirectoryFile(
                fileHandle,
                FiArgPattern ? &pattern : NULL,
                FipEnumDirectoryFileForDir,
                NULL
                );
            NtClose(fileHandle);

            totalSize = PhFormatUInt64(FipDirTotalSize, TRUE);
            totalAllocSize = PhFormatUInt64(FipDirTotalAllocSize, TRUE);

            wprintf(
                L"%12I64u file(s)  %11s bytes\n"
                L"%12I64u dir(s)   %11s bytes allocated\n",
                FipDirFileCount,
                totalSize->Buffer,
                FipDirDirCount,
                totalAllocSize->Buffer
                );

            PhDereferenceObject(totalSize);
            PhDereferenceObject(totalAllocSize);
        }
    }
    else if (PhEqualString2(FiArgAction, L"streams", TRUE))
    {
        HANDLE fileHandle;
        PVOID streams;
        PFILE_STREAM_INFORMATION stream;

        if (FiCreateFile(
            &fileHandle,
            FILE_READ_ATTRIBUTES | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            if (NT_SUCCESS(PhEnumFileStreams(fileHandle, &streams)))
            {
                stream = PH_FIRST_STREAM(streams);

                while (stream)
                {
                    PPH_STRING size, allocationSize;

                    size = PhFormatUInt64(stream->StreamSize.QuadPart, TRUE);
                    allocationSize = PhFormatUInt64(stream->StreamAllocationSize.QuadPart, TRUE);

                    wprintf(
                        L"%11s %11s %.*s\n",
                        size->Buffer,
                        allocationSize->Buffer,
                        stream->StreamNameLength / 2,
                        stream->StreamName
                        );

                    PhDereferenceObject(size);
                    PhDereferenceObject(allocationSize);

                    stream = PH_NEXT_STREAM(stream);
                }
            }

            NtClose(fileHandle);
        }
    }
    else
    {
        wprintf(L"Error: invalid action \"%s\".\n", FiArgAction->Buffer);
        FiPrintHelp();
        return 1;
    }
}