黑基网 首页 学院 网络安全 查看内容

读写其他进程内存技术

2009-10-18 10:25| 投稿: security

摘要:  最近看了篇文章,关于读写其他进程内存的技巧,感觉有可取之处,贴出来共勉之! 众所周知,在win32中,每个应用程序都可“看见”4GB的线性地址空间,其中最开始的4MB和最后的2GB由操作...
 最近看了篇文章,关于读写其他进程内存的技巧,感觉有可取之处,贴出来共勉之! 众所周知,在win32中,每个应用程序都可“看见”4GB的线性地址空间,其中最开始的4MB和最后的2GB由操作系统保留,剩下的不足2GB的空间是应用程序的私有空间。具体分配原则是:(从高到低)0xFFFFFFFF~0xC0000000的1GB用于Vxd,存储器管理和文件系统,0xBFFFFFFF~0x80000000的1GB用于共享的win32Dll,存储器映像文件和共享存储区,0x7FFFFFFF~0x00400000为每个应用程序的私有空间,0x00300000~0x00001000位MS—DOS和win16应用程序,0x00000FFF~0x00000000为防止使用空指针而保留的4096字节。所以,我们通常用LordPe查看到的基地址大都是00400000。下面的程序例子是读取其他进程内存的例子,其中读取的数据放到lpBuffer中,写数据时将读取的lpBuffer中的数据原样写入,因为一不小心就可能挂掉被访问的进程。我就是这么想的,能挂掉最好,想通过在这种方法结束360tray.exe的进程,结果是失败了。代码贴出来做个记录吧!代码中的EnabledDebugPrivilege和KillTask是我自己后来为了结束其他进程而加入的。程序运行后会自行结束360的主动防御进程。其他地方做了注释! 注意在uses里加上 Tlhelp32;在测试的时候发现不提升权限,很多系统进程的内存没法访问,后来就加上了提升权限的功能。 unit Unit1; interface uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls, Mask,Tlhelp32; type  TForm1 = class(TForm)    ComboBox1: TComboBox;    Memo1: TMemo;    Label1: TLabel;    MaskEdit1: TMaskEdit;    MaskEdit2: TMaskEdit;    Label2: TLabel;    Label3: TLabel;    Button1: TButton;    procedure Button1Click(Sender: TObject);    procedure FormCreate(Sender: TObject);  private    { Private declarations }  public    { Public declarations }     FSnapShotHandle: THandle;    Function GetProcessID(var List : TStringList; FileName: string = ''): TProcessEntry32;  end; var  Form1: TForm1; implementation {$R *.dfm}function EnabledDebugPrivilege(const bEnabled:Boolean):Boolean;    //提升权限varhToken:Thandle;tp:TOKEN_PRIVILEGES;a:DWORD;const SE_DEBUG_NAME = 'SeDebugPrivilege';beginResult:=False;if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,hToken)) then begin tp.PrivilegeCount:=1; LookupPrivilegeValue(nil,SE_DEBUG_NAME,tp.Privileges[0].luid); if bEnabled then tp.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED else tp.Privileges[0].Attributes:=0; a:=0; AdjustTokenPrivileges(hToken,false,tp,sizeof(tp),nil,a); Result:= GetLastError = Error_SUCCESS; closehandle(hToken); end;end; function KillTask(ExeFileName: string): integer;  //结束指定进程const  PROCESS_TERMINATE = $0001;var  ContinueLoop: BOOL;  FSnapshotHandle: THandle;  FProcessEntry32: TProcessEntry32;begin  result := 0;   FSnapshotHandle := CreateToolhelp32Snapshot    (TH32CS_SNAPPROCESS, 0);  FProcessEntry32.dwSize := Sizeof(FProcessEntry32);  ContinueLoop := Process32First(FSnapshotHandle,    FProcessEntry32);   while integer(ContinueLoop) <> 0 do  begin    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =      UpperCase(ExeFileName))      or (UpperCase(FProcessEntry32.szExeFile) =      UpperCase(ExeFileName))) then      Result := Integer(TerminateProcess(OpenProcess(        PROCESS_TERMINATE, BOOL(0),        FProcessEntry32.th32ProcessID), 0));    ContinueLoop := Process32Next(FSnapshotHandle,      FProcessEntry32);  end;  CloseHandle(FSnapshotHandle);end; Function HexToInt(HexStr: String):Int64;var Retvar : Int64; i: Byte;begin HexStr := UpperCase(HexStr); if HexStr[Length(HexStr)] = 'H' then Delete(HexStr,Length(HexStr),1); Retvar := 0; for i := 1 to Length(HexStr) do  begin   Retvar := Retvar shl 4;   if HexStr[i] in ['0'..'9'] then    Retvar := Retvar + (Byte(HexStr[i]) - 48)   else    if HexStr[i] in ['A'..'F'] then     Retvar := Retvar + (Byte(HexStr[i]) - 55)    else     begin      Retvar := 0;      Break;      end;   end; Result := Retvar;end; procedure TForm1.Button1Click(Sender: TObject);var FProcessEntry32 : TProcessEntry32; ProcessID : Integer; ProcessHandle : THandle; lpBuffer : Pchar; nSize : DWORD; lpNumberOfBytes : DWORD; i : Integer; addr : DWORD; s : String; List : TStringList; mbi_thunk : TMemoryBasicInformation; //内存状态的结构,返回内存状态 dwOldProtect : DWORD; begin if Combobox1.ItemIndex = -1 then exit; List := TStringList.Create; FProcessEntry32 := GetProcessID(list,Combobox1.text); //查找指定进程 if  FProcessEntry32.th32ProcessID = 0 then exit; ProcessID := FProcessEntry32.th32ProcessID; Memo1.Lines.Clear; Memo1.Lines.Add('Process ID : '+IntToHex(FProcessEntry32.th32ProcessID,8)); Memo1.Lines.Add('File Name : '+ FProcessEntry32.szExeFile); ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,false,ProcessID); //以所有存取权打开进程 Memo1.Lines.Add('Process Handle : '+ inttohex(ProcessHandle,8)); Memo1.Lines.Add('虚拟内存中的数据:'); addr:= HexToInt(MaskEdit1.Text);  //起始地址 nSize := HexTOInt(MaskEdit2.Text) - addr +1;//长度 if HexToInt(MaskEdit2.Text)> addr then   //如果输入的起始,结束地址有效 begin   lpBuffer := AllocMem(nSize);   //开始读取其他进程的数据   if (not ReadProcessMemory(ProcessHandle,Pointer(addr),lpBuffer,nSize,lpNumberOfBytes)) or (nSize<>lpNumberOfBytes) then    begin             //被读进程句柄  读的起始地址  存放数据缓冲区  读取字节数  返回实际读取字节数     showmessage('读取数据出错,可能是指定地址不存在');     exit;    end;   s :='';   for i := 0 to nSize -1 do   begin    S := s + format('%.2X ',[ord(lpBuffer[i])]);    if ((i mod 16) = 15) or (i=nSize -1) then    //每16字节分行显示     begin      Memo1.Lines.Add(s);      s:='';     end;    end;         //进程句柄   内存区域有地址  内存状态       结构长度  VirtualQueryEx(ProcessHandle,Pointer(addr),mbi_thunk, sizeof(TMemoryBasicInformation)); //取得内存状态                       //进程句柄   指向改变首地址 大小    新的访问属性           当前访问属性     VirtualProtectEx(ProcessHandle,Pointer(addr),nSize,PAGE_EXECUTE_READWRITE,mbi_thunk.Protect);  //修改内存属性     if(not WriteProcessMemory(ProcessHandle, Pointer(addr), lpBuffer, nSize, lpNumberOfBytes))         then     begin        showmessage('写数据出错,可能是该地址不允许写。如果该处不是Rom,可以通过Ring0或其它特权写该内存。');     end;     VirtualProtectEx(ProcessHandle,Pointer(addr), nSize, mbi_thunk.Protect,dwOldProtect); //恢复内存属性     FreeMem(lpBuffer, nSize);  end;  CloseHandle(ProcessHandle);    //关闭句柄,释放内存  List.free;end;//获取全部进程的名字Function Tform1.GetProcessID(var List : TStringList; FileName: string = ''):TProcessEntry32;var  Ret: BOOL;  s: string;  FProcessEntry32: TProcessEntry32;begin  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //创建进程快照  FProcessEntry32.dwSize := Sizeof(FProcessEntry32);  //初始化结构大小  Ret := Process32First(FSnapshotHandle, FProcessEntry32); //取第一个进程  while Ret do  begin    s := ExtractFileName(FProcessEntry32.szExeFile);    if (FileName = '') then  //如果filename为空,则列出全部进程    begin      List.Add(Pchar(s));    end    else if (AnsiCompareText(Trim(s),Trim(FileName))=0) and (FileName <> '') then    begin      List.Add(Pchar(s));      result := FProcessEntry32;      break;    end;    Ret := Process32Next(FSnapshotHandle, FProcessEntry32); //取下一进程   end;  //循环枚举出系统所有进程  CloseHandle(FSnapshotHandle);end; procedure TForm1.FormCreate(Sender: TObject);var  List: TStringList;  i: integer;begin  EnabledDebugPrivilege(true);    //提升权限  if KillTask('zhudongfangyu.exe') =1 then  showmessage('Ok!')  else showmessage('failed');  Combobox1.clear;  List := TStringList.Create;  GetProcessID(List);  for i := 0 to List.Count - 1 do  begin    Combobox1.items.add(Trim(List.strings[i]));  end;  List.Free;  Combobox1.itemindex := 0;end; end. 
小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册黑基账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!



免责声明:本文由投稿者转载自互联网,版权归原作者所有,文中所述不代表本站观点,若有侵权或转载等不当之处请联系我们处理,让我们一起为维护良好的互联网秩序而努力!联系方式见网站首页右下角。


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论


新出炉

返回顶部