发表贴子前,其实是想发一些论坛没有的内容的源代码的,比如检查系统字体(大量没有公开的API和结构体),或光驱设备等,但这些功能单独再抽出来,代码很多,很麻烦,所以最后只能选择一些简单的,分享出来目的,节省大家重复分析的时间。比如以前为了实现检测光驱序列号等,没有找到相关资料,就花了成个月时间才慢慢折腾出来。
WIN 7“任务管理器”的“结束任务”菜单的实现,其实也是简单的结束进程,只是多加检测是否是核心进程,
并检测是否为16位程序?(可能是16 位任务的任务编号),并当前系统是否32位的,如果是的,用相关API(VDMTerminateTaskWOW)。
如果是64位的系统,当前要结束的进程是16位的,直接返回 ERROR_INVALID_PARAMETER。
“任务管理器”内部是查询自已保存的自定义结构的进程信息数组。所以结束进程,他也不用实时查询进程信息。都是查询他保存的数组指针。
“任务管理器”内部结束进程等操作,都有一个参数: CreateTime : LONGLONG, 通过对比这个时间来区分相同PID的不同进程。
MyQuerySystemInformation 是 ntQuerySystemInformation 调用,我们为了单独实现出来,简单一些,我直接查询进程信息
function MyKillAllChildrenProcess(const dwTaskPid, dwProcessId : DWORD; const pSystemProcesses : PSYSTEM_PROCESS_INFORMATION; LCreateTime : LONGLONG; var StrError : WideString) : Boolean;
var
dwQueryProcessIsEnd, dwNewProcessId : DWORD;
newCreateTime : LONGLONG;
pSystemProcesses2 : PSYSTEM_PROCESS_INFORMATION;
begin
Result:=False;
pSystemProcesses2:=pSystemProcesses;
dwQueryProcessIsEnd:=1; // 因为0后面还有一个进程
while (dwQueryProcessIsEnd > 0) do
begin
with pSystemProcesses2^ do
begin
// 父 PID 等于要结束的进程 ID
if (InheritedFromUniqueProcessId = dwProcessId) and (UniqueProcessId <> dwProcessId) and (LCreateTime < CreateTime.QuadPart) then
begin
dwNewProcessId:=UniqueProcessId;
newCreateTime:=CreateTime.QuadPart;
MyKillAllChildrenProcess(dwTaskPid, dwNewProcessId, pSystemProcesses, newCreateTime, StrError);
if (dwNewProcessId <> dwTaskPid) then
begin
Result:=MyTerminateProcessEx(dwNewProcessId, StrError);
MyAddDebugInfo('结束进程树,子进程 PID:' + IntToStr(dwNewProcessId) + ',操作:' + C_FailOrSuccess[Result]);
end;
end;
if (NextEntryOffset > 0) then
begin
Inc(ULONG(pSystemProcesses2), NextEntryOffset);
end else Dec(dwQueryProcessIsEnd); // 因为0后面还有一个进程
[培训]科锐逆向工程师培训第53期2025年7月8日开班!
最后于 2025-2-18 12:22
被kagayaki编辑
,原因: