H
hqiang
Unregistered / Unconfirmed
GUEST, unregistred user!
在windows里,每个进程都分配有(好像该说是线程,呵呵,没法英语太差了,大家将就一下了)<br>4GB的线性地址空间,2GB由操作系统保留,剩下不足2GB的空间用于应用程序私有空间(拥户数据从4M区~2G)。<br>具体分配如下:0xFFFFFFFF-0xC0000000的1GB用于VxD、存储器管理和文件系统;0xBFFFFFFF-0x80000000的1GB<br>用于共享的WIN32 DLL、存储器映射文件和共享存储区;0x7FFFFFFF-0x00400000为每个进程的WIN32专用地址;<br>0x003FFFFF-0x00001000为MS-DOS 和 WIN16应用程序;0x00000FFF-0x00000000为防止使用空指针的4,096字节。<br>所以只要处理这些地址就可以达到我们处理内存的目的了,大家可千万别直接去处理内存,不然可会当机n次。<br>我也是前些日子在处理线程时,猛然反应过来的。<br><br>好!下面进入正题:<br>1.相关单元 TLHelp32<br>2.相关函数<br>Process32First(<br>HANDLE hSnapshot // 由 CreateToolhelp32Snapshot 返回的系统快照句柄;<br>LPPROCESSENTRY32 lppe // 指向第一个PROCESSENTRY32 结构;<br>);<br><br>Process32Next(<br>HANDLE hSnapshot // 由 CreateToolhelp32Snapshot 返回的系统快照句柄;<br>LPPROCESSENTRY32 lppe // 指向下一个 PROCESSENTRY32 结构;<br>);<br><br>hSnapshot 由 CreateToolhelp32Snapshot 返回的系统快照句柄;<br>CreateToolhelp32Snapshot(<br>DWORD dwFlags, // 快照标志; <br>DWORD th32ProcessID // 进程ID;<br>);<br>注:进程信息的dwFlags为TH32CS_SNAPPROCESS,<br> th32ProcessID为nil(0);<br><br>PROCESSENTRY32 结构如下:<br>typedef struct tagPROCESSENTRY32 { <br>DWORD dwSize; // 结构大小;<br>DWORD cntUsage; // 此进程的引用计数;<br>DWORD th32ProcessID; // 进程ID;<br>DWORD th32DefaultHeapID; // 进程默认堆ID;<br>DWORD th32ModuleID; // 进程模块ID;<br>DWORD cntThreads; // 此进程开启的线程计数;<br>DWORD th32ParentProcessID;// 父进程ID;<br>LONG pcPriClassBase; // 线程优先权;<br>DWORD dwFlags; // 保留; <br>char szExeFile[MAX_PATH]; // 进程全名;<br>} PROCESSENTRY32;<br><br>取指定进程的内存内容<br>BOOL ReadProcessMemory(<br>HANDLE hProcess, // 被读取进程的句柄;<br>LPCVOID lpBaseAddress, // 读的起始地址;<br>LPVOID lpBuffer, // 存放读取数据缓冲区;<br>DWORD nSize, // 一次读取的字节数;<br>LPDWORD lpNumberOfBytesRead // 实际读取的字节数;<br>);<br><br>写指定进程的内存内容<br>BOOL WriteProcessMemory(<br>HANDLE hProcess, // 被写进程的句柄;<br>LPCVOID lpBaseAddress, // 写的起始地址;<br>LPVOID lpBuffer, // 写数据缓冲区;<br>DWORD nSize, // 一次写的字节数;<br>LPDWORD lpNumberOfBytesRead // 实际写入的字节数;<br>);<br><br>hProcess: 进程句柄可由OpenProcess 函数获得<br>HANDLE OpenProcess(<br>DWORD dwDesiredAccess, // 访问标志;<br>BOOL bInheritHandle, // 继承标志,我不清楚用法,不过不管它也好用;<br>DWORD dwProcessId // 进程ID;<br>);<br><br>注意:读一个进程时 dwDesiredAccess 须指定为 PROCESS_VM_READ <br> 写一个进程时dwDesiredAccess 须指定为 PROCESS_VM_WRITE <br> 进程ID可由 Process32First 和 Process32Next取得<br><br>关闭打开的进程居柄<br>BOOL CloseHandle(<br> HANDLE hObject // 要关闭的进程句柄 <br>);<br><br>呵呵,好象该说的都说了<br>下面给出我编得控件,水平有限请大家多多指教:<br><br>{MEM_LIST<br>作者:黄强<br>用途:获得WIN9X或NT内存中的进程中的数目、进程名称、进程入口地址(ID)}<br><br>unit mem_list;<br><br>interface<br>uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,TLHelp32;<br>TYPE<br> TMEMObject = record<br> ProcessID : integer;<br> ProcessHndle : THandle;<br> Processname:string[30];<br> end;<br> PTMEMobject = ^TMEMObject;<br> TMEMList = class(TComponent)<br> private<br> memLst : TList;<br> FCount : Integer;<br> procedure Getmemlist;<br> protected<br> function Getmem(Index: Integer): TmemObject;<br> public<br> constructor Create(AOwner: TComponent); override;<br> destructor Destroy; override;<br><br> Procedure Refresh;<br> Property memstatus[Index : Integer]: TmemObject read Getmem;<br> Property Count : Integer read FCount;<br> published<br> { Published declarations }<br> end;<br><br>procedure Register;<br><br>implementation<br><br>{ TMEMList }<br>constructor TMEMList.Create(AOwner: TComponent);<br>begin<br> inherited;<br> memLst:= TList.Create;<br> If Not ( csDesigning in ComponentState ) Then getmemlist<br>end;<br><br>procedure TMEMList.Getmemlist;<br>var<br>FSnapshotHandle:THandle;<br>FProcessEntry32:TProcessEntry32;<br>Ret : BOOL;<br>i:integer;<br>MyMEMPtr : ^TMEMObject;<br>begin<br> FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//创建系统快照<br> FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);//先初始化 FProcessEntry32 的大小<br> Ret:=Process32First(FSnapshotHandle,FProcessEntry32);<br> i:=0;<br> while Ret do<br> begin<br> i:=i+1;<br> New(MyMEMPtr);<br> MYMEMptr.Processname:=ExtractFileName(FProcessEntry32.szExeFile);<br> mymemptr.ProcessID:=FProcessEntry32.th32ProcessID;<br> mymemptr.ProcessHndle:=OpenProcess(PROCESS_VM_READ,false,mymemptr.ProcessID);<br> CloseHandle(mymemptr.ProcessHndle);<br> Ret:=Process32Next(FSnapshotHandle,FProcessEntry32);<br> memLst.Add(MymemPtr);<br> end;<br> fcount:=i;<br>end;<br><br>destructor TMEMList.Destroy;<br>var<br>i:integer;<br>begin<br> If MEMLst.Count > 0 Then<br> Begin<br> For I := 0 To (MEMLst.Count - 1) Do<br> Dispose(PTMEMObject(MEMLst));<br> End;<br> MEMLst.Free;<br> inherited;<br>end;<br><br>procedure Register;<br>begin<br> RegisterComponents('狒狒的空间', [TmemList]);<br>end;<br><br>function TMEMList.Getmem(Index: Integer): TmemObject;<br>begin<br> Result := PtmemObject(memLst[Index])^;<br>end;<br><br>procedure TMEMList.Refresh;<br>begin<br> memLst.Clear;<br> getmemlist;<br>end;<br><br>end.<br><br><br>下面简单说一下如何利用我的控件进行读写操作<br>step1:从memlist找到你想要程序的入口ID<br>step2: 为了说明问题,假设ProcessHndle为thandle <br> ProcessHndle:=OpenProcess(PROCESS_VM_READ,false,ProcessID);//读操作<br> ProcessHndle:=OpenProcess(PROCESS_VM_write,false,ProcessID);//写操作<br>step3 :读操作,设lpBuffer为pbyte<br> ex:<br> for i=$400000 to $80000000 do (fpe里好像是这样的,自己随便)<br> ReadProcessMemory(<br> ProcessHndle,<br> Pointer(i),<br> lpBuffer,<br> 4,<br> lpNumberOfBytesRead);<br> 写操作:换 ReadProcessMemory为 writeProcessMemory一切ok;<br> 注: 1.nSize最好设为4(我的例子里,好像不设4不行,嘻嘻)<br> 2.lpBuffer:=AllocMem(nSize);<br> 3.最后记得关闭句柄,释放内存<br> FreeMem(lpBuffer,nSize);<br> CloseHandle(ProcessHndle);<br><br><br>天啊!终于写完了,这可是我第一次打那么大的文字,好累啊!希望对大家有点帮助<br>唉!我有个秘书多好啊,最好还是mm!