从内存运行程序

时间:2015-12-15 23:55:04

标签: c++ memory reverse-engineering portable-executable

如果有一个我在缓冲区中读取的二进制文件。如何通过在随机进程中注入数据来运行此文件?

我尝试了以下途径:

  1. 在char []

  2. 中读取文件
  3. 获取流程的句柄

  4. 在此过程中保留虚拟内存等于文件长度via VirtualAllocEx来

  5. 在此过程中将二进制内容写入已分配的虚拟内存

  6. 创建从二进制文件的入口点运行的线程。

  7. 这是我的代码:

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <fstream>
    #include <cstring>
    #include <string.h>
    
    IMAGE_DOS_HEADER        image_dos_header;
    IMAGE_NT_HEADERS        image_nt_headers;
    PCHAR pMem;
    
    
    using namespace std;
    int getfile(const char * name, char ** ret=0)
    {
    FILE * pFile=new FILE;
    long size;
    
    pFile = fopen (name,"rb");
    
    fseek (pFile, 0, SEEK_END);
    size=ftell (pFile);
    rewind(pFile);
    
    if(ret)
    
    {
        char *buffer;
        buffer = new char [size];
        // read data as a block:
        fread(buffer,1,size,pFile);
        *ret=buffer;
    }
    
    fclose (pFile);
    
    return size;
    }
    int main()
    {
    
    DWORD PID=2356;
    DWORD j;
    char *buffer;
    int filelen=getfile("understanding.exe",&buffer);//filename //#1
    
    
    int virLen = filelen;
    
    HANDLE hprocess = OpenProcess(PROCESS_ALL_ACCESS,false,PID);//#2
    if(hprocess != 0)
    {
        LPVOID lpviraddr = VirtualAllocEx(hprocess,NULL,virLen,MEM_COMMIT|              MEM_RESERVE,PAGE_EXECUTE_READWRITE);//#3
        if (lpviraddr != 0)
        {
            BOOL k = WriteProcessMemory(hprocess,lpviraddr,buffer,filelen,&j);
            if (k != 0)//#4
            {
    
    
    
    
                CreateRemoteThread(hprocess,NULL,0,LPTHREAD_START_ROUTINE(lpviraddr+0xA8),NULL,0,NULL);//#5
    
    
    
    
    
            }
            else
            {
                std::cout <<GetLastError();
                printf("[*]Something Wrong - Operation Aborted1\n");
            }
    
        }
        else
        {
            printf("[*]Something Wrong - Operation Aborted2\n");
        }
    
    }
    else
    {
    
        std::cout <<GetLastError();
        printf("[*]Something Wrong - Operation Aborted3\n");
    }
    
    
    
    
    return 0;
    }
    

    0xA8是一个偏移量,位于文件中的入口点。

    问题似乎是在最后一步,因为它导致主机进程崩溃而不执行我的文件。

1 个答案:

答案 0 :(得分:0)

直接映射文件,修复它以使其成为(半)有效PE文件然后运行它的过程通常称为ManualMapping。 我相信这个术语是由Darawk创造的, <div id="dropzone" style="height:200px; border: 4px double black;" ></div> <script> window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; var dropzone = document.getElementById('dropzone'); dropzone.ondrop = function(e) { var length = e.dataTransfer.items.length; for (var i = 0; i < length; i++) { var entry = e.dataTransfer.items[i].webkitGetAsEntry(); if (entry.isFile) { // do whatever you want } else if (entry.isDirectory) { // do whatever you want } } }; </script> 也写了第一个(公共)样本之一。 但请注意,他的实现缺少一些(非常需要的)功能。

有漂浮的样本更完整, 一个更完整(和经过良好测试)的样本是: https://github.com/DarthTon/Blackbone/tree/master/src/BlackBone/ManualMap

请注意,这应该是从驱动程序运行的,因此有一些与驱动程序相关的代码。