首頁
社區(qū)
課程
招聘
從內(nèi)存中加載PE文件,通過入口點(diǎn)執(zhí)行,不支持靜態(tài)局部變量
jsft 2022-11-29 1650

從內(nèi)存中加載PE文件,對(duì)各個(gè)段映射完后,獲取入口點(diǎn)函數(shù)并執(zhí)行,程序能夠正常執(zhí)行,但是靜態(tài)全局變量的初始化卻不支持,有沒有大佬知道原因呀,測(cè)試的代碼如下:

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!

從內(nèi)存中加載PE的邏輯也是常規(guī)寫法,這里截取關(guān)鍵的函數(shù),詳細(xì)代碼是github上的一個(gè)項(xiàng)目(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

我用代碼測(cè)試沒有問題
圖片描述

回復(fù)
PE 內(nèi)存加載
  參與學(xué)習(xí)     人
  提問次數(shù)     100 個(gè)
0
我的提問
0
我的回答
0
學(xué)習(xí)收益