unit
Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, PsAPI, TlHelp32;
type
TForm2 =
class
(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure
Button1Click(Sender: TObject);
procedure
Button2Click(Sender: TObject);
private
public
end
;
var
Form2: TForm2;
implementation
{$R *.dfm}
function
GetProcessIDByName(
const
ProcessName:
string
): DWORD;
var
hSnapshot: THandle;
pe32: TProcessEntry32;
begin
Result :=
0
;
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,
0
);
if
hSnapshot <> INVALID_HANDLE_VALUE
then
try
pe32
.
dwSize := SizeOf(TProcessEntry32);
if
Process32First(hSnapshot, pe32)
then
begin
repeat
if
LowerCase(pe32
.
szExeFile) = LowerCase(ProcessName)
then
begin
Result := pe32
.
th32ProcessID;
Break;
end
;
until
not
Process32Next(hSnapshot, pe32);
end
;
finally
CloseHandle(hSnapshot);
end
;
end
;
function
VAtoFOA(hProcess: THandle; VA:
Pointer
): DWORD;
type
TImageDosHeader =
packed
record
e_magic:
Word
;
e_lfanew:
LongWord
;
end
;
TImageNtHeaders =
packed
record
Signature: DWORD;
FileHeader: TImageFileHeader;
OptionalHeader: TImageOptionalHeader;
end
;
TImageSectionHeader =
packed
record
Name:
array
[
0
..
7
]
of
AnsiChar
;
VirtualSize: DWORD;
VirtualAddress: DWORD;
SizeOfRawData: DWORD;
PointerToRawData: DWORD;
end
;
var
DosHeader: TImageDosHeader;
NtHeaders: TImageNtHeaders;
SectionHeaders:
array
of
TImageSectionHeader;
i:
Integer
;
BaseAddress:
Pointer
;
BytesRead: SIZE_T;
begin
Result :=
0
;
if
not
ReadProcessMemory(hProcess, BaseAddress, @DosHeader, SizeOf(DosHeader),
BytesRead)
then
Exit;
if
not
ReadProcessMemory(hProcess,
Pointer
(DWORD(BaseAddress) + DosHeader
.
e_lfanew), @NtHeaders,
SizeOf(NtHeaders), BytesRead)
then
Exit;
SetLength(SectionHeaders, NtHeaders
.
FileHeader
.
NumberOfSections);
for
i :=
0
to
NtHeaders
.
FileHeader
.
NumberOfSections -
1
do
begin
if
not
ReadProcessMemory(hProcess,
Pointer
(DWORD(BaseAddress) + DosHeader
.
e_lfanew + SizeOf(NtHeaders) + i *
SizeOf(TImageSectionHeader)), @SectionHeaders[i],
SizeOf(TImageSectionHeader), BytesRead)
then
Exit;
end
;
for
i :=
0
to
High(SectionHeaders)
do
begin
if
(DWORD(VA) >= SectionHeaders[i].VirtualAddress)
and
(DWORD(VA) < SectionHeaders[i].VirtualAddress + SectionHeaders[i]
.VirtualSize)
then
begin
Result := DWORD(VA) - SectionHeaders[i].VirtualAddress + SectionHeaders[i]
.PointerToRawData;
Exit;
end
;
end
;
end
;
procedure
TForm2
.
Button1Click(Sender: TObject);
const
TARGET_STRING =
'No luck there'
;
var
hProcess: THandle;
ProcessID: DWORD;
mbi: TMemoryBasicInformation;
dwAddress: DWORD;
Buffer:
array
[
0
..
4095
]
of
AnsiChar
;
BytesRead: SIZE_T;
Found:
Boolean
;
FOA: DWORD;
begin
ProcessID := GetProcessIDByName(
'CrackMe.exe'
);
if
ProcessID =
0
then
begin
ShowMessage(
'进程未找到'
);
end
else
begin
ShowMessage(
'PID:'
+ ProcessID
.
ToString);
end
;
hProcess := OpenProcess(PROCESS_VM_READ
or
PROCESS_QUERY_INFORMATION,
False
,
ProcessID);
if
hProcess =
0
then
begin
ShowMessage(
'无法打开进程'
);
end
else
begin
ShowMessage(
'I am here!'
);
end
;
try
dwAddress :=
0
;
Found :=
False
;
while
VirtualQueryEx(hProcess,
Pointer
(dwAddress), mbi, SizeOf(mbi))
= SizeOf(mbi)
do
begin
if
(mbi
.
State = MEM_COMMIT)
and
(mbi
.
Protect = PAGE_READONLY
or
PAGE_READWRITE)
then
begin
if
ReadProcessMemory(hProcess, mbi
.
BaseAddress, @Buffer, SizeOf(Buffer),
BytesRead)
then
begin
if
Pos(TARGET_STRING, Buffer) >
0
then
begin
dwAddress := DWORD(mbi
.
BaseAddress) +
Pos(TARGET_STRING, Buffer) -
1
;
Found :=
True
;
Break;
end
;
end
;
end
;
dwAddress := DWORD(mbi
.
BaseAddress) + mbi
.
RegionSize;
end
;
if
Found
then
begin
FOA := VAtoFOA(hProcess,
Pointer
(dwAddress));
Edit1
.
Text := Format(
'0x%.8x'
, [FOA]);
end
else
begin
ShowMessage(
'字符串未找到'
);
end
;
finally
CloseHandle(hProcess);
end
;
end
;
procedure
TForm2
.
Button2Click(Sender: TObject);
const
TARGET_STRING =
'No luck there'
;
var
hProcess: THandle;
ProcessID: DWORD;
mbi: TMemoryBasicInformation;
dwAddress: DWORD;
Buffer:
array
[
0
..
4095
]
of
AnsiChar
;
BytesRead: SIZE_T;
Found:
Boolean
;
FOA: DWORD;
begin
ProcessID := GetProcessIDByName(
'CrackMe.exe'
);
if
ProcessID =
0
then
begin
ShowMessage(
'进程未找到'
);
Exit;
end
else
begin
ShowMessage(
'PID:'
+ ProcessID
.
ToString);
end
;
hProcess := OpenProcess(PROCESS_VM_READ
or
PROCESS_QUERY_INFORMATION,
False
,
ProcessID);
if
hProcess =
0
then
begin
ShowMessage(
'无法打开进程'
);
Exit;
end
else
begin
ShowMessage(
'成功打开进程'
);
end
;
try
dwAddress :=
0
;
Found :=
False
;
while
VirtualQueryEx(hProcess,
Pointer
(dwAddress), mbi, SizeOf(mbi))
= SizeOf(mbi)
do
begin
if
(mbi
.
State = MEM_COMMIT)
and
((mbi
.
Protect = PAGE_READONLY)
or
(mbi
.
Protect = PAGE_READWRITE))
then
begin
if
ReadProcessMemory(hProcess, mbi
.
BaseAddress, @Buffer, SizeOf(Buffer),
BytesRead)
then
begin
if
Pos(TARGET_STRING, Buffer) >
0
then
begin
dwAddress := DWORD(mbi
.
BaseAddress) +
Pos(TARGET_STRING, Buffer) -
1
;
Found :=
True
;
Break;
end
;
end
else
begin
ShowMessage(Format(
'无法读取内存区域 0x%x,错误代码: %d'
, [DWORD(mbi
.
BaseAddress),
GetLastError]));
end
;
end
;
dwAddress := DWORD(mbi
.
BaseAddress) + mbi
.
RegionSize;
end
;
if
Found
then
begin
FOA := VAtoFOA(hProcess,
Pointer
(dwAddress));
Edit1
.
Text := Format(
'0x%.8x'
, [FOA]);
end
else
begin
ShowMessage(
'字符串未找到'
);
end
;
finally
CloseHandle(hProcess);
end
;
end
;
end
.