線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3412
推到 Plurk!
推到 Facebook!

readprocessmemory讀取記憶體,該如何得知Offset??

尚未結案
shihyi
一般會員


發表:8
回覆:12
積分:4
註冊:2009-01-03

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-01-03 13:34:59 IP:203.67.xxx.xxx 訂閱
Dear All,

首先,這篇文章純碎是好奇心作祟,並無任何商業或利益的問題。

在KTOP看了很久的文章(雖然我都沒有申請帳號)
最近逛到,拜讀了seaturn99了版大的文章
http://delphi.ktop.com.tw/board.php?cid=31&fid=79&tid=43101
覺得滿好玩的,怎麼寫Windows程式還可以讀到別人的Process
然後我就又搜尋了一下,發現我們可以用readprocessmemory跟writeprocessmemory去讀寫記憶體的值
tagModuleEntry32這個structure告訴我們,tagModuleEntry32.modBaseAddr是該Process開始的記憶體位置
好了,我的問題來了
小時候恐龍書告訴我們,一個Process起始的時候,OS會配置起始的記憶體位置跟一個Offset
如果我們要像遊戲修改大師一樣,去看一個Process的記憶體長的怎麼樣,可以用上述的方法
可是我知道了tagModuleEntry32.modBaseAddr,我們也可以設定一次要讀多少,
可是我們該如何知道我要讀到哪邊,才是這個Process記憶體的結束呢??

假設我寫了個簡單的程式

[code delphi]
procedure TForm1.Button1Click(Sender: TObject);
begin
iSrc := StrToInt(srcEdit.Text);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
iDst := iSrc;
dstEdit.Text := IntToStr(iDst);
end;

[/code]
我只是用了2個Edit跟2個button,然後button1按下時用iSrc變數存起來,button2按下時把iSrc的資料copy過來,然後show出來。
假設我們要寫另一支程式去看這支程式的記憶體的話,我該怎麼得知Process的記憶體該讀到哪邊算結束呢?



若有錯誤,還請不吝指教。
編輯記錄
shihyi 重新編輯於 2009-01-03 13:36:48, 註解 無‧
shihyi
一般會員


發表:8
回覆:12
積分:4
註冊:2009-01-03

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-01-10 22:16:37 IP:203.67.xxx.xxx 訂閱
各位先進

雖然沒能夠在delphi中找到解法
但是在下面這篇文章中能夠看出一些端倪

http://www.programmersheaven.com/mb/CandCPP/163442/163442/readprocessmemory/?S=B20000

我是還未寫出來啦~~如果有好消息再跟大家報告
有好心的先進也可以幫忙試一下

當然啦,在試的過程中,還是有些問題想請教大家。問題看這裡
hotswin
中階會員


發表:72
回覆:92
積分:52
註冊:2003-11-06

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-01-11 11:37:36 IP:220.134.xxx.xxx 訂閱
要看你要查什麼資料的記憶体位址
先找出基址再去計算你的資料的位址,可算出位移量
------
http://xinjier.0424617287.com/gift/
禮贈品
RootKit
資深會員


發表:16
回覆:357
積分:419
註冊:2008-01-02

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-01-12 10:36:10 IP:61.222.xxx.xxx 訂閱
你知道何謂 PE 格式嗎,當程式執行後某段位置開始便映射至記憶體。

一般些改值,大多是全局變數才行。
某些值位置,有些需要跟蹤得知。(SoftIce)
或要反編譯瞭解。-> 當然這都需要有ASM 概念。

建議閱讀這一本書 『加密與解密』簡體版。
參考
shihyi
一般會員


發表:8
回覆:12
積分:4
註冊:2009-01-03

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-01-30 02:38:06 IP:211.74.xxx.xxx 訂閱
感謝先進們的回應
適逢年節期間,有點空好好弄個清楚我當初問的這個問題
以下是我個人的一點淺見,若有錯誤的地方,還麻煩請各位先進指導一下

這篇中,wameng版主所post的觀念我再補充一下
每一個Process執行時,底下都有一些Module(程式本身再加上一些DLL檔),可以利用一套軟體叫PrcView的去觀查
選擇一個Process後,然後選「memory」就可以看到module們在記憶裡的狀況了

[code delphi]
mHPSnap:=CreateToolhelp32Snapshot(TH32CS_SnapProcess,0);
mPE.dwSize:=Sizeof(mPE);
Process32First(mHPSnap,mPE)

repeat
begin
mHMSnap := CreateToolhelp32Snapshot(TH32CS_SnapModule,mPE.th32ProcessID);
mME.dwSize := sizeof(mME);
Module32First(mHMSnap, mME);

repeat
begin

// 顯示
{
edNote.Lines.Add(mME.szExePath ' '
IntToStr(mPE.th32ProcessID) ' '
format('$%p',[mME.modBaseAddr]) ' '
IntToStr(mME.hModule) ' '
inttostr(mME.modBaseSize));
}

end until not Module32Next(mHMSnap, mME);
closehandle(mHMSnap);
end until not Process32Next(mHPSnap,mPE);
CloseHandle(mHPSnap);

[/code]

以上的程式碼是我修改自ktop某位先進所發表的文章
很抱歉我臨時找不到文章的超連結,往後找到或是哪位大德幫我找到的話,我再做reference
這個程式片段把每個Process中的每個Module都列出來
當然啦,mPE代表的是PROCESSENTRY32結構,mME代表的是ModuleEntry32結構,MSDN裡都有清楚的記載

OK,回歸正題,若用readprocessmemory去讀每個process的話,很簡單,ModuleEntry32中的modBaseAddr開始
一直讀到讀不到值,就可以把整個module用到的記憶體dump出來
但是事實上只是讀到module用到的記憶體而已,並不會讀到module中「變數」所用到的記憶體

所以,或許我改修正一下我的標題,「該如何讀到process中,變數的記憶體位置」
像是GameMaster就可以很快的去讀到這一部份的資料
不知道各位先進們有沒有這一方面的參考資料或是觀念可以指導我一下


roviury
一般會員


發表:3
回覆:49
積分:15
註冊:2008-08-28

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-08-02 13:16:20 IP:203.186.xxx.xxx 訂閱
參照vb文章
http://sunh.hosp.ncku.edu.tw/~cww/html/q00534.html
(如何掃描外部程式的記憶體)
while VirtualQueryEx(hProcess, Pointer(lBassAddr), mbi, sizeof(mbi)) do begin
//mbi會得到相關的offset
end;

我參考這文章後,做到了類似gm8那東西(delphi)
可是還有很多問題解不下
系統時間:2017-10-22 10:48:05
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!