摘要:对Adobe产品的一些函数进行拦截,来对命令参数进行过滤,帮助企业建立信息安全机制
保证:本人保证绝不用于非法目的
1. Adobe Acrobat PEP
1.1 窗口 Merge Data Files into Spreadsheet中非法文件路径拦截
任务:Tools ->Forms->More Form Options ->Merge Data Files into Spreadsheet窗口
要求:Export按钮点击后,取得SysTreeView32控件上的所有节点以及其的path,如果path中包含受保护的文件则abort本次操作
1.1.1 逆向分析角度
做法:
Wind Class: #32770 一个标准模态对话框,
从winproc找办法:但是直接挂钩其Windproc不是一个好办法,要想办法把挂钩至于Export按钮的点击处。从栈上回调发现了
CallWindowProc:The CallWindowProc function passes message information to the specified window procedure.
Acrobat.dll会调用这个函数把消息给指定的窗口过程,hook这个函数,当消息为WM_LBUTTONDOWN时看看,WinUser.h中定义的WM_LBUTTONDOWN数据
以后的方法:找到窗口的过程 直接挂 命令
解决:
代码在Acrobat_dll中 只要找到这个点就好办了。 故意找一个存在的文件 让其MsgBox 文件已经存在是否覆盖。
1. 加入新节点 会调用 _wsplitpath 对节点进行分析 这里可以想办法找到每个有效节点的地址
最终找到了两个关键点:
6D3FFBBF | after calling,Eax is Path Name |
6D3FFBD4 | use eax to perform tasks |
应该对 这两个地址处的函数调用 进行仔细分析,找到真正的取点地方。
但是由于时间关系,基本上任务已经解决,凡是调用6D3FFBD4的地方进行拦截判断,如果路径非法,取消其的载入,但实际上这么做并不完美,因为如果客户多选文件的话,只要有一个文件被ban了,那整个这次任务都失败
2.关键知识点回顾:
2.1如何找到子窗口的WindProc。
关键函数是CallWindowsProc() adobe中的窗口已经被子类化了,break this function 然后看看 export的具体窗口过程是多少,仅此而已。
下条件断点,WM_LBUTTONUP 这个
虽然其树形控件上 只有节点没有其他信息,但是 断 _wsplitpath()可以帮助用来快速定位节点被处理的地方。
可以通过监控树型控件的消息, 挂 SendMessage 条件断 TreeView_DeleteItem,然后在栈上回溯也可以找到任务。
3.是不是我把问题想复杂了?
那对话框明显是一个open or save as 这里应该有标准函数 如 GetOpenFileName; 但是adobe好像完成了对其对话框的子类化,所以这里没有挂到
当Dlg关闭前,功能已经做完。
学习:
DialogBoxParam:TheDialogBoxParam function creates a modal dialog box from a dialog box template resource
1.1.2 Adobe Acrobat插件角度
1.1.1中逆向分析汇编代码 然后hook一个内部函数估计不够稳定,所以打算从标准插件角度进行处理。
keywords:
PluginUnload
Handshake:PIHandshake
HTF(Host Function Table): 一种机制 使插件可以调用其他插件提供的方法
Importing HTF
PluginInit procedure:
插件调用:
ASCallbackCreateProto: 定义回调函数
ASCallbackCreateReplacement,
ASCallbackCreateNotification
callbacks的调用方式 必须是:Pascal calling convention, 使用ACCB1 ACCB2宏
Notifications: 让plug-in指名他对那么指定的事件感兴趣
Handling events:处理不同事件
插件编写:
1.PIMain.c永不变
2.NextlabsInit.c实现基本业务逻辑框架:
PluginExportHFTs
PluginImportReplaceAndRegister
PluginInit
PluginUnload
GetExtensionName
PIHandshake
PluginImportReplaceAndRegister
PluginInit
PluginUnload
GetExtensionName
PIHandshake
3.在PluginInit中定义回调函数通过ASCallbaceCreateProto
在PluginUnLoad中调用ASCallbackDestory() 来清除具体的注册callback
4.注册制定事件的通告
在
PluginInit 中可以注册事件通知:见:Registering for Event Notificaitons
具体办法:
在AVAPP中找到所代表的OpenFile对话框, AVAPP代表acrobat app自身
2.1 在ACCB1 ASBool ACCB2 PIHandshake(Uns32 handshakeVersion, void *handshakeData)函数中调用
hsData->importReplaceAndRegisterCallback = (void*)ASCallbackCreateProto(PIImportReplaceAndRegisterProcType,
&PluginImportReplaceAndRegister);
&PluginImportReplaceAndRegister);
创建一个关于method替换或者事件通知注册的回调函数
PluginImportReplaceAndRegister,稍后系统会调用这个回调函数。
2.2在ACCB1 ASBool ACCB2 PluginImportReplaceAndRegister(void)函数中执行:
gcbAVAppOpenDialog = (void*)ASCallbackCreateReplacement(AVAppOpenDialogSEL,
MyAVAppOpenDialog);
MyAVAppOpenDialog);
用以创建一个回调函数指针
gcbAVAppOpenDialog
2.3调用REPLACE宏
REPLACE(gAcroViewHFT, AVAppOpenDialogSEL, gcbAVAppOpenDialog);
REPLACE宏的三个参数分别是:
a)要替换的HFT对象
b)HFT中的哪一个Entry要进行替换
c)要将entry替换为 那个回调函数。
//具体参见文档Wording with Host Function Tables->Replacing HFT methods
替换Acrobat核心API的行为,而
AVAppOpenDialog是acrobat的可替换method
注意:整个2.2,2.3的意思就是:
a)创建一个回调函数原型
gcbAVAppOpenDialog(把
AVAppOpenDialogSEL替换为
MyAVAppOpenDialog);
b)向系统注册此回调机制:把
gAcroViewHFT对象的
AVAppOpenDialogSEL替换为
gcbAVAppOpenDialog中定义的函数
MyAVAppOpenDialog。
2.4要在替换函数中执行
CALL_REPLACED_PROC macro用来允许本方法先前注册的回调函数执行(包括adobe自有方法),先前注册的方法不会自动执行。
在
MyAVAppOpenDialog()函数中先执行宏CALL_REPLACED_PROC 然后执行我们的文件路径过滤代码,问题解决
1.2调试Acrobat插件 (debug acrobat plug-in)
步骤:
1)Od 挂 LoadLibraryExW,下条件断点
[UNICODE[ESP+4]]=="C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\plug_ins\\myplugin
.api"
[STRING[ESP+4]]=="C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\plug_ins\\myplugin
.api"
注意:两个斜杠