然后利用Process32First函数和,获取进程句柄   

2020-01-05 19:23 来源:未知

unit Unit1;

演示工程下载:

3个 API函数
  GetWindowThreadProcessId :获取进程ID 
  OpenProcess              :获取进程句柄     
  ReadProcessMemory        :读出指定进程 指定位置 的数据到缓冲区 
DWORD GetWindowThreadProcessId(
  HWND hWnd,             // 窗口句柄 由FindWindow获取
  LPDWORD lpdwProcessId  // 存放进程ID的 变量
);

interface

永利平台娱乐 1

HANDLE OpenProcess(
  DWORD dwDesiredAccess,    // PROCESS_VM_READ or PROCESS_VM_WRITE 访问权限
  BOOL bInheritHandle,      // 这个是继承标志 在这里 为false
  DWORD dwProcessId         // 进程ID  由GetWindowThreadProcessId 获取
);
BOOL ReadProcessMemory(
  HANDLE hProcess,            // 进程句柄 由OpenProcess函数获取
  LPCVOID lpBaseAddress,      // 要读出数据的地址:$47d814
  LPVOID lpBuffer,            // 用于存放读取数据的地址:sitNum
  DWORD nSize,                // 要读出的数据大小  4
  LPDWORD lpNumberOfBytesRead // 读出数据的实际大小 
);


uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls,TLHelp32,PSAPI, ComCtrls;

{总体流程:
利用CreateToolhelp32Snapshot函数创建一个进程快照,然后利用Process32First函数和
Process32Next函数遍历出所有进程ID等信息,保存到ListView控件中。当获取到进程ID后
交给OpenProcess函数使用打开一个进程,从而获取一个进程句柄,当获取进程句柄后则交
给VirtualAllocEx和WriteProcessMemory函数使用,从而进行虚拟内存分配和写入。然后
则利用GetProcAddress函数和GetModuleHandle函数获取定的动态链接库'kernel32.dll'中
的'LoadLibraryA'函数地址。然后把这个地址交给CreateRemoteThread函数使用。最后用
WaitForSingleObject、VirtualFreeEx、CloseHandle清楚现场。}

一.读指定进程内存:ReadProcessMemory
  此函数的定义为:function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesRead: DWORD): BOOL; stdcall;
  hProcess指向被读取内存的进程的句柄,此句柄必须有PROCESS_VM_READ权限.
  lpBaseAddress:指向被读取的内存在进程中基地址的指针.
  lpBuffer:指向用于保存读出数据的缓冲区的指针.
  nSize:指定从指定进程中要读取的字节数.
  lpNumberOfBytesRead:指向读出数据的实际字节数.

获得进程可执行文件的路径: GetModuleFileNameEx, GetProcessImageFileName, QueryFullProcessImageName

2009-11-05 23:20 2782人阅读 评论(0) 收藏 举报

 

 

想获得进程可执行文件的路径通常有三个方法:

一: 调用GetModuleFileNameEx函数获得可执行文件的模块路径这个函数从Windows NT 4.0开始到现在的Vista系统都能使用,向后兼容性比较好。

 

二:调用GetProcessImageFileName函数,这个函数在Windows XP及其以后的系统中都能使用。

 

三:调用Windows Vista新增的函数QueryFullProcessImageName,由于是Vista新增的,所以兼容性不好。

 

下面来看看这三个函数的原型:

DWORD GetModuleFileNameEx(HANDLE hProcess,HMODULE hModule,LPTSTR lpFilename,DWORD nSize)
      hProcess是目标进程的句柄、hModule是目标模块的句柄(当此参数为NULL时函数返回的是进程可执行文件的路径)、lpFilename是 存放路径的字符串缓冲区、nSize表示缓冲区的大小。函数调用失败将返回0。注:进程的句柄须有PROCESS_QUERY_INFORMATION和 PROCESS_VM_READ权限。

 

DWORD GetProcessImageFileName(HANDLE hProcess,LPTSTR lpImageFileName,DWORD nSize)
      hProcess是目标进程的句柄、lpImageFileName是存放路径的字符串缓冲区、nSize表示缓冲区的大小。函数失败将返回0。注:进程句柄需要有PROCESS_QUERY_INFORMATION的权限。

 

BOOL QueryFullProcessImageName(HANDLE hProcess,DWORD dwFlags,LPTSTR lpExeName,PDWORD lpdwSize)
      hProcess是目标进程的句柄、dwFlags一般设为0(表示返回的路径是Win32的路径格式,如"C:/...",如将其设为 PROCESS_NAME_NATIVE将返回"/Device/HarddiskVolume1/..."这样的格式路径)、lpExeName是存放 路径的字符串缓冲区、lpdwSize表示缓冲区的大小。函数失败将返回FALSE。注:调用此函数的句柄须有 PROCESS_QUERY_INFORMATION或这是PROCESS_QUERY_LIMITED_INFORMATION的权限,并且只能在 Vista或更高版本的系统中使用。

 

      调用GetModuleFileNameExGetProcessImageFileName需要包含Psapi.h头文件,并链接到Psapi.lib

#include <Psapi.h>
#pragma comment (lib,"Psapi.lib")

 

GetProcessImageFileName获取进程路径

HANDLE hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe.th32ProcessID);
if ( GetProcessImageFileName(hProcess,szFilePath,MAX_PATH)!=0 ){
mystring strFilePath = CCommon::DosDevicePath2LogicalPath(szFilePath);

}

复制代码

DosDevicePath2LogicalPath代码摘自:ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.WIN32COM.v10.en/fileio/fs/obtaining_a_file_name_from_a_file_handle.htm

mystring CCommon::DosDevicePath2LogicalPath(LPCTSTR lpszDosPath)
{
mystring strResult;

// Translate path with device name to drive letters.
TCHAR szTemp[MAX_PATH];
szTemp[0] = '';

if ( lpszDosPath==NULL || !GetLogicalDriveStrings(_countof(szTemp)-1, szTemp) ){
return strResult;
}

TCHAR szName[MAX_PATH];
TCHAR szDrive[3] = TEXT(" :");
BOOL bFound = FALSE;
TCHAR* p = szTemp;

do{
// Copy the drive letter to the template string
*szDrive = *p;

// Look up each device name
if ( QueryDosDevice(szDrive, szName, _countof(szName)) ){
UINT uNameLen = (UINT)_tcslen(szName);

if (uNameLen < MAX_PATH) 
{
bFound = _tcsnicmp(lpszDosPath, szName, uNameLen) == 0;

if ( bFound ){
// Reconstruct pszFilename using szTemp
// Replace device path with DOS path
TCHAR szTempFile[MAX_PATH];
_stprintf_s(szTempFile, TEXT("%s%s"), szDrive, lpszDosPath+uNameLen);
strResult = szTempFile;
}
}
}

// Go to the next NULL character.
while (*p++);
} while (!bFound && *p); // end of string

return strResult;
}

 

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Button1: TButton;
    ListView1: TListView;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

unit Unit1;

二.写指定进程内存:WriteProcessMemory
  此函数的定义为:function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesWritten: DWORD): BOOL; stdcall;
参数含义同ReadProcessMemory,其中hProcess句柄要有对进程的PROCESS_VM_WRITE和PROCESS_VM_OPERATION权限.lpBuffer为要写到指定进程的数据的指针.

var
  Form1: TForm1;

interface

procedure TForm1.Timer1Timer(Sender: TObject);
var
  hgame:HWND;
  pidgame:DWORD;
  hprocess:HWND;
  chessdata:DWORD;
  readbyte:DWORD;
  meney:DWORD;

implementation

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, TLHelp32, ComCtrls;

begin
    meney:=10000;
  //获取游戏窗口句柄
    hGame:=Findwindow(nil,'Red Alert 2');
    //获取游戏进程 PID
    windows.GetWindowThreadProcessId(hGame,PidGame) ;
    //获取游戏进程句柄
    hProcess:=windows.OpenProcess(windows.PROCESS_ALL_ACCESS,false,PidGame);
      if hgame<>0 then Label1.Caption:='游戏运行中'

{$R *.dfm}

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListView1: TListView;
    Button2: TButton;
    Button3: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure ListView1SelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

      else
      Label1.Caption:='游戏未启动';

procedure TForm1.Button1Click(Sender: TObject);
var
  lpidProcess:Array[0..1024] of DWORD;
  cbNeeded:DWORD;
  i:Integer;
  item:TListItem;
  hProcessHandle:DWORD;
  ModuleFileName:Array[0..1024] of char;
begin
     ListView1.Clear;
      {lpidProcess:返回进程ID标识的数组。}
      {cb:是进程组数的大小。}
      {cbNeeded返回进程数组的大小(单位:字节).}
      {返回值:如果函数执行成功,返回True。如果函数执行失败,返回False.}
      {function EnumProcesses(lpidProcess: LPDWORD; cb: DWORD; var cbNeeded: DWORD): BOOL;}
      {此函数在PSAPI模块}
     if not EnumProcesses(LPDWORD(@lpidProcess), SizeOf(lpidProcess),cbNeeded) then begin
        ShowMessage('枚举进程失败!');
        Abort();
     end;

var
  Form1: TForm1;
  hProcess:THandle;
  Procedure GetProcess();
  function LoadLibraryA(lpLibFileName: PAnsiChar): HMODULE; stdcall;
  external kernel32 name 'LoadLibraryA';
implementation

      if CheckBox1.Checked then  //写数据
      meneyxg;
    //  WriteProcessMemory(hprocess,Pointer($00a1e0c4),@ChessData,4,readbyte);

     for i:=0 to cbNeeded div SizeOf(DWORD)-1 do begin
         {dwDesiredAccess:访问进程的权限}
         {bInheritHandle:句柄是否继承进程属性。}
         {dwProcessId:进程ID。}
         {返回值:函数调用成功将返回一个进程句柄值,否则将返回0}
         {注意:在使用完所获得的进程句柄后一定要调用CloseHandle(handle)来关闭进程的句柄。}
         {此函数在Windows模块}
         {function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle:
                               BOOL; dwProcessId: DWORD): THandle; stdcall;}
         {dwDesiredAccess参数详细说明:
          PROCESS_ALL_ACCESS        所有能获得的权限
          PROCESS_CREATE_PROCESS    需要创建一个进程
          PROCESS_CREATE_THREAD     需要创建一个线程
          PROCESS_DUP_HANDLE        重复使用DuplicateHandle句柄
          PROCESS_QUERY_INFORMATION 获得进程信息的权限,如它的退出代码、优先级
          PROCESS_QUERY_LIMITED_INFORMATION  /*获得某些信息的权限,如果获得了
                                               PROCESS_QUERY_INFORMATION,
                                               也拥有PROCESS_QUERY_LIMITED_INFORMATION权限*/
          PROCESS_SET_INFORMATION   设置某些信息的权限,如进程优先级
          PROCESS_SET_QUOTA         设置内存限制的权限,使用SetProcessWorkingSetSize
          PROCESS_SUSPEND_RESUME    暂停或恢复进程的权限
          PROCESS_TERMINATE         终止一个进程的权限,使用TerminateProcess
          PROCESS_VM_OPERATION      操作进程内存空间的权限(可用VirtualProtectEx和WriteProcessMemory)
          PROCESS_VM_READ           读取进程内存空间的权限,可使用ReadProcessMemory
          PROCESS_VM_WRITE          读取进程内存空间的权限,可使用WriteProcessMemory
          SYNCHRONIZE               等待进程终止
          }
         hProcessHandle:=OpenProcess(PROCESS_ALL_永利平台娱乐,ACCESS,False,lpidProcess[i]);
         if hProcessHandle=0 then continue;
         item:=ListView1.Items.Add();
         item.Caption:=IntToStr(lpidProcess[i]);
         {hProcess:用OpenProcesses函数打开进程返回的句柄}
         {HMODULE:hModule是目标模块的句柄(当此参数为0时函数返回的是进程可执行文件的路径)}
         {lpFilename:模块名字字符串缓冲区}
         {nSize:模块名字字符串缓冲区大小}
         {返回值:函数调用成功将返回非0,否则将返回0}
         {GetModuleFileNameEx函数功能:获得可执行文件的模块路径}
         {此函数在PsAPI模块}
         {function GetModuleFileNameEx(hProcess: THandle; hModule: HMODULE;
                                       lpFilename: PChar; nSize: DWORD): DWORD;}
         if GetModuleFileNameEx(hProcessHandle,0,PChar(@ModuleFileName),SizeOf(ModuleFileName))=0 then continue;
         item.SubItems.Text:=ModuleFileName;
         CloseHandle(hProcessHandle);
     end;
end;

{$R *.dfm}

      //读出数据
      ReadProcessMemory(hProcess,Pointer($00a1e0c4),@ChessData,4,readByte);
      ReadProcessMemory(hProcess,Pointer(ChessData+$24c),@ChessData,4,readByte);

end.

procedure TForm1.Button1Click(Sender: TObject);begin
    GetProcess;
end;

      if Label1.Caption='游戏运行中' then Label2.Caption:='金钱:'+IntToStr(chessdata)
      else
      Label2.Caption:='';

演示工程下载地址:

Procedure GetProcess();
var
  hSnapshot:THandle;
  pe32:TProcessEntry32;
  item:TListItem;
  count:Integer;
begin
    count:=1;
    hSnapshot:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if hSnapshot=0 then begin
        Form1.Caption:='创建进程快照失败!';
        Abort();
    end else begin
        Form1.Caption:='创建进程快照成功!';
    end;
    pe32.dwSize:=SizeOf(PROCESSENTRY32);
    if not Process32First(hSnapshot,pe32) then begin
        Form1.Caption:='获取第'+IntToStr(count)+'个进程失败!';
    end else begin
        Form1.Caption:='获取第'+IntToStr(count)+'个进程成功!';
    end;
    Form1.ListView1.Clear;
    repeat
         count:=count+1;
         Form1.Caption:='获取第'+IntToStr(count)+'个进程成功!';
         item:=Form1.ListView1.Items.Add;
         item.Caption:=IntToStr(pe32.th32ProcessID);
         item.SubItems.Add(pe32.szExeFile);
         item.SubItems.Add(IntToStr(pe32.pcPriClassBase));
         item.SubItems.Add(IntToStr(pe32.th32ParentProcessID));
    until not Process32Next(hSnapshot,pe32);
    Form1.Caption:='成功获取'+IntToStr(count)+'个进程!';
end;

       //释放进程句柄
      CloseHandle(Hprocess);
end;

TAG标签:
版权声明:本文由永利平台娱乐发布于新闻动态,转载请注明出处:然后利用Process32First函数和,获取进程句柄