【问题标题】:Running a program from memory从内存中运行程序
【发布时间】:2016-03-21 23:29:41
【问题描述】:

如果有我在缓冲区中读取的二进制文件。我怎样才能通过在随机过程中注入它的数据来运行这个文件?

我尝试了以下途径:

  1. 在char[]中读取文件

  2. 获取进程句柄

  3. 在此进程中保留虚拟内存等于文件长度通过 VirtualAllocEx

  4. 将二进制内容写入本进程分配的虚拟内存中

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

这是我的代码:

#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 是文件入口点的偏移量。

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

【问题讨论】:

  • 检查错误代码! (并使用调试器)
  • 这并不容易......你必须模拟加载器的整个工作(在正确的地址加载,读取依赖关系,以正确的顺序加载它们,修复重定位,根据 PE 标头的要求设置所需的环境,...)手动(并非所有这些都可以在用户模式下实现 - 例如,如果托管代码正在调用 - 比如说 GetModuleFileName 操作系统将返回错误的东西,因为它在自己的数据结构中查找,您无法更改)。你真的应该更好地解释你在做什么。
  • 我只是想将一些文件的代码注入一个进程。 ِ
  • 注入 DLL has some techniques,您尝试过一些基本搜索吗?
  • 可移植的可执行文件通常不会以这种方式工作。他们必须重新安置他们的地址。如果它是一个 DLL,它被设计为在运行时加载,这将使您的生活轻松一百万倍。

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


【解决方案1】:

直接映射文件、修复它使其成为(半)有效的PE文件然后运行它的过程通常称为ManualMapping。 我相信这个术语是由Darawk 创造的,他还编写了第一个这样做的(公共)样本。 但是请注意,他的实现缺少一些(非常需要的)功能。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 2017-06-16
    • 2013-01-03
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多