5 changed files with 217 additions and 0 deletions
-
10go.mod
-
23go.sum
-
23readmemory/handler.go
-
77readmemory/memory.go
-
84readmemory/processes.go
@ -0,0 +1,10 @@ |
|||
module github.com/pedro-walter/golang-readmemory |
|||
|
|||
go 1.18 |
|||
|
|||
require ( |
|||
github.com/0xrawsec/golang-win32 v1.0.14 |
|||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 |
|||
) |
|||
|
|||
require github.com/0xrawsec/golang-utils v1.3.0 // indirect |
|||
@ -0,0 +1,23 @@ |
|||
github.com/0xrawsec/golang-utils v1.3.0 h1:fMgwKu5M2PXFwEfwN9B2T1bfg7LPCaV9fL6Xs/nf2Ps= |
|||
github.com/0xrawsec/golang-utils v1.3.0/go.mod h1:DADTtCFY10qXjWmUVhhJqQIZdSweaHH4soYUDEi8mj0= |
|||
github.com/0xrawsec/golang-win32 v1.0.14 h1:Lj45Cd7qnhCbtnrNCBI3twefRVh759q/rDXrutxQQOo= |
|||
github.com/0xrawsec/golang-win32 v1.0.14/go.mod h1:LDGq8VzCwLZccK1qg7oKBc8n5DmPLi79w+wjew1UApg= |
|||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= |
|||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
|||
github.com/pkg/sftp v1.10.0/go.mod h1:NxmoDg/QLVWluQDUYG7XBZTLUpKeFa8e3aMf1BfjyHk= |
|||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
|||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
|||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
|||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
|||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
|||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
|||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= |
|||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
|||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
|||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= |
|||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
|||
golang.org/x/tools v0.0.0-20190320215829-36c10c0a621f/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= |
|||
golang.org/x/tools v0.0.0-20190625160430-252024b82959/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |
|||
@ -0,0 +1,23 @@ |
|||
package readmemory |
|||
|
|||
import ( |
|||
windows "golang.org/x/sys/windows" |
|||
) |
|||
|
|||
type Handle struct { |
|||
processHandle windows.Handle |
|||
baseAddress int64 |
|||
procReadProcessMemory *windows.Proc |
|||
} |
|||
|
|||
func NewHandle(processName string) Handle { |
|||
var handle Handle |
|||
|
|||
pid, _ := bindDefaultProcess(processName) |
|||
handle.processHandle, _ = windows.OpenProcess(0x0010|windows.PROCESS_VM_READ|windows.PROCESS_QUERY_INFORMATION, false, pid) |
|||
handle.procReadProcessMemory = windows.MustLoadDLL("kernel32.dll").MustFindProc("ReadProcessMemory") |
|||
baseAddress, _ := memoryReadInit(pid, processName) |
|||
handle.baseAddress = baseAddress |
|||
|
|||
return handle |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
package readmemory |
|||
|
|||
import ( |
|||
"encoding/binary" |
|||
"path/filepath" |
|||
"unsafe" |
|||
|
|||
"github.com/0xrawsec/golang-win32/win32" |
|||
kernel32 "github.com/0xrawsec/golang-win32/win32/kernel32" |
|||
windows "golang.org/x/sys/windows" |
|||
) |
|||
|
|||
func memoryReadInit(pid uint32, targetModuleFilename string) (int64, bool) { |
|||
win32handle, _ := kernel32.OpenProcess(0x0010|windows.PROCESS_VM_READ|windows.PROCESS_QUERY_INFORMATION, win32.BOOL(0), win32.DWORD(pid)) |
|||
moduleHandles, _ := kernel32.EnumProcessModules(win32handle) |
|||
for _, moduleHandle := range moduleHandles { |
|||
s, _ := kernel32.GetModuleFilenameExW(win32handle, moduleHandle) |
|||
if filepath.Base(s) == targetModuleFilename { |
|||
info, _ := kernel32.GetModuleInformation(win32handle, moduleHandle) |
|||
baseAddress := int64(info.LpBaseOfDll) |
|||
return baseAddress, true |
|||
} |
|||
} |
|||
return 0, false |
|||
} |
|||
|
|||
func (handle *Handle) ReadMemoryAtByte8(address int64) uint64 { |
|||
var ( |
|||
data [8]byte |
|||
length uint32 |
|||
) |
|||
|
|||
handle.procReadProcessMemory.Call( |
|||
uintptr(handle.processHandle), |
|||
uintptr(handle.baseAddress+address), |
|||
uintptr(unsafe.Pointer(&data[0])), |
|||
uintptr(len(data)), |
|||
uintptr(unsafe.Pointer(&length)), |
|||
) |
|||
|
|||
byte8 := binary.LittleEndian.Uint64(data[:]) |
|||
return byte8 |
|||
} |
|||
|
|||
func (handle *Handle) ReadMemoryAtByte1(address int64) byte { |
|||
var ( |
|||
data [1]byte |
|||
length uint32 |
|||
) |
|||
|
|||
handle.procReadProcessMemory.Call( |
|||
uintptr(handle.processHandle), |
|||
uintptr(handle.baseAddress+address), |
|||
uintptr(unsafe.Pointer(&data[0])), |
|||
uintptr(len(data)), |
|||
uintptr(unsafe.Pointer(&length)), |
|||
) |
|||
|
|||
return data[0] |
|||
} |
|||
|
|||
func (handle *Handle) ReadMemoryAtByte2(address int64) uint16 { |
|||
var ( |
|||
data [2]byte |
|||
length uint32 |
|||
) |
|||
|
|||
handle.procReadProcessMemory.Call( |
|||
uintptr(handle.processHandle), |
|||
uintptr(handle.baseAddress+address), |
|||
uintptr(unsafe.Pointer(&data[0])), |
|||
uintptr(len(data)), |
|||
uintptr(unsafe.Pointer(&length)), |
|||
) |
|||
|
|||
return binary.LittleEndian.Uint16(data[:]) |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
package readmemory |
|||
|
|||
import ( |
|||
"strings" |
|||
"syscall" |
|||
"unsafe" |
|||
|
|||
windows "golang.org/x/sys/windows" |
|||
) |
|||
|
|||
const TH32CS_SNAPPROCESS = 0x00000002 |
|||
|
|||
type WindowsProcess struct { |
|||
ProcessID int |
|||
ParentProcessID int |
|||
Exe string |
|||
} |
|||
|
|||
func processes() ([]WindowsProcess, error) { |
|||
handle, err := windows.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer windows.CloseHandle(handle) |
|||
|
|||
var entry windows.ProcessEntry32 |
|||
entry.Size = uint32(unsafe.Sizeof(entry)) |
|||
err = windows.Process32First(handle, &entry) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
results := make([]WindowsProcess, 0, 50) |
|||
for { |
|||
results = append(results, newWindowsProcess(&entry)) |
|||
|
|||
err = windows.Process32Next(handle, &entry) |
|||
if err != nil { |
|||
if err == syscall.ERROR_NO_MORE_FILES { |
|||
return results, nil |
|||
} |
|||
return nil, err |
|||
} |
|||
} |
|||
} |
|||
|
|||
func findProcessByName(processes []WindowsProcess, name string) *WindowsProcess { |
|||
for _, p := range processes { |
|||
if strings.ToLower(p.Exe) == strings.ToLower(name) { |
|||
return &p |
|||
} |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
func newWindowsProcess(e *windows.ProcessEntry32) WindowsProcess { |
|||
end := 0 |
|||
for { |
|||
if e.ExeFile[end] == 0 { |
|||
break |
|||
} |
|||
end++ |
|||
} |
|||
|
|||
return WindowsProcess{ |
|||
ProcessID: int(e.ProcessID), |
|||
ParentProcessID: int(e.ParentProcessID), |
|||
Exe: syscall.UTF16ToString(e.ExeFile[:end]), |
|||
} |
|||
} |
|||
|
|||
func bindDefaultProcess(defaultName string) (uint32, bool) { |
|||
procs, err := processes() |
|||
if err != nil { |
|||
return 0, false |
|||
} |
|||
|
|||
explorer := findProcessByName(procs, defaultName) |
|||
if explorer == nil { |
|||
return 0, false |
|||
} |
|||
|
|||
return uint32(explorer.ProcessID), true |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue