Execute shellcode Exception 0xc0000005 0x8

Hello,

i have created a simple messagebox in golang and converted it to a shellcode using this one GitHub - TheWover/donut: Generates x86, x64, or AMD64+x86 position-independent shellcode that loads .NET Assemblies, PE files, and other Windows payloads from memory and runs them with parameters

Command to generate:
donut.exe -i messagebox.exe

I wrote a simple loader in golang, tested it with the shellcode messagebox and it worked.

But i noticed, if the messagebox filesize is above 3MB i will get an error when trying to load it with the loader script. The original messagebox filesize when compiled is around 2MB. So i have created a filepumper script, which just appends zero bytes at the end of the file. This way i have created two more messageboxes, one with 3MB and the other one with 4MB. The one with 3MB loads fine, but with the 4MB messagebox i will get the error. The same loader script written in C works just fine.

Why does that happen?

Shellcode messageboxes generated with donut:
(Its possible that some Antivirus will flag these files, because it was generated with donut. It is one of the most popular shellcode generators on github and many people abusing it for malicious activity. So if you are unsure please generate it by yourself.)

https://www.mediafire.com/file/i0mw9ntdg73ak17/messagebox.rar/file
Password: golang123

Filepumper:

package main

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

// Function to append zeros to the file
func appendZerosToFile(inputFilePath, outputFilePath string, sizeInMB int) error {
	// Open the input file
	inputFile, err := os.Open(inputFilePath)
	if err != nil {
		return fmt.Errorf("failed to open input file: %v", err)
	}
	defer inputFile.Close()

	// Create the output file
	outputFile, err := os.Create(outputFilePath)
	if err != nil {
		return fmt.Errorf("failed to create output file: %v", err)
	}
	defer outputFile.Close()

	// Copy the input file content to the output file
	_, err = io.Copy(outputFile, inputFile)
	if err != nil {
		return fmt.Errorf("failed to copy input file content: %v", err)
	}

	// Append the specified number of zero bytes to the output file
	zeroBuffer := make([]byte, 1024*1024) // 1 MB buffer
	for i := 0; i < sizeInMB; i++ {
		_, err = outputFile.Write(zeroBuffer)
		if err != nil {
			return fmt.Errorf("failed to write zero bytes: %v", err)
		}
	}

	return nil
}

func main() {
	if len(os.Args) != 4 {
		fmt.Println("Usage: filepumper <input file> <output file> <size in MB>")
		return
	}

	inputFilePath := os.Args[1]
	outputFilePath := os.Args[2]
	sizeInMB := 0
	_, err := fmt.Sscanf(os.Args[3], "%d", &sizeInMB)
	if err != nil || sizeInMB <= 0 {
		fmt.Println("Invalid size in MB")
		return
	}

	err = appendZerosToFile(inputFilePath, outputFilePath, sizeInMB)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
	} else {
		fmt.Printf("Successfully appended %d MB of zero bytes to %s\n", sizeInMB, outputFilePath)
	}
}

Loader C:

#include <stdio.h>
#include <windows.h>

int main()
{
    const char* filePath = "messagebox-pumped-2.bin"; // Replace with the path to your file

    // Open the file for reading in binary mode
    FILE* file = fopen(filePath, "rb");
    if (file == NULL) {
        printf("Failed to open file\n");
        return 1;
    }

    // Get the file size
    fseek(file, 0, SEEK_END);
    long fileSize = ftell(file);
    fseek(file, 0, SEEK_SET); // Rewind the file pointer to the beginning

    if (fileSize <= 0) {
        printf("Failed to get file size\n");
        fclose(file);
        return 1;
    }

    // Allocate memory to store file content
    char* buffer = (char*)malloc(fileSize);
    if (buffer == NULL) {
        printf("Failed to allocate memory for file content\n");
        fclose(file);
        return 1;
    }

    // Read file content into buffer
    size_t bytesRead = fread(buffer, 1, fileSize, file);
    if (bytesRead != fileSize) {
        printf("Failed to read file content\n");
        free(buffer);
        fclose(file);
        return 1;
    }

    // Close the file
    fclose(file);

    // Print the size of the buffer
    printf("File size: %ld bytes\n", fileSize);

    DWORD oldprotect = 0;

    BOOL ret = VirtualProtect(buffer, fileSize, PAGE_EXECUTE_READWRITE, &oldprotect);
    if ( ret != 0 ) {
        void (*func)() = (void (*)())buffer;  // Cast ptr to a function pointer
        func();                            // Call the function
    }
}

Loader golang:

package main

/*
void* executePointer(void* ptr) {
    void (*func)() = (void (*)())ptr;  // Cast ptr to a function pointer
    func();                            // Call the function
    return NULL;
}
*/
import "C"
import (
	"fmt"
	"io"
	"os"
	"bufio"
	"unsafe"

	"golang.org/x/sys/windows"
)

func main() {
	file, err := os.Open("messagebox-pumped-2.bin")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer file.Close()

	// Get the file size
	stat, err := file.Stat()
	if err != nil {
		fmt.Println(err)
		return
	}

	// Read the file into a byte slice
	code := make([]byte, stat.Size())
	_, err = bufio.NewReader(file).Read(code)
	if err != nil && err != io.EOF {
		fmt.Println(err)
		return
	}

	kernel32DLL	:= windows.NewLazySystemDLL("kernel32.dll")
	VirtualProtectEx := kernel32DLL.NewProc("VirtualProtectEx")

	var oldProtect uint32
	_, _, _ = VirtualProtectEx.Call(uintptr(0xffffffffffffffff), uintptr(unsafe.Pointer(&code[0])), uintptr(stat.Size()), windows.PAGE_EXECUTE_READWRITE, uintptr(unsafe.Pointer(&oldProtect)))
	//if errVirtualProtectEx != nil && errVirtualProtectEx.Error() != "The operation completed successfully." {
		//fmt.Printf("[!] Error on VirtualProtect:", errVirtualProtectEx, "\n")
	//}

	C.executePointer(unsafe.Pointer(&code[0]))

}

Messagebox:

package main

import (
	"golang.org/x/sys/windows"
)

func main() {
	hWnd := uintptr(0)
	windows.MessageBox(
		windows.HWND(hWnd), 		         	  // [in, optional] HWND    hWnd,
		windows.StringToUTF16Ptr("hi"), // [in, optional] LPCTSTR lpText,
		windows.StringToUTF16Ptr("ho"),       // [in, optional] LPCTSTR lpCaption,
		windows.MB_OK) 				          // [in] UINT    uType

}

Error:

Exception 0xc0000005 0x8 0xc000100000 0xc000100000
PC=0xc000100000
signal arrived during external code execution

runtime.cgocall(0x7ff729256ae0, 0xc000027d60)
        C:/Program Files/Go/src/runtime/cgocall.go:157 +0x3e fp=0xc000027d38 sp=0xc000027d00 pc=0x7ff7291b56de
main._Cfunc_executePointer(0xc000100000)
        _cgo_gotypes.go:43 +0x52 fp=0xc000027d60 sp=0xc000027d38 pc=0x7ff7292564f2
main.main.func1(0xc00001c360?)
        C:/Users/Admin/Desktop/gobug/loader.go:53 +0x58 fp=0xc000027db0 sp=0xc000027d60 pc=0x7ff729256a38
main.main()
        C:/Users/Admin/Desktop/gobug/loader.go:53 +0x454 fp=0xc000027f50 sp=0xc000027db0 pc=0x7ff729256994
runtime.main()
        C:/Program Files/Go/src/runtime/proc.go:271 +0x28b fp=0xc000027fe0 sp=0xc000027f50 pc=0x7ff7291eab8b
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000027fe8 sp=0xc000027fe0 pc=0x7ff729217541

goroutine 2 gp=0xc00003a700 m=nil [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00003dfa8 sp=0xc00003df88 pc=0x7ff7291eaf8e
runtime.goparkunlock(...)
        C:/Program Files/Go/src/runtime/proc.go:408
runtime.forcegchelper()
        C:/Program Files/Go/src/runtime/proc.go:326 +0xb8 fp=0xc00003dfe0 sp=0xc00003dfa8 pc=0x7ff7291eae18
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00003dfe8 sp=0xc00003dfe0 pc=0x7ff729217541
created by runtime.init.6 in goroutine 1
        C:/Program Files/Go/src/runtime/proc.go:314 +0x1a

goroutine 3 gp=0xc00003aa80 m=nil [GC sweep wait]:
runtime.gopark(0x1?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00003ff80 sp=0xc00003ff60 pc=0x7ff7291eaf8e
runtime.goparkunlock(...)
        C:/Program Files/Go/src/runtime/proc.go:408
runtime.bgsweep(0xc00001a070)
        C:/Program Files/Go/src/runtime/mgcsweep.go:318 +0xdf fp=0xc00003ffc8 sp=0xc00003ff80 pc=0x7ff7291d5d5f
runtime.gcenable.gowrap1()
        C:/Program Files/Go/src/runtime/mgc.go:203 +0x25 fp=0xc00003ffe0 sp=0xc00003ffc8 pc=0x7ff7291ca825
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00003ffe8 sp=0xc00003ffe0 pc=0x7ff729217541
created by runtime.gcenable in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:203 +0x66

goroutine 4 gp=0xc00003ac40 m=nil [GC scavenge wait]:
runtime.gopark(0x10000?, 0x7ff7292b7a28?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00004ff78 sp=0xc00004ff58 pc=0x7ff7291eaf8e
runtime.goparkunlock(...)
        C:/Program Files/Go/src/runtime/proc.go:408
runtime.(*scavengerState).park(0x7ff72933e9e0)
        C:/Program Files/Go/src/runtime/mgcscavenge.go:425 +0x49 fp=0xc00004ffa8 sp=0xc00004ff78 pc=0x7ff7291d3709
runtime.bgscavenge(0xc00001a070)
        C:/Program Files/Go/src/runtime/mgcscavenge.go:658 +0x59 fp=0xc00004ffc8 sp=0xc00004ffa8 pc=0x7ff7291d3cb9
runtime.gcenable.gowrap2()
        C:/Program Files/Go/src/runtime/mgc.go:204 +0x25 fp=0xc00004ffe0 sp=0xc00004ffc8 pc=0x7ff7291ca7c5
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00004ffe8 sp=0xc00004ffe0 pc=0x7ff729217541
created by runtime.gcenable in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:204 +0xa5

goroutine 5 gp=0xc00003b180 m=nil [finalizer wait]:
runtime.gopark(0xc000041e48?, 0x7ff7291bf065?, 0xa8?, 0x1?, 0xc00003a000?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc000041e20 sp=0xc000041e00 pc=0x7ff7291eaf8e
runtime.runfinq()
        C:/Program Files/Go/src/runtime/mfinal.go:194 +0x107 fp=0xc000041fe0 sp=0xc000041e20 pc=0x7ff7291c98a7
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000041fe8 sp=0xc000041fe0 pc=0x7ff729217541
created by runtime.createfing in goroutine 1
        C:/Program Files/Go/src/runtime/mfinal.go:164 +0x3d

goroutine 6 gp=0xc00003b340 m=nil [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc000051f50 sp=0xc000051f30 pc=0x7ff7291eaf8e
runtime.gcBgMarkWorker()
        C:/Program Files/Go/src/runtime/mgc.go:1310 +0xe5 fp=0xc000051fe0 sp=0xc000051f50 pc=0x7ff7291cc765
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000051fe8 sp=0xc000051fe0 pc=0x7ff729217541
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:1234 +0x1c

goroutine 18 gp=0xc0004fc000 m=nil [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00004bf50 sp=0xc00004bf30 pc=0x7ff7291eaf8e
runtime.gcBgMarkWorker()
        C:/Program Files/Go/src/runtime/mgc.go:1310 +0xe5 fp=0xc00004bfe0 sp=0xc00004bf50 pc=0x7ff7291cc765
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00004bfe8 sp=0xc00004bfe0 pc=0x7ff729217541
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:1234 +0x1c

goroutine 19 gp=0xc0004fc1c0 m=nil [GC worker (idle)]:
runtime.gopark(0x177fa8942ac0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00004df50 sp=0xc00004df30 pc=0x7ff7291eaf8e
runtime.gcBgMarkWorker()
        C:/Program Files/Go/src/runtime/mgc.go:1310 +0xe5 fp=0xc00004dfe0 sp=0xc00004df50 pc=0x7ff7291cc765
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00004dfe8 sp=0xc00004dfe0 pc=0x7ff729217541
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:1234 +0x1c

goroutine 34 gp=0xc0000841c0 m=nil [GC worker (idle)]:
runtime.gopark(0x177fa8942ac0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00008df50 sp=0xc00008df30 pc=0x7ff7291eaf8e
runtime.gcBgMarkWorker()
        C:/Program Files/Go/src/runtime/mgc.go:1310 +0xe5 fp=0xc00008dfe0 sp=0xc00008df50 pc=0x7ff7291cc765
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00008dfe8 sp=0xc00008dfe0 pc=0x7ff729217541
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:1234 +0x1c

goroutine 35 gp=0xc000084380 m=nil [GC worker (idle)]:
runtime.gopark(0x177fa8942ac0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc00008ff50 sp=0xc00008ff30 pc=0x7ff7291eaf8e
runtime.gcBgMarkWorker()
        C:/Program Files/Go/src/runtime/mgc.go:1310 +0xe5 fp=0xc00008ffe0 sp=0xc00008ff50 pc=0x7ff7291cc765
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00008ffe8 sp=0xc00008ffe0 pc=0x7ff729217541
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:1234 +0x1c

goroutine 7 gp=0xc00003b500 m=nil [GC worker (idle)]:
runtime.gopark(0x177fa8942ac0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Program Files/Go/src/runtime/proc.go:402 +0xce fp=0xc000089f50 sp=0xc000089f30 pc=0x7ff7291eaf8e
runtime.gcBgMarkWorker()
        C:/Program Files/Go/src/runtime/mgc.go:1310 +0xe5 fp=0xc000089fe0 sp=0xc000089f50 pc=0x7ff7291cc765
runtime.goexit({})
        C:/Program Files/Go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000089fe8 sp=0xc000089fe0 pc=0x7ff729217541
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Program Files/Go/src/runtime/mgc.go:1234 +0x1c
rax     0xc000028000
rbx     0xc000027d60
rcx     0x7ff72933f098
rdx     0xc000027cf0
rdi     0x310
rsi     0xc000028000
rbp     0xdba1bffc00
rsp     0xdba1bffb98
r8      0x7ff72933f040
r9      0x0
r10     0x3a
r11     0x0
r12     0xc00000a070
r13     0x0
r14     0xc00003a000
r15     0x7
rip     0xc000100000
rflags  0x10206
cs      0x33
fs      0x53
gs      0x2b
exit status 2