Skip to content

Windows PE custom initialization functions #56

@AiDaiP

Description

@AiDaiP

I try to patch e9loader_pe.cpp and e9pe.cpp to support Windows PE custom initialization functions. It can work in f57a9d4.
But it can't work in 501a289.
It is my patch for 501a289, it can work in f57a9d4.

diff -ruNa ./install/tmp/e9patch-501a2898b0335bda481f3b3b0e8b8448b2b999c4/src/e9patch/e9loader_pe.cpp ./install/tmp/e9patch-501a2898b0335bda481f3b3b0e8b8448b2b999c4/src/e9patch_patch/e9loader_pe.cpp
--- ./install/tmp/e9patch-501a2898b0335bda481f3b3b0e8b8448b2b999c4/src/e9patch/e9loader_pe.cpp	2022-05-01 03:14:24.000000000 +0000
+++ ./install/tmp/e9patch-501a2898b0335bda481f3b3b0e8b8448b2b999c4/src/e9patch_patch/e9loader_pe.cpp	2022-05-20 10:36:30.310565513 +0000
@@ -516,8 +516,8 @@
             config->magic[4] != 'T' || config->magic[5] != 'C' ||
             config->magic[6] != 'H' || config->magic[7] != '\0')
         e9error("missing \"E9PATCH\" magic number");
-    if (config->inits != 0x0)
-        e9error("custom initialization functions are not-yet-implemented");
+    // if (config->inits != 0x0)
+    //     e9error("custom initialization functions are not-yet-implemented");
     if (config->finis != 0x0)
         e9error("custom finalization functions are not-yet-implemented");
     if (config->mmap != 0x0)
@@ -641,7 +641,18 @@
         uint32_t old_prot;
         (void)VirtualProtect(base, config->size, PAGE_EXECUTE_READ, &old_prot);
     }
-    
+
+    if (config->inits != 0x0)
+    {
+        const intptr_t *inits = (const intptr_t *)(loader_base + config->inits);
+        typedef void (*init_t)(const struct e9_config_s *config);
+        for (uint32_t i = 0; i < config->num_inits; i++)
+        {
+            init_t init = (init_t)(inits[i]+image_base);
+            init(config);
+        }
+    }
+
     return entry;
 }
 
diff -ruNa ./install/tmp/e9patch-501a2898b0335bda481f3b3b0e8b8448b2b999c4/src/e9patch/e9pe.cpp ./install/tmp/e9patch-501a2898b0335bda481f3b3b0e8b8448b2b999c4/src/e9patch_patch/e9pe.cpp
--- ./install/tmp/e9patch-501a2898b0335bda481f3b3b0e8b8448b2b999c4/src/e9patch/e9pe.cpp	2022-05-01 03:14:24.000000000 +0000
+++ ./install/tmp/e9patch-501a2898b0335bda481f3b3b0e8b8448b2b999c4/src/e9patch_patch/e9pe.cpp	2022-05-20 10:37:21.427918522 +0000
@@ -371,6 +371,16 @@
     memcpy(data + size, e9loader_pe_bin, sizeof(e9loader_pe_bin));
     size += sizeof(e9loader_pe_bin);
 
+    config->inits = (B->inits.size() > 0? (uint32_t)(size - config_offset): 0);
+    for (auto init: B->inits)
+    {
+        intptr_t addr = BASE_ADDRESS(init);
+        addr |= (IS_ABSOLUTE(init)? E9_ABS_ADDR: 0);
+        memcpy(data + size, &addr, sizeof(addr));
+        size += sizeof(addr);
+        config->num_inits++;
+    }
+
     uint32_t loader_virtual_size = (uint32_t)(size - config_offset);
     size = ALIGN(size, file_align);
     uint32_t loader_disk_size = (uint32_t)(size - config_offset);
@@ -493,9 +503,9 @@
         warning("ignoring `--loader-phdr' option for Windows PE binary");
     if (option_loader_static_set)
         warning("ignoring `--loader-static' option for Windows PE binary");
-    if (B->inits.size() > 0)
-        error("initialization routines are non-yet-implemented for "
-            "Windows PE binaries");
+    // if (B->inits.size() > 0)
+    //     error("initialization routines are non-yet-implemented for "
+    //         "Windows PE binaries");
     if (B->finis.size() > 0)
         error("finalization routines are non-yet-implemented for "
             "Windows PE binaries");

The Windows PE custom initialization functions execute in the end of void *e9loader(PEB *peb, const struct e9_config_s *config). In 501a289, the e9loader will execute again after custom initialization functions so it will fail.

e9patch loader debug: MapViewOfFileEx(addr=0x1cd8b0000,size=65536,offset=+655360,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x1c8000000,size=65536,offset=+655360,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x194450000,size=65536,offset=+655360,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x1588d0000,size=65536,offset=+655360,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x1dd000000,size=65536,offset=+720896,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x1c58b0000,size=65536,offset=+720896,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x190450000,size=65536,offset=+720896,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x1592d0000,size=65536,offset=+720896,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x180120000,size=65536,offset=+786432,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x1596e0000,size=65536,offset=+786432,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x15f500000,size=65536,offset=+851968,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x15aa40000,size=65536,offset=+851968,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x1f0bf0000,size=65536,offset=+917504,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x1f0000000,size=65536,offset=+983040,prot=rwx) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x163e70000,size=65536,offset=+983040,prot=r-x) succeed (error=0)
e9patch loader debug: MapViewOfFileEx(addr=0x159af0000,size=65536,offset=+983040,prot=r-x) succeed (error=0)
exit Windows PE custom initialization functions!
e9patch loader error: MapViewOfFileEx(addr=0x1f0bf0000,size=65536,offset=+131072,prot=r-x) failed (error=487)

the init() is

void init(const struct e9_config_s *config)
{
    const struct e9_config_pe_s *config_pe =
        (const struct e9_config_pe_s *)(config + 1);
    if (safe_call == NULL)
        safe_call = config_pe->safe_call; 
    if (set_console_text_attribute_fn == NULL)
        set_console_text_attribute_fn =
            (set_console_text_attribute_t)config_pe->get_proc_address(
                config_pe->kernel32, "SetConsoleTextAttribute");
    if (write_file_fn == NULL)
        write_file_fn =
            (write_file_t)config_pe->get_proc_address(
                config_pe->kernel32, "WriteFile");
    if (set_console_text_attribute_fn == NULL || write_file_fn == NULL)
        asm volatile ("ud2");
    stderr = get_stderr(config);
    SetConsoleTextAttribute(stderr, FOREGROUND_WHITE);
    fprintf(stderr, "exit Windows PE custom initialization functions!\n");
}

But I think it should return return entry after init(), what's wrong with my patch for 501a289?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions