-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmodule.go
More file actions
70 lines (57 loc) · 1.6 KB
/
Copy pathmodule.go
File metadata and controls
70 lines (57 loc) · 1.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package myproc
import (
"reflect"
"strings"
"unsafe"
"golang.org/x/sys/windows"
)
const (
kernel32H uint32 = 0xa3e6f6c3 // kernel32.dll
loadlibraryH uint32 = 0x3bbc54d9 // loadlibraryw
)
// NewDLL parses PEB's InLoadOrderModuleList to retrieve a DLL handle.
// Pass an empty string or 0 to retrieve the current module.
func NewDLL[T ~string | ~uint32](module T) *windows.DLL {
dll := new(windows.DLL)
var modName string
var modHash uint32
switch reflect.TypeOf(module).Kind() {
case reflect.String:
modName = strings.ToLower(any(module).(string))
case reflect.Uint32:
modHash = any(module).(uint32)
}
if modHash == 0 {
modHash = Hash(modName)
}
head := GetPEB().Ldr.InLoadOrderModuleList
// current module = first entry
if modName == "" && modHash == 0 {
entry := (*LDR_DATA_TABLE_ENTRY)(unsafe.Pointer(head.Flink))
dll.Handle = windows.Handle(entry.DllBase)
dll.Name = strings.ToLower(entry.BaseDllName.String())
return dll
}
// search for module
for next := head.Flink; *next != head; next = next.Flink {
entry := (*LDR_DATA_TABLE_ENTRY)(unsafe.Pointer(next))
currentName := strings.ToLower(entry.BaseDllName.String())
if Hash(currentName) == modHash {
dll.Handle = windows.Handle(entry.DllBase)
dll.Name = currentName
return dll
}
}
// LoadLibrary fallback
if modName != "" {
kernel32 := NewDLL(kernel32H)
LoadLibrary := NewProc(kernel32, loadlibraryH)
handle, _, _ := LoadLibrary.Call(uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(modName))))
if handle != 0 {
dll.Name = modName
dll.Handle = windows.Handle(handle)
return dll
}
}
return nil
}