Go语言设置Windows事件钩子

huangapple go评论83阅读模式
英文:

Go lang set windows events hooks

问题

package main

import (
"fmt"
"log"
"syscall"
"unsafe"

"golang.org/x/sys/windows"

)

var (
user32 = windows.NewLazyDLL("user32.dll")
modkernel32 = windows.NewLazyDLL("kernel32.dll")
procSetWinEventHook = user32.NewProc("SetWinEventHook")
procUnhookWinEvent = user32.NewProc("UnhookWinEvent")
procGetMessage = user32.NewProc("GetMessageW")
procTranslateMessage = user32.NewProc("TranslateMessage")
procDispatchMessage = user32.NewProc("DispatchMessageW")
procGetModuleHandle = modkernel32.NewProc("GetModuleHandleW")
ActiveWinEventHook WINEVENTPROC = func(hWinEventHook HWINEVENTHOOK, event uint32, hwnd HWND, idObject int32, idChild int32, idEventThread uint32, dwmsEventTime uint32) {
log.Println("fond")
}
)

type WINEVENTPROC func(hWinEventHook HWINEVENTHOOK, event uint32, hwnd HWND, idObject int32, idChild int32, idEventThread uint32, dwmsEventTime uint32) uintptr

type (
HANDLE uintptr
HINSTANCE HANDLE
HHOOK HANDLE
HMODULE HANDLE
HWINEVENTHOOK HANDLE
DWORD uint32
INT int
WPARAM uintptr
LPARAM uintptr
LRESULT uintptr
HWND HANDLE
UINT uint32
BOOL int32
ULONG_PTR uintptr
LONG int32
LPWSTR *WCHAR
WCHAR uint16
)

type POINT struct {
X, Y int32
}

type MSG struct {
Hwnd HWND
Message uint32
WParam uintptr
LParam uintptr
Time uint32
Pt POINT
}

const (
EVENT_SYSTEM_FOREGROUND = 3
WINEVENT_OUTOFCONTEXT = 0
WINEVENT_INCONTEXT = 4
WINEVENT_SKIPOWNPROCESS = 2
WINEVENT_SKIPOWNTHREAD = 1
)

func main() {

log.Println("starting")
hinst := GetModuleHandle("")
fmt.Println(hinst)

winEvHook := SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, 0, ActiveWinEventHook, 0, 0, WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNPROCESS)
log.Println("Windows Event Hook:")
log.Println("Windows Event Hook:", winEvHook)

for {

	var msg MSG
	if m := GetMessage(&msg, 0, 0, 0); m != 0 {
		TranslateMessage(&msg)
		DispatchMessage(&msg)
	}
}
UnhookWinEvent(winEvHook)
return

}

func SetWinEventHook(eventMin DWORD, eventMax DWORD, hmodWinEventProc HMODULE, pfnWinEventProc WINEVENTPROC, idProcess DWORD, idThread DWORD, dwFlags DWORD) HWINEVENTHOOK {
log.Println("procSetWinEventHook S")
ret, ret2, err := procSetWinEventHook.Call(
uintptr(eventMin),
uintptr(eventMax),
uintptr(hmodWinEventProc),
pfnWinEventProcCallback,
uintptr(idProcess),
uintptr(idThread),
uintptr(dwFlags),
)

log.Printf("%#v", err)
log.Printf("%#v", ret)
log.Printf("%#v", ret2)
log.Println("procSetWinEventHook E")
return HWINEVENTHOOK(ret)

}

func UnhookWinEvent(hWinEventHook HWINEVENTHOOK) bool {
ret, _, _ := procUnhookWinEvent.Call(
uintptr(hWinEventHook),
)
return ret != 0
}

func GetModuleHandle(modulename string) HINSTANCE {
var mn uintptr
if modulename == "" {
mn = 0
} else {
mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename)))
}
ret, _, _ := procGetModuleHandle.Call(mn)
return HINSTANCE(ret)
}

func GetMessage(msg *MSG, hwnd HWND, msgFilterMin UINT, msgFilterMax UINT) int {
ret, _, _ := procGetMessage.Call(
uintptr(unsafe.Pointer(msg)),
uintptr(hwnd),
uintptr(msgFilterMin),
uintptr(msgFilterMax))

return int(ret)

}

func TranslateMessage(msg *MSG) bool {
ret, _, _ := procTranslateMessage.Call(
uintptr(unsafe.Pointer(msg)))
return ret != 0
}

func DispatchMessage(msg *MSG) uintptr {
ret, _, _ := procDispatchMessage.Call(
uintptr(unsafe.Pointer(msg)))
return ret
}

英文:

Hi am trying to set a global event hook in go but i dont get the event handle or any error message , kindly help , below is code , from my code below i expected to get error message from SetWinEventHook if any but it just blocks at Logger.Println("procSetWinEventHook S") please not that i have not included my custo Logger but thats not a blocker.

  package main

import(
	"fmt"
	"syscall"
	"unsafe"
	"log"
	"golang.org/x/sys/windows"
)

var(
	user32 = windows.NewLazyDLL("user32.dll")
	modkernel32 = windows.NewLazyDLL("kernel32.dll")
	
	procSetWinEventHook		= user32.NewProc("SetWinEventHook")
	procUnhookWinEvent		= user32.NewProc("UnhookWinEvent")
	procGetMessage = user32.NewProc("GetMessageW")
	procTranslateMessage = user32.NewProc("TranslateMessage")
	procDispatchMessage = user32.NewProc("DispatchMessageW")
	
	procGetModuleHandle            = modkernel32.NewProc("GetModuleHandleW")
	
	ActiveWinEventHook WINEVENTPROC = func (hWinEventHook HWINEVENTHOOK, event uint32, hwnd HWND, idObject int32, idChild int32, idEventThread uint32, dwmsEventTime uint32)  {
		log.Println("fond")
		
	}

)

type WINEVENTPROC func(hWinEventHook HWINEVENTHOOK, event uint32, hwnd HWND, idObject int32, idChild int32, idEventThread uint32, dwmsEventTime uint32) uintptr

type (
	HANDLE          uintptr
	HINSTANCE       HANDLE
	HHOOK       HANDLE
	HMODULE     HANDLE
	HWINEVENTHOOK HANDLE
	DWORD           uint32
	INT           int
	WPARAM           uintptr
	LPARAM uintptr
	LRESULT uintptr
	HWND HANDLE
	UINT uint32
	BOOL int32
	ULONG_PTR uintptr
	LONG                  int32
	LPWSTR                *WCHAR
	WCHAR                 uint16
)

type POINT struct {
	X, Y int32
}

type MSG struct {
	Hwnd    HWND
	Message uint32
	WParam  uintptr
	LParam  uintptr
	Time    uint32
	Pt      POINT
}


const (
	//~ EVENT_SYSTEM_FOREGROUND DWORD = 0x0003
	//~ WINEVENT_OUTOFCONTEXT  DWORD = 0x0000
	//~ WINEVENT_INCONTEXT   = 0x0004
	EVENT_SYSTEM_FOREGROUND  = 3
	WINEVENT_OUTOFCONTEXT   = 0
	WINEVENT_INCONTEXT   = 4
	WINEVENT_SKIPOWNPROCESS   = 2
	WINEVENT_SKIPOWNTHREAD   = 1
)

func main() {
	
	log.Println("starting")
	hinst := GetModuleHandle("")
	fmt.Println(hinst)
	
	winEvHook := SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, 0 , ActiveWinEventHook, 0, 0, WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNPROCESS )
	log.Println("Windows Event Hook: ")
	log.Println("Windows Event Hook: ", winEvHook)
	
	for {
		
		var msg MSG
		if m := GetMessage(&msg, 0, 0, 0); m != 0 {
			TranslateMessage(&msg)
			DispatchMessage(&msg)
	   }
	}
	UnhookWinEvent(winEvHook)
	return

}


func SetWinEventHook(eventMin DWORD, eventMax DWORD, hmodWinEventProc HMODULE, pfnWinEventProc WINEVENTPROC, idProcess DWORD, idThread DWORD, dwFlags DWORD) HWINEVENTHOOK {
	log.Println("procSetWinEventHook S")
	ret, ret2 , err := procSetWinEventHook.Call(
		uintptr(eventMin),
		uintptr(eventMax),
		uintptr(hmodWinEventProc),
		pfnWinEventProcCallback,
		uintptr(idProcess),
		uintptr(idThread),
		uintptr(dwFlags),
	)
	
	log.Printf("%#v", err)
	log.Printf("%#v", ret)
	log.Printf("%#v", ret2)
	log.Println("procSetWinEventHook E")
	return HWINEVENTHOOK(ret)
}

func UnhookWinEvent(hWinEventHook HWINEVENTHOOK) bool {
	ret, _, _ := procUnhookWinEvent.Call(
		uintptr(hWinEventHook),
	)
	return ret != 0
}

func GetModuleHandle(modulename string) HINSTANCE {
	var mn uintptr
	if modulename == "" {
		mn = 0
	} else {
		mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename)))
	}
	ret, _, _ := procGetModuleHandle.Call(mn)
	return HINSTANCE(ret)
}

func GetMessage(msg *MSG, hwnd HWND, msgFilterMin UINT, msgFilterMax UINT) int {
	ret, _, _ := procGetMessage.Call(
		uintptr(unsafe.Pointer(msg)),
		uintptr(hwnd),
		uintptr(msgFilterMin),
		uintptr(msgFilterMax))

	return int(ret)
}

func TranslateMessage(msg *MSG) bool {
	ret, _, _ := procTranslateMessage.Call(
		uintptr(unsafe.Pointer(msg)))
	return ret != 0
}

func DispatchMessage(msg *MSG) uintptr {
	ret, _, _ := procDispatchMessage.Call(
		uintptr(unsafe.Pointer(msg)))
	return ret
}

答案1

得分: 2

所以在研究后,我注意到syscall.NewCallback()需要一个输出值,而对于WinEventProc,根据MSDN的说明,回调函数WinEventProc没有返回任何值,所以我"强制"返回了一个uintptr类型的值,并且完美地工作了。代码如下:

package main

import (
	"fmt"
	"log"
	"syscall"
	"unsafe"

	"golang.org/x/sys/windows"
)

var (
	user32       = windows.NewLazyDLL("user32.dll")
	modkernel32  = windows.NewLazyDLL("kernel32.dll")
	procSetWinEventHook   = user32.NewProc("SetWinEventHook")
	procUnhookWinEvent    = user32.NewProc("UnhookWinEvent")
	procGetMessage        = user32.NewProc("GetMessageW")
	procTranslateMessage  = user32.NewProc("TranslateMessage")
	procDispatchMessage   = user32.NewProc("DispatchMessageW")
	procGetModuleHandle   = modkernel32.NewProc("GetModuleHandleW")

	ActiveWinEventHook WINEVENTPROC = func(hWinEventHook HWINEVENTHOOK, event uint32, hwnd HWND, idObject int32, idChild int32, idEventThread uint32, dwmsEventTime uint32) uintptr {
		log.Println("found")
	}

)

type WINEVENTPROC func(hWinEventHook HWINEVENTHOOK, event uint32, hwnd HWND, idObject int32, idChild int32, idEventThread uint32, dwmsEventTime uint32) uintptr

type (
	HANDLE          uintptr
	HINSTANCE       HANDLE
	HHOOK       HANDLE
	HMODULE     HANDLE
	HWINEVENTHOOK HANDLE
	DWORD           uint32
	INT           int
	WPARAM           uintptr
	LPARAM uintptr
	LRESULT uintptr
	HWND HANDLE
	UINT uint32
	BOOL int32
	ULONG_PTR uintptr
	LONG                  int32
	LPWSTR                *WCHAR
	WCHAR                 uint16
)

type POINT struct {
	X, Y int32
}

type MSG struct {
	Hwnd    HWND
	Message uint32
	WParam  uintptr
	LParam  uintptr
	Time    uint32
	Pt      POINT
}

const (
	EVENT_SYSTEM_FOREGROUND = 3
	WINEVENT_OUTOFCONTEXT   = 0
	WINEVENT_INCONTEXT      = 4
	WINEVENT_SKIPOWNPROCESS = 2
	WINEVENT_SKIPOWNTHREAD  = 1
)

func main() {

	log.Println("starting")
	hinst := GetModuleHandle("")
	fmt.Println(hinst)

	winEvHook := SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, 0, ActiveWinEventHook, 0, 0, WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNPROCESS)
	log.Println("Windows Event Hook:")
	log.Println("Windows Event Hook:", winEvHook)

	for {
		var msg MSG
		if m := GetMessage(&msg, 0, 0, 0); m != 0 {
			TranslateMessage(&msg)
			DispatchMessage(&msg)
		}
	}
	UnhookWinEvent(winEvHook)
	return

}

func SetWinEventHook(eventMin DWORD, eventMax DWORD, hmodWinEventProc HMODULE, pfnWinEventProc WINEVENTPROC, idProcess DWORD, idThread DWORD, dwFlags DWORD) HWINEVENTHOOK {
	log.Println("procSetWinEventHook S")
	pfnWinEventProcCallback := syscall.NewCallback(pfnWinEventProc)
	ret, ret2, err := procSetWinEventHook.Call(
		uintptr(eventMin),
		uintptr(eventMax),
		uintptr(hmodWinEventProc),
		pfnWinEventProcCallback,
		uintptr(idProcess),
		uintptr(idThread),
		uintptr(dwFlags),
	)

	log.Printf("%#v", err)
	log.Printf("%#v", ret)
	log.Printf("%#v", ret2)
	log.Println("procSetWinEventHook E")
	return HWINEVENTHOOK(ret)
}

func UnhookWinEvent(hWinEventHook HWINEVENTHOOK) bool {
	ret, _, _ := procUnhookWinEvent.Call(
		uintptr(hWinEventHook),
	)
	return ret != 0
}

func GetModuleHandle(modulename string) HINSTANCE {
	var mn uintptr
	if modulename == "" {
		mn = 0
	} else {
		mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename)))
	}
	ret, _, _ := procGetModuleHandle.Call(mn)
	return HINSTANCE(ret)
}

func GetMessage(msg *MSG, hwnd HWND, msgFilterMin UINT, msgFilterMax UINT) int {
	ret, _, _ := procGetMessage.Call(
		uintptr(unsafe.Pointer(msg)),
		uintptr(hwnd),
		uintptr(msgFilterMin),
		uintptr(msgFilterMax))

	return int(ret)
}

func TranslateMessage(msg *MSG) bool {
	ret, _, _ := procTranslateMessage.Call(
		uintptr(unsafe.Pointer(msg)))
	return ret != 0
}

func DispatchMessage(msg *MSG) uintptr {
	ret, _, _ := procDispatchMessage.Call(
		uintptr(unsafe.Pointer(msg)))
	return ret
}

希望对你有帮助!

英文:

So after research i noticed that

syscall.NewCallback() required an output value , for WinEventProc however from MSDN , the callback WinEventProc didn't return any value , so a "forced" a return value of type uintptr and worked perfectly.Like below code :

package main
import(
"fmt"
"syscall"
"unsafe"
"log"
"golang.org/x/sys/windows"
)
var(
user32 = windows.NewLazyDLL("user32.dll")
modkernel32 = windows.NewLazyDLL("kernel32.dll")
procSetWinEventHook		= user32.NewProc("SetWinEventHook")
procUnhookWinEvent		= user32.NewProc("UnhookWinEvent")
procGetMessage = user32.NewProc("GetMessageW")
procTranslateMessage = user32.NewProc("TranslateMessage")
procDispatchMessage = user32.NewProc("DispatchMessageW")
procGetModuleHandle            = modkernel32.NewProc("GetModuleHandleW")
ActiveWinEventHook WINEVENTPROC = func (hWinEventHook HWINEVENTHOOK, event uint32, hwnd HWND, idObject int32, idChild int32, idEventThread uint32, dwmsEventTime uint32) uintptr  {
log.Println("fond")
}
)
type WINEVENTPROC func(hWinEventHook HWINEVENTHOOK, event uint32, hwnd HWND, idObject int32, idChild int32, idEventThread uint32, dwmsEventTime uint32) uintptr
type (
HANDLE          uintptr
HINSTANCE       HANDLE
HHOOK       HANDLE
HMODULE     HANDLE
HWINEVENTHOOK HANDLE
DWORD           uint32
INT           int
WPARAM           uintptr
LPARAM uintptr
LRESULT uintptr
HWND HANDLE
UINT uint32
BOOL int32
ULONG_PTR uintptr
LONG                  int32
LPWSTR                *WCHAR
WCHAR                 uint16
)
type POINT struct {
X, Y int32
}
type MSG struct {
Hwnd    HWND
Message uint32
WParam  uintptr
LParam  uintptr
Time    uint32
Pt      POINT
}
const (
//~ EVENT_SYSTEM_FOREGROUND DWORD = 0x0003
//~ WINEVENT_OUTOFCONTEXT  DWORD = 0x0000
//~ WINEVENT_INCONTEXT   = 0x0004
EVENT_SYSTEM_FOREGROUND  = 3
WINEVENT_OUTOFCONTEXT   = 0
WINEVENT_INCONTEXT   = 4
WINEVENT_SKIPOWNPROCESS   = 2
WINEVENT_SKIPOWNTHREAD   = 1
)
func main() {
log.Println("starting")
hinst := GetModuleHandle("")
fmt.Println(hinst)
winEvHook := SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, 0 , ActiveWinEventHook, 0, 0, WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNPROCESS )
log.Println("Windows Event Hook: ")
log.Println("Windows Event Hook: ", winEvHook)
for {
var msg MSG
if m := GetMessage(&msg, 0, 0, 0); m != 0 {
TranslateMessage(&msg)
DispatchMessage(&msg)
}
}
UnhookWinEvent(winEvHook)
return
}
func SetWinEventHook(eventMin DWORD, eventMax DWORD, hmodWinEventProc HMODULE, pfnWinEventProc WINEVENTPROC, idProcess DWORD, idThread DWORD, dwFlags DWORD) HWINEVENTHOOK {
log.Println("procSetWinEventHook S")
pfnWinEventProcCallback := syscall.NewCallback(pfnWinEventProc)
ret, ret2 , err := procSetWinEventHook.Call(
uintptr(eventMin),
uintptr(eventMax),
uintptr(hmodWinEventProc),
pfnWinEventProcCallback,
uintptr(idProcess),
uintptr(idThread),
uintptr(dwFlags),
)
log.Printf("%#v", err)
log.Printf("%#v", ret)
log.Printf("%#v", ret2)
log.Println("procSetWinEventHook E")
return HWINEVENTHOOK(ret)
}
func UnhookWinEvent(hWinEventHook HWINEVENTHOOK) bool {
ret, _, _ := procUnhookWinEvent.Call(
uintptr(hWinEventHook),
)
return ret != 0
}
func GetModuleHandle(modulename string) HINSTANCE {
var mn uintptr
if modulename == "" {
mn = 0
} else {
mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename)))
}
ret, _, _ := procGetModuleHandle.Call(mn)
return HINSTANCE(ret)
}
func GetMessage(msg *MSG, hwnd HWND, msgFilterMin UINT, msgFilterMax UINT) int {
ret, _, _ := procGetMessage.Call(
uintptr(unsafe.Pointer(msg)),
uintptr(hwnd),
uintptr(msgFilterMin),
uintptr(msgFilterMax))
return int(ret)
}
func TranslateMessage(msg *MSG) bool {
ret, _, _ := procTranslateMessage.Call(
uintptr(unsafe.Pointer(msg)))
return ret != 0
}
func DispatchMessage(msg *MSG) uintptr {
ret, _, _ := procDispatchMessage.Call(
uintptr(unsafe.Pointer(msg)))
return ret
}

huangapple
  • 本文由 发表于 2017年1月10日 07:58:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/41559026.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定