Skip to content

Instantly share code, notes, and snippets.

@ZenLiuCN
Forked from chanwit/win32_jit.go
Last active November 17, 2021 07:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZenLiuCN/c4832b309cf7902b5f6983dff52f996f to your computer and use it in GitHub Desktop.
Save ZenLiuCN/c4832b309cf7902b5f6983dff52f996f to your computer and use it in GitHub Desktop.
package main
import (
"syscall"
"unsafe"
)
const (
MemCommit = 0x1000
MemReserve = 0x2000
PageExecuteReadwrite = 0x40
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
virtualAlloc = kernel32.MustFindProc("VirtualAlloc")
)
func sysAlloc(n uintptr) (uintptr, error) {
addr, _, err := virtualAlloc.Call(0, n, MemReserve|MemCommit, PageExecuteReadwrite)
if addr == 0 {
return 0, err
}
return addr, nil
}
const SIZE = 64 * 1024
func Execute(data []byte,invoker func(unsafe.Pointer) error) (er error) {
size := len(data)
addr, err := sysAlloc(uintptr(size))
if err != nil {
return err
}
buf := (*[SIZE]byte)(unsafe.Pointer(addr))
for i := range data {
buf[i] = data[i]
}
unsafeFunc := (uintptr)(unsafe.Pointer(&buf))
return invoker(unsafe.Pointer(&unsafeFunc))
}
func main() {
ret:=0
//binary dump of an compiled object
/**
package inc
func inc(v int) int{
return v+1
}
*/
err:=Execute([]byte{
0x48,0x83,0xec,0x10,
0x48,0x89,0x6c,0x24,0x08,
0x48,0x8d,0x6c,0x24,0x08,
0x48,0x89,0x44,0x24,0x18,
0x48,0xc7,0x04,0x24,0x00,0x00,0x00,0x00,
0x48,0x8b,0x4c,0x24,0x18,
0x48,0x8d,0x41,0x01,
0x48,0x89,0x04,0x24,
0x48,0x8b,0x6c,0x24,0x08,
0x48,0x83,0xc4,0x10,
0xc3,
},func(pointer unsafe.Pointer) error {
fn:=*(*func(int)int)(pointer)
ret=fn(10)
return nil
})
if err!=nil{
panic(err)
}
println("invoked :",ret)
}
package main
import (
"fmt"
"log"
"syscall"
"unsafe"
)
const (
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_EXECUTE_READWRITE = 0x40
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
VirtualAlloc = kernel32.MustFindProc("VirtualAlloc")
)
func SysAlloc(n uintptr) (uintptr, error) {
addr, _, err := VirtualAlloc.Call(0, n, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE)
if addr == 0 {
return 0, err
}
return addr, nil
}
const SIZE = 64 * 1024
type FunctionBuilder struct {
size uint32
pc int
buf unsafe.Pointer
}
func (fb *FunctionBuilder) Nop() {
b := (*[SIZE]byte)(fb.buf)
b[fb.pc] = 0x90;
fb.pc++;
}
func (fb *FunctionBuilder) Push_EBP() {
b := (*[SIZE]byte)(fb.buf)
b[fb.pc] = 0x55;
fb.pc++;
}
func (fb *FunctionBuilder) Pop_EBP() {
b := (*[SIZE]byte)(fb.buf)
b[fb.pc] = 0x5d;
fb.pc++;
}
func (fb *FunctionBuilder) Mov_ESP_EBP() {
b := (*[SIZE]byte)(fb.buf)
b[fb.pc] = 0x8b;
fb.pc++;
b[fb.pc] = 0xec;
fb.pc++;
}
func (fb *FunctionBuilder) Mov_EBP_Param_EAX(i int) {
b := (*[SIZE]byte)(fb.buf)
b[fb.pc] = 0x8b; fb.pc++;
b[fb.pc] = 0x45; fb.pc++;
b[fb.pc] = byte((i+2)*4); fb.pc++;
}
func (fb *FunctionBuilder) IMul_EBP_Param_EAX(i int) {
b := (*[SIZE]byte)(fb.buf)
b[fb.pc] = 0x0f; fb.pc++;
b[fb.pc] = 0xaf; fb.pc++;
b[fb.pc] = 0x45; fb.pc++;
b[fb.pc] = byte((i+2)*4); fb.pc++;
}
func (fb *FunctionBuilder) Add_EBP_Param_EAX(i int) {
b := (*[SIZE]byte)(fb.buf)
b[fb.pc] = 0x03; fb.pc++;
b[fb.pc] = 0x45; fb.pc++;
b[fb.pc] = byte((i+2)*4); fb.pc++;
}
func (fb *FunctionBuilder) Ret() {
b := (*[SIZE]byte)(fb.buf)
b[fb.pc] = 0xc3;
fb.pc++;
}
/*
func Mul(x, y) {
}
func Add(x, y) {
}
func Ret(x) {
}
*/
func mkprog() error {
const size = SIZE
addr, err := SysAlloc(size)
if err != nil {
return err
}
fb := &FunctionBuilder{SIZE, 0, unsafe.Pointer(addr)}
fb.Push_EBP()
fb.Mov_ESP_EBP()
fb.Mov_EBP_Param_EAX(0)
fb.IMul_EBP_Param_EAX(1)
fb.Add_EBP_Param_EAX(2)
fb.Pop_EBP()
fb.Ret()
fb.Nop()
r1, r2, e := syscall.Syscall(addr, 3, 3, 5, 2)
fmt.Printf("%d\n", r1)
fmt.Printf("%d\n", r2)
fmt.Printf("%s\n", e)
return nil
}
func main() {
err := mkprog()
if err != nil {
log.Fatal(err)
}
fmt.Printf("HELLO\n")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment