forked from vdisasm/pe-image-for-delphi
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathPE.ProcessModuleStream.pas
126 lines (104 loc) · 3.09 KB
/
PE.ProcessModuleStream.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
{
* Class to access memory of Windows process.
*
* Stream begin is base of module.
* Stream size is size of image of target module.
}
unit PE.ProcessModuleStream;
interface
uses
Classes,
SysUtils,
PsApi,
TlHelp32,
Windows,
WinHelper;
type
TProcessModuleStream = class(TStream)
private
FProcessHandle: THandle;
FModuleBase: NativeUInt;
FModuleSize: DWORD;
private
FCurrentRVA: UInt64;
public
constructor Create(ProcessID: DWORD; const me: TModuleEntry32);
// Create from known process ID. Module base is found from ModuleName.
// If process id is invalid or no module found exception raised.
constructor CreateFromPidAndModuleName(ProcessID: DWORD; const ModuleName: string);
constructor CreateFromPidAndAddress(ProcessID: DWORD; Address: NativeUInt);
// Create from known process id. Main module used (i.e. started exe).
constructor CreateFromPid(ProcessID: DWORD);
destructor Destroy; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
function Read(var Buffer; Count: Longint): Longint; override;
property ModuleBase: NativeUInt read FModuleBase;
end;
implementation
{ TProcessModuleStream }
procedure RaiseFailedToFindModule;
begin
raise Exception.Create('Failed to find main module.');
end;
constructor TProcessModuleStream.Create(ProcessID: DWORD; const me: TModuleEntry32);
begin
inherited Create;
FProcessHandle := OpenProcess(MAXIMUM_ALLOWED, False, ProcessID);
if FProcessHandle = 0 then
RaiseLastOSError;
FModuleBase := NativeUInt(me.modBaseAddr);
FModuleSize := me.modBaseSize;
end;
constructor TProcessModuleStream.CreateFromPidAndModuleName(ProcessID: DWORD; const ModuleName: string);
var
me: TModuleEntry32;
begin
if not FindModuleByName(ProcessID, ModuleName) then
RaiseFailedToFindModule;
Create(ProcessID, me);
end;
constructor TProcessModuleStream.CreateFromPidAndAddress(ProcessID: DWORD; Address: NativeUInt);
var
me: TModuleEntry32;
begin
if not FindModuleByAddress(ProcessID, Address, me) then
RaiseFailedToFindModule;
Create(ProcessID, me);
end;
constructor TProcessModuleStream.CreateFromPid(ProcessID: DWORD);
var
me: TModuleEntry32;
begin
if not FindMainModule(ProcessID, me) then
RaiseFailedToFindModule;
Create(ProcessID, me);
end;
destructor TProcessModuleStream.Destroy;
begin
CloseHandle(FProcessHandle);
inherited;
end;
function TProcessModuleStream.Read(var Buffer; Count: Integer): Longint;
var
p: pbyte;
done: NativeUInt;
begin
p := pbyte(FModuleBase) + FCurrentRVA;
done := 0;
ReadProcessMemory(FProcessHandle, p, @Buffer, Count, done);
inc(FCurrentRVA, done);
Result := done;
end;
function TProcessModuleStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
case Origin of
soBeginning:
FCurrentRVA := Offset;
soCurrent:
FCurrentRVA := FCurrentRVA + Offset;
soEnd:
FCurrentRVA := FModuleSize + Offset;
end;
Result := FCurrentRVA;
end;
end.