diff --git a/go.mod b/go.mod index 6c1e574..2967675 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,11 @@ module github.com/hectorgimenez/d2go -go 1.21 +go 1.22 require ( github.com/faiface/beep v1.1.0 github.com/stretchr/testify v1.8.4 - github.com/winlabs/gowin32 v0.0.0-20221003142512-0d265587d3c9 - golang.org/x/sys v0.16.0 + golang.org/x/sys v0.17.0 ) require ( diff --git a/go.sum b/go.sum index 570b1fa..ca9419f 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/winlabs/gowin32 v0.0.0-20221003142512-0d265587d3c9 h1:U8aCPFEMnxAEyj9IonhMVV1gSL4nzelh8uvoXp0hrq0= -github.com/winlabs/gowin32 v0.0.0-20221003142512-0d265587d3c9/go.mod h1:N51TYkG9JGR5sytj0EoPl31Xg2kuB507lxEmrwSNvfQ= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8 h1:idBdZTd9UioThJp8KpM/rTSinK/ChZFBE43/WtIy8zg= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/image v0.0.0-20190220214146-31aff87c08e9/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -42,8 +40,8 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/memory/process.go b/pkg/memory/process.go index 938696b..caecd0a 100644 --- a/pkg/memory/process.go +++ b/pkg/memory/process.go @@ -3,19 +3,19 @@ package memory import ( "bytes" "encoding/binary" - "github.com/winlabs/gowin32" "golang.org/x/sys/windows" "strings" + "syscall" "unsafe" ) -const moduleName = "D2R.exe" +const moduleName = "d2r.exe" type Process struct { handler windows.Handle - pid uint + pid uint32 moduleBaseAddressPtr uintptr - moduleBaseSize uint + moduleBaseSize uint32 } func NewProcess() (Process, error) { @@ -24,7 +24,7 @@ func NewProcess() (Process, error) { return Process{}, err } - h, err := windows.OpenProcess(0x0010, false, uint32(module.ProcessID)) + h, err := windows.OpenProcess(0x0010, false, module.ProcessID) if err != nil { return Process{}, err } @@ -32,42 +32,41 @@ func NewProcess() (Process, error) { return Process{ handler: h, pid: module.ProcessID, - moduleBaseAddressPtr: uintptr(unsafe.Pointer(module.ModuleBaseAddress)), + moduleBaseAddressPtr: module.ModuleBaseAddress, moduleBaseSize: module.ModuleBaseSize, }, nil } -func getGameModule() (gowin32.ModuleInfo, error) { +func getGameModule() (ModuleInfo, error) { processes := make([]uint32, 2048) length := uint32(0) err := windows.EnumProcesses(processes, &length) if err != nil { - return gowin32.ModuleInfo{}, err + return ModuleInfo{}, err } for _, process := range processes { - module, _ := getMainModule(process) - - if strings.Contains(module.ExePath, moduleName) { + module, found := getMainModule(process) + if found { return module, nil } } - return gowin32.ModuleInfo{}, err + return ModuleInfo{}, err } -func getMainModule(pid uint32) (gowin32.ModuleInfo, error) { - mi, err := gowin32.GetProcessModules(pid) +func getMainModule(pid uint32) (ModuleInfo, bool) { + mi, err := GetProcessModules(pid) if err != nil { - return gowin32.ModuleInfo{}, err + return ModuleInfo{}, false } for _, m := range mi { - if m.ModuleName == moduleName { - return m, nil + if strings.Contains(strings.ToLower(m.ModuleName), moduleName) { + return m, true } } - return gowin32.ModuleInfo{}, err + return ModuleInfo{}, false } func (p Process) getProcessMemory() ([]byte, error) { @@ -161,6 +160,52 @@ func (p Process) FindPattern(memory []byte, pattern, mask string) uintptr { return 0 } -func (p Process) GetPID() uint { +func (p Process) GetPID() uint32 { return p.pid } + +type ModuleInfo struct { + ProcessID uint32 + ModuleBaseAddress uintptr + ModuleBaseSize uint32 + ModuleHandle syscall.Handle + ModuleName string +} + +func GetProcessModules(processID uint32) ([]ModuleInfo, error) { + hProcess, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION|windows.PROCESS_VM_READ, false, processID) + if err != nil { + return nil, err + } + defer windows.CloseHandle(hProcess) + + var modules [1024]windows.Handle + var needed uint32 + if err := windows.EnumProcessModules(hProcess, &modules[0], uint32(unsafe.Sizeof(modules[0]))*1024, &needed); err != nil { + return nil, err + } + count := needed / uint32(unsafe.Sizeof(modules[0])) + + var moduleInfos []ModuleInfo + for i := uint32(0); i < count; i++ { + var mi windows.ModuleInfo + if err := windows.GetModuleInformation(hProcess, modules[i], &mi, uint32(unsafe.Sizeof(mi))); err != nil { + return nil, err + } + + var moduleName [windows.MAX_PATH]uint16 + if err := windows.GetModuleFileNameEx(hProcess, modules[i], &moduleName[0], windows.MAX_PATH); err != nil { + return nil, err + } + + moduleInfos = append(moduleInfos, ModuleInfo{ + ProcessID: processID, + ModuleBaseAddress: mi.BaseOfDll, + ModuleBaseSize: mi.SizeOfImage, + ModuleHandle: syscall.Handle(modules[i]), + ModuleName: syscall.UTF16ToString(moduleName[:]), + }) + } + + return moduleInfos, nil +}