研究筆記
上個(gè)筆記起作用了,原本存在txt里面的代碼,因?yàn)殡娔X關(guān)機(jī)沒保存全丟了.....
今天筆記的作用主要是整理思路。
首先我對(duì)Windows沒什么了解,最開始學(xué)的JAVA,然后是安卓,買了電腦先裝的Ubuntu,幾年后才換win10。去年在B站看了小甲魚的課程,才對(duì)windows有初步認(rèn)識(shí)......
網(wǎng)上說CE讀取內(nèi)存用的是ReadProcessMemory函數(shù),這話對(duì)了一半。

當(dāng)勾選下面兩個(gè)選項(xiàng),CE讀取內(nèi)存的方式就會(huì)變成驅(qū)動(dòng)讀寫。
這是結(jié)論,然后是得出這個(gè)理所當(dāng)然結(jié)論的過程。
我認(rèn)為認(rèn)識(shí)某件事的過程是很重要的,因?yàn)槿丝倳?huì)在了解某個(gè)原理后忘記理解的過程,遇到了不了解的人就會(huì)抱有優(yōu)越感,要教別人的時(shí)候也會(huì)忘記自己當(dāng)時(shí)的處境。網(wǎng)上很多教程基本都是這樣,在那些所謂大佬的視角下理所當(dāng)然的事,在小白看來是不可理喻的,所以我留下這個(gè)過程,記一下還一無所知的自己。
當(dāng)我用ReadProcessMemory去讀取某個(gè)游戲的內(nèi)存,返回值變成了false。中間花了好幾個(gè)小時(shí)解決了諸如編譯位數(shù),管理員權(quán)限等等問題,依舊沒辦法正常讀取。
然后我調(diào)用了GetLastError,得到返回值5——拒絕訪問。
為了知道是我哪里寫錯(cuò)了,還是游戲真的有保護(hù),我又試著讀了某個(gè)單機(jī)游戲的內(nèi)存——一切正常。
于是得出結(jié)論,游戲被保護(hù)了。但是具體怎么保護(hù)的,原理是什么,我沒理由知道。
但是我知道CE是能讀到內(nèi)存的,而且只有開了那兩個(gè)選項(xiàng)才能讀到。CE的原理我也摸不透,于是我想到易語言好像很擅長(zhǎng)這個(gè),于是就開始搜內(nèi)存讀寫的模塊。
得到兩個(gè)關(guān)鍵字:內(nèi)核 驅(qū)動(dòng)
以C++ 驅(qū)動(dòng)讀寫內(nèi)存 為關(guān)鍵字繼續(xù)網(wǎng)上沖浪,找到了一篇看雪論壇的帖子,得到關(guān)鍵庫:
Blackbone
據(jù)樓主說這個(gè)庫提供了三種讀寫內(nèi)存的方式:
1.ReadProcessMemory(系統(tǒng)函數(shù)
2.NtWow64ReadVirtualMemory64(內(nèi)核
3.MmCopyVirtualMemory(驅(qū)動(dòng)
第一種略過,樓主說第二種在R3,第三種在R0,而且第三種需要額外用軟件加載驅(qū)動(dòng)。
看到這我的心情依舊是平靜的,只要把這個(gè)庫封裝一下編譯一個(gè)dll給C#用應(yīng)該就完事了。解決了各種編譯問題,經(jīng)過無數(shù)次斷點(diǎn)跟蹤,幾個(gè)小時(shí)過去,我發(fā)現(xiàn)這個(gè)庫對(duì)外提供的API,還是在用ReadProcessMemory這個(gè)函數(shù)讀寫。雖然里面有調(diào)用NtWow64ReadVirtualMemory64的代碼,但是并沒有對(duì)外提供。于是我試著強(qiáng)行調(diào)用,意料之中的報(bào)錯(cuò)。第三種方式不考慮,要加載驅(qū)動(dòng),得用win7虛擬機(jī)。
白白浪費(fèi)半天以后,我又回到了原點(diǎn)。打開github繼續(xù)看CE的源碼,想找到ReadProcessMemory以外的讀取方式。結(jié)果發(fā)現(xiàn)了一個(gè)關(guān)鍵的函數(shù):
NtDeviceIoControlFile
看了一眼微軟的文檔,在Driver分類里面,也就是和驅(qū)動(dòng)有關(guān)。好暫停一下:
現(xiàn)在我認(rèn)為讀寫內(nèi)存一共三種方式,一種是系統(tǒng)API,一種是內(nèi)核API,一種是驅(qū)動(dòng)讀寫,一層比一層麻煩,而且驅(qū)動(dòng)讀寫的話我隱約記得要安裝一個(gè)未簽名驅(qū)動(dòng),究極麻煩。
所以我覺得CE應(yīng)該是用的第二層,因?yàn)槲覜]安裝任何驅(qū)動(dòng),CE依舊能讀到內(nèi)存。但稍微想想有點(diǎn)不對(duì)勁,ReadProcessMemory調(diào)用以后,最終還是會(huì)來到ntdll調(diào)用NtReadVirtualMemory,這兩種方式?jīng)]有什么區(qū)別。
CE的源碼里有一個(gè)dbk32的文件夾,NtDeviceIoControlFile就在這個(gè)文件夾里面被調(diào)用的。而我每次啟動(dòng)CE都會(huì)出現(xiàn)DBK64 LOADED閃爍,關(guān)了那兩個(gè)選項(xiàng)就沒有。再結(jié)合那個(gè)驅(qū)動(dòng)有關(guān)的函數(shù),基本可以確定CE也是用的驅(qū)動(dòng)讀寫了。
但是記憶里,開啟CE的驅(qū)動(dòng)讀寫會(huì)藍(lán)屏,而且很麻煩要用win7要用Pchunter?,F(xiàn)在看是記錯(cuò)了,那個(gè)是調(diào)試器,和內(nèi)存讀寫不是一回事。另外要win7的說法屬于被忽悠了,畢竟我真的對(duì)windows沒什么了解。
知道是驅(qū)動(dòng)讀寫了,但我還是不太可能去學(xué)驅(qū)動(dòng)開發(fā),另外那個(gè)庫我其實(shí)沒怎么看懂,都不知道怎么調(diào)用驅(qū)動(dòng)讀寫。
于是我果斷來到github,又搜索到一個(gè)新庫,只做內(nèi)存讀寫,而且代碼很容易看懂。
這次終于,正常讀到了數(shù)據(jù)......我感動(dòng)地哭了出來。
既然如此一開始就直接github搜不就行了嗎?不行的。一開始我僅僅知道ReadProcessMemory這個(gè)函數(shù)用不了,但是到底怎么才行,還是沒頭緒,雖然聽說過驅(qū)動(dòng)讀寫這個(gè)詞,但是是怎么實(shí)現(xiàn)的,我還是沒任何概念。所以彎路是絕對(duì)必要的。