首页
社区
课程
招聘
从内存中加载PE文件,通过入口点执行,不支持静态局部变量
jsft 2022-11-29 1429

从内存中加载PE文件,对各个段映射完后,获取入口点函数并执行,程序能够正常执行,但是静态全局变量的初始化却不支持,有没有大佬知道原因呀,测试的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Test {
public:
    Test() {
        printf("Test:Test\n");
    }
    ~Test() {
        printf("Test:~Test\n");
    }
};
 
int main()
{
    static Test static_tt;
    static std::string static_str = "123456";
 
    std::cout << "static_str = " << static_str << "\n";
    std::cout << "Hello World!\n";
 
    return 0;
}

输出为:

1
2
static_str =
Hello World!

从内存中加载PE的逻辑也是常规写法,这里截取关键的函数,详细代码是github上的一个项目(https://github.com/aaaddress1/RunPE-In-Memory):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
bool peLoader(const char *exePath, const wchar_t* cmdline)
{
    LONGLONG fileSize = -1;
    BYTE *data = MapFileToMemory(exePath, fileSize);
    BYTE* pImageBase = NULL;
    LPVOID preferAddr = 0;
    IMAGE_NT_HEADERS *ntHeader = (IMAGE_NT_HEADERS *)getNtHdrs(data);
    if (!ntHeader)
    {
        printf("[+] File %s isn't a PE file.", exePath);
        return false;
    }
 
    IMAGE_DATA_DIRECTORY* relocDir = getPeDir(data, IMAGE_DIRECTORY_ENTRY_BASERELOC);
    preferAddr = (LPVOID)ntHeader->OptionalHeader.ImageBase;
    printf("[+] Exe File Prefer Image Base at %x\n", preferAddr);
 
    HMODULE dll = LoadLibraryA("ntdll.dll");
    ((int(WINAPI*)(HANDLE, PVOID))GetProcAddress(dll, "NtUnmapViewOfSection"))((HANDLE)-1, (LPVOID)ntHeader->OptionalHeader.ImageBase);
 
    pImageBase = (BYTE *)VirtualAlloc(preferAddr, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (!pImageBase && !relocDir)
    {
        printf("[-] Allocate Image Base At %x Failure.\n", preferAddr);
        return false;
    }
    if (!pImageBase && relocDir)
    {
        printf("[+] Try to Allocate Memory for New Image Base\n");
        pImageBase = (BYTE *)VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        if (!pImageBase)
        {
            printf("[-] Allocate Memory For Image Base Failure.\n");
            return false;
        }
    }
 
    puts("[+] Mapping Section ...");
    ntHeader->OptionalHeader.ImageBase = (size_t)pImageBase;
    memcpy(pImageBase, data, ntHeader->OptionalHeader.SizeOfHeaders);
 
    IMAGE_SECTION_HEADER * SectionHeaderArr = (IMAGE_SECTION_HEADER *)(size_t(ntHeader) + sizeof(IMAGE_NT_HEADERS));
    for (int i = 0; i < ntHeader->FileHeader.NumberOfSections; i++)
    {
        printf("    [+] Mapping Section %s\n", SectionHeaderArr[i].Name);
        memcpy
        (
            LPVOID(size_t(pImageBase) + SectionHeaderArr[i].VirtualAddress),
            LPVOID(size_t(data) + SectionHeaderArr[i].PointerToRawData),
            SectionHeaderArr[i].SizeOfRawData
        );
    }
 
    // for demo usage:
    // masqueradeCmdline(L"C:\\Windows\\RunPE_In_Memory.exe Demo by aaaddress1");
    masqueradeCmdline(cmdline);
    fixIAT(pImageBase);
 
    if (pImageBase != preferAddr)
        if (applyReloc((size_t)pImageBase, (size_t)preferAddr, pImageBase, ntHeader->OptionalHeader.SizeOfImage))
        puts("[+] Relocation Fixed.");
    size_t retAddr = (size_t)(pImageBase)+ntHeader->OptionalHeader.AddressOfEntryPoint;
    printf("Run Exe Module: %s\n", exePath);
 
    ((void(*)())retAddr)();
}
收藏
1条回答
0346954 2022-12-12

我用代码测试没有问题
图片描述

回复