unit Unit33;
interface
uses
PsAPI, TlHelp32, Winapi.Windows, Winapi.Messages, System.SysUtils,
System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.StdCtrls;
type
TForm33 = class(TForm)
Edit1: TEdit;
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
function GetProcessIDByName(const ProcessName: string): DWORD;
function SearchStringInProcessMemory(ProcessID: DWORD): TStringList;
public
{ Public declarations }
end;
var
Form33: TForm33;
implementation
{$R *.dfm}
// 根据进程名获取进程 ID
function TForm33.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 TForm33.SearchStringInProcessMemory(ProcessID: DWORD): TStringList;
var
hProcess: THandle;
ML: MODULEINFO;
hModules: array[0..0] of HMODULE;
BytesReadEnum: DWORD; // 用于 EnumProcessModules
BytesReadMem: NativeUInt; // 用于 ReadProcessMemory
Buffer: array of Byte;
i: Integer;
StartPos, EndPos: Integer;
FoundString: string;
UTF8Str: UTF8String;
begin
Result := TStringList.Create;
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID);
if hProcess = 0 then
begin
ShowMessage('无法打开进程!');
Exit;
end;
try
if EnumProcessModules(hProcess, @hModules[0], SizeOf(hModules), BytesReadEnum) then
begin
if GetModuleInformation(hProcess, hModules[0], @ML, SizeOf(ML)) then
begin
SetLength(Buffer, ML.SizeOfImage);
if ReadProcessMemory(hProcess, ML.lpBaseOfDll, Pointer(Buffer), ML.SizeOfImage, BytesReadMem) then
begin
i := 0;
while i < Length(Buffer) - 2 do
begin
// 查找 【(UTF-8 编码:0xE3 0x80 0x90)
if (Buffer[i] = $E3) and (Buffer[i + 1] = $80) and (Buffer[i + 2] = $90) then
begin
StartPos := i + 3; // 跳过 【
// 查找 】(UTF-8 编码:0xE3 0x80 0x91)
while i < Length(Buffer) - 2 do
begin
if (Buffer[i] = $E3) and (Buffer[i + 1] = $80) and (Buffer[i + 2] = $91) then
begin
EndPos := i - 1; // 结束位置
// 提取 UTF-8 字符串
SetLength(UTF8Str, EndPos - StartPos + 1);
Move(Buffer[StartPos], UTF8Str[1], EndPos - StartPos + 1);
FoundString := string(UTF8Str); // 转换为 Unicode 字符串
Result.Add(FoundString);
Break;
end;
Inc(i);
end;
end;
Inc(i);
end;
end
else
begin
ShowMessage('无法读取进程内存!');
end;
end
else
begin
ShowMessage('无法获取模块信息!');
end;
end
else
begin
ShowMessage('无法枚举进程模块!');
end;
finally
CloseHandle(hProcess);
end;
end;
procedure TForm33.Button1Click(Sender: TObject);
var
ProcessID: DWORD;
FoundStrings: TStringList;
begin
ProcessID := GetProcessIDByName(Edit1.Text); // 获取进程 ID
if ProcessID = 0 then
begin
ShowMessage('未找到进程!');
Exit;
end;
FoundStrings := SearchStringInProcessMemory(ProcessID); // 搜索字符串
try
Memo1.Lines.Clear;
Memo1.Lines.AddStrings(FoundStrings); // 显示结果
finally
FoundStrings.Free;
end;
end;
end.