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