来自windows核心编程教程
一直以来,都是拖控件,或者用delphi的控件动态创建,
在看核心编程时,发现例子中根本没dfm窗体文件,而且编译出的exe大小十几k。
上代码吧
项目同名的 .RC文件
// 语言
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
// Define
#define IDD_PROCESSINFO 101
#define IDR_PROCESSINFO 102
#define IDI_PROCESSINFO 103
#define IDC_PROCESSMODULELIST 1000
#define IDC_RESULTS 1011
#define IDC_MODULEHELP 1014
#define ID_PROCESSES 40001
#define ID_MODULES 40002
#define ID_VMMAP 40006
#define ID_MHELP 40007
#define ID_MWINDOWS 40008
// Dialog
IDD_PROCESSINFO DIALOGEX 0, 0, 400, 317
STYLE DS_3DLOOK | DS_NOFAILCREATE | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
CAPTION "Process Information"
MENU IDR_PROCESSINFO
FONT 8, "MS Sans Serif"
BEGIN
COMBOBOX IDC_PROCESSMODULELIST, 4, 4, 392, 156, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LISTBOX IDC_MODULEHELP, 0, 0, 48, 40, NOT LBS_NOTIFY | LBS_SORT | LBS_NOINTEGRALHEIGHT | NOT WS_VISIBLE | NOT WS_BORDER | WS_TABSTOP
EDITTEXT IDC_RESULTS, 4, 24, 392, 284, ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
END
// Menu
IDR_PROCESSINFO MENU DISCARDABLE
BEGIN
MENUITEM "&Processes!", ID_PROCESSES
MENUITEM "&Modules!", ID_MODULES
MENUITEM "&VMMap!", ID_VMMAP
//弹出菜单
POPUP "&Help!"
BEGIN
//子菜单
MENUITEM "&Windows!", ID_MWINDOWS
END
END
// Icon
IDI_PROCESSINFO ICON DISCARDABLE "ProcessInfo.ico"
项目同名的.pas文件
program ProcessInfo;
{$R 'ProcessInfo.res' 'ProcessInfo.rc'}
uses
Windows,
Messages,
TlHelp32,
Toolhelp in 'Toolhelp.pas';
const
// 资源ID
IDD_PROCESSINFO = 101;
IDI_PROCESSINFO = 103;
// 控件ID
IDC_PROCESSMODULELIST = 1000;
IDC_RESULTS = 1011;
IDC_MODULEHELP = 1014;
// 菜单ID
ID_PROCESSES = 40001;
ID_MODULES = 40002;
ID_VMMAP = 40006;
ID_MWINDOWS = 40008;
// 定位字符串中指定字符
function SearchChar(const S: PChar; C: Char; Back: BOOL): PChar;
begin
if (Back = TRUE) then
begin // 从前向后搜索
Result := S;
while (Result^ <> #0) and (Result^ <> C) do
Inc(Result);
end
else
begin // 从后向前搜索
Result := SearchChar(S, #0, TRUE);
if (Result <> S) then
repeat
Dec(Result)
until (Result = S) or (Result^ = C);
end;
if (Result^ <> C) then
Result := nil;
end;
// 简单包装格式输出API
function wvsprintf(Output: PChar; Format: PChar; Arg_List: array of Integer): Integer;
begin
Result := Windows.wvsprintf(Output, Format, @Arg_List[Low(Arg_List)]);
end;
// 向Edit控件添加字符串
procedure AddText(hWnd: hWnd; pszFormat: PChar; Arg_List: array of Integer);
var
sz: array[0..20 * 1024] of Char;
begin
GetWindowText(hWnd, sz, SizeOf(sz));
wvsprintf(SearchChar(sz, #0, TRUE), pszFormat, Arg_List);
SetWindowText(hWnd, sz);
end;
// 刷新进程列表至ComboBox
procedure Dlg_PopulateProcessList(hWnd: hWnd);
var
hWndList: LongWord; // ComboBox句柄
thProcesses: TToolhelp; // 进程枚举对象
pe: TProcessEntry32; // 进程枚举结构
fOk: BOOL;
pszExeFile: PChar;
sz: array[0..1024] of Char;
n: Integer;
begin
pe.dwSize := SizeOf(TProcessEntry32);
hWndList := GetDlgItem(hWnd, IDC_PROCESSMODULELIST);
SendMessage(hWndList, WM_SETREDRAW, 0, 0);
SendMessage(hWndList, CB_RESETCONTENT, 0, 0);
// 枚举进程
thProcesses := TToolhelp.Create(TH32CS_SNAPPROCESS);
fOk := thProcesses.ProcessFirst(@pe);
while fOk do
begin
pszExeFile := SearchChar(pe.szExeFile, '\', FALSE);
if (pszExeFile = nil) then
pszExeFile := pe.szExeFile
else
Inc(pszExeFile);
// 添加进程名(不含路径)及ID
wvsprintf(sz, '%s (0x%08X)', [Integer(pszExeFile), pe.th32ProcessID]);
n := SendMessage(hWndList, CB_ADDSTRING, 0, Integer(@sz[0]));
// 保存进程ID至ComboBox子项
SendMessage(hWndList, CB_SETITEMDATA, n, pe.th32ProcessID);
// 下一进程
fOk := thProcesses.ProcessNext(@pe);
end;
thProcesses.Free;
// ComboBox选项'改变为'第一项
SendMessage(hWndList, CB_SETCURSEL, 0, 0);
SendMessage(hWnd, WM_COMMAND, MakeWParam(IDC_PROCESSMODULELIST, CBN_SELCHANGE), hWndList);
SendMessage(hWndList, WM_SETREDRAW, 1, 0);
InvalidateRect(hWndList, nil, FALSE);
end;
// 刷新模块列表至ComboBox
procedure Dlg_PopulateModuleList(hWnd: hWnd);
var
hWndModuleHelp, hWndList: LongWord; // HWND
thProcesses, thModules: TToolhelp;
pe: TProcessEntry32;
me: TModuleEntry32;
fpOk, fmOk: BOOL;
n, j, nNumModules, nIndex: Integer;
sz: array[0..1024] of Char;
begin
pe.dwSize := SizeOf(TProcessEntry32);
me.dwSize := SizeOf(TModuleEntry32);
// 利用ListBox管理模块列表
hWndModuleHelp := GetDlgItem(hWnd, IDC_MODULEHELP);
SendMessage(hWndModuleHelp, LB_RESETCONTENT, 0, 0);
// 枚举进程
thProcesses := TToolhelp.Create(TH32CS_SNAPPROCESS);
fpOk := thProcesses.ProcessFirst(@pe);
while fpOk do
begin
// 枚举模块
thModules := TToolhelp.Create(TH32CS_SNAPMODULE, pe.th32ProcessID);
fmOk := thModules.ModuleFirst(@me);
while fmOk do
begin
// 该模块是否已存在于ListBox, 不存在则添加
n := SendMessage(hWndModuleHelp, LB_FINDSTRINGEXACT, -1, Integer(@me.szExePath[0]));
if (n = LB_ERR) then
begin
SendMessage(hWndModuleHelp, LB_ADDSTRING, 0, Integer(@me.szExePath[0]));
end;
// 下一模块
fmOk := thModules.ModuleNext(@me);
end;
thModules.Free;
// 下一进程
fpOk := thProcesses.ProcessNext(@pe);
end;
thProcesses.Free;
// ListBox -> ComboBox
hWndList := GetDlgItem(hWnd, IDC_PROCESSMODULELIST);
SendMessage(hWndList, WM_SETREDRAW, 0, 0);
SendMessage(hWndList, CB_RESETCONTENT, 0, 0);
nNumModules := SendMessage(hWndModuleHelp, LB_GETCOUNT, 0, 0);
for j := 0 to nNumModules - 1 do
begin
// ListBox第j项(完整路径)
SendMessage(hWndModuleHelp, LB_GETTEXT, j, Integer(@sz[0]));
// 添加模块名称(不含路径)
nIndex := SendMessage(hWndList, CB_ADDSTRING, 0, Integer(SearchChar(sz, '\', FALSE)) + 1);
// 保存模块的ListBox编号
SendMessage(hWndList, CB_SETITEMDATA, nIndex, j);
end;
// ComboBox选项'改变为'第一项
SendMessage(hWndList, CB_SETCURSEL, 0, 0);
SendMessage(hWnd, WM_COMMAND, MakeWParam(IDC_PROCESSMODULELIST, CBN_SELCHANGE), hWndList);
SendMessage(hWndList, WM_SETREDRAW, 1, 0);
InvalidateRect(hWndList, nil, FALSE);
end;
// 取得模块默认基地址
function GetModulePreferredBaseAddr(dwProcessId: DWORD; pvModuleRemote: Pointer): Pointer;
var
idh: TImageDosHeader;
inth: TImageNtHeaders;
begin
Result := nil;
// 读取远程模块Dos头
Toolhelp32ReadProcessMemory(dwProcessId, pvModuleRemote, idh, SizeOf(TImageDosHeader), PDWORD(nil)^);
// 检测Dos头标志('MZ')
if (idh.e_magic = IMAGE_DOS_SIGNATURE) then
begin
// 读取远程模块Nt头
Inc(PByte(pvModuleRemote), idh._lfanew);
Toolhelp32ReadProcessMemory(dwProcessId, pvModuleRemote, inth, SizeOf(TImageNtHeaders), PDWORD(nil)^);
// 检测Nt头标志('PE00')
if (inth.Signature = IMAGE_NT_SIGNATURE) then
begin
Result := Pointer(inth.OptionalHeader.ImageBase);
end;
end;
end;
// 显示指定进程信息
procedure ShowProcessInfo(hWndEdit: hWnd; dwProcessID: DWORD);
var
th: TToolhelp;
fOk: BOOL;
pe: TProcessEntry32;
me: TModuleEntry32;
te: TThreadEntry32;
pvPreferredBaseAddr: Pointer;
nPriority: Integer;
begin
pe.dwSize := SizeOf(TProcessEntry32);
me.dwSize := SizeOf(TModuleEntry32);
te.dwSize := SizeOf(TThreadEntry32);
SetWindowText(hWndEdit, '');
th := TToolhelp.Create(TH32CS_SNAPALL, dwProcessID);
// 显示指定进程基本信息
fOk := th.ProcessFirst(@pe);
while fOk do
begin
if (pe.th32ProcessID = dwProcessID) then
begin
AddText(hWndEdit, 'Filename: %s'#13#10, [Integer(@pe.szExeFile[0])]);
AddText(hWndEdit, ' PID=%08X, ParentPID=%08X, PriorityClass=%d, Threads=%d, Heaps=%d'#13#10, [pe.th32ProcessID, pe.th32ParentProcessID, pe.pcPriClassBase, pe.cntThreads, th.HowManyHeaps()]);
Break;
end;
fOk := th.ProcessNext(@pe);
end;
// 显示进程所含模块信息
AddText(hWndEdit, #13#10'Modules Information:'#13#10' Usage %-8s(%-8s) %8s Module'#13#10, [Integer(PChar('BaseAddr')), Integer(PChar('ImagAddr')), Integer(PChar('Size'))]);
fOk := th.ModuleFirst(@me);
while fOk do
begin
// 引用次数
if (me.ProccntUsage <> 65535) then
AddText(hWndEdit, ' %5d', [me.ProccntUsage])
else
AddText(hWndEdit, ' Fixed', []);
// 映像地址
pvPreferredBaseAddr := GetModulePreferredBaseAddr(pe.th32ProcessID, me.modBaseAddr);
if (me.modBaseAddr = pvPreferredBaseAddr) then
AddText(hWndEdit, ' %p %8s %8u %s'#13#10, [Integer(me.modBaseAddr), Integer(PChar('')), me.modBaseSize, Integer(@me.szExePath[0])])
else
AddText(hWndEdit, ' %p(%p) %8u %s'#13#10, [Integer(me.modBaseAddr), Integer(pvPreferredBaseAddr), me.modBaseSize, Integer(@me.szExePath)]);
fOk := th.ModuleNext(@me);
end;
// 显示进程所含线程信息
AddText(hWndEdit, #13#10'Thread Information:'#13#10' TID Priority'#13#10, []);
fOk := th.ThreadFirst(@te);
while fOk do
begin
if (te.th32OwnerProcessID = dwProcessID) then
begin
nPriority := te.tpBasePri + te.tpDeltaPri;
if (te.tpBasePri < 16) and (nPriority > 15) then
nPriority := 15;
if (te.tpBasePri > 15) and (nPriority > 31) then
nPriority := 31;
if (te.tpBasePri < 16) and (nPriority < 1) then
nPriority := 1;
if (te.tpBasePri > 15) and (nPriority < 16) then
nPriority := 16;
AddText(hWndEdit, ' %08X %2d'#13#10, [te.th32ThreadID, nPriority]);
end;
fOk := th.ThreadNext(@te);
end;
th.Free;
end;
// 显示指定模块信息
procedure ShowModuleInfo(hWndEdit: hWnd; pszModulePath: PChar);
var
thProcesses, thModules: TToolhelp;
pe: TProcessEntry32;
me: TModuleEntry32;
fpOk, fmOk: BOOL;
begin
pe.dwSize := SizeOf(TProcessEntry32);
me.dwSize := SizeOf(TModuleEntry32);
SetWindowText(hWndEdit, '');
AddText(hWndEdit, 'Pathname: %s'#13#10#13#10, [Integer(pszModulePath)]);
AddText(hWndEdit, 'Process Information:'#13#10, []);
AddText(hWndEdit, ' PID BaseAddr Process'#13#10, []);
// 列出所有使用此模块的进程
thProcesses := TToolhelp.Create(TH32CS_SNAPPROCESS);
fpOk := thProcesses.ProcessFirst(@pe);
while fpOk do
begin
thModules := TToolhelp.Create(TH32CS_SNAPMODULE, pe.th32ProcessID);
fmOk := thModules.ModuleFirst(@me);
while fmOk do
begin
if (lstrcmpi(me.szExePath, pszModulePath) = 0) then
begin
AddText(hWndEdit, ' %08X %p %s'#13#10, [pe.th32ProcessID, Integer(me.modBaseAddr), Integer(@pe.szExeFile[0])]);
end;
fmOk := thModules.ModuleNext(@me);
end;
thModules.Free;
fpOk := thProcesses.ProcessNext(@pe);
end;
thProcesses.Free;
end;
// 对话框WM_INITDIALOG消息处理
function Dlg_OnInitDialog(hWnd, hWndFocus: hWnd; lParam: lParam): BOOL;
begin
// 设置窗体图标
SendMessage(hWnd, WM_SETICON, ICON_BIG, LoadIcon(HInstance, MakeIntResource(IDI_PROCESSINFO)));
SendMessage(hWnd, WM_SETICON, ICON_SMALL, LoadIcon(HInstance, MakeIntResource(IDI_PROCESSINFO)));
// 隐藏ListBox(此控件用来管理模块列表)
ShowWindow(GetDlgItem(hWnd, IDC_MODULEHELP), SW_HIDE);
// 使用等宽字体
SendMessage(GetDlgItem(hWnd, IDC_RESULTS), WM_SETFONT, GetStockObject(ANSI_FIXED_FONT), 0);
// 枚举当前进程
Dlg_PopulateProcessList(hWnd);
// 接受默认焦点
Result := TRUE;
end;
// 对话框WM_SIZE消息处理
function Dlg_OnSize(hWnd: hWnd; state: UINT; cx, cy: Integer): BOOL;
var
Rc: TRect;
n: Integer;
hWndCtl: LongWord; // HWND
begin
n := LOWORD(GetDialogBaseUnits());
hWndCtl := GetDlgItem(hWnd, IDC_PROCESSMODULELIST);
GetClientRect(hWndCtl, Rc);
SetWindowPos(hWndCtl, 0, n, n, cx - n - n, Rc.bottom, SWP_NOZORDER);
hWndCtl := GetDlgItem(hWnd, IDC_RESULTS);
SetWindowPos(hWndCtl, 0, n, n + Rc.bottom + n, cx - n - n, cy - (n + Rc.bottom + n) - n, SWP_NOZORDER);
Result := FALSE;
end;
// 对话框WM_COMMAND消息处理
procedure Dlg_OnCommand(hWnd: hWnd; id: Integer; hWndCtl: hWnd; codeNotify: UINT);
const
{$J+}
s_fProcesses: BOOL = TRUE;
{$J-}
var
dw: DWORD;
szModulePath: array[0..1024] of Char;
si: TStartupInfo;
pi: TProcessInformation;
szCmdLine: array[0..1024] of Char;
hWndCB: LongWord; // HWND
dwProcessId: DWORD;
fOk: BOOL;
begin
case (id) of
IDCANCEL: // 要求关闭
begin
EndDialog(hWnd, id);
end;
ID_PROCESSES: // 枚举进程(菜单)
begin
s_fProcesses := TRUE;
EnableMenuItem(GetMenu(hWnd), ID_VMMAP, MF_BYCOMMAND or MF_ENABLED);
DrawMenuBar(hWnd);
Dlg_PopulateProcessList(hWnd);
end;
ID_MODULES: // 枚举模块(菜单)
begin
s_fProcesses := FALSE;
EnableMenuItem(GetMenu(hWnd), ID_VMMAP, MF_BYCOMMAND or MF_GRAYED);
DrawMenuBar(hWnd);
Dlg_PopulateModuleList(hWnd);
end;
IDC_PROCESSMODULELIST: // ComboBox控件
begin
if (codeNotify = CBN_SELCHANGE) then // 选中项目改变
begin
dw := SendMessage(hWndCtl, CB_GETCURSEL, 0, 0); // 当前选中项目
if (s_fProcesses) then
begin
dw := SendMessage(hWndCtl, CB_GETITEMDATA, dw, 0); // 进程ID
ShowProcessInfo(GetDlgItem(hWnd, IDC_RESULTS), dw);
end
else
begin
dw := SendMessage(hWndCtl, CB_GETITEMDATA, dw, 0); // ListBox编号
SendMessage(GetDlgItem(hWnd, IDC_MODULEHELP), LB_GETTEXT, dw, Integer(@szModulePath[0]));
ShowModuleInfo(GetDlgItem(hWnd, IDC_RESULTS), szModulePath);
end;
end;
end;
ID_VMMAP: // 启动进程
begin
hWndCB := GetDlgItem(hWnd, IDC_PROCESSMODULELIST);
dwProcessId := SendMessage(hWndCB, CB_GETITEMDATA, SendMessage(hWndCB, CB_GETCURSEL, 0, 0), 0);
wvsprintf(szCmdLine, '..\14-VMMap\VMMap.exe %d', [dwProcessId]);
si.cb := SizeOf(TStartupInfo);
fOk := CreateProcess(nil, szCmdLine, nil, nil, FALSE, 0, nil, nil, si, pi);
if (fOk) then
begin
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
end
else
begin
MessageBox(GetActiveWindow(), 'Failed to execute VMMAP.EXE.', 'ProcessInfo', 0);
end;
end;
ID_MWINDOWS:
begin
MessageBox(GetActiveWindow(), 'HelloWorld', 'ProcessInfo', 0);
end;
end;
end;
// 对话框消息处理回调
function Dlg_Proc(hWnd: hWnd; uMsg: UINT; wParam: wParam; lParam: lParam): BOOL; stdcall;
begin
Result := FALSE;
case (uMsg) of
WM_INITDIALOG:
begin
Result := BOOL(SetWindowLong(hWnd, DWL_MSGRESULT, Longint(Dlg_OnInitDialog(hWnd, wParam, lParam))));
end;
WM_SIZE:
begin
Dlg_OnSize(hWnd, wParam, LOWORD(lParam), HIWORD(lParam));
end;
WM_COMMAND:
begin
Dlg_OnCommand(hWnd, LOWORD(wParam), lParam, HIWORD(wParam));
end;
end;
end;
// 程序主线程入口
begin
TToolhelp(nil).EnableDebugPrivilege(TRUE);
DialogBox(HInstance, MakeIntResource(IDD_PROCESSINFO), 0, @Dlg_Proc);
TToolhelp(nil).EnableDebugPrivilege(FALSE);
end.
Toolhelp.pas,
unit Toolhelp;
interface
uses
Windows, TlHelp32;
type
TToolhelp = class(TObject)
private
m_hSnapshot: THandle;
public
constructor Create(dwFlags: DWORD = 0; dwProcessID: DWORD = 0);
destructor Destroy(); override;
function CreateSnapshot(dwFlags: DWORD; dwProcessID: DWORD = 0): BOOL;
function ProcessFirst(ppe: PProcessEntry32): BOOL;
function ProcessNext(ppe: PProcessEntry32): BOOL;
function ProcessFind(dwProcessId: DWORD; ppe: PProcessEntry32): BOOL;
function ModuleFirst(pme: PModuleEntry32): BOOL;
function ModuleNext(pme: PModuleEntry32): BOOL;
function ModuleFind_BaseAddr(pvBaseAddr: Pointer; pme: PModuleEntry32): BOOL;
function ModuleFind_ModName(pszModName: PChar; pme: PModuleEntry32): BOOL;
function ThreadFirst(pte: PThreadEntry32): BOOL;
function ThreadNext(pte: PThreadEntry32): BOOL;
function HeapListFirst(phl: PHeapList32): BOOL;
function HeapListNext(phl: PHeapList32): BOOL;
function HowManyHeaps(): Integer;
function HeapFirst(phe: PHeapEntry32; dwProcessID, dwHeapID: DWORD): BOOL;
function HeapNext(phe: PHeapEntry32): BOOL;
function HowManyBlocksInHeap(dwProcessID, dwHeapId: DWORD): Integer;
function IsAHeap(hProcess: THandle; pvBlock: Pointer; pdwFlags: PDWORD): BOOL;
function EnableDebugPrivilege(fEnable: BOOL = TRUE): BOOL;
function ReadProcessMemory(dwProcessID: DWORD; pvBaseAddress, pvBuffer: Pointer;
cbRead: DWORD; pdwNumberOfBytesRead: PDWORD = nil): BOOL;
end;
implementation
// 构造函数
constructor TToolhelp.Create(dwFlags: DWORD = 0; dwProcessID: DWORD = 0);
begin
m_hSnapshot := INVALID_HANDLE_VALUE;
CreateSnapshot(dwFlags, dwProcessID);
end;
// 析构函数
destructor TToolhelp.Destroy();
begin
if (m_hSnapshot <> INVALID_HANDLE_VALUE) then CloseHandle(m_hSnapshot);
end;
// 建立快照
function TToolhelp.CreateSnapshot(dwFlags: DWORD; dwProcessID: DWORD = 0): BOOL;
begin
if (m_hSnapshot <> INVALID_HANDLE_VALUE) then CloseHandle(m_hSnapshot);
if (dwFlags = 0) then
m_hSnapshot := INVALID_HANDLE_VALUE
else
m_hSnapshot := CreateToolhelp32Snapshot(dwFlags, dwProcessID);
Result := m_hSnapshot <> INVALID_HANDLE_VALUE;
end;
// 进程枚举
function TToolhelp.ProcessFirst(ppe: PProcessEntry32): BOOL;
begin
Result := Process32First(m_hSnapshot, ppe^);
if (Result = TRUE) and (ppe.th32ProcessID = 0) then
Result := ProcessNext(ppe); // Remove the "[System Process]" (PID = 0)
end;
function TToolhelp.ProcessNext(ppe: PProcessEntry32): BOOL;
begin
Result := Process32Next(m_hSnapshot, ppe^);
if (Result = TRUE) and (ppe.th32ProcessID = 0) then
Result := ProcessNext(ppe); // Remove the "[System Process]" (PID = 0)
end;
function TToolhelp.ProcessFind(dwProcessId: DWORD; ppe: PProcessEntry32): BOOL;
begin
Result := ProcessFirst(ppe);
while Result do
begin
if (ppe.th32ProcessID = dwProcessId) then Break;
Result := ProcessNext(ppe);
end;
end;
// 模块枚举
function TToolhelp.ModuleFirst(pme: PModuleEntry32): BOOL;
begin
Result := Module32First(m_hSnapshot, pme^);
end;
function TToolhelp.ModuleNext(pme: PModuleEntry32): BOOL;
begin
Result := Module32Next(m_hSnapshot, pme^);
end;
function TToolhelp.ModuleFind_BaseAddr(pvBaseAddr: Pointer; pme: PModuleEntry32): BOOL;
begin
Result := ModuleFirst(pme);
while Result do
begin
if (pme.modBaseAddr = pvBaseAddr) then Break;
Result := ModuleNext(pme);
end;
end;
function TToolhelp.ModuleFind_ModName(pszModName: PChar; pme: PModuleEntry32): BOOL;
begin
Result := ModuleFirst(pme);
while Result do
begin
if (lstrcmpi(pme.szModule, pszModName) = 0) or
(lstrcmpi(pme.szExePath, pszModName) = 0) then Break;
Result := ModuleNext(pme);
end;
end;
// 线程枚举
function TToolhelp.ThreadFirst(pte: PThreadEntry32): BOOL;
begin
Result := Thread32First(m_hSnapshot, pte^);
end;
function TToolhelp.ThreadNext(pte: PThreadEntry32): BOOL;
begin
Result := Thread32Next(m_hSnapshot, pte^);
end;
// 内存枚举
function TToolhelp.HowManyHeaps(): Integer;
var
hl: THeapList32;
fOk: BOOL;
begin
Result := 0;
hl.dwSize := SizeOf(THeapList32);
fOk := HeapListFirst(@hl);
while fOK do
begin
Inc(Result);
fOk := HeapListNext(@hl);
end;
end;
function TToolhelp.HowManyBlocksInHeap(dwProcessID, dwHeapId: DWORD): Integer;
var
he: THeapEntry32;
fOK: BOOL;
begin
Result := 0;
he.dwSize := SizeOf(he);
fOk := HeapFirst(@he, dwProcessID, dwHeapID);
while fOK do
begin
Inc(Result);
fOk := HeapNext(@he);
end;
end;
function TToolhelp.HeapListFirst(phl: PHeapList32): BOOL;
begin
Result := Heap32ListFirst(m_hSnapshot, phl^);
end;
function TToolhelp.HeapListNext(phl: PHeapList32): BOOL;
begin
Result := Heap32ListNext(m_hSnapshot, phl^);
end;
function TToolhelp.HeapFirst(phe: PHeapEntry32; dwProcessID, dwHeapID: DWORD): BOOL;
begin
Result := Heap32First(phe^, dwProcessID, dwHeapID);
end;
function TToolhelp.HeapNext(phe: PHeapEntry32): BOOL;
begin
Result := Heap32Next(phe^);
end;
function TToolhelp.IsAHeap(hProcess: THandle; pvBlock: Pointer; pdwFlags: PDWORD): BOOL;
var
hl: THeapList32;
he: THeapEntry32;
mbi: TMemoryBasicInformation;
fOkHL, fOkHE: BOOL;
begin
Result := FALSE;
hl.dwSize := SizeOf(THeapList32);
he.dwSize := SizeOf(THeapEntry32);
fOkHL := HeapListFirst(@hl);
while fOkHL do
begin
fOkHE := HeapFirst(@he, hl.th32ProcessID, hl.th32HeapID);
while fOkHE do
begin
VirtualQueryEx(hProcess, Pointer(he.dwAddress), mbi, SizeOf(TMemoryBasicInformation));
if (DWORD(mbi.AllocationBase) <= DWORD(pvBlock)) and
(DWORD(pvBlock) <= DWORD(mbi.AllocationBase) + mbi.RegionSize) then
begin
pdwFlags^ := hl.dwFlags;
Result := TRUE;
Exit;
end;
fOkHE := HeapNext(@he);
end;
fOkHL := HeapListNext(@hl);
end;
end;
// 提升权限
function TToolhelp.EnableDebugPrivilege(fEnable: BOOL = TRUE): BOOL;
const
SE_DEBUG_NAME: PChar = 'SeDebugPrivilege';
var
hToken: THandle;
tp: TTokenPrivileges;
begin
Result := FALSE;
if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken) then
begin
tp.PrivilegeCount := 1;
LookupPrivilegeValue(nil, SE_DEBUG_NAME, tp.Privileges[0].Luid);
if fEnable then
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
tp.Privileges[0].Attributes := 0;
AdjustTokenPrivileges(hToken, FALSE, tp, SizeOf(TTokenPrivileges), nil, PDWORD(nil)^);
Result := (GetLastError() = ERROR_SUCCESS);
CloseHandle(hToken);
end;
end;
// 内存读取
function TToolhelp.ReadProcessMemory(dwProcessID: DWORD; pvBaseAddress, pvBuffer: Pointer;
cbRead: DWORD; pdwNumberOfBytesRead: PDWORD = nil): BOOL;
begin
Result := Toolhelp32ReadProcessMemory(dwProcessID, pvBaseAddress, pvBuffer^, cbRead, pdwNumberOfBytesRead^);
end;
end.