从内存中的缓冲区运行EXE

时间:2016-08-18 12:02:57

标签: c++ exe

我试图制作exe包装工 5

  1. 将exe提取到缓冲区(在我的例子中:vector)
  2. 添加新栏目
  3. 获得新EP的偏移并运行
  4. 但在致电newmain后我得到了0xC0000005

    main.cpp中: pastebin

        #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include "main.h"
    typedef struct _BASE_RELOCATION_ENTRY
    {
        WORD Offset : 12;
        WORD Type : 4;
    } BASE_RELOCATION_ENTRY;
    
    BOOL applyRelocBlock(BASE_RELOCATION_ENTRY* block, size_t entriesNum, DWORD page, PVOID newBase)
    {
        PVOID ImageBaseAddress = NtCurrentTeb()->Peb->ImageBaseAddress;
        BASE_RELOCATION_ENTRY* entry = block;
    
        for (int i = 0; i < entriesNum; i++)
        {
            DWORD offset = entry->Offset;
            DWORD type = entry->Type;
            if (entry == NULL || type == 0 || offset == 0)
            {
                //printf("Applied relocations: %d\n", i);
                return TRUE; //finish
            }
            if (type != 3)
            {
                printf("Not supported relocations format at %d: %d\n", i, type);
                return FALSE;
            }
            uint32_t* relocateAddr = (uint32_t*)((ULONG_PTR)newBase + page + offset);
            (*relocateAddr) = ((*relocateAddr) - (ULONG_PTR)ImageBaseAddress) + (ULONG_PTR)newBase;
            entry = (BASE_RELOCATION_ENTRY*)((ULONG_PTR)entry + sizeof(uint16_t));
        }
        return TRUE;
    }
    
    BOOL applyRelocations(PIMAGE_NT_HEADERS NtHeaders, PVOID newBase)
    {
        PVOID ImageBaseAddress = NtCurrentTeb()->Peb->ImageBaseAddress;
        //fetch relocation table from current image:
        IMAGE_DATA_DIRECTORY relocDir = NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
        if (relocDir.VirtualAddress == NULL)
        {
            printf("Cannot relocate - application have no relocation table!");
            return FALSE;
        }
        DWORD maxSize = relocDir.Size;
        DWORD parsedSize = 0;
    
        DWORD relocAddr = relocDir.VirtualAddress;
        IMAGE_BASE_RELOCATION* reloc = NULL;
    
        while (parsedSize < maxSize)
        {
            reloc = (IMAGE_BASE_RELOCATION*)(relocAddr + parsedSize + (ULONG_PTR)ImageBaseAddress);
            parsedSize += reloc->SizeOfBlock;
    
            if (reloc->VirtualAddress == NULL || reloc->SizeOfBlock == 0)
            {
                continue;
            }
    
            printf("RelocBlock: %p %p\n", reloc->VirtualAddress, reloc->SizeOfBlock);
    
            size_t entriesNum = (reloc->SizeOfBlock - 2 * sizeof(uint32_t)) / sizeof(uint16_t);
            DWORD page = reloc->VirtualAddress;
    
            BASE_RELOCATION_ENTRY* block = (BASE_RELOCATION_ENTRY*)((ULONG_PTR)reloc + sizeof(uint32_t) + sizeof(uint32_t));
            if (applyRelocBlock(block, entriesNum, page, newBase) == FALSE)
            {
                return FALSE;
            }
        }
        return TRUE;
    }
    
    bool checkLibs()
    {
        return load_ntdll_functions() && load_kernel32_functions();
    }
    
    bool mapAndRun()
    {
        HANDLE hSection = NULL;
    
        PVOID ImageBaseAddress = NtCurrentTeb()->Peb->ImageBaseAddress;
        PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(ImageBaseAddress);
    
        if (NtHeaders == NULL)
        {
            printf("[ERROR] RtlImageNtHeader failed, error : %d\n", GetLastError());
            return false;
        }
    
        LARGE_INTEGER MaximumSize;
        ULONG ImageSize = NtHeaders->OptionalHeader.SizeOfImage;
    
        MaximumSize.LowPart = ImageSize;
        MaximumSize.HighPart = 0;
    
        NTSTATUS Status = NULL;
    
        if ((Status = ZwCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &MaximumSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL)) != STATUS_SUCCESS)
        {
            printf("[ERROR] ZwCreateSection failed, status : %x\n", Status);
            system("pause");
            return false;
        }
    
        printf("Section handle: %x\n", hSection);
    
        HANDLE hProcess = NULL;
        PVOID pSectionBaseAddress = NULL;
        SIZE_T ViewSize = 0;
        DWORD dwInheritDisposition = 1; //VIEW_SHARE
    
        // map the section in context of current process:
        if ((Status = NtMapViewOfSection(hSection, GetCurrentProcess(), &pSectionBaseAddress, NULL, NULL, NULL, &ViewSize, dwInheritDisposition, NULL, PAGE_EXECUTE_READWRITE)) != STATUS_SUCCESS)
        {
            printf("[ERROR] NtMapViewOfSection failed, status : %x\n", Status);
            system("pause");
            return false;
        }
    
        printf("Created new section, BaseAddress: %p ViewSize: %p\n", pSectionBaseAddress, ViewSize);
        printf("Mapping into: %p <- current image: %p %p\n", pSectionBaseAddress, ImageBaseAddress, ImageSize);
        RtlCopyMemory(pSectionBaseAddress, ImageBaseAddress, ImageSize);
    
        ZwClose(hSection);
        hSection = NULL;
        if (applyRelocations(NtHeaders, pSectionBaseAddress) == FALSE) {
            printf("Applying relocations failed, cannot continue!");
            ZwTerminateProcess(GetCurrentProcess(), STATUS_FAILURE);
        }
        printf("Applied relocations!\n");
    
        //
    
        std::vector<unsigned char> extractedData = unpackExe(); //packe exe
    
        IMAGE_NT_HEADERS INH;
        IMAGE_DOS_HEADER IDH;
        memcpy(&IDH, &extractedData[0], sizeof(IDH));
        memcpy(&INH, (void*)((DWORD)&extractedData[0] + IDH.e_lfanew), sizeof(INH));
    
        LARGE_INTEGER MaximumSizeEX;
        ULONG ImageSizeEX = INH.OptionalHeader.SizeOfImage;
    
        MaximumSizeEX.LowPart = ImageSizeEX;
        MaximumSizeEX.HighPart = 0;
        ULONG_PTR exEP = INH.OptionalHeader.AddressOfEntryPoint;
    
        ULONG_PTR offsetFromBase = exEP - (ULONG_PTR)ImageBaseAddress;
        printf("extracted EP offset: %p\n", offsetFromBase);
    
        ULONG_PTR newMain = ((ULONG_PTR)pSectionBaseAddress + offsetFromBase);
        printf("extracted EP address in new section: %p\n", newMain);
    
        __asm {
            call newMain
        };
    
        return true;
    }
    
    bool mapAndExecute()
    {
        if (checkLibs())
        {
            if (mapAndRun())
            {
            }
        }
        return true;
    }
    
    
    int main()
    {
        mapAndExecute();
        std::cin.get();
    }
    

    main.h:pastebin:pastebin.com/Spc5WTsQ

        #pragma once
    
    #include <stdio.h>
    #define WIN32_LEAN_AND_MEAN
    #include <Windows.h>
    
    #if !defined NTSTATUS
    typedef LONG NTSTATUS;
    #endif
    
    #define STATUS_SUCCESS 0
    #define STATUS_FAILURE (-1)
    #define NtCurrentProcess() ((HANDLE)-1)
    
    typedef struct _CLIENT_ID
    {
        HANDLE UniqueProcess;
        HANDLE UniqueThread;
    } CLIENT_ID, *PCLIENT_ID;
    
    typedef LONG NTSTATUS, *PNTSTATUS;
    typedef struct _UNICODE_STRING {
        USHORT Length;
        USHORT MaximumLength;
        PWSTR  Buffer;
    } UNICODE_STRING, *PUNICODE_STRING;
    
    typedef struct _PEB_LDR_DATA
    {
        ULONG               Length;
        BOOLEAN             Initialized;
        PVOID               SsHandle;
        LIST_ENTRY          InLoadOrderModuleList;
        LIST_ENTRY          InMemoryOrderModuleList;
        LIST_ENTRY          InInitializationOrderModuleList;
    } PEB_LDR_DATA, *PPEB_LDR_DATA;
    
    typedef struct _PEB
    {
        BYTE                         Reserved1[2];       /*  00 */
        BYTE                         BeingDebugged;      /*  02 */
        BYTE                         Reserved2[5];       /*  03 */
        HMODULE                      ImageBaseAddress;   /*  08 */
        PPEB_LDR_DATA                LdrData;            /*  0c */
        DWORD                        ProcessParameters;  /*  10 */
        PVOID                        __pad_14;           /*  14 */
        HANDLE                       ProcessHeap;        /*  18 */
        BYTE                         __pad_1c[36];       /*  1c */
        DWORD                        TlsBitmap;          /*  40 */
        ULONG                        TlsBitmapBits[2];   /*  44 */
        BYTE                         __pad_4c[24];       /*  4c */
        ULONG                        NumberOfProcessors; /*  64 */
        BYTE                         __pad_68[128];      /*  68 */
        PVOID                        Reserved3[59];      /*  e8 */
        ULONG                        SessionId;          /* 1d4 */
    } PEB, *PPEB;
    
    typedef struct _TEB
    {
        NT_TIB          Tib;                        /* 000 */
        PVOID           EnvironmentPointer;         /* 01c */
        CLIENT_ID       ClientId;                   /* 020 */
        PVOID           ActiveRpcHandle;            /* 028 */
        PVOID           ThreadLocalStoragePointer;  /* 02c */
        PPEB            Peb;                        /* 030 */
        ULONG           LastErrorValue;             /* 034 */
        BYTE            __pad038[140];              /* 038 */
        ULONG           CurrentLocale;              /* 0c4 */
        BYTE            __pad0c8[1752];             /* 0c8 */
        PVOID           Reserved2[278];             /* 7a0 */
        UNICODE_STRING  StaticUnicodeString;        /* bf8 used by advapi32 */
        WCHAR           StaticUnicodeBuffer[261];   /* c00 used by advapi32 */
        PVOID           DeallocationStack;          /* e0c */
        PVOID           TlsSlots[64];               /* e10 */
        LIST_ENTRY      TlsLinks;                   /* f10 */
        PVOID           Reserved4[26];              /* f18 */
        PVOID           ReservedForOle;             /* f80 Windows 2000 only */
        PVOID           Reserved5[4];               /* f84 */
        PVOID           TlsExpansionSlots;          /* f94 */
    } TEB, *PTEB;
    
    typedef
    void
    (*PKNORMAL_ROUTINE) (
        void* NormalContext,
        void* SystemArgument1,
        void* SystemArgument2
        );
    
    typedef struct {
        int info;
        PKNORMAL_ROUTINE fun;
    } *PIO_STATUS_BLOCK;
    
    // Make sure we print the __stdcall properly
    typedef
    void
    (__stdcall *PIO_APC_ROUTINE) (
        void* ApcContext,
        PIO_STATUS_BLOCK IoStatusBlock,
        long Reserved
        );
    
    
    #if !defined PROCESSINFOCLASS
    typedef LONG PROCESSINFOCLASS;
    #endif
    
    #if !defined THREADINFOCLASS
    typedef LONG THREADINFOCLASS;
    #endif
    
    #if !defined PPEB
    typedef struct _PEB *PPEB;
    #endif
    
    #if !defined PROCESS_BASIC_INFORMATION
    typedef struct _PROCESS_BASIC_INFORMATION {
        PVOID Reserved1;
        PPEB PebBaseAddress;
        PVOID Reserved2[2];
        ULONG_PTR UniqueProcessId;
        PVOID Reserved3;
    } PROCESS_BASIC_INFORMATION;
    #endif;
    
    /*
    typedef LONG NTSTATUS, *PNTSTATUS;
    typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
    } UNICODE_STRING, *PUNICODE_STRING;
    */
    
    typedef struct _OBJECT_ATTRIBUTES {
        ULONG Length;
        HANDLE RootDirectory;
        PUNICODE_STRING ObjectName;
        ULONG Attributes;
        PVOID SecurityDescriptor;
        PVOID SecurityQualityOfService;
    } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
    
    typedef NTSTATUS(WINAPI * PFN_ZWQUERYINFORMATIONPROCESS)(HANDLE, PROCESSINFOCLASS,
        PVOID, ULONG, PULONG);
    
    //ntdll api:
    NTSTATUS(NTAPI *ZwQueryInformationProcess)(
        HANDLE  ProcessHandle,
        PROCESSINFOCLASS  ProcessInformationClass,
        PVOID  ProcessInformation,
        ULONG  ProcessInformationLength,
        PULONG  ReturnLength  OPTIONAL
        );
    
    NTSTATUS(NTAPI *ZwCreateSection)(
        __out    PHANDLE            SectionHandle,
        __in     ACCESS_MASK        DesiredAccess,
        __in POBJECT_ATTRIBUTES ObjectAttributes,
        __in PLARGE_INTEGER     MaximumSize,
        __in     ULONG              SectionPageProtection,
        __in     ULONG              AllocationAttributes,
        __in HANDLE             FileHandle
        );
    
    
    NTSTATUS(NTAPI *NtMapViewOfSection)(
        __in        HANDLE          SectionHandle,
        __in        HANDLE          ProcessHandle,
        __inout     PVOID           *BaseAddress,
        __in        ULONG_PTR       ZeroBits,
        __in        SIZE_T          CommitSize,
        __inout  PLARGE_INTEGER  SectionOffset,
        __inout     PSIZE_T         ViewSize,
        __in        DWORD InheritDisposition,
        __in        ULONG           AllocationType,
        __in        ULONG           Win32Protect
        );
    
    NTSTATUS(NTAPI *ZwCreateThreadEx) (
        __out PHANDLE ThreadHandle,
        __in ACCESS_MASK DesiredAccess,
        __in POBJECT_ATTRIBUTES ObjectAttributes,
        __in HANDLE ProcessHandle,
        __in PVOID StartRoutine,
        __in PVOID Argument,
        __in ULONG CreateFlags,
        __in ULONG_PTR ZeroBits,
        __in SIZE_T StackSize,
        __in SIZE_T MaximumStackSize,
        __in PVOID AttributeList
        );
    
    NTSTATUS(NTAPI *ZwUnmapViewOfSection) (
        __in     HANDLE ProcessHandle,
        __in PVOID  BaseAddress
        );
    
    NTSTATUS(NTAPI *ZwClose) (
        __in HANDLE Handle
        );
    
    NTSTATUS(NTAPI *ZwTerminateProcess) (
        __in HANDLE   ProcessHandle,
        __in     NTSTATUS ExitStatus
        );
    
    NTSTATUS(NTAPI *NtQueueApcThread)(
        __in HANDLE ThreadHandle,
        __in PVOID ApcRoutine,
        __in PVOID ApcRoutineContext OPTIONAL,
        __in PVOID ApcStatusBlock OPTIONAL,
        __in ULONG ApcReserved OPTIONAL
        );
    
    NTSTATUS(NTAPI *ZwSetInformationThread) (
        __in HANDLE ThreadHandle,
        __in THREADINFOCLASS ThreadInformationClass,
        __in PVOID ThreadInformation,
        __in ULONG ThreadInformationLength
        );
    
    PIMAGE_NT_HEADERS(NTAPI *RtlImageNtHeader) (
        __in PVOID ModuleAddress
        );
    
    
    //kernel32 api
    BOOL
    (WINAPI *CreateProcessInternalW)(HANDLE hToken,
        LPCWSTR lpApplicationName,
        LPWSTR lpCommandLine,
        LPSECURITY_ATTRIBUTES lpProcessAttributes,
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        BOOL bInheritHandles,
        DWORD dwCreationFlags,
        LPVOID lpEnvironment,
        LPCWSTR lpCurrentDirectory,
        LPSTARTUPINFOW lpStartupInfo,
        LPPROCESS_INFORMATION lpProcessInformation,
        PHANDLE hNewToken
        );
    

    尝试从这里采用来源

      

    https://github.com/hasherezade/snippets/tree/master/inject4

3 个答案:

答案 0 :(得分:0)

您加载的数据位于加载应用程序的数据空间中,并且数据的执行在现代内存保护的操作系统中被阻止 - 因为之前这是一种常见且相当容易的病毒攻击。

为了运行,必须由操作系统加载和定位可执行文件。

答案 1 :(得分:-1)

如果没有可执行数据驻留在物理文件中,则无法从内存运行可执行文件。 Windows不允许它。没有Windows API提供直接从内存执行文件的机制。所有Windows API(如CreateProcess()或ShellExcute())都需要存在物理文件。如果 某种方式,它将被视为漏洞,并且很快就会修补。

答案 2 :(得分:-1)

不确定如何发布大型代码段以响应作为备注的请求。 Michael Haephrati要求以x64代码执行数据的x64示例。这是代码(x64仅适用于此代码,调用约定在32位代码中有所不同):

#include <windows.h>
#include <iostream>

typedef int(*PMULFUNC)(int l, int r);

PMULFUNC buildFunction()
{
    LPVOID pMem = VirtualAlloc(NULL, 6, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    unsigned char *pNext = (unsigned char *)pMem;

    *pNext = 0x8b; ++pNext;     // mov eax, ecx
    *pNext = 0xc1; ++pNext;

    *pNext = 0x0f; ++pNext;     // imul eax, edx
    *pNext = 0xaf; ++pNext;
    *pNext = 0xc2; ++pNext;

    *pNext = 0xc3; ++pNext;     // ret

    return (PMULFUNC)pMem;
}

int main()
{
    using namespace std;

    PMULFUNC pMul = buildFunction();

    int l = 5;
    for (int r=1; r<=12; ++r)
    {
        cout << l << "x" << r << "=" << (*pMul)(l, r) << endl;
    }

    return 0;
}

typedef int(__stdcall *PMULFUNC)(int l, int r);

PMULFUNC buildFunction()
{
    LPVOID pMem = VirtualAlloc(NULL, 6, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    unsigned char *pNext = (unsigned char *)pMem;

    *pNext = 0x8b; ++pNext;     // mov eax, ecx
    *pNext = 0xc1; ++pNext;

    *pNext = 0x0f; ++pNext;     // imul eax, edx
    *pNext = 0xaf; ++pNext;
    *pNext = 0xc2; ++pNext;

    *pNext = 0xc3; ++pNext;     // ret

    return (PMULFUNC)pMem;
}

int main()
{
    using namespace std;

    PMULFUNC pMul = buildFunction();

    int l = 5;
    for (int r=1; r<=12; ++r)
    {
        cout << l << "x" << r << "=" << (*pMul)(l, r) << endl;
    }

    return 0;
}

在回答具体问题时,它可能会有所提升。 EXE不是简单地复制到内存中:解析对其他DLL的引用,图像中相邻的部分可能在内存中分离,还有许多其他内容。简而言之,您必须重新实现加载器。但有一点可以肯定,如果页面具有正确的权限,则可以执行,