“进程监控器”小工具的编写(包含整个项目源码)

“进程监控器”小工具的编写(包含整个项目源码)

一.思路

         1.1【起因】:写的采集驱动在测试的时候发现,由于频繁通讯、数据量有些大,所以偶尔驱动会死掉,造成一段时间数据没采集到。所以打算写一个“进程监控器”,定时扫描驱动的情况,如果驱动没有运行则让驱动运行。

         1.2【思路】:先从配置文件读取需要监控程序的信息,进程监控器运行时定时扫描驱动的情况,如果驱动没有运行则让驱动运行。

         进程监控器写好后运行起来并拖到服务器的开机启动中,这样以后就可以避免驱动死掉,而数据没有采集了。

二.知识点讲解

 

         2.1【知识点】:1.INI文件数据的读取;

                               2.用一个Timer组件,利用进程快照遍历被监控的进程是否运行,没有的话,运行进程;

         2.2【知识点讲解】

2.2.1   delphi中如何让主窗体在程序运行之初不显示

无法实现的操作:

1oncreate事件中设置visible属性或调用hide方法

2onshow事件中设置visible属性或调用hide方法

3、对象观察器中设置visible属性

即设置主窗体的事件或属性都不能实现功能。

 

可实现的操作:

procedure TForm1.FormCreate(Sender: TObject);

begin

Application.ShowMainForm:=False; //放在工程里也可以

end;

 

2.2.2   利用进程快照查找进程

         从配置文件中智能读到进程的名称,需要查找它的运行情况,利用API函数CreateToolhelp32Snapshot(),建立进程快照,再用Process32First()Process32Next()遍历,找到进程。

        

//名称:FindProcessFromName

//功能:用进程名称找到进程ID

//参数:可执行文件名称

//返回:若该可执行文件在运行,返回进程ID

//       若该可执行文件没有运行则返回0

function TForm1.FindProcessFromName(name: string ): DWORD;//name为你要终止的进程的名称,Win9X则需包括路径

var

  pe : TPROCESSENTRY32;//定义一个PROCESSENTRY32结类型的变量

  hShot : THANDLE;

  ProcessID : DWORD;

begin

  ProcessID := 0;

  Result := ProcessID;

  hShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);// 创建快照句柄

  pe.dwSize := sizeof(TPROCESSENTRY32);//一定要先为dwSize赋值

  if (Process32First(hShot,pe)) then

  begin

    repeat

      if pe.szExeFile = name then //判断此进程是否为你要终止的进程

      begin

        ProcessID   :=   pe.th32ProcessID;

        Result := ProcessID;

        Break;

      end;

    until(not(Process32Next(hShot, pe)));

  end;

  CloseHandle(hShot);           //最后别忘记Close

end;

 

2.2.3   运行进程

         有三个API函数可以运行可执行文件WinExecShellExecuteCreateProcess

(1).CreateProcess因为使用复杂,比较少用。

(2).WinExec主要运行EXE文件。如:WinExec(Notepad.exe Readme.txt, SW_SHOW); (3).ShellExecute不仅可以运行EXE文件,也可以运行已经关联的文件。

我们这里用WinExecShellExecute都可以:

WinExec(PAnsiChar(ProcessInfo[i].PrcoessPath), SW_RESTORE);      //WinExec也可以实现

  ShellExecute(0,'Open', PAnsiChar(ProcessInfo[i].PrcoessPath), nil, nil, SW_RESTORE);

 

三.源码

         3.1INI文件】

文件内容如下:

[监视进程配置]

扫描周期()=10

进程数量=2

程序运行周期(分钟)1=0

进程名称1=串口调试助手V2.2.exe

程序运行路径1=D:\串口调试助手V2.2.exe

程序运行周期(分钟)2=0

进程名称2=sscom32.exe

程序运行路径2=D:\sscom32.exe

 

         3.2【数据定义】

新建CustomDef.pas来定义数据类型。

 

unit CustomDef;

 

interface

 

type TProjectInfo= record

  ProcessNum: integer;                //进程数量

  Monitorcycle: integer;              //扫描周期()

end;

 

 

type TProcessInfo= record

  IsUse : Boolean;

  ProcessCycle : integer;            //程序运行周期(分钟)

  ProcessName : string;         //进程名称

  PrcoessPath : string;         //程序运行路径

end;

 

implementation

 

end.

 

         3.3【窗口界面】

         3.4Delphi源码】

unit Main;

 

interface

 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, CustomDef, ExtCtrls,

  tlhelp32,

  shellapi;

 

type

  TForm1 = class(TForm)

    tmr1: TTimer;

    procedure FormCreate(Sender: TObject);

    procedure GetInitPara(Filename: string);

    procedure tmr1Timer(Sender: TObject);

  private

    { Private declarations }

    function FindProcessFromName(name: string ): DWORD;

  public

    { Public declarations }

    ProDirPath: string;

    ProjectInfo: TProjectInfo;

    ProcessInfo: array of TProcessInfo;

  end;

 

var

  Form1: TForm1;

 

implementation

 

{$R *.dfm}

 

uses IniFiles;

 

procedure TForm1.FormCreate(Sender: TObject);

begin

  GetInitPara('Monitor.ini');

 

  tmr1Timer(nil);

 

  tmr1.Interval := ProjectInfo.Monitorcycle * 1000;

  tmr1.Enabled := True;

 

  Application.ShowMainForm := False;

end;

 

//名称:GetInitPara

//功能:获取系统初始化参数函数

//参数:Filename 配置文件名称

//返回:无

procedure TForm1.GetInitPara(Filename: string);

var

  IniFile:TInifile;

  i: integer;

  tempProcessCycle,tempProcessName,tempPrcoessPath: string;

begin

  ProDirPath:=ExtractFilePath(Application.ExeName);

  if FileExists(ProDirPath + Filename) then

  begin

    IniFile:=TiniFile.Create(ProDirPath+Filename);              //IniFile全路径

 

    ProjectInfo.ProcessNum:=IniFile.ReadInteger('监视进程配置','进程数量',0);

    ProjectInfo.Monitorcycle:=IniFile.ReadInteger('监视进程配置','扫描周期()',10);

 

    SetLength(ProcessInfo, ProjectInfo.ProcessNum);

 

    for I := 0 to ProjectInfo.ProcessNum - 1 do

    begin

      tempProcessCycle:='程序运行周期(分钟)' + InttoStr(i+1);

      tempProcessName:='进程名称' + InttoStr(i+1);

      tempPrcoessPath:='程序运行路径' + InttoStr(i+1);

 

      ProcessInfo[i].ProcessCycle := IniFile.ReadInteger('监视进程配置',tempProcessCycle,0);

      ProcessInfo[i].ProcessName := IniFile.ReadString('监视进程配置',tempProcessName,'');

      ProcessInfo[i].PrcoessPath := IniFile.ReadString('监视进程配置',tempPrcoessPath,'');

 

      if (ProcessInfo[i].ProcessName<>'') and (ProcessInfo[i].PrcoessPath<>'') then

        ProcessInfo[i].IsUse := True;

    end;

    IniFile.Free;

  end

  else

  begin

    showmessage('[报错:]"'+ProDirPath+'"路径下找不到文件"'+Filename+'",程序无法初始化!');

    Exit;

  end;

end;

 

//功能:定时器1定时响应

procedure TForm1.tmr1Timer(Sender: TObject);

var

  i: integer;

  ProID: DWORD;

begin

  GetInitPara('Monitor.ini');

  tmr1.Enabled := False;

  tmr1.Interval := ProjectInfo.Monitorcycle * 1000;

  tmr1.Enabled := True;

 

  for I := 0 to ProjectInfo.ProcessNum - 1 do

  begin

    ProID := FindProcessFromName(ProcessInfo[i].ProcessName);

    if ProID=0 then

    begin

//      WinExec(PAnsiChar(ProcessInfo[i].PrcoessPath), SW_RESTORE);      //WinExec也可以实现

      ShellExecute(0,'Open', PAnsiChar(ProcessInfo[i].PrcoessPath), nil, nil, SW_RESTORE);

    end;

  end;

end;

 

//名称:FindProcessFromName

//功能:用进程名称找到进程ID

//参数:可执行文件名称

//返回:若该可执行文件在运行,返回进程ID

//       若该可执行文件没有运行则返回0

function TForm1.FindProcessFromName(name: string ): DWORD;//name为你要终止的进程的名称,Win9X则需包括路径

var

  pe : TPROCESSENTRY32;//定义一个PROCESSENTRY32结类型的变量

  hShot : THANDLE;

  ProcessID : DWORD;

begin

  ProcessID := 0;

  Result := ProcessID;

  hShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);// 创建快照句柄

  pe.dwSize := sizeof(TPROCESSENTRY32);//一定要先为dwSize赋值

  if (Process32First(hShot,pe)) then

  begin

    repeat

      if pe.szExeFile = name then //判断此进程是否为你要终止的进程

      begin

        ProcessID   :=   pe.th32ProcessID;

        Result := ProcessID;

        Break;

      end;

    until(not(Process32Next(hShot, pe)));

  end;

  CloseHandle(hShot);           //最后别忘记Close

end;

 

end.

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一:SSDT表的hook检测和恢复 ~!~~~ 二:IDT表的hook检测和恢复 ~~~~~~(idt多处理器的恢复没处理,自己机器是单核的,没得搞,不过多核的列举可以) 三:系统加载驱动模块的检测 通过使用一个全局hash表(以DRIVEROBJECT为对象)来使用以下的方法来存储得到的结果,最终显示出来 1.常规的ZwQuerySystemInformation来列举 2通过打开驱动对象目录来列举 3搜索内核空间匹配驱动的特征来列举(这个功能里面我自己的主机一运行就死机,别的机器都没事,手动设置热键来蓝屏都不行,没dump没法分析,哎,郁闷) 4从本驱动的Modulelist开始遍历来列举驱动 四:进程的列举和进程所加载的dll检测 采用以下方法来列举进程: 1ZwQuerySystemInformation参数SystemProcessesAndThreadsInformation来枚举 2进程EPROCESS 结构的Activelist遍历来枚举 3通过解析句柄表来枚举进程 4通过Handletablelisthead枚举进程 5进程创建时都会向csrss来注册,从这个进程里面句柄表来枚举进程 6通过自身进程的HANDLETABLE来枚举进程 7通过EPROCESS的SessionProcessLinks来枚举进程 8通过EPROCESS ---VM---WorkingSetExpansionLinks获取进程 9暴力搜索内存MmSystemRangeStart以上查找PROCESS对象 进程操作: 进程的唤醒和暂停通过获取PsSuspendProcess和PsResumeProcess来操作的 进程结束通过进程空间清0和插入apc。 采用以下方法查找DLL: 1遍历VAD来查找dll 2挂靠到对应的进程查找InLoadOrderLinks来枚举dll 3暴力搜索对应进程空间查找pe特征来枚举dll DLL的操作: Dll的卸载是通过MmUnmapViewOfSection和MmmapViewOfSection(从sdt表中相应函数搜索到的)来实现的(本来想直接清0 dll空间,有时行有时不行)(只要将这个进程的ntdll卸载了,进程就结束了,一个好的杀进程的办法撒,绿色环保无污染),注入dll使用的是插入apc实现的。(注入的dll必须是realse版的。Debug版会出现***错误,全局dll注入貌似也是)插入apc效果不是很好,要有线程有告警状态才执行。 五:线程信息的检测 遍历ThreadList来枚举线程 线程的暂停和唤醒都是通过反汇编获取PsResumeThread和PsSuspendThread直接从r3传来ETHREAD来操作的,通过插入APC来结束线程 六:shadow sdt表的hook检测与恢复 没有采用pdb来解决函数名问题,直接写入xp和03的shandow表函数名(主要是自己的网不稳定,连windbg有时都连不上微软) 七:系统所有的过滤驱动的检测 查看各device下是否挂接有驱动之类的,可直接卸载 八:系统常用回调历程的检测和清除 只检查了PsSetLoadImageNotifyRoutine PsSetCreateThreadNotifyRoutine PsSetCreateProcessNotifyRoutine CmRegisterCallback这几个,至于那个什么shutdown回调不知道是啥玩意,就没搞了,有知道的顺便告诉我下撒,谢谢 九:文件系统fat和ntfs的分发函数检测 直接反汇编fat和ntfs的DriverEntry得到对应的填充分发的偏移,然后和当前已经运行的文件系统的分发相比是否被hook,并附带恢复 十:文件查看功能 自己解析ntfs和fat的结构,来实现列举文件和直接写磁盘删除。附带有普通的删除和发生IRP来删除。不过这里面有点问题,ntfs删除有时把目录给搞坏了,大家凑合着吧, Ntfs网上删除这些操作的代码不多,就是sudami大大的利用ntfs-3g来实现的,看了下,太多了,充满了结构。然后自己对照着系统删除文件时目录的变化来自己实现的。只处理了$BITMAP对应的位清除,父目录的对应文件的索引项的覆盖,删除文件对应的filerecord清0. 另外偷懒时间都没处理,呵呵,y的,一个破时间都都搞好几个字节移来移去的。 十一:常用内核模块钩子的检测和恢复 这里只检测了主要的内核模块nkrnlpa**.exe的.win32k.sys,hal.dll,比对它们的原始文件从而查找eat inline hook,iat hook ,和inline hook。Inline是从TEXT段开始一段位置开始比较的。(有点慢貌似,等待显示扫描完成就好了) 十二:应用层进程所加载dll的钩子 应用层钩子检测和内核模块钩子检测原理一样,不过为了能读写别的进程的空间,并没有使用openprocess去打开进程,而是通过KiattachProcess挂靠到当前进程,然后通过在r0直接读写进程空间的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值