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
- MemoryModule library: For manual mapping internally, supports EXEs, I used this to solve this exact problem.
- Load EXE as DLL: Mission Possible