有没有人对透明加解密有过研究?
我现在的需求如下:
我们公司有一个老的项目,它的功能主要是对xml文档进行数据分析。现在我们需要使用这个老项目,但是xml文档是些比较重要的文档,不希望客户能够用记事本打开,所以我们想把xml文档进行加密。
对老项目不能做任何代码级的改动了,我们希望用C#实现的功能就是,先把所有xml文档进行加密,然后用API HOOK技术监控老项目读写文件的API进行解密。这样就限制了没有我们的程序用户拿xml文件是没法查看也没法使用的。
实现大概原理如下图:就是在原来的应用程序老项目调用API读程序的中间hook了一个处理程序,这个处理程序就负责解密。
谁有这方面的实现?下周一就要给客户使用了,最好有C#实现的源码。先谢谢了。
MiniHook库开源地址http://www.codeproject.com/Articles/21414/Powerful-x86-x64-Mini-Hook-Engine
我做过一个改变文件名的demo,就是监听系统中读文件,假如是a文件,我自动改成b文件,这样实现了加密,即没有我的程序,找到的数据都是错的,只有我的程序才能映射到正确的文件进行读取。代码如下:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.IO;
namespace HookDemo
{
public partial class Form2 : Form
{
#region 使用 Interop 服务调入非托管代码
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = false, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("NtHookEngine.dll", CharSet = CharSet.Ansi, ExactSpelling = false, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr HookFunction(IntPtr OriginalFunction, IntPtr NewFunction);
[DllImport("NtHookEngine.dll", CharSet = CharSet.Ansi, ExactSpelling = false, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr UnhookFunction(IntPtr Function);
[DllImport("NtHookEngine.dll", CharSet = CharSet.Ansi, ExactSpelling = false, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr GetOriginalFunction(IntPtr Hook);
#endregion
private DelegateMyCreateFile delegateMy;
private IntPtr delegateIntPtr;
public Form2()
{
InitializeComponent();
delegateMy = CreateFile_Hooked;
delegateIntPtr = Marshal.GetFunctionPointerForDelegate(delegateMy);
}
private void button1_Click(object sender, EventArgs e)
{
Console.WriteLine("----------------------------");
string fileName = textBox1.Text.Trim();
//string fileName = "c:\\b.txt";
var str = File.ReadAllText(fileName);
Console.WriteLine(str);
Console.WriteLine("----------------------------");
}
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
public delegate IntPtr DelegateMyCreateFile(
String FileName,
UInt32 DesiredAccess,
UInt32 ShareMode,
IntPtr SecurityAttributes,
UInt32 CreationDisposition,
UInt32 FlagsAndAttributes,
IntPtr hTemplateFile);
// 这是挂的勾子,所有文件创建时执行
public IntPtr CreateFile_Hooked(
String FileName,
UInt32 DesiredAccess,
UInt32 ShareMode,
IntPtr SecurityAttributes,
UInt32 CreationDisposition,
UInt32 FlagsAndAttributes,
IntPtr hTemplateFile)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss " + FileName));
//if (FileName =="c:\\abcc")
// FileName = "c:\\a.txt";
FileName = EffectiveFiles.GetEffectiveFileName(FileName);
var a = GetOriginalFunction(delegateIntPtr);
var b = Marshal.GetDelegateForFunctionPointer(a, typeof(DelegateMyCreateFile)) as DelegateMyCreateFile;
if (b != null)
{
return b(FileName, DesiredAccess, ShareMode, SecurityAttributes, CreationDisposition, FlagsAndAttributes, hTemplateFile);
//return (IntPtr)b.DynamicInvoke(FileName, DesiredAccess, ShareMode, SecurityAttributes, CreationDisposition, FlagsAndAttributes, hTemplateFile);
}
return IntPtr.Zero;
}
#region hook和unhook按钮事件
private void button2_Click(object sender, EventArgs e)
{
//Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0])
//HookFunction(GetProcAddress(LoadLibrary("kernel32"), "CreateFileA"), delegateIntPtr);
HookFunction(GetProcAddress(LoadLibrary("kernel32"), "CreateFileW"), delegateIntPtr);
}
private void button3_Click(object sender, EventArgs e)
{
//UnhookFunction(GetProcAddress(LoadLibrary("kernel32"), "CreateFileA"));
UnhookFunction(GetProcAddress(LoadLibrary("kernel32"), "CreateFileW"));
}
#endregion
}
}
如果可以将XML导入数据库,可以试用sql server 2008的透明加密
http://www.cnblogs.com/downmoon/archive/2011/03/17/1986383.html
谢谢你的回复。sqlserver2008有这个功能,挺不错的。
不过好像解决不了我的问题,因为:
1,假如用这个的话,那我的老项目读xml的部分需要修改成读数据库,而我的老项目是不允许修改代码的,经过测试的项目不允许再进行任何修改。
2,xml数据文件有将近2G,这些数据文件是根据需要读取的,可能这次分析用到的是a.xml,下次是用到b.xml,而改成数据库的话,查询可能就会费时间。
3,xml数据文件中的格式并不是标准的关系型的,修改成table的话会比较麻烦。
不好意思,你没看明白我的意思。对xml的加密解密我懂,但是不懂怎么怎么不敢动原程序代码的情况下,本来读取非加密xml文档变成读取加密xml文档。
@LCM: 不好意思
看来这种方式不好实现。只能换其它方式。
谢谢。不过这个文档我看过。我是想实现inline hook,调用readfile方法时先切换到调用自己的readfile,在readfile里调用系统的readfile后立刻解密。