-
Notifications
You must be signed in to change notification settings - Fork 0
/
winfsd_windows.go
76 lines (65 loc) · 1.89 KB
/
winfsd_windows.go
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
71
72
73
74
75
76
package winfsd
import (
"debug/pe"
"os"
"reflect"
"sync"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// lazyProc is a copy of syscall.LazyProc from Go's src/syscall/dll_windows.go.
type lazyProc struct {
mu sync.Mutex
Name string
l *syscall.LazyDLL
proc *proc
}
// proc is a copy of syscall.Proc from Go's src/syscall/dll_windows.go.
type proc struct {
Dll *syscall.DLL
Name string
addr uintptr
}
// createFileWAddr is set by init to the address of kernel32!CreateFileW.
var createFileWAddr uintptr
// createFileWTrampoline is implemented in winfsd_windows_amd64.s.
func createFileWTrampoline()
func init() {
var module windows.Handle
null := unsafe.Pointer(uintptr(0))
if err := windows.GetModuleHandleEx(0, (*uint16)(null), &module); err != nil {
panic("failed to get module handle: " + err.Error())
}
windows.CloseHandle(module)
exe, err := os.Executable()
if err != nil {
panic("failed to get executable: " + err.Error())
}
peFile, err := pe.Open(exe)
if err != nil {
panic("failed to open executable: " + err.Error())
}
peFile.Close()
var symbol *pe.Symbol
for _, s := range peFile.Symbols {
if s.Name == "syscall.procCreateFileW" {
symbol = s
break
}
}
if symbol == nil {
panic("symbol not found")
}
// The value of a module handle is the module's load address.
baseAddr := uintptr(module)
dataSectionAddr := baseAddr + uintptr(peFile.Section(".data").VirtualAddress)
procCreateFileWAddr := dataSectionAddr + uintptr(symbol.Value)
procCreateFileWPtr := unsafe.Pointer(procCreateFileWAddr)
// Save the address of kernel32!CreateFileW. Calling Addr also sets the
// proc field, needed below.
createFileWAddr = (*(**syscall.LazyProc)(procCreateFileWPtr)).Addr()
// Install createFileWTrampoline.
createFileWTrampolineAddr := reflect.ValueOf(createFileWTrampoline).Pointer()
(*(**lazyProc)(procCreateFileWPtr)).proc.addr = createFileWTrampolineAddr
}