您的位置:首页 > 其它

PGP透明加解密研究-----简要技术分析

2010-04-21 11:03 330 查看
技术分析
⑴.主要派遣例程
IRP_MJ_CREATE例程
对应的函数: CFilterEngine::DispatchCreate(DEVICE_OBJECT
*device, IRP *irp)
如果是自己的设备访问则直接放过

if(device ==CFilterControl::s_control)
{

irp->IoStatus.Status
= STATUS_SUCCESS;
irp->IoStatus.Information
=FILE_OPENED;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return
STATUS_SUCCESS;
}
再次判断一些系统进程请求如:svchost.exe则放过不进行加解密操作

if(SkipCreate(device,irp))
{
status =
irp->IoStatus.Status;
IoCompleteRequest(irp,IO_DISK_INCREMENT);

return
status;
}

1. PreCreate阶段:初次判断当前状态,并标志上下文flag,以便在PostCreate阶段进行相应操作
extension->Volume.PreCreate(irp,track),在pre-Create函数中首先判断经过candidate.NormalizeCreate(irp),此函数判断当前irp是否来自网络重定向器,如果来自网络重定向器的请求则返回失败禁止访问,这样可以防止访问网络共享。若果不是则返回到成功到pre-Create函数,接下来判断SL_OPEN_TARGET_DIRECTORY标志,如果是应用的访问必须是带有SL_OPEN_TARGET_DIRECTORY标志,这个标志表示当前访问的文件或者文件夹的父路径已经被打开,内核层的访问不必有这个标志。就接下来就是判断是否是系统相关的目录比如系统盘:/windows
,temp,Document and Setting,IE等等,如果是这些目录则不进行加解密,实现函数是IsSpecific(track,TRACK_SYSTEM
| TRACK_IE_CACHE),如果不是这些目录则开始检查当前文件夹下的配置文件,如果当前访问的文件或者文件夹的当前文件夹不存在配置文件,则检查父目录是否存在配置文件,如果不存在则不对当前访问的对象加解密,如果父目录存在配置文件则在当前上下文中设置TRACK_AUTO_CONFIG标志,在postcreate中生成一个配置文件。
2.PostCreate阶段
根据PreCreate阶段分析的结果过设置的标志位,如果标志位是TRACK_AUTO_CONFIG标志,则根据父目录的配置信息,在当前文件夹生成一个配置文件,成功后上下文标志为待加密状态,即TRACK_YES标志,以便在IRP_MJ_WRITE派遣例程中判断标志是否加密。如果此文件夹已经存在配置文件,即之前已经访问过此加密文件夹,则直接把加密链表的加密信息复制到当前上下文加密中。
IRP_MJ_WRITE例程
1. extension->Volume.CheckFileCooked(file,
&link)
首先检查加密文件对象cooked中是否存在当前文件夹对象,如果不存在直接调用下一层驱动,存在则进行加密操作。
2.extension->Volume.m_context->Tracker().Check(file)
&FILFILE_TRACKER_BYPASS
检查当前文件类型是否属于不被加密操作文件类型,不被加密的文件类型,则WriteBypass(extension,irp,
&link),直接写文件原文,不加密。
3. WriteAlreadyEncrypted(extension,irp);
检查当前文件是否已经被加密
4.EstimateCaching(extension,irp,
file, &link)
如果文件没有被加密,检查IRP是否需要缓存.
5.写文件
根据文件对象是否需要缓存的标志,来采用不同的方式来写
IRP_MJ_READ例程
1. extension->Volume.CheckFileCooked(file,
&link)
首先检查文件对象cooked中是否存在当前文件夹对象,如果不存在直接调用下一层驱动,存在则在后续操作中进行解密操作。

2.extension->Volume.m_context->Tracker().Check(file)
&FILFILE_TRACKER_BYPASS
检查当前文件类型是否属于不被加密操作文件类型,不被加密的文件类型,则ReadBypass(extension,irp,
&link);直接调用下一层驱动。
3.检查是否读取到文件尾
4.如果没有读取到文件尾部,检查文件是否需要缓存,如果需要则解密读取并缓存
不需要则直接解密文件数据
IRP_MJ_DEVICE_CONTROL例程
应用层代理和驱动层交互例程CFilterEngine::DispatchDeviceControl

1. IOCTL_FILFILE_GET_STATE
获得驱动的状态,驱动的状态有下面几种
enumDriverState
{

Unknown, //
错误未知状态
NotInstalled,
// 没有被安装
Active, //安装了被激活状态
Passive,
// 安装了没有被激活
};
2. IOCTL_FILFILE_SET_STATE
设置驱动的状态,设置Active激活态和Passive不激活态。
Active激活态:对加密文件夹实施透明加解密
Passive不激活态:不对加密文件夹实施透明加解密

2. IOCTL_FILFILE_GET_HEADER
获得加密文件头信息

3. IOCTL_FILFILE_SET_HEADER
设置加密文件头

4. IOCTL_FILFILE_ENTITY
加密文件夹入口点信息管理链表的信息的添加与删除

5. IOCTL_FILFILE_ENUM_ENTITIES
从加密文件夹信息管理链表中获得入口点数量及信息。

6. IOCTL_FILFILE_ENCRYPTION
对指定文件进行加密

7. IOCTL_FILFILE_CALLBACK_CONNECTION
应用层代理和驱动链接传递一些全局事件,这些事情作用就是用于请求密码的交互,即在
IOCTL_FILFILE_CALLBACK_REQUEST和IOCTL_FILFILE_CALLBACK_RESPONSE交互

8. IOCTL_FILFILE_ADD_CREDIBLE_PROCESS
添加可信进程,可信进程以及其子进程有权访问加密文件夹

9. IOCTL_FILFILE_CALLBACK_REQUEST
驱动通过激活IOCTL_FILFILE_CALLBACK_CONNECTION传递进来的事件,是应用层发送
此控制码来请求待解密的密码数据

10.IOCTL_FILFILE_CALLBACK_RESPONSE
应用层代码通过IOCTL_FILFILE_CALLBACK_REQUEST请求的密码数据解密所得密码通过此控制码返回密码给驱动

11.IOCTL_FILFILE_OPEN_FILE
调用IoCreateFileSpecifyDeviceObjectHint函数打开文件,此函数打开文件可以直接从下层设备打开而不进入文件系统栈,避免文件系统重入问题
⑵.其他主要功能函数

1. NTSTATUSCFilterCallback::Connect(HANDLErandom,
HANDLE key,
HANDLE
notify)

HANDLErandom,
HANDLE key,
HANDLE notify,从应用层代理传进驱动的三个事件,分别是请求random随机数事件,请求加密解密Key事件,通知回调事件。

2. 应用层与驱动进行Key请求交互的函数
请求key函数
NTSTATUSCFilterCallback::FireKey(ULONGflags,
FILFILE_TRACK_CONTEXT *track)
NTSTATUSCFilterCallback::RequestKey(ULONGflags,
FILFILE_CONTROL_OUT *request,ULONG *requestSize)
NTSTATUSCFilterCallback::Request(ULONGflags,
FILFILE_CONTROL_OUT *request,ULONG *requestSize)
返回key函数
NTSTATUSCFilterCallback::Response(ULONGcookie,
UCHAR *response,ULONG
responseSize)

3. 注册回调IoRegisterFsRegistrationChange

当一个文件系统激活或者解注册过滤驱动会得到一个通知,注册的回调函数FileSystemRegister,在此函数中实现了对FILE_DEVICE_DISK_FILE_SYSTEM磁盘文件系统的挂载,并生成了设备驱动的扩展设备设备,扩展设备结构为
structFILFILE_COMMON_EXTENSION
{
USHORT
Type;
USHORT
Size;
DEVICE_OBJECT*
Device;
};
structFILFILE_VOLUME_EXTENSION
{
FILFILE_COMMON_EXTENSION
Common;//自己设备
LIST_ENTRY
Link;
DEVICE_OBJECT* Real;//真实设备
DEVICE_OBJECT* Lower;
ULONG
LowerType;
UNICODE_STRING LowerName;
CFilterVolume
Volume;
bool
System;
};

4. NTSTATUSCFilterCipherManager::RecognizeHeader(

FILE_OBJECT *file,

CFilterHeader *header,

ULONGflags)
识别文件头的功能函数。在检查文件夹存在一个pgpFs.INI配置文件后,首先就要检查加密文件头是否是本设备对象所识别的加密文件头。
文件头的结构如下:
structFILFILE_HEADER_BLOCK
{
ULONG
Magic; //
文件头标志: FilF;
ULONG
Version; //
文件头版本
ULONG
Cipher; //加密核心算法选择分为AES128
AES256 AES192
ULONG
BlockSize; //当前文件头Block大小
ULONG
PayloadSize; //文件头bloak后的payload大小
ULONG
PayloadCrc; //Payload的crc32校验和

ULONG Deepness;
// AutoConfig files only: Deepness of correspondig Entity [~0u:=INFINITE, 0:=1, ..., N:=N+1]
ULONG
Reserved; // not used yet
LARGE_INTEGER
Nonce; // Nonce, unique for each file, combined with file Offset forms an IV
UCHAR
FileKey[32]; //
驱动请求解密key的密码
};
加密文件开始即以上的FILFILE_HEADER_BLOCK结构,在这段结构之后即payload块,两者加在一起是4K的大小。

验证文件头块的过程中首先验证文件头的Magic标志,如果标志位不是FilF,则是无效文件头,再次验证payload的crc32校验和,计算payload校验和和FILFILE_HEADER_BLOCK.
PayloadCrc不相等则是无效头文件,最后验证Cipher的高位和低位,高位必须是0xF,低位必须是{1,2,3}中的一个值,否则就是无效文件头,有效的文件头才可以实施透明加解密。
5. NTSTATUSCFilterBase::CreateFile(DEVICE_OBJECT* device,

UNICODE_STRING* path,

ULONG access,

ULONG share,

ULONG options,

ULONG attribs,

FILE_OBJECT** file,

HANDLE* fileHandle)
设备驱动打开文件,函数中调用了IoCreateFileSpecifyDeviceObjectHint函数,此函数打开文件可以直接从下层设备打开而不进入文件系统栈,解决文件系统重入问题
6.NTSTATUSCFilterBase::ReadWrite(DEVICE_OBJECT
*device,

FILE_OBJECT *file,

FILFILE_READ_WRITEconst*
readWrite)
FILFILE_READ_WRITE结构如下

structFILFILE_READ_WRITE

{

UCHAR* Buffer;

MDL* Mdl;

LARGE_INTEGEROffset;

ULONG Length;

ULONG Flags;

UCHAR Major;

BOOLEAN Wait;

};
利用IRP同步转发的技术实现文件的同步读写,等待device设备返回结果,使用IoAllocateIrp分配IRP,根据FILFILE_READ_WRITE传入的参数设置IRP相关参数,最后通过IoCallDriver调用转发IRP到下一层设备中读取文件,跳过当前设备栈,设置等待事件,达到同步的目的,通过IoSetCompletionRoutine设置回调通知事件态,重新获得IRP的控制权,而获得读取或者写入文件数据。
7.CFilterVolume::IsSpecific(FILFILE_TRACK_CONTEXT
*track,

ULONG flags)
检查一些特别目录的函数,如"//Documents and Settings//","//Local
Settings//Temporary Internet Files//Content.IE5//",”//Wndows”等系统特有的目录则不进行加密,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: