Home > Net >  Load EXE file into memory in the address space of another process
Load EXE file into memory in the address space of another process

Time:11-06

I have an exe file and I want to have its hex bytes to load it in the memory of another process and then execute it (something like process injection). What I want is almost what this post implements. The payload in this post in calculator software and it works well, but I want to substitute it with each exe file that I want. In short, how can I do this exe to hex conversion in such a way that it can be executed in another process context?

Methods like copying hex of exe from hex editors and debugger, online exe to hex converters and also using c instructions to do this conversion was not successful for me. This is the code I wrote in Go language:

file, err := ioutil.ReadFile("...\\helper.exe")
if err != nil {
}
//fmt.Print(file)
f, err := os.Create("...\\fileInByte.txt")
if err != nil {
}
defer f.Close()
_, err = f.Write([]byte(file))
file2, err2 := ioutil.ReadFile("...\\fileInByte.txt")
if err2 != nil {
}
fmt.Print(file2)

And this is c code first instructions to load fileInByte.txt hex bytes for process injectio:

std::ifstream input("...\\fileInByte.txt", std::ios::binary);
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
unsigned char* my_payload;
my_payload = &buffer[0];
unsigned int my_payload_len = sizeof(my_payload);
...
...
...


// allocate memory buffer for remote process
rb = VirtualAllocEx(ph, NULL, my_payload_len, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// write payload to memory buffer
if(!WriteProcessMemory(ph, rb, my_payload, my_payload_len, NULL))

CodePudding user response:

So, you need to print an executable as a C-style hex array because you need to replace the payload in the C program, right?

Then you don't need go or c for that. The utility xxd -i does the trick: xxd -i super_duper_kill_em_all_malware.exe prints the hex array of super_duper_kill_em_all_malware.exe

But if it is too complicated for you, here is a simple Go program that does almost the same:

package main

import (
    "fmt"
    "io"
    "os"
    "path"
)

func main() {
    if len(os.Args) == 1 {
        die("Missing file name")
    }
    fname := os.Args[1]
    file, err := os.Open(fname)
    if err != nil {
        die_f("Failed to open %s: %s", fname, err.Error())
    }
    defer file.Close()

    // Print 16 bytes in a row
    buf := make([]byte, 16)
    first := true
    for {
        n, err := io.ReadFull(file, buf)
        if err != nil {
            if err == io.EOF {
                break
            }
            if err != io.ErrUnexpectedEOF {
                file.Close()
                die_f("Error reading %s: %s", fname, err.Error())
            }
        }
        // finish the previous line
        if !first {
            fmt.Println(",")
        }
        // Print the first column
        fmt.Printf("0xx", buf[0])
        // Print other columns
        for i := 1; i < n; i   {
            fmt.Printf(", 0xx", buf[i])
        }
        first = false
    }
    fmt.Println()
}

func usage() {
    progname := path.Base(os.Args[0])
    fmt.Fprintf(os.Stderr, "%s FILE\n\n", progname)
    fmt.Fprintf(os.Stderr, "Prints the file as C-style hex array\n")
}

func die(msg string) {
    fmt.Fprintln(os.Stderr, msg)
    fmt.Fprintln(os.Stderr)
    usage()
    os.Exit(1)
}

func die_f(format string, vals ...any) {
    fmt.Fprintf(os.Stderr, format, vals...)
    fmt.Fprintln(os.Stderr)
    fmt.Fprintln(os.Stderr)
    usage()
    os.Exit(1)
}

Example: C-style hex array of go.mod

$ go run . go.mod
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x6f,
0x72, 0x67, 0x0a, 0x0a, 0x67, 0x6f, 0x20, 0x31, 0x2e, 0x31, 0x39, 0x0a

(here is what's inside go.mod:

module example.org

go 1.19

)

CodePudding user response:

So you want to do DLL Injection, but with EXE, right?

LoadLibrary approach

When injecting a DLL, what you would normally do is create a remote thread in the target process that calls LoadLibrary to load your DLL, interestingly, LoadLibrary can load EXEs.

The main difference between DLLs and EXEs is that DLLs have the flag IMAGE_FILE_DLL set in its PE characteristics, so when LoadLibrary is called, it will try to map the DLL into memory, fix its IAT table and call its entry point.

When using LoadLibrary on an EXE, it doesn't have the flag IMAGE_FILE_DLL so it only gets mapped into memory, the IAT is left untouched and its entry point is never called.

You could manually set the IMAGE_FILE_DLL in an EXE characteristics and load it, but it would fail to call the entry point because of the differences between DLLs and EXEs. A workaround is to remove the entry point in the PE header entirely and manually call it.

Manual mapping approach

The idea of Manual mapping is to get rid of LoadLibrary, and try to manually map our DLL into the memory space, fix its IAT, and call its entry point - basically recreating the LoadLibrary function. Of course, by manual mapping, we could avoid patching the PE header as described above.

There are plenty of codes and libraries found on the internet, both external and internal.

Related links

  1. MemoryModule library: For manual mapping internally, supports EXEs, I used this to solve this exact problem.
  2. Load EXE as DLL: Mission Possible
  • Related