第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

在 Go 中調(diào)用 kernel32 的 ReadProcessMemory

在 Go 中調(diào)用 kernel32 的 ReadProcessMemory

Go
開滿天機(jī) 2021-11-08 19:23:38
我正在嘗試使用 Go 語(yǔ)言在 Windows 上操作進(jìn)程,并且我通過(guò)使用ReadProcessMemory.但是,對(duì)于大多數(shù)地址,我都會(huì)Error: Only part of a ReadProcessMemory or WriteProcessMemory request was completed.出錯(cuò)。也許我的參數(shù)列表是錯(cuò)誤的,但我不知道為什么。誰(shuí)能指出我在這里做錯(cuò)了什么?package mainimport (  "fmt")import (  windows "golang.org/x/sys/windows")func main() {  handle, _ := windows.OpenProcess(0x0010, false, 6100) // 0x0010 PROCESS_VM_READ, PID 6100  procReadProcessMemory := windows.MustLoadDLL("kernel32.dll").MustFindProc("ReadProcessMemory")  var data uint   = 0  var length uint = 0  for i := 0; i < 0xffffffff; i += 2 {    fmt.Printf("0x%x\n", i)    // BOOL ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead)    ret, _, e := procReadProcessMemory.Call(uintptr(handle), uintptr(i), uintptr(data), 2, uintptr(length)) // read 2 bytes    if (ret == 0) {        fmt.Println("  Error:", e)              } else {        fmt.Println("  Length:", length)        fmt.Println("  Data:", data)                            }  }  windows.CloseHandle(handle)}
查看完整描述

1 回答

?
阿波羅的戰(zhàn)車

TA貢獻(xiàn)1862條經(jīng)驗(yàn) 獲得超6個(gè)贊

uintptr(data)不正確:它從data(0 of type uint)獲取值并將其轉(zhuǎn)換為unitptrtype — 產(chǎn)生轉(zhuǎn)換為另一種類型的相同值 — 在 x86 上產(chǎn)生空指針。


請(qǐng)注意,Go 不是 C,并且您不能真正玩帶有指針的骯臟游戲,或者更確切地說(shuō),您可以,但只能通過(guò)使用unsafe內(nèi)置包及其Pointer類型void*(指向數(shù)據(jù)存儲(chǔ)器中的某個(gè)位置)塊)在 C 中。


你需要的是類似的東西


import "unsafe"


var (

    data   [2]byte

    length uint32

)

ret, _, e := procReadProcessMemory.Call(uintptr(handle), uintptr(i),

    uintptr(unsafe.Pointer(&data[0])),

    2, uintptr(unsafe.Pointer(&length))) // read 2 bytes

觀察這里做了什么:

  1. 聲明了一個(gè)“兩字節(jié)數(shù)組”類型的變量;

  2. 取這個(gè)數(shù)組第一個(gè)元素的地址;

  3. 該地址被類型轉(zhuǎn)換為類型unsafe.Pointer;

  4. 然后將獲得的值類型轉(zhuǎn)換為uintptr。

需要最后兩個(gè)步驟,因?yàn)?Go 具有垃圾收集功能:

  • 在 Go 中,當(dāng)你在內(nèi)存中獲取一個(gè)值的地址并將其存儲(chǔ)在一個(gè)變量中時(shí),GC 知道這個(gè)“隱式”指針,并且即使它變得無(wú)法訪問(wèn),該地址的值也不會(huì)被垃圾收集保存其地址的值是唯一的引用。

  • 即使您使該地址值丟失了它所維護(hù)的類型信息——通過(guò)將其類型轉(zhuǎn)換為unsafe.Pointer,新值仍會(huì)被 GC 考慮并且表現(xiàn)得像包含地址的“正常”值——如上所述。

  • 通過(guò)將此類值類型轉(zhuǎn)換為uintptr您可以讓 GC 停止將其視為指針。因此,這種類型僅適用于 FFI/互操作。

    換句話說(shuō),在

    var data [2]byte
    a := &data[0]
    p := unsafe.Pointer(a)
    i := uintptr(p)

    中的值只有三個(gè)引用data:該變量本身ap,但不是i

在處理調(diào)用外部代碼時(shí),您應(yīng)該考慮這些規(guī)則,因?yàn)槟肋h(yuǎn)不應(yīng)該傳遞unitptr-typed 值:它們僅用于將數(shù)據(jù)編組到被調(diào)用的函數(shù)并將其解組回來(lái),并且必須“在現(xiàn)場(chǎng)”使用 - 在與它們從/到類型轉(zhuǎn)換的值相同的范圍。

另請(qǐng)注意,在 Go 中,您不能只獲取整數(shù)類型變量的地址并將該地址提供給需要指向適當(dāng)大小的內(nèi)存塊的指針的函數(shù)。您必須處理字節(jié)數(shù)組,并且在被調(diào)用函數(shù)寫入數(shù)據(jù)后,您需要將其顯式轉(zhuǎn)換為所需類型的值。這就是為什么 Go 中沒有“類型轉(zhuǎn)換”而只有“類型轉(zhuǎn)換”:您不能通過(guò)類型轉(zhuǎn)換重新解釋值的數(shù)據(jù)類型,uintptr(unsafe.Pointer)對(duì)于 FFI/互操作而言,(和返回)是一個(gè)顯著的例外,即使在這種情況下,您也基本上將指針轉(zhuǎn)換為指針,只需將其通過(guò) GC 邊界傳輸即可。

要“序列化”和“反序列化”整數(shù)類型的值,您可以使用encoding/binary標(biāo)準(zhǔn)包或手卷簡(jiǎn)單的簡(jiǎn)單函數(shù),這些函數(shù)執(zhí)行按位移位和or-s 等;-)


2015-10-05,根據(jù) James Henstridge 的建議更新。

請(qǐng)注意,在函數(shù)返回并發(fā)出ret信號(hào)后,您必須檢查length變量的值沒有錯(cuò)誤。


查看完整回答
反對(duì) 回復(fù) 2021-11-08
  • 1 回答
  • 0 關(guān)注
  • 513 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)