知识大全 Delphi深度探索之外壳执行操作记录器

Posted 函数

篇首语:学习知识要善于思考,思考,再思。我就是靠这个方法成为科学家的。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Delphi深度探索之外壳执行操作记录器相关的知识,希望对你有一定的参考价值。

Delphi深度探索之外壳执行操作记录器  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

记录外壳的活动

  记录外壳活动有很多好处 比如当需要监控用户的行为 回溯系统崩溃前的过程 实现这一功能的关键工具相当简单 它就是接口IShellExecuteHook 编写一个实现了这一接口的对象后 再在系统中注册 就可以容易地控制并影响Windows外壳的运行 Windows 和Windows 都支持IShellExecuteHook外壳扩展 而在Windows 和Windows NT 上则必须安装活动桌面扩展后才支持(也就是说必须安装IE )

  一个实现了IShellExecuteHook接口的对象可以截获所有对ShellExecute和ShellExecuteEx函数的调用 ShellExecute和ShellExecuteEx函数主要用于执行应用程序 它们可以接收一个文件名并能自动获得同文件名相关的可执行文件名 此外 它们还支持系统安全认证 如果在NT上设定了用户的可执行权限 ShellExecute和ShellExecuteEx函数将会在创建新的进程前检查权限(CreateProcess和WinExec函数则没有这项功能) 函数调用的流程如下

  ( )获得将要运行的可执行文件名

  ( )根据程序名检查用户执行权限

  ( )激活全部已注册的IshellExecuteHook扩展

  ( )当所有扩展和权限都同意执行 创建新的进程并返回

  Windows外壳大量调用ShellExecute和ShellExecuteEx函数来执行几乎是所有的资源管理器的操作 比如双击目录 浏览文件夹内容 打印编辑文档 查看文件属性 选择文档的上下文相关菜单等等 此外 开始菜单的运行对话框和DOS方式下的Start exe也使用ShellExecuteEx函数来执行程序 简单地说几乎用户的所有外壳操作都可以被扩展截获 包括其他应用程序对ShellExecute和ShellExecteEx的调用

编写外壳活动记录器

  首先需要创建一个进程内对象 选菜单命令New | ActiveX Library 然后点击菜单New|Com Object 创建对象框架 按图 填充对话框的内容 然后点击OK按钮 Delphi就会自动生成框架文件 并保存生成的文件

  IShellExecuteHook的接口定义在shlobj pas单元中 添加shlobj到单元uses部分 然后添加IShellExecuteHooko方法原型到对象声明部分 声明部分代码如下

unit ShellExecuteHookObj;

interface

uses

Windows ActiveX ComObj ShlObj ShellAPI;

type

TTShellExecuteHook = class (TComObject IShellExecuteHook)

protected

function Execute(var ShellExecuteInfo: TShellExecuteInfo): HResult; stdcall;

end;

const

Class_TShellExecuteHook: TGUID = FA D D B E B AE BE ;

  下面就是用来截获并记录外壳操作的实现部分 一旦外壳扩展被注册后 每次ShellExecute 和ShellExecuteEx函数运行时都会调用对象的Execute函数 我们的核心代码就是通过Execute方法实现的 方法定义如下

function TTShellExecuteHook Execute(var ShellExecuteInfo: TShellExecuteInfo): HResult;

  Execute方法会从外壳获得一个类型为TshellExecuteInfo的参数 参数定义如下

_SHELLEXECUTEINFOA = record

cbSize: DWORD;

fMask: ULONG;

Wnd: HWND;

lpVerb: PAnsiChar;

lpFile: PAnsiChar;

lpParameters: PAnsiChar;

lpDirectory: PAnsiChar;

nShow: Integer;

hInstApp: HINST;

Optional fields

lpIDList: Pointer;

lpClass: PAnsiChar;

eyClass: HKEY;

dwHotKey: DWORD;

hIcon: THandle;

hProcess: THandle;

end;

  这个记录结构中的lpFile包含了要运行的文件名 而lpVerb则表明执行的动作 动作由一些标准的字符串代表 比如 open(打开) print(打印) edit(编辑) explore(浏览) properties(属性) find(查找)和其他上下文菜单的命令名 有时 lpFile并不包含可执行文件名 这是因为ShellExecute接到的运行参数是一个文档名 比如当我们在资源管理器中双击文本文件时 Windows用文本文件名作为参数调用ShellExecute函数 而ShellExecute函数则获得同文本文件相关联的可执行文件名 然后执行

  TShellExecuteInfo结构中还记录了要运行程序的很多信息 然而这里我们只能在Execute方法中修改nCmdShow参数 nCmdShow参数定义了窗口在运行后的显示状态 包括最大化 最小化 正常等选项 对于其他参数的修改都会被外壳忽略 除此之外 在Execute方法中可以根据情况允许外壳继续缺省的任务或通知外壳取消执行 这可以通过Execute函数的返回值来实现

  如果Execute的返回值为S_FALSE 外壳就继续缺省的任务 如果返回S_OK 则外壳认为扩展已经成功 就不再继续执行了 另外如果返回一个错误代码或系统无法识别的值 则外壳会弹出错误信息 这给了我们一个控制程序运行的机会 比如可以限制任何对记事本的调用 代码如下

function TTShellExecuteHook Execute(var ShellExecuteInfo: TShellExecuteInfo): HResult;

var

FileName: String;

begin

Result := S_FALSE;

with ShellExecuteInfo do

begin

FileName := UpperCase(ExtractFileName(lpFile));

if Pos( NOTEPAD FileName) = then

begin

Result := S_OK;

hInstApp := ;

MessageBox(Wnd 不允许记事本运行! 错误 MB_OK or MB_ICONERROR);

end;

end;

end;

  进一步 我们甚至可以利用这点实现一个自定义的安全认证机制 根据用户要求限制运行的程序 有兴趣的朋友可以试验一下 一定很有意思

  有一点要注意的是 在Execute方法下不能调用ShellExecute和ShellExecuteEx函数外部程序 如果是这样的话 我们的Execute方法又会被新的ShellExecute调用 这样系统就会进入死循环 如果我们确实想在Execute方法中调用外部程序的话 可以使用CreateProcess或WinExec函数来替代 这两个函数不会被ShellExecuteHook截获

  对于外壳动作记录器来说 只要在Execute方法中记录程序信息到日志文件中就可以了 代码非常简单 因为所有需要的信息都在TShellExecuteInfo记录中包含了 这里只记录运行的动作 文件名和时间 需要记录其他信息的话 大家可自行修改 代码示意如下

function TTShellExecuteHook Execute(var ShellExecuteInfo: TShellExecuteInfo): HResult;

var

FileStream: TFileStream;

a:TStringList;

S:string;

begin

Result := S_FALSE;

with ShellExecuteInfo do

begin

FileStream:=TFileStream Create( c:\\shellexecutehook txt fmopenwrite);

S:=string(lpVerb)+ : +string(lpFile)+DateTimeToStr(Now)+# # ;

FileStream Seek(FileStream Size soFromBeginning);

FileStream Write(PChar(S)^ Length(S));

FileStream Free;

end;

end;

注册ShellExecuteHook

  要想使对象被外壳加载 需要在注册表中注册一些信息 在下面这个子键中添加类的GUID及描述字符串后就可以了(描述字符串可以不赋值 但不妨给一个以便于识别)

HKEY_LOCAL_MACHINE

SOFARE

Microsoft

Windows

CurrentVersion

Explorer

ShellExecuteHooks

CLSID= 描述字符串

  修改注册表可以通过重载的类工厂的UpdateRegistry方法来实现 代码示意如下

implementation

uses ComServ SysUtils;

resourcestring

sCreateRegKeyError = 创建注册表项失败 ;

type

TShellExComObjectFactory = class(TComObjectFactory)

public

procedure UpdateRegistry(Register: Boolean); override;

end;

TShellExComObjectFactory

procedure TShellExComObjectFactory UpdateRegistry(Register: Boolean);

const

hellExecuteHooksKey= SOFARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellExecuteHooks ;

var

Handle: HKey;

Status Disposition: Integer;

ClassID: String;

begin

ClassID := GUIDToString(Class_TShellExecuteHook);

if Register then

begin

Status := RegCreateKeyEx(HKEY_LOCAL_MACHINE PChar(ShellExecuteHooksKey) REG_OPTION_NON_VOLATILE KEY_READ or KEY_WRITE nil Handle @Disposition);

if Status = then

begin

Status := RegSetValueEx(Handle PChar(ClassID) REG_SZ

PChar(Description) Length(Description) + );

RegCloseKey(Handle);

end;

end else

begin

Status := RegOpenKeyEx(HKEY_LOCAL_MACHINE PChar(ShellExecuteHooksKey)

KEY_READ or KEY_WRITE Handle);

if Status = then

begin

Status := RegDeleteValue(Handle PChar(ClassID));

RegCloseKey(Handle);

end;

end;

if Status <> then raise EOleError Create(sCreateRegKeyError);

inherited UpdateRegistry(Register);

end;

initialization

TShellExComObjectFactory Create(ComServer TTShellExecuteHook Class_TShellExecuteHook TShellExecuteHook ShellExecute hook sample ciMultiInstance tmApartment);

end   如果系统中有多个ShellExecuteHook的话 外壳会按照ShellExecuteHook的安装顺序进行调用 如果要想使某个外壳扩展优先运行 可先删除其他扩展然后添加优先扩展 原来的扩展依次放在后面 不过这样做也可能意义不大 因为别人也会这么干 最后 程序运行的结果

  记住ShellExecuteHook并不是一个完善的用于监视系统运行的扩展 它只能监视ShellExecute和ShellExecuteEx的运行 它不能保证记录系统所有的行为 特别是很多情况下外壳并不使用ShellExecute来进行一些常用的操作 比如我们在资源管理器中选择一个文件 然后调用右键菜单的属性命令后 记录器没有记录这个动作 但如果直接调用ShellExecute(如下示)的话 ShellExecuteHook却会正确执行

ShellExecute(nil properties foo txt nil nil SW_SHOW);

cha138/Article/program/Delphi/201311/24787

相关参考

知识大全 Delphi深度探索之PItemIDList的基本概念

Delphi深度探索之PItemIDList的基本概念  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧

知识大全 Delphi深度探索之使用Bold开发数据库应用(1)

Delphi深度探索之使用Bold开发数据库应用(1)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧

知识大全 Delphi深度探索之使用Bold开发数据库应用(2)

Delphi深度探索之使用Bold开发数据库应用(2)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧

知识大全 Delphi深度探索之使用Bold开发数据库应用(3)

Delphi深度探索之使用Bold开发数据库应用(3)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧

知识大全 Delphi深度探索-CodeSite应用指南

Delphi深度探索-CodeSite应用指南  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  D

知识大全 Delphi深度探索-数据库明了的ActiveX控件

Delphi深度探索-数据库明了的ActiveX控件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

操作和执行单元的操作器校准项目与技术标准有哪些?

操作和执行单元的操作器校准项目与技术标准有哪些?参考答案:1、输出电流表示值误差校准(1)在全量程范围内,输入信号以量程的20%,依次递增至各校准点,然后再依次递减至各校准点,记录各校准点上操作器对应

操作和执行单元的操作器校准项目与技术标准有哪些?

操作和执行单元的操作器校准项目与技术标准有哪些?参考答案:1、输出电流表示值误差校准(1)在全量程范围内,输入信号以量程的20%,依次递增至各校准点,然后再依次递减至各校准点,记录各校准点上操作器对应

知识大全 数据结构之算法和算法分析[4]

  一个算法是由控制结构和原操作构成的其执行时间取决于两者的综合效果为了便于比较同一问题的不同的算法通常的做法是从算法中选取一种对于所研究的问题来说是基本运算的原操作以该原操作重复执行的次数作为算法的

垃圾渗滤液生物处理

摘要:采用“混凝-电解氧化-完全混合式活性污泥法(CSTR)”组合工艺深度处理垃圾渗滤液生物处理出水。探索了工艺的组合及各种工艺操作条件对垃圾渗滤液深度处理效果的影响,并对其影响机理进行了初步探讨。结