[Delphi] 纯文本查看 复制代码
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
{ Private declarations }
public
{ Public declarations }
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
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;
// 读取DOS头
if not ReadProcessMemory(hProcess, BaseAddress, @DosHeader, SizeOf(DosHeader),
BytesRead) then
Exit;
// 读取NT头
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.