来来看看,有钱的捧个钱场,没钱的捧个人场!(管于内存处理的一些问题!)(0分)

  • 主题发起人 主题发起人 hqiang
  • 开始时间 开始时间
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>&nbsp; &nbsp; 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>&nbsp; &nbsp; &nbsp; 写一个进程时dwDesiredAccess 须指定为 PROCESS_VM_WRITE <br>&nbsp; &nbsp; &nbsp; 进程ID可由 Process32First 和 Process32Next取得<br><br>关闭打开的进程居柄<br>BOOL CloseHandle(<br>&nbsp; &nbsp; 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 &nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,TLHelp32;<br>TYPE<br>&nbsp;TMEMObject = record<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ProcessID : integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ProcessHndle : THandle;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Processname:string[30];<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; PTMEMobject = ^TMEMObject;<br>&nbsp;TMEMList = class(TComponent)<br>&nbsp; private<br>&nbsp; &nbsp; memLst : TList;<br>&nbsp; &nbsp; FCount : Integer;<br>&nbsp; &nbsp; procedure Getmemlist;<br>&nbsp; protected<br>&nbsp; &nbsp; function Getmem(Index: Integer): TmemObject;<br>&nbsp; public<br>&nbsp; &nbsp; constructor Create(AOwner: TComponent); override;<br>&nbsp; &nbsp; destructor Destroy; override;<br><br>&nbsp; &nbsp; Procedure Refresh;<br>&nbsp; &nbsp; Property memstatus[Index : Integer]: TmemObject read Getmem;<br>&nbsp; &nbsp; Property Count : Integer read FCount;<br>&nbsp; published<br>&nbsp; &nbsp; { Published declarations }<br>&nbsp; end;<br><br>procedure Register;<br><br>implementation<br><br>{ TMEMList }<br>constructor TMEMList.Create(AOwner: TComponent);<br>begin<br>&nbsp; inherited;<br>&nbsp; memLst:= TList.Create;<br>&nbsp; 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>&nbsp; FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//创建系统快照<br>&nbsp; FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);//先初始化 FProcessEntry32 的大小<br>&nbsp; Ret:=Process32First(FSnapshotHandle,FProcessEntry32);<br>&nbsp; i:=0;<br>&nbsp; while Ret do<br>&nbsp; begin<br>&nbsp; &nbsp; i:=i+1;<br>&nbsp; &nbsp; New(MyMEMPtr);<br>&nbsp; &nbsp; MYMEMptr.Processname:=ExtractFileName(FProcessEntry32.szExeFile);<br>&nbsp; &nbsp; mymemptr.ProcessID:=FProcessEntry32.th32ProcessID;<br>&nbsp; &nbsp; mymemptr.ProcessHndle:=OpenProcess(PROCESS_VM_READ,false,mymemptr.ProcessID);<br>&nbsp; &nbsp; CloseHandle(mymemptr.ProcessHndle);<br>&nbsp; &nbsp; Ret:=Process32Next(FSnapshotHandle,FProcessEntry32);<br>&nbsp; &nbsp; memLst.Add(MymemPtr);<br>&nbsp; end;<br>&nbsp; fcount:=i;<br>end;<br><br>destructor TMEMList.Destroy;<br>var<br>i:integer;<br>begin<br>&nbsp; If MEMLst.Count &gt; 0 Then<br>&nbsp; &nbsp; Begin<br>&nbsp; &nbsp; &nbsp; For I := 0 To (MEMLst.Count - 1) Do<br>&nbsp; &nbsp; &nbsp; &nbsp; Dispose(PTMEMObject(MEMLst));<br>&nbsp; &nbsp; End;<br>&nbsp; MEMLst.Free;<br>&nbsp; inherited;<br>end;<br><br>procedure Register;<br>begin<br>&nbsp; RegisterComponents('狒狒的空间', [TmemList]);<br>end;<br><br>function TMEMList.Getmem(Index: Integer): TmemObject;<br>begin<br>&nbsp; Result := PtmemObject(memLst[Index])^;<br>end;<br><br>procedure TMEMList.Refresh;<br>begin<br>&nbsp; memLst.Clear;<br>&nbsp; getmemlist;<br>end;<br><br>end.<br><br><br>下面简单说一下如何利用我的控件进行读写操作<br>step1:从memlist找到你想要程序的入口ID<br>step2: 为了说明问题,假设ProcessHndle为thandle <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ProcessHndle:=OpenProcess(PROCESS_VM_READ,false,ProcessID);//读操作<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ProcessHndle:=OpenProcess(PROCESS_VM_write,false,ProcessID);//写操作<br>step3 :读操作,设lpBuffer为pbyte<br>&nbsp; &nbsp; &nbsp; ex:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for i=$400000 to $80000000 &nbsp;do (fpe里好像是这样的,自己随便)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ReadProcessMemory(<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ProcessHndle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Pointer(i),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lpBuffer,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lpNumberOfBytesRead);<br>&nbsp; &nbsp; &nbsp; 写操作:换 &nbsp;ReadProcessMemory为 writeProcessMemory一切ok;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;注: 1.nSize最好设为4(我的例子里,好像不设4不行,嘻嘻)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2.lpBuffer:=AllocMem(nSize);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3.最后记得关闭句柄,释放内存<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FreeMem(lpBuffer,nSize);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CloseHandle(ProcessHndle);<br><br><br>天啊!终于写完了,这可是我第一次打那么大的文字,好累啊!希望对大家有点帮助<br>唉!我有个秘书多好啊,最好还是mm! :)
 
&nbsp; 附加功能 &nbsp; &nbsp;添加到收藏夹 &nbsp;
 
问一下:TLHelp32函数集好像不支持nt的说;比如建立系统的快照,枚举系统进程等的函数<br>在winnt下,都不存在。呵呵!!!!!<br>不知hqiang怎么看!!!!<br>要枚举nt系统的进程必须使用别的方法!!!!<br>
 
呵呵!是不可以的啊,我把nt哪部分去了!其实支持不支持nt主要看api库!<br>建立系统的快照,枚举系统进程等的函数可不是api函数,是delphi扩充的而已。你可以去看一下<br>函数原型,不行的话自己写一个(嘻嘻!实话告诉你,主要是我也没完全看明白nt的说明,<br>没法英语太遭了,自己写的那部分函数十分不稳定,所以干脆就先去掉了,想不到还是被你给逮了,<br>佩服!)<br>
 
高手!高手!
 
〉呵呵!是不可以的啊,我把nt哪部分去了!其实支持不支持nt主要看api库!<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ~~~~~~~~~~~~~~~说来听听嘛,我现在不用98了
 
hqiang:如果还想接着讨论请定期提前自己的帖子,如果不想继续讨论请结束帖子。
 
接受答案了.
 
后退
顶部