Exemple #1
0
NTSTATUS ModifySelfSizeOfImage(LPWSTR ExeFullPath, LPWSTR CommandLine, ULONG SizeOfImage)
{
    BOOL                        Result;
    ULONG                       Length;
    PVOID                       FakeCPInfoBuffer;
    WCHAR                       CmdFullPath[MAX_NTPATH];
    PWCHAR                      CmdLineBuffer;
    NTSTATUS                    Status;
    PLDR_MODULE                 LdrModule;
    PIMAGE_DOS_HEADER           DosHeader;
    PIMAGE_NT_HEADERS           NtHeader;
    PIMAGE_SECTION_HEADER       SectionHeader;
    FAKE_CREATE_PROCESS_INFO   *fcpi;
    PROCESS_INFORMATION         ProcessInformation;
    CONTEXT                     Context;
    NtFileDisk                 file;
    UNICODE_STRING              ExeNtPath, *ProcessCommandLine;

    UNREFERENCED_PARAMETER(CommandLine);

    LdrModule = Nt_FindLdrModuleByName(NULL);

    DosHeader   = (PIMAGE_DOS_HEADER)&__ImageBase;
    NtHeader    = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);

    fcpi = (FAKE_CREATE_PROCESS_INFO *)AllocStack(0x2000);
    fcpi->PeHeaderSize = (ULONG_PTR)(IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections) - (ULONG_PTR)DosHeader;

    Status = file.Open(LdrModule->FullDllName.Buffer);
    if (!NT_SUCCESS(Status))
        return Status;

    Status = file.Read(fcpi->PeHeader, fcpi->PeHeaderSize);
    if (!NT_SUCCESS(Status))
        return Status;

    CmdLineBuffer = (PWCHAR)((ULONG_PTR)fcpi->PeHeader + fcpi->PeHeaderSize);

    fcpi->CommandLine.Buffer        = CmdLineBuffer;
    fcpi->CommandLine.Length        = (USHORT)(StrLengthW(ExeFullPath) * sizeof(WCHAR));

    ProcessCommandLine = &Nt_CurrentPeb()->ProcessParameters->CommandLine;
    CopyMemory(CmdLineBuffer, ProcessCommandLine->Buffer, ProcessCommandLine->Length);
    *(PULONG_PTR)&CmdLineBuffer += ProcessCommandLine->Length;
    CmdLineBuffer[0] = 0;

    fcpi->CommandLine.Length        = ProcessCommandLine->Length;
    fcpi->CommandLine.MaximumLength = fcpi->CommandLine.Length + sizeof(WCHAR);

    ++CmdLineBuffer;
    CmdLineBuffer = (PWCHAR)ROUND_UP((ULONG_PTR)CmdLineBuffer, 16);

    RtlDosPathNameToNtPathName_U(LdrModule->FullDllName.Buffer, &ExeNtPath, NULL, NULL);

    fcpi->ExeNtPath.Buffer = CmdLineBuffer;
    CopyMemory(CmdLineBuffer, ExeNtPath.Buffer, ExeNtPath.Length);
    *(PULONG_PTR)&CmdLineBuffer += ExeNtPath.Length;
    CmdLineBuffer[0] = 0;

    fcpi->ExeNtPath.Length        = ExeNtPath.Length;
    fcpi->ExeNtPath.MaximumLength = fcpi->ExeNtPath.Length + sizeof(WCHAR);

    *CmdLineBuffer++ = 0;

    RtlFreeUnicodeString(&ExeNtPath);

    DosHeader       = (PIMAGE_DOS_HEADER)fcpi->PeHeader;
    NtHeader        = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);
    SectionHeader   = IMAGE_FIRST_SECTION(NtHeader);

    SectionHeader   += NtHeader->FileHeader.NumberOfSections - 1;
    SizeOfImage     -= LdrModule->SizeOfImage;
    SizeOfImage      = ROUND_UP(SizeOfImage, MEMORY_PAGE_SIZE);

    SectionHeader->Misc.VirtualSize = ROUND_UP(SectionHeader->Misc.VirtualSize, MEMORY_PAGE_SIZE) + SizeOfImage;

    if (NtHeader->FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage))
        NtHeader->OptionalHeader.SizeOfImage += SizeOfImage;

    Length = Nt_GetSystemDirectory(CmdFullPath, countof(CmdFullPath));
    StrCopyW(CmdFullPath + Length, L"cmd.exe");

    ProcessInformation.hProcess = NtCurrentProcess();
    ProcessInformation.hThread  = NtCurrentThread();

#if 1
    Result = Nt_CreateProcess(NULL, CmdFullPath, NULL, CREATE_SUSPENDED, NULL, &ProcessInformation);
    if (!Result)
        return STATUS_UNSUCCESSFUL;
#endif

    FakeCPInfoBuffer = NULL;
    LOOP_ONCE
    {
        ULONG_PTR Offset;

        Status = NtDuplicateObject(
                    NtCurrentProcess(),
                    NtCurrentProcess(),
                    ProcessInformation.hProcess,
                    &fcpi->ProcessHandle,
                    0,
                    0,
                    DUPLICATE_SAME_ACCESS
                 );
        if (!NT_SUCCESS(Status))
            break;
/*
        Status = NtDuplicateObject(
                    NtCurrentProcess(),
                    file,
                    ProcessInformation.hProcess,
                    &fcpi->FileHandle,
                    0,
                    0,
                    DUPLICATE_SAME_ACCESS
                 );
        if (!NT_SUCCESS(Status))
            break;
*/
        Status = Nt_AllocateMemory(ProcessInformation.hProcess, &FakeCPInfoBuffer, MEMORY_PAGE_SIZE);
        if (!NT_SUCCESS(Status))
            break;

        fcpi->CreateProcessInternalW    = CreateProcessInternalW;
        fcpi->NtTerminateProcess        = NtTerminateProcess;
        fcpi->LdrShutdownProcess        = LdrShutdownProcess;
        fcpi->NtCreateFile              = NtCreateFile;
        fcpi->NtWriteFile               = NtWriteFile;
        fcpi->NtClose                   = NtClose;
        fcpi->NtWaitForSingleObject     = NtWaitForSingleObject;
        fcpi->InitialDirectory.Buffer   = NULL;

        Offset = (ULONG_PTR)FakeCPInfoBuffer - (ULONG_PTR)fcpi;
        *(PULONG_PTR)&fcpi->CommandLine.Buffer += Offset;
        *(PULONG_PTR)&fcpi->ExeNtPath.Buffer   += Offset;

        Status = Nt_WriteMemory(
                    ProcessInformation.hProcess,
                    FakeCPInfoBuffer,
                    fcpi,
                    (ULONG_PTR)CmdLineBuffer - (ULONG_PTR)fcpi,
                    &Length
                );
        if (!NT_SUCCESS(Status))
            break;

        Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
        Status = NtGetContextThread(ProcessInformation.hThread, &Context);
        if (!NT_SUCCESS(Status))
            break;

        Context.Eip = (ULONG_PTR)FakeCPInfoBuffer + Length;
        Context.Eip = ROUND_UP(Context.Eip, 16);
        Context.Ecx = (ULONG_PTR)FakeCPInfoBuffer;

        Status = Nt_WriteMemory(
                    ProcessInformation.hProcess,
                    (PVOID)Context.Eip,
                    ModifySizeOfImage,
                    (ULONG_PTR)ModifySizeOfImageEnd - (ULONG_PTR)ModifySizeOfImage,
                    &Length
                );
        if (!NT_SUCCESS(Status))
            break;

#if 1
        Status = NtSetContextThread(ProcessInformation.hThread, &Context);
        if (!NT_SUCCESS(Status))
            break;

        Status = NtResumeThread(ProcessInformation.hThread, NULL);
#else
        INLINE_ASM jmp Context.Eip;
#endif
    }

    if (!NT_SUCCESS(Status))
    {
        if (FakeCPInfoBuffer != NULL)
            Nt_FreeMemory(ProcessInformation.hProcess, FakeCPInfoBuffer);

        NtTerminateProcess(ProcessInformation.hProcess, 0);
    }

    NtClose(ProcessInformation.hProcess);
    NtClose(ProcessInformation.hThread);

    return Status;
}
Exemple #2
0
BOOL Initialize(PVOID BaseAddress)
{
    PVOID   hModule;
    SizeT   Length, Length2;
    LPWSTR  lpCmdLineW, pCmdLine;
    WChar   end, szCmdLine[MAX_PATH + 40];

    static WChar AddCmdLineHeadW[] = L" --user-data-dir=\"";
    static WChar AddCmdLineTailW[] = L"UserData\" --purge-memory-button";
    
    LdrDisableThreadCalloutsForDll(BaseAddress);

    Length = Nt_GetSystemDirectory(szCmdLine, countof(szCmdLine));
    CopyStruct(szCmdLine + Length, L"wtsapi32.dll", sizeof(L"wtsapi32.dll"));
    hModule = Ldr::LoadDll(szCmdLine);

    *(PVOID *)&StubWTSFreeMemory                    = GetRoutineAddress(hModule, "WTSFreeMemory");
    *(PVOID *)&StubWTSQuerySessionInformationW      = GetRoutineAddress(hModule, "WTSQuerySessionInformationW");
    *(PVOID *)&StubWTSUnRegisterSessionNotification = GetRoutineAddress(hModule, "WTSUnRegisterSessionNotification");
    *(PVOID *)&StubWTSRegisterSessionNotification   = GetRoutineAddress(hModule, "WTSRegisterSessionNotification");
    *(PVOID *)&StubWTSQueryUserToken                = GetRoutineAddress(hModule, "WTSQueryUserToken");

    lpCmdLineW = Ps::GetCommandLine();

    Length = StrLengthW(lpCmdLineW);

    pCmdLine = szCmdLine;
    StrCopyW(pCmdLine, AddCmdLineHeadW);
    pCmdLine += countof(AddCmdLineHeadW) - 1;
    pCmdLine += Nt_GetExeDirectory(pCmdLine, countof(szCmdLine) - (pCmdLine - szCmdLine));
    StrCopyW(pCmdLine, AddCmdLineTailW);
    pCmdLine += countof(AddCmdLineTailW);
    Length2 = pCmdLine - szCmdLine;

    g_pCmdLineW = (PWChar)AllocateMemory(Length * 2 + Length2 * 2 + 2);

    pCmdLine = lpCmdLineW;
    end = *pCmdLine++ == '\"' ? '\"' : ' ';
    while (*pCmdLine && *pCmdLine != end) ++pCmdLine;
    ++pCmdLine;
/*
    if (*++pCmdLine)
    {
        while (*pCmdLine == ' ' || *pCmdLine == '\t') ++pCmdLine;
    }
*/
    end = *pCmdLine;
    *pCmdLine = 0;
    StrCopyW(g_pCmdLineW, lpCmdLineW);
    *pCmdLine = end;

    lpCmdLineW = g_pCmdLineW + (pCmdLine - lpCmdLineW);
    StrCopyW(lpCmdLineW, szCmdLine);
    lpCmdLineW += Length2 - 1;
    StrCopyW(lpCmdLineW, pCmdLine);

    Length = StrLengthW(g_pCmdLineW);
    g_pCmdLineA = (PChar)AllocateMemory(Length * 2);
//    WideCharToMultiByte(CP_ACP, 0, g_pCmdLineW, -1, g_pCmdLineA, Length * 2, NULL, NULL);
    UnicodeToAnsi(g_pCmdLineA, Length * 2, g_pCmdLineW, -1);

    hModule = Nt_GetModuleHandle(L"chrome.dll");

    MEMORY_FUNCTION_PATCH f[] =
    {
        INLINE_HOOK_JUMP_NULL(::GetCommandLineW, MyGetCommandLineW),
        INLINE_HOOK_JUMP_NULL(::GetCommandLineA, MyGetCommandLineA),

        INLINE_HOOK_JUMP(LoadAcceleratorsW, MyLoadAcceleratorsW, StubLoadAcceleratorsW),
    };

    Nt_PatchMemory(0, 0, f, countof(f), 0);    

    return TRUE;
}