http://www.vado.org -- Videogames are a conduit for the soul. They expand our lives, channel our imagination, test our skillz. Games exist as a channel for the boundless energy of people all over the world. -MegaTokyo
Het antwoord heb ik inmiddels gevonden, danzij Madshi op Expert-Exchange.com. Voor de volledigheid post ik het antwoord hier ook nog even. 
Basically each process has a full memory range from $00000000 - $FFFFFFFF (in win9x only $7FFFFFFF). The executable is usually (but not always) loaded at $400000, the modules are usually loaded at higher addresses. The application can allocate memory, which can be *anywhere* in that memory/address range. You can use VirtualQueryEx to ask which memory area is readable in the other process, then you can use ReadProcessMemory to read the readable parts of the other process. But be prepared: That will be some megabytes!
Regards, Madshi.
Basically each process has a full memory range from $00000000 - $FFFFFFFF (in win9x only $7FFFFFFF). The executable is usually (but not always) loaded at $400000, the modules are usually loaded at higher addresses. The application can allocate memory, which can be *anywhere* in that memory/address range. You can use VirtualQueryEx to ask which memory area is readable in the other process, then you can use ReadProcessMemory to read the readable parts of the other process. But be prepared: That will be some megabytes!
Regards, Madshi.
http://www.vado.org -- Videogames are a conduit for the soul. They expand our lives, channel our imagination, test our skillz. Games exist as a channel for the boundless energy of people all over the world. -MegaTokyo
Verwijderd
Omdat ik dit wel een interessant probleem vind, en omdat ik niet zoveel te doen had
heb ik effe een voorbeeldje gemaakt:
Kleine beschrijving:
Dit programma past een constante waarde in het programma aan dmv API calls. Dit werkt btw niet op Windows NT geloof ik omdat ik gebruik maak van de Tool Help Library.
We maken dus gebruik van de Tool Help Library
Ik gebruik de API's CreateToolhelp32Snapshot, Process32First, Process32Next, Module32First, Module32Next om een MODULEENTRY32 struct te vinden van een bepaalde executable. Hierin staan dan weer een process ID en een base adress van het process.
Als we een handle naar een process hebben, en een base address van dat process hebben, kunnen we in dit stuk geheugen gaan zoeken:
En nog een procedure om een stukje geheugen te veranderen:
Deze functie maakt gebruik van een mbv FindModule gevonden MODULEENTRY32 struct, om een stuk geheugen te veranderen.
Deze constanten willen we veranderen:
Met een button click voeren we alle code uit:
En dat was die
Kleine beschrijving:
Dit programma past een constante waarde in het programma aan dmv API calls. Dit werkt btw niet op Windows NT geloof ik omdat ik gebruik maak van de Tool Help Library.
We maken dus gebruik van de Tool Help Library
code:
1
2
| uses TLHelp32; |
Ik gebruik de API's CreateToolhelp32Snapshot, Process32First, Process32Next, Module32First, Module32Next om een MODULEENTRY32 struct te vinden van een bepaalde executable. Hierin staan dan weer een process ID en een base adress van het process.
code:
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
| function FindProcess(const AExeFile: string; var ProcessEntry: TProcessEntry32):
Boolean;
var
SnapShotHnd: THandle;
begin
Result := False;
SnapShotHnd := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if SnapShotHnd <> INVALID_HANDLE_VALUE then
try
ProcessEntry.dwSize := SizeOf(TProcessEntry32);
if Process32First(SnapShotHnd, ProcessEntry) then
repeat
Result := ProcessEntry.szExeFile = AExeFile;
ProcessEntry.dwSize := SizeOf(TProcessEntry32);
until Result or not Process32Next(SnapShotHnd, ProcessEntry);
finally
CloseHandle(SnapShotHnd);
end;
end;
function FindModule(const AExeFile: string; var ModuleEntry: TModuleEntry32):
Boolean;
var
SnapShotHnd: THandle;
ProcessEntry: TProcessEntry32;
begin
Result := False;
if FindProcess(AExeFile, ProcessEntry) then
begin
SnapShotHnd := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
ProcessEntry.th32ProcessID);
if SnapShotHnd <> INVALID_HANDLE_VALUE then
try
ModuleEntry.dwSize := SizeOf(TModuleEntry32);
if Module32First(SnapShotHnd, ModuleEntry) then
repeat
Result := ModuleEntry.th32ModuleID = ProcessEntry.th32ModuleID;
ModuleEntry.dwSize := SizeOf(TModuleEntry32);
until Result or not Module32Next(SnapShotHnd, ModuleEntry);
finally
CloseHandle(SnapShotHnd);
end;
end;
end; |
Als we een handle naar een process hebben, en een base address van dat process hebben, kunnen we in dit stuk geheugen gaan zoeken:
code:
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
| function FindStringInMemory(AProcessHandle: THandle; const ABaseAddress:
PChar; const ASize: Integer; const S: string; var Address_S: PChar): Boolean;
var
Buffer: array[0..200] of Char;
NrRead: DWORD;
TotalRead: Integer;
DoubleCheckSize: Integer;
function FindIt(const ASearchSize: Integer; var APos: Integer): Boolean;
var
Count: Integer;
begin
APos := 0;
Count := 0;
Result := False;
while not Result and (APos < ASearchSize) do
begin
if Buffer[APos] = S[Count + 1] then
Inc(Count)
else
begin
APos := APos - Count;
Count := 0;
end;
Result := Count = DoubleCheckSize + 1;
if Result then
Dec(APos, DoubleCheckSize)
else
Inc(APos);
end;
end;
var
PosInBuffer: Integer;
begin
FillChar(Buffer, SizeOf(Buffer), #0);
DoubleCheckSize := Length(S) - 1;
Result := False;
TotalRead := 0;
while not Result and (TotalRead < ASize) do
begin
if not ReadProcessMemory(AProcessHandle, ABaseAddress + TotalRead,
PChar(@Buffer) + DoubleCheckSize, SizeOf(Buffer) - DoubleCheckSize, NrRead)
then Exit;
if NrRead = 0 then Exit;
Result := FindIt(DoubleCheckSize + Integer(NrRead), PosInBuffer);
if Result then
Address_S := ABaseAddress + TotalRead + PosInBuffer - DoubleCheckSize
else
begin
Move((PChar(@Buffer) + NrRead)^, Buffer, DoubleCheckSize);
Inc(TotalRead, NrRead);
end;
end;
end; |
En nog een procedure om een stukje geheugen te veranderen:
code:
1
2
3
4
5
6
7
8
| procedure WriteStringInMemory(AProcessHandle: THandle; const AAddress:
PChar; const S: string);
var
NrWritten: DWORD;
begin
WriteProcessMemory(AProcessHandle, AAddress, PChar(S), Length(S) + 1,
NrWritten);
end; |
Deze functie maakt gebruik van een mbv FindModule gevonden MODULEENTRY32 struct, om een stuk geheugen te veranderen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| function ModifyStringInModule(ModuleEntry: TModuleEntry32; const OldString,
NewString: string): Boolean;
var
ProcessHandle: THandle;
OldStringAddress: PChar;
begin
Result := False;
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False,
ModuleEntry.th32ProcessID);
if ProcessHandle <> INVALID_HANDLE_VALUE then
try
Result := FindStringInMemory(ProcessHandle, PChar(ModuleEntry.modBaseAddr),
ModuleEntry.modBaseSize, OldString, OldStringAddress);
if Result then
WriteStringInMemory(ProcessHandle, OldStringAddress, NewString);
finally
CloseHandle(ProcessHandle);
end;
end; |
Deze constanten willen we veranderen:
code:
1
2
| const CValue = 'Atjemenou'; |
Met een button click voeren we alle code uit:
code:
1
2
3
4
5
6
7
8
9
10
11
| procedure TForm1.Button1Click(Sender: TObject);
var
ModuleEntry: TModuleEntry32;
begin
if FindModule(Application.ExeName, ModuleEntry) then
begin
ShowMessage(CValue);
ModifyStringInModule(ModuleEntry, 'Atjemenou', 'abcdefghi');
ShowMessage(CValue);
end;
end; |
En dat was die