首页 新闻 会员 周边 捐助

C#实现透明加解密

0
悬赏园豆:200 [已解决问题] 解决于 2012-04-06 21:28

有没有人对透明加解密有过研究?

我现在的需求如下:

我们公司有一个老的项目,它的功能主要是对xml文档进行数据分析。现在我们需要使用这个老项目,但是xml文档是些比较重要的文档,不希望客户能够用记事本打开,所以我们想把xml文档进行加密。

对老项目不能做任何代码级的改动了,我们希望用C#实现的功能就是,先把所有xml文档进行加密,然后用API HOOK技术监控老项目读写文件的API进行解密。这样就限制了没有我们的程序用户拿xml文件是没法查看也没法使用的。

实现大概原理如下图:就是在原来的应用程序老项目调用API读程序的中间hook了一个处理程序,这个处理程序就负责解密。

谁有这方面的实现?下周一就要给客户使用了,最好有C#实现的源码。先谢谢了。

LCM的主页 LCM | 大侠五级 | 园豆:6876
提问于:2012-03-16 09:33
< >
分享
最佳答案
0

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

}
}
收获园豆:200
雨族 | 菜鸟二级 |园豆:402 | 2012-04-05 15:33
其他回答(4)
0

如果可以将XML导入数据库,可以试用sql server 2008的透明加密
http://www.cnblogs.com/downmoon/archive/2011/03/17/1986383.html

邀月 | 园豆:25475 (高人七级) | 2012-03-16 09:54

谢谢你的回复。sqlserver2008有这个功能,挺不错的。

不过好像解决不了我的问题,因为:

1,假如用这个的话,那我的老项目读xml的部分需要修改成读数据库,而我的老项目是不允许修改代码的,经过测试的项目不允许再进行任何修改。

2,xml数据文件有将近2G,这些数据文件是根据需要读取的,可能这次分析用到的是a.xml,下次是用到b.xml,而改成数据库的话,查询可能就会费时间。

3,xml数据文件中的格式并不是标准的关系型的,修改成table的话会比较麻烦。

支持(0) 反对(0) LCM | 园豆:6876 (大侠五级) | 2012-03-16 10:02
0
dudu | 园豆:29817 (高人七级) | 2012-03-16 21:32

不好意思,你没看明白我的意思。对xml的加密解密我懂,但是不懂怎么怎么不敢动原程序代码的情况下,本来读取非加密xml文档变成读取加密xml文档。

支持(0) 反对(0) LCM | 园豆:6876 (大侠五级) | 2012-03-16 21:47

@LCM: 不好意思

支持(0) 反对(0) dudu | 园豆:29817 (高人七级) | 2012-03-16 22:19
0

看来这种方式不好实现。只能换其它方式。

LCM | 园豆:6876 (大侠五级) | 2012-03-19 14:04
0
sweetjian | 园豆:276 (菜鸟二级) | 2012-03-20 13:24

谢谢。不过这个文档我看过。我是想实现inline hook,调用readfile方法时先切换到调用自己的readfile,在readfile里调用系统的readfile后立刻解密。

支持(0) 反对(0) LCM | 园豆:6876 (大侠五级) | 2012-03-20 15:35
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册