当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > 采用Native 引导方式的.Net加密保护

ASP.NET
.NET框架类库中的定时器类的使用
net得到本地电脑基本信息的简单方法
如何通过ASP.NET页面重启服务器
.net开发工具LINQ框架设计指南
.net ajax 与Ext2框架在.net程序中的应用
.Net上传图片按比例自动缩小或放大
.NET的死锁调试工具:ACorns.Debugging
ADO在vb.net中的使用(与datagrid结合)
Visual C++中实现双缓冲的基本原理
.net App中集成COM组件的一些简单技巧
vb.net通过app.config来改变编译路径
实例了解Asp.Net的继承和多态性
asp.net里导出excel表方法汇总
ASP.NET上传大于4M的文件的相关设置
.Net开发漫谈:关于命名空间和目录划分
.Net(C#)开发漫谈:关于变量的命名和属性
.Net新手学堂:Lambda表达式的一般应用
故障解析:.NET开发正则表达式中BUG一例
一步一步安装VB.Net(图片较多,请稍等)
关于用VB做更漂亮的窗体的思考

ASP.NET 中的 采用Native 引导方式的.Net加密保护


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-23   浏览: 206 ::
收藏到网摘: n/a

这类加密保护方式属于整体程序集的加密保护.这个方法首要解决的问题就是 native code 和 .Net Code如何交互.这里介绍三种实现方式.

1. C++/CLI 实现.
这个比较简单了,会C++/CLI一下子就能完成了.
Loader是由C++/CLI实现的.运行时通过解码程序集通过反射载入然后运行.

2. 利用C#导出Com接口和native code交互.Loader由C#和native code两部分组成.

C#部分代码

public interface IInvokeAssembly
{
void LoadAndExecute(byte[] pBuf);
};

public class CInvokeAssembly : IInvokeAssembly
{
public CInvokeAssembly()
{
}
public void LoadAndExecute(byte[] pBuf)
{
try
{
Assembly asm = Assembly.Load(pBuf);
asm.EntryPoint.Invoke(null,null);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

这里导出的 IInvokeAssembly 接口,将在native code中使用.

native code 部分

void InvokeAssemblyResource()
{
IInvokeAssemblyPtr pInvoker; //COM Pointer to the .Net Interface

if(FAILED(pInvoker.CreateInstance(CLSID_CInvokeAssembly)))
{
MessageBox(NULL,_T("Unable to Create Invoke Assembly Object !!"),_T("Error"),MB_OK|MB_ICONERROR);
return;
}

HRSRC hRC = FindResource(NULL,MAKEINTRESOURCE(IDR_EMBEDDED_ASSEMBLY),"RT_EMBEDDED_ASSEMBLY");
HGLOBAL hRes = LoadResource(NULL,hRC);
DWORD dwSize = SizeofResource(NULL,hRC);

SAFEARRAY* pSA = NULL;

if(NULL !=(pSA = SafeArrayCreateVector(VT_UI1, 0, dwSize)))
{
LPVOID pBuf = NULL;

if(FAILED(SafeArrayAccessData(pSA,&pBuf)))
MessageBox(NULL,_T("Unable to Access SafeArray Data"), _T("Error"),MB_OK|MB_ICONERROR);
else
{
LPVOID hAsm = LockResource(hRes);

memcpy(pBuf, hAsm, dwSize);

UnlockResource(hRes);

SafeArrayUnaccessData(pSA);
}

pInvoker->LoadAndExecute(pSA); //Invoke the Reflection to load and Execute our Byte[]
}
else
MessageBox(NULL,_T("Unable to Allocate Memory"),_T("Memory Allocate Error"),MB_OK|MB_ICONERROR);

if(pSA) SafeArrayDestroy(pSA);
}

这里还有一个问题,loader是两部分.加密的程序集可以作为资源签入到native code loader中.但是C#部分怎么处理?一个比较隐蔽的方式是,在安装程序时将它安装到gac中.

3 是利用 CLR-Hosting 接口. 可以参考msdn中 本地接口部分的文档.

以下为引用的内容:
bool InvokeAssemblyResource()
{
CComPtr spRuntimeHost;
CComPtr<_AppDomain> spAppDomain;
CComPtr spUnk;

bool bSuccess = false;

if(FAILED(CorBindToRuntimeEx( NULL, // Latest Version by Default
L"wks", // Workstation build
STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN,
CLSID_CorRuntimeHost ,
IID_ICorRuntimeHost ,
(void**)&spRuntimeHost)))
{
gErrMsg = _T("Unable to Bind CLR");
return false;
}
if(FAILED(spRuntimeHost->Start()))
{
gErrMsg = _T("Unable to Start CLR");
return false;
}
do
{
if(FAILED(spRuntimeHost->GetDefaultDomain(&spUnk)))
{
gErrMsg = _T("Unable to GetDefaultDomain");
break;
}
if(FAILED(spUnk->QueryInterface(&spAppDomain.p)))
{
gErrMsg = _T("Unable to Query AppDomain Interface");
break;
}

SAFEARRAY* pSA = GetDecryptedResource();
if(pSA)
{
try
{ // Invoke the Entry Point with No Arguments
spAppDomain->Load_3(pSA)->EntryPoint->Invoke_3(_variant_t(), NULL);
bSuccess = true; // Everything Went Fine !!
}
catch(_com_error ex)
{
gErrMsg = ex.ErrorMessage();
}

SafeArrayDestroy(pSA);
pSA = NULL;
}
}while(false);

if(FAILED(spRuntimeHost->Stop()))
{
gErrMsg = _T("Unable to Stop CLR");
return false;
}

return bSuccess;
}

一般这类加密工具都会选择第三种实现方式.如 .Net Reactor.

不过单纯的整体加密保护安装性是很低的,可以配合一些其它的方式来提高保护强度,如 .Net Reactor的 NecroBit。因为在Load时很容易被dump出程序集.这种方式就是让Load时载入的程序集不是完整的(除去了IL代码部分,NecroBit).然后在Load完成后,程序集执行之前,还原IL代码.