Last active
May 12, 2022 20:09
-
-
Save NaniteFactory/181ac6be5ac13c200612677f17e3f352 to your computer and use it in GitHub Desktop.
API hook in Golang.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"syscall" | |
"unsafe" | |
"github.com/nanitefactory/gominhook" // In order to use this package you need to have MinHook.x64.dll in your system. | |
) | |
//#include <windows.h> | |
//DWORD64 override(DWORD64 arg, DWORD64 arg2, DWORD64 arg3, DWORD64 arg4); | |
//DWORD64 foo(DWORD64 arg, DWORD64 arg2, DWORD64 arg3, DWORD64 arg4); | |
import "C" | |
// or... DWORD64 (*fpFoo)(DWORD64 arg, DWORD64 arg2, DWORD64 arg3, DWORD64 arg4); | |
var fpFoo *func(arg1, arg2, arg3, arg4 uintptr) (ret uintptr) | |
//export foo | |
func foo(arg1, arg2, arg3, arg4 uintptr) uintptr { | |
log.Println("hi", arg1, arg2, arg3, arg4) | |
return arg1 + arg2 + arg3 + arg4 | |
} | |
//export override | |
func override(arg1, arg2, arg3, arg4 uintptr) (ret uintptr) { | |
log.Println("hooked", arg1, arg2, arg3, arg4) | |
ret, _, _ = syscall.Syscall6( | |
uintptr(unsafe.Pointer(fpFoo)), | |
4, 9, 9, 9, 9, 0, 0, | |
) | |
return ret | |
} | |
func main() { | |
log.Println("init") | |
gominhook.Initialize() | |
defer gominhook.Uninitialize() | |
log.Println("creat") | |
if err := gominhook.CreateHook( | |
uintptr(unsafe.Pointer(C.foo)), | |
uintptr(unsafe.Pointer(C.override)), | |
uintptr(unsafe.Pointer(&fpFoo)), | |
); err != nil { | |
log.Println(err) | |
} | |
log.Println("enable") | |
gominhook.EnableHook(gominhook.AllHooks) | |
log.Println("call foo") | |
log.Println( | |
syscall.Syscall6( | |
uintptr(unsafe.Pointer(C.foo)), | |
4, uintptr(0x1), uintptr(0x2), 3, 4, 0, 0, | |
), | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"syscall" | |
"unsafe" | |
"github.com/nanitefactory/gominhook" // In order to use this package you need to have MinHook.x64.dll in your system. | |
) | |
//#include <windows.h> | |
//DWORD32 override(DWORD32 arg, DWORD32 arg2, DWORD32 arg3, DWORD32 arg4); | |
//DWORD32 foo(DWORD32 arg, DWORD32 arg2, DWORD32 arg3, DWORD32 arg4); | |
import "C" | |
// or... DWORD32 (*fpFoo)(DWORD32 arg, DWORD32 arg2, DWORD32 arg3, DWORD32 arg4); | |
var fpFoo *func(arg1, arg2, arg3, arg4 uintptr) (ret uintptr) | |
//export foo | |
func foo(arg1, arg2, arg3, arg4 uintptr) uintptr { | |
log.Println("hi", arg1, arg2, arg3, arg4) | |
return arg1 + arg2 + arg3 + arg4 | |
} | |
//export override | |
func override(arg1, arg2, arg3, arg4 uintptr) (ret uintptr) { | |
log.Println("hooked", arg1, arg2, arg3, arg4) | |
ret, _, _ = syscall.Syscall6( | |
uintptr(unsafe.Pointer(fpFoo)), | |
4, 9, 9, 9, 9, 0, 0, | |
) | |
return ret | |
} | |
func main() { | |
log.Println("init") | |
gominhook.Initialize() | |
defer gominhook.Uninitialize() | |
log.Println("creat") | |
if err := gominhook.CreateHook( | |
uintptr(unsafe.Pointer(C.foo)), | |
uintptr(unsafe.Pointer(C.override)), | |
uintptr(unsafe.Pointer(&fpFoo)), | |
); err != nil { | |
log.Println(err) | |
} | |
log.Println("enable") | |
gominhook.EnableHook(gominhook.AllHooks) | |
log.Println("call foo") | |
log.Println( | |
syscall.Syscall6( | |
uintptr(unsafe.Pointer(C.foo)), | |
4, uintptr(0x1), uintptr(0x2), 3, 4, 0, 0, | |
), | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"syscall" | |
"unsafe" | |
"github.com/nanitefactory/gominhook" | |
) | |
/* | |
#include <Windows.h> | |
// Put C prototypes here | |
// Delegate type for calling original MessageBoxW. | |
typedef int (WINAPI *MESSAGEBOXW)(HWND, LPCWSTR, LPCWSTR, UINT); | |
// (!) This way you can connect/convert a go function to a c function. | |
int MessageBoxWOverrideHellYeah(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); | |
*/ | |
import "C" | |
// Pointer for calling original MessageBoxW. | |
var fpMessageBoxW C.MESSAGEBOXW | |
// (!) This way you can connect/convert a go function to a c function. | |
//export MessageBoxWOverrideHellYeah | |
func MessageBoxWOverrideHellYeah(hWnd C.HWND, lpText C.LPCWSTR, lpCaption C.LPCWSTR, uType C.UINT) C.int { | |
fmt.Println(" - MessageBoxW Override") | |
foo() | |
ret, _, _ := syscall.Syscall6( | |
uintptr(unsafe.Pointer(fpMessageBoxW)), | |
4, | |
uintptr(unsafe.Pointer(hWnd)), | |
uintptr(unsafe.Pointer(lpText)), | |
uintptr(unsafe.Pointer(lpCaption)), | |
uintptr(uint(uType)), | |
0, 0, | |
) | |
return C.int(ret) | |
} | |
func foo() { | |
fmt.Println(" - I'm so hooked now.") | |
} | |
func main() { | |
// Initialize minhook | |
err := gominhook.Initialize() | |
if err != nil { | |
log.Fatalln(err) | |
} | |
defer gominhook.Uninitialize() | |
// Get procedure user32.MessageBoxW | |
procedure := syscall.NewLazyDLL("user32.dll").NewProc("MessageBoxW") | |
fmt.Println("-- not hooked yet") | |
procedure.Call( | |
0, | |
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("Hello1"))), | |
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("World1"))), | |
1, | |
) | |
fmt.Println(fmt.Sprintf("0x%X", procedure.Addr()), fmt.Sprintf("0x%X", &fpMessageBoxW), fmt.Sprintf("0x%X", fpMessageBoxW)) | |
fmt.Println() | |
// Create a hook for MessageBoxW. | |
err = gominhook.CreateHook(procedure.Addr(), uintptr(C.MessageBoxWOverrideHellYeah), uintptr(unsafe.Pointer(&fpMessageBoxW))) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
// Enable the hook for MessageBoxW. | |
err = gominhook.EnableHook(gominhook.AllHooks) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
// Calling our hooked procedure user32.MessageBoxW. | |
fmt.Println("-- after hook") | |
procedure.Call( | |
0, | |
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("Hello2"))), | |
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("World2"))), | |
1, | |
) | |
fmt.Println(fmt.Sprintf("0x%X", procedure.Addr()), fmt.Sprintf("0x%X", &fpMessageBoxW), fmt.Sprintf("0x%X", fpMessageBoxW)) | |
fmt.Println() | |
// Disable the hook for MessageBoxW. | |
err = gominhook.DisableHook(gominhook.AllHooks) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
// Calling our unhooked procedure user32.MessageBoxW. | |
fmt.Println("-- after unhook") | |
procedure.Call( | |
0, | |
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("Hello3"))), | |
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("World3"))), | |
1, | |
) | |
fmt.Println(fmt.Sprintf("0x%X", procedure.Addr()), fmt.Sprintf("0x%X", &fpMessageBoxW), fmt.Sprintf("0x%X", fpMessageBoxW)) | |
fmt.Println() | |
} | |
/* This outputs... | |
-- not hooked yet | |
0x7FFE6CA4EE10 0x578180 0x0 | |
-- after hook | |
- MessageBoxW Override | |
- I'm so hooked now. | |
0x7FFE6CA4EE10 0x578180 0x& | |
-- after unhook | |
0x7FFE6CA4EE10 0x578180 0x& | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment