一 模組**
複製內容到剪貼簿
**:option explicit
public declare function findwindow lib "user32" alias "findwindowa" (byval lpclassname as string, byval lpwindowname as string) as long
public declare function getwindowthreadprocessid lib "user32" (byval hwnd as long, lpdwprocessid as long) as long
public declare function openprocess lib "kernel32" (byval dwdesiredaccess as long, byval binherithandle as long, byval dwprocessid as long) as long
public const process_all_access = &h1f0fff '引數決定了對程序的儲存許可權,使用完全控制
public declare function readprocessmemory lib "kernel32.dll" ( _
byval hprocess as long, _
byval lpbaseaddress as long, _
byref lpbuffer as any, _
byval nsize as long, _
byref lpnumberofbyteswritten as long) as long
public declare function closehandle lib "kernel32" (byval hobject as long) as long
二 窗體**
複製內容到剪貼簿
**:option explicit
dim hwd as long '存放窗體控制代碼
dim pid as long '存放程序id
dim hprocess as long '存放程序控制代碼
dim h as long '存放二級指標
dim buffer as long '存放一級指標
dim hp as integer '存放血量
dim mp as integer '存放魔法值
dim jy as integer '存放經驗值
dim maxmp as integer '存放魔法上限
dim maxhp as integer '存放血量上限
dim dj as integer '人物等級
private sub form_load()
hwd = findwindow(vbnullstring, "element client") '讀取hwnd
if hwd = 0 then
msgbox "遊戲未執行!!!!!", , "遊戲未執行"
end if
getwindowthreadprocessid hwd, pid '獲取程序識別符號
hprocess = openprocess(process_all_access, 0, pid) '將程序識別符號做為引數,返回目標程序pid的控制代碼,得到此控制代碼後即可對目標進行讀寫操,process_all_access表示完全控制,許可權最大
if hprocess = 0 then
msgbox "不能開啟程序!!!!!", , "開啟程序錯誤"
exit sub
end if
hwdlab.caption=」遊戲窗體控制代碼:」 & hwd
pidlab.caption=」遊戲程序id:」 & pid
prolab.caption=」遊戲程序控制代碼:」 & hprocess 『這幾句,我是為了自己除錯用的,方 便隨時了解一些資訊的
buffer = val(text1.text) '賦值初始化一級指標,這是我自己電腦上找到的,所以就不貼 出來了,可能每個人的都不同吧~我是直接把
end sub
private function ncnr(lpaddress as long) as long ' 宣告一些需要的變數,注意型別必須為long,偶開始在網上找回來的時候,是integer的,試了半天都通不過~~~~後來改了這才通過的~~原因就是 integer的數值容量太少,記憶體中存的溢位了
dim hwnd as long ' 儲存 findwindow 函式返回的控制代碼
dim phandle as long ' 儲存程序控制代碼
hwnd = findwindow(vbnullstring, "element client") ' 取得程序識別符號,雙開的話最好把"element client"用變數代替,這樣方便更改窗體後直接用
getwindowthreadprocessid hwnd, pid ' 使用程序識別符號取得程序控制代碼
phandle = openprocess(process_all_access, false, pid) ' 在記憶體位址中讀取資料
readprocessmemory phandle, lpaddress, byval varptr(ncnr), 4, 0& ' 關閉程序控制代碼
closehandle hprocess 『記得一定要釋放記憶體,不然,呵呵,你等著vb崩潰吧
end function
private sub timer1_timer() 『我設的interval是100
h = ncnr(buffer) '讀記憶體得到一級指標
azhizen.caption=hex(h) 『方便自己直觀的看記憶體變化
h = ncnr(h + 36) '讀記憶體得到二級,+號後面的數值是偏移量十六進製制24轉成十進位制的數,以下都相同
bzhizen,caption=hex(h) 『方便自己直觀的看記憶體變化
hp = ncnr(h + 596) '得到血量值
mp = ncnr(h + 600) '得到魔法值
jy = ncnr(h + 604) '得到經驗值
maxmp = ncnr(h + 624) '得到魔法上限
maxhp = ncnr(h + 620) '得到血量上限
dj = ncnr(h + 588) '得到人物等級
hplab.caption = "人物血量值: " & hp & " / " & maxhp
mplab.caption = "人物魔法值: " & mp & " / " & maxmp
jylab.caption = "人物經驗值: " & jy & " / " & "暫時未知"
djlab.caption = "人物等級數: " & dj & " 級"
end sub
個人認為,難就在readprocessmemory phandle, lpaddress, byval varptr(ncnr), 4, 0&這裡,偶試了好久,才弄明白
我的理解如下:
public declare function readprocessmemory lib "kernel32.dll" ( _
byval hprocess as long, _ 『遊戲程序控制代碼,也就是上面找到的hprocess,一定要是long型
byval lpbaseaddress as long, _』不用講了,你需要讀取的記憶體位址
byref lpbuffer as any, _』api解釋是快取區,偶簡單的認為就是說你要設乙個變數,作為讀取出指定位址lpbaseaddress裡的內容後的存放地方,其實這句最好改為 byval lpbuffer as long來用,所以,你直接宣告乙個變數dim *** as long ,然後直接在這裡填***就行了
byval nsize as long, _需讀取的位元組數,偶是用的4位元組
byref lpnumberofbyteswritten as long) as long 『作用不明,看到大家都是用的0&
呵呵,水平不高,見諒~~~~~有錯的地方大家指教
其它數值正在查詢中,怪物血條是找到了,可是找不到它的一級指標,他每次用三個指標來表示,在遊戲中一直不變,當你小退後再回來,全變了,正在用od除錯中~~~~~~~~~
偶找到的一級指標是:&h008bc2a4,
各偏移量
紅:指標+&h254
藍:指標+&h258
經驗"指標+&h25c
等級:指標+&h24c
藍上限:指標+&h270
紅上限:指標+&h26c
**段在記憶體中好像是0454***x那塊,都連在一起
還有兩個+268,+260,不知道作什麼用的,返回值是0
VB 讀取《武林外傳》角色名的原始碼
private declare function getwindowthreadprocessid lib user32 byval hwnd as long lpdwprocessid as long as long private declare function findwindow lib ...
記憶體位址分配
inti 1 intj 1 cout i endl j endl 2 函式引數列表的存放方式是,先對最右邊的形參分配位址,後對最左邊的形參分配位址。3 little endian模式的cpu對運算元的存放方式是從低位元組到高位元組的 0x1234的存放方式入下 0x4000 0x34 0x4001 ...
理解記憶體位址
物理記憶體 記憶體條實際提供的記憶體空間 記憶體定址 在記憶體上找到正確的位置以便進行訪問的過程 硬編碼 通過實體地址操作物理記憶體的寫碼方式 線性記憶體和物理記憶體 相似點 從0編號,線性增加 不同 1.實體地址一一對應於實際物理記憶體空間的位置,而線性位址可多對一 多個線性位址對應乙個實體地址 ...