看流星社区

 找回密码
 注册账号
查看: 3272|回复: 0

[Delphi] 【转】读写其他进程内存技术

[复制链接]

该用户从未签到

发表于 2011-11-18 07:33:07 | 显示全部楼层 |阅读模式
本帖最后由 hapi 于 2011-11-25 12:05 编辑

最近看了篇文章,关于读写其他进程内存的技巧,感觉有可取之处,贴出来共勉之!

众所周知,在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;    //提升权限
var
hToken:Thandle;
tp:TOKEN_PRIVILEGES;
aWORD;
const SE_DEBUG_NAME = 'SeDebugPrivilege';
begin
Result:=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
    ( := 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));
    Co op := 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 in ['0'..'9'] then
    Retvar := Retvar + (Byte(HexStr) - 48)
   else
    if HexStr in ['A'..'F'] then
       (Byte(HexStr) - 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 :  ; //内存状态的结构,返回内存状态
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:=  .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 +  (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 := Proces2First(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));
  end;
  List.Free;
  Combobox1.itemindex := 0;
end;

end.
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-26 16:15

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表