Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows PE custom initialization functions #56

Open
AiDaiP opened this issue May 31, 2022 · 5 comments
Open

Windows PE custom initialization functions #56

AiDaiP opened this issue May 31, 2022 · 5 comments

Comments

@AiDaiP
Copy link
Contributor

AiDaiP commented May 31, 2022

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?

@GJDuck
Copy link
Owner

GJDuck commented Jun 2, 2022

Regarding the specific error, the following function call is invoked twice, with the same addr but different offset:

    MapViewOfFileEx(addr=0x1f0bf0000,size=65536,offset=...,prot=r-x)

As for how MapViewOfFileEx is invoked after the call to the init function, I am not sure. It may be necessary to step through using a debugger and --trap-entry.

@AiDaiP
Copy link
Contributor Author

AiDaiP commented Jun 2, 2022

Sorry I made a stupid mistake. I patched a program that was already patched. So return entry will return to e9loader().
I mistake it for the original program so I think maybe something wrong with init.

@AiDaiP AiDaiP closed this as completed Jun 2, 2022
GJDuck added a commit that referenced this issue Jun 3, 2022
@GJDuck
Copy link
Owner

GJDuck commented Jun 3, 2022

It should not be allowable to rewrite an already-rewritten binary. I have added a check to ensure this does not happen.

@AiDaiP
Copy link
Contributor Author

AiDaiP commented Jul 6, 2022

Have you planned to implement init for Windows PE? I test init in some PE program and dll, maybe it can work.

@GJDuck
Copy link
Owner

GJDuck commented Jul 11, 2022

It really should be added, but to do it "properly" is a bit tricky and it is difficult to test (I do not use Windows). I will reopen the issue to remind myself that this is not yet addressed.

@GJDuck GJDuck reopened this Jul 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants