Windows下用Go改写其他进程内存字符串的技术疑问
Go结合Windows API改写外部Go程序的[]rune数组内存问题
场景说明
我正在用Go语言调用Windows API改写另一个Go程序内存中的字符串,改用[]rune数组而非普通字符串(之前处理普通字符串时遇到问题)。目标程序代码如下:
package main import ( "fmt" "time" "unsafe" ) func main() { stringVariable := "i_am_the_value" var theRuneVariable []rune = []rune(stringVariable) memoryPointer := uintptr(unsafe.Pointer(&theRuneVariable)) fmt.Printf("Memory address of 'theRuneVariable': 0x%x\n", memoryPointer) for { fmt.Println(string(theRuneVariable)) time.Sleep(5 * time.Second) } }
已完成操作与问题点
- 目标程序中打印
theRuneVariable的地址(如0xc00009bf08),通过Cheat Engine确认该地址指向的是包含字符串数据指针和长度的结构体。 - 以管理员身份运行外部Go程序,已通过
OpenProcess、WriteProcessMemory等API成功改写目标程序中的字符串数据。 - 内存扫描的核心问题:
- 从
0x0开始全内存扫描耗时过长(任务管理器显示目标程序仅占用1.5MB内存)。 - 用
Module32FirstW和Module32NextW获取的target.exe基地址为0x880000,远低于目标地址(超过0xc000000000),扫描效果和从0x0开始无差异。 - 尝试用
VirtualQueryEx遍历内存区域,通过以下过滤代码得到了0xc000000000这个起始地址,但不确定该区域的类型(数据段?堆?栈?),也不确定是否能作为合理的扫描起始点;另外如果该地址动态变化,有没有更精准的定位方法?
- 从
遍历内存区域的过滤代码:
func inspectMemoryRegions(processHandle syscall.Handle, address uintptr) uintptr { for { mbi, err := queryMemoryRegion(processHandle, address) if err != nil { fmt.Println("Error querying memory region:", err) break } // 0x007ffe0000 // 0xc00009bf08 // if mbi.BaseAddress == 0xc000000000 { if mbi.Type == MEM_PRIVATE && mbi.State == MEM_COMMIT && mbi.Protect == 0x4 && mbi.RegionSize > 0x80000 { fmt.Printf("Memory region found at: 0x%x\n", mbi.BaseAddress) fmt.Printf("mbi.State: 0x%x\n", mbi.State) fmt.Printf("mbi.Type: 0x%x\n", mbi.Type) fmt.Printf("mbi.Protect: 0x%x\n", mbi.Protect) fmt.Printf("mbi.RegionSize: 0x%x\n", mbi.RegionSize) fmt.Println() return mbi.BaseAddress } // Move to the next region address = mbi.BaseAddress + mbi.RegionSize if address == 0 { break // End of address space } } return uintptr(0) }
内容的提问来源于stack exchange,提问作者Ninjaxor
相关产品推荐
相关产品推荐

