Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nanitefactory/gominhook
MinHook binding for Go (Golang) with support for Windows API.
https://github.com/nanitefactory/gominhook
api-hook go golang hacking hooking library module win32api windows
Last synced: 18 days ago
JSON representation
MinHook binding for Go (Golang) with support for Windows API.
- Host: GitHub
- URL: https://github.com/nanitefactory/gominhook
- Owner: NaniteFactory
- License: unlicense
- Created: 2018-10-03T14:57:13.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2019-07-04T08:17:24.000Z (over 5 years ago)
- Last Synced: 2024-06-18T23:03:17.032Z (7 months ago)
- Topics: api-hook, go, golang, hacking, hooking, library, module, win32api, windows
- Language: Go
- Homepage: https://www.youtube.com/watch?v=rMQqD08C3Wc
- Size: 37.1 KB
- Stars: 73
- Watchers: 6
- Forks: 11
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# gominhook
`gominhook` is a Golang wrapper of [minhook](https://github.com/TsudaKageyu/minhook).
This stuff heavily relies on `cgo`.
- - -
### Installation
1. Install `gominhook`.
`go get -v github.com/nanitefactory/gominhook`2. Get `Minhook` library.
---
**For x64 users:**
Have `MinHook.x64.dll` with your project.
You can get it from either of these sites:
- [gominhook/MinHook_133_bin/bin/MinHook.x64.dll](./MinHook_133_bin/bin)
- https://github.com/TsudaKageyu/minhook/releases
---
**For x86 users:**
You need `MinHook.gcc.x86.dll`.
- [gominhook/MinHook_133_bin/bin/MinHook.gcc.x86.dll](./MinHook_133_bin/bin)
---
3. That's it!
`import "github.com/nanitefactory/gominhook"`
- - -
### Exports
Here is a list of all supported functions & data by `gominhook`,
```Go
func gominhook.Initialize() error
func gominhook.Uninitialize() error
``````Go
func gominhook.CreateHook(pTarget, pDetour, ppOriginal uintptr) error
func gominhook.CreateHookAPI(strModule, strProcName string, pDetour, ppOriginal uintptr) error
func gominhook.CreateHookAPIEx(strModule, strProcName string, pDetour, ppOriginal, ppTarget uintptr) error
``````Go
func gominhook.RemoveHook(pTarget uintptr) error
func gominhook.EnableHook(pTarget uintptr) error
func gominhook.DisableHook(pTarget uintptr) error
``````Go
func gominhook.QueueEnableHook(pTarget uintptr) error
func gominhook.QueueDisableHook(pTarget uintptr) error
func gominhook.ApplyQueued() error
``````Go
const gominhook.AllHooks = NULL
const gominhook.NULL = 0
```which is straightforward & effective enough. xD
- - -
### Samples
- https://github.com/NaniteFactory/hookwin10calc
- https://gist.github.com/NaniteFactory/181ac6be5ac13c200612677f17e3f352This example below tries to hook `user32.MessageBoxW`.
```Go
package mainimport (
"fmt"
"log"
"syscall"
"unsafe""github.com/nanitefactory/gominhook"
)/*
#include// 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&*/
```- - -
### More information
See `minhook` ref for C/C++ users.
- https://github.com/TsudaKageyu/minhook
- https://github.com/TsudaKageyu/minhook/blob/master/include/MinHook.h
- https://github.com/TsudaKageyu/minhook/wiki
- https://www.codeproject.com/Articles/44326/MinHook-The-Minimalistic-x-x-API-Hooking-Libra- - -