Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "log"
- "reflect"
- "syscall"
- "unsafe"
- )
- var helloworldInstructions = []byte{
- 0x48, 0x83, 0xec, 0x48, // sub $0x48,%rsp
- 0x48, 0x89, 0x6c, 0x24, 0x40, // mov %rbp,0x40(%rsp)
- 0x48, 0x8d, 0x6c, 0x24, 0x40, // lea 0x40(%rsp),%rbp
- 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, // lea 0x0(%rip),%rax # string type address
- 0x48, 0x89, 0x44, 0x24, 0x30, // mov %rax,0x30(%rsp)
- 0x48, 0x8d, 0x05, 0x2f, 0x00, 0x00, 0x00, // lea 0x2f(%rip),%rax # string value address
- 0x48, 0x89, 0x44, 0x24, 0x38, // mov %rax,0x38(%rsp)
- 0x48, 0x8d, 0x44, 0x24, 0x30, // lea 0x30(%rsp),%rax
- 0x48, 0x89, 0x04, 0x24, // mov %rax,(%rsp)
- 0x48, 0xc7, 0x44, 0x24, 0x08, 0x01, 0x00, 0x00, 0x00, // movq $0x1,0x8(%rsp)
- 0x48, 0xc7, 0x44, 0x24, 0x10, 0x01, 0x00, 0x00, 0x00, // movq $0x1,0x10(%rsp)
- 0xe8, 0x00, 0x00, 0x00, 0x00, // callq 0x0(%rip) # fmt.Println
- 0x48, 0x8b, 0x6c, 0x24, 0x40, // mov 0x40(%rsp),%rbp
- 0x48, 0x83, 0xc4, 0x48, // add $0x48,%rsp
- 0xc3, // retq
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # points to data
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # data length
- 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "Hello world"
- }
- func createHelloworldFunction() func() {
- region, err := anonMMap(len(helloworldInstructions))
- if err != nil {
- log.Fatalf("failed to mmap: %+v", err)
- }
- copy(region, helloworldInstructions)
- regionAddr := *(*uintptr)(unsafe.Pointer(®ion))
- strTypeAddr := stringTypeAddr()
- relAddr := strTypeAddr - (regionAddr + 21)
- region[17] = byte(relAddr)
- region[18] = byte(relAddr >> 8)
- region[19] = byte(relAddr >> 16)
- region[20] = byte(relAddr >> 24)
- printlnFunc := fmt.Println
- printlnAddr := **(**uintptr)(unsafe.Pointer(&printlnFunc))
- relAddr = printlnAddr - (regionAddr + 70)
- region[66] = byte(relAddr)
- region[67] = byte(relAddr >> 8)
- region[68] = byte(relAddr >> 16)
- region[69] = byte(relAddr >> 24)
- helloworldDataAddr := (regionAddr + 96)
- region[80] = byte(helloworldDataAddr)
- region[81] = byte(helloworldDataAddr >> 8)
- region[82] = byte(helloworldDataAddr >> 16)
- region[83] = byte(helloworldDataAddr >> 24)
- region[84] = byte(helloworldDataAddr >> 32)
- region[85] = byte(helloworldDataAddr >> 40)
- region[86] = byte(helloworldDataAddr >> 48)
- region[87] = byte(helloworldDataAddr >> 56)
- pointerToFunc := (uintptr)(unsafe.Pointer(®ion))
- return *(*func())(unsafe.Pointer(&pointerToFunc))
- }
- func anonMMap(len int) ([]byte, error) {
- flags := syscall.MAP_PRIVATE | syscall.MAP_ANON | syscall.MAP_32BIT
- prot := syscall.PROT_READ | syscall.PROT_WRITE | syscall.PROT_EXEC
- return syscall.Mmap(0, 0, len, prot, flags)
- }
- func munmap(addr, len int) error {
- _, _, errno := syscall.Syscall(syscall.SYS_MUNMAP, uintptr(addr), uintptr(len), 0)
- if errno != 0 {
- return syscall.Errno(errno)
- }
- return nil
- }
- func stringTypeAddr() uintptr {
- var str string
- efaceToString := reflect.TypeOf(str)
- collapsedEfaceToString := *(*struct {
- typ uintptr
- val uintptr
- })(unsafe.Pointer(&efaceToString))
- return collapsedEfaceToString.val
- }
- func main() {
- helloworld := createHelloworldFunction()
- helloworld()
- }
Add Comment
Please, Sign In to add comment