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

如何在背景執行下指定按鍵修改記憶體位置

尚未結案
sswb
一般會員


發表:9
回覆:3
積分:2
註冊:2003-12-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-19 20:47:49 IP:61.61.xxx.xxx 未訂閱
比如我執行2個程式,一個是遊戲,一個是delphi的程式,我想要在遊戲畫面下執行delphi程式修改電腦某一個位置的記憶體內容列如(004428EF 0F8D --> 90E9),有大大能提供funtion嗎 最好是只要使用一個form就能完成,不需在建立dll檔    小弟先行感激 新手剛學,請多包函
------
新手剛學,請多包函
wameng
版主


發表:31
回覆:1336
積分:1188
註冊:2004-09-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-20 17:23:06 IP:61.222.xxx.xxx 未訂閱
<轉載> 如何訪問一個進程的內存空間 ---- 在WIN32中,每個應用程序都可"看見"4GB的線性地址空間,其中最開始的4MB和最後的2GB由操作系統保留, 剩下不足2GB的空間用於應用程序私有空間。具體分配如下:0xFFFFFFFF-0xC0000000的1GB 用於VxD、存儲器管理和文件系統;0xBFFFFFFF-0x80000000的1GB用於共享的WIN32 DLL、 存儲器映射文件和共享存儲區;0x7FFFFFFF-0x00400000為每個進程的WIN32專用地址; 0x003FFFFF-0x00001000為MS-DOS 和 WIN16應用程序;0x00000FFF-0x00000000為防止 使用空指針的4,096字節。以上都是指邏輯地址,也就是虛擬內存。 ---- 虛擬內存通常是由固定大小的塊來實現的,在WIN32中這些塊稱為"頁",每頁大小 為4,096字節。在Intel CPU結構中,通過在一個控制寄存器中設置一位來啟用分頁。 啟用分頁時CPU並不能直接訪問內存,對每個地址要經過一個映射進程,通過一系列稱 作"頁表"的查找表把虛擬內存地址映射成實際內存地址。通過使用硬件地址映射和頁表 WIN32可使虛擬內存即有好的性能而且還提供保護。利用處理器的頁映射能力,操作系統 為每個進程提供獨立的從邏輯地址到物理地址的映射,使每個進程的地址空間對另一個 進程完全不可見。WIN32中也提供了一些訪問進程內存空間的函數,但使用時要謹慎, 一不小心就有可能破壞被訪問的進程。本文介紹如何讀另一個進程的內存,寫內存與之 相似,完善一下你也可以做個 FPE 之類的內存修改工具。好吧,先準備好編程利器 Delphi 和 參考手冊 MSDN ,Now begin! ReadProcessMemory 讀另一個進程的內存,原形如下: BOOL ReadProcessMemory( HANDLE hProcess, // 被讀取進程的句柄; LPCVOID lpBaseAddress, // 讀的起始地址; LPVOID lpBuffer, // 存放讀取數據緩衝區; DWORD nSize, // 一次讀取的字節數; LPDWORD lpNumberOfBytesRead // 實際讀取的字節數; ); hProcess 進程句柄可由OpenProcess 函數得到,原形如下: HANDLE OpenProcess( DWORD dwDesiredAccess, // 訪問標誌; BOOL bInheritHandle, // 繼承標誌; DWORD dwProcessId // 進程ID; ); ---- 當然,用完別忘了用 CloseHandle 關閉打開的句柄。讀另一個進程的內存 dwDesiredAccess 須指定為 PROCESS_VM_READ ,寫另一個進程的內存 dwDesiredAccess 須指定為 PROCESS_VM_WRITE ,繼承標誌無所謂,進程ID可由 Process32First 和 Process32Next 得到,這兩個函數可以枚舉出所有開啟的進程, 這樣進程的信息也就得到了。 Process32First 和 Process32Next是由 TLHelp32 單元提供的,需在 uses 裡加上TLHelp32。ToolsHelp32 封裝了一些訪問堆、線程、 進程等的函數,只適用於Win9x,原形如下: BOOL WINAPI Process32First( HANDLE hSnapshot // 由 CreateToolhelp32Snapshot 返回 的系統快照句柄; LPPROCESSENTRY32 lppe // 指向一個 PROCESSENTRY32 結構; ); BOOL WINAPI Process32Next( HANDLE hSnapshot // 由 CreateToolhelp32Snapshot 返回 的系統快照句柄; LPPROCESSENTRY32 lppe // 指向一個 PROCESSENTRY32 結構; ); hSnapshot 由 CreateToolhelp32Snapshot 返回的系統快照句柄; CreateToolhelp32Snapshot 原形如下: HANDLE WINAPI CreateToolhelp32Snapshot( DWORD dwFlags, // 快照標誌; DWORD th32ProcessID // 進程ID; ); 現在需要的是進程的信息,所以將 dwFlags 指定為 TH32CS_SNAPPROCESS, th32ProcessID 忽略;PROCESSENTRY32 結構如下: typedef struct tagPROCESSENTRY32 { DWORD dwSize; // 結構大小; DWORD cntUsage; // 此進程的引用計數; DWORD th32ProcessID; // 進程ID; DWORD th32DefaultHeapID; // 進程默認堆ID; DWORD th32ModuleID; // 進程模塊ID; DWORD cntThreads; // 此進程開啟的線程計數; DWORD th32ParentProcessID;// 父進程ID; LONG pcPriClassBase; // 線程優先權; DWORD dwFlags; // 保留; char szExeFile[MAX_PATH]; // 進程全名; } PROCESSENTRY32; ---- 至此,所用到的主要函數已介紹完,實現讀內存只要從下到上依次調用上述函數即可,具體參見原代碼: procedure TForm1.Button1Click(Sender: TObject); var FSnapshotHandle:THandle; FProcessEntry32:TProcessEntry32; Ret : BOOL; ProcessID : integer; ProcessHndle : THandle; lpBuffer:pByte; nSize: DWORD; lpNumberOfBytesRead: DWORD; i:integer; s:string; begin FSnapshotHandle:=CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS,0); //創建系統快照 FProcessEntry32.dwSize:=Sizeof(FProcessEntry32); //先初始化 FProcessEntry32 的大小 Ret:=Process32First(FSnapshotHandle,FProcessEntry32); while Ret do begin s:=ExtractFileName(FProcessEntry32.szExeFile); if s='KERNEL32.DLL' then begin ProcessID:=FProcessEntry32.th32ProcessID; s:=''; break; end; Ret:=Process32Next(FSnapshotHandle,FProcessEntry32); end; //循環枚舉出系統開啟的所有進程,找出"Kernel32.dll" CloseHandle(FSnapshotHandle); Memo1.Lines.Clear ; memo1.lines.add('Process ID ' IntToHex( FProcessEntry32.th32ProcessID,8)); memo1.lines.Add('File name ' FProcessEntry32.szExeFile); ////輸出進程的一些信息 nSize:=4; lpBuffer:=AllocMem(nSize); ProcessHndle:=OpenProcess(PROCESS_VM_READ,false,ProcessID); memo1.Lines.Add ('Process Handle ' intTohex(ProcessHndle,8)); for i:=$00800001 to $0080005f do begin ReadProcessMemory( ProcessHndle, Pointer(i), lpBuffer, nSize, lpNumberOfBytesRead ); s:=s intTohex(lpBuffer^,2) ' '; //讀取內容 if (i mod 16) =0 then begin Memo1.Lines.Add(s); s:=''; end; //格式化輸出 end; FreeMem(lpBuffer,nSize); CloseHandle(ProcessHndle); //關閉句柄,釋放內存 end;
sswb
一般會員


發表:9
回覆:3
積分:2
註冊:2003-12-18

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-21 20:05:12 IP:61.61.xxx.xxx 未訂閱
感謝大大的指教@@來器試看看 新手剛學,請多包函
------
新手剛學,請多包函
系統時間:2024-04-27 4:15:10
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!