您的位置:首页 > 其它

放心分发EXE有效保护自己的DotNet源码

2011-10-01 12:04 501 查看
前言:

文章的技巧在DotNet1.0发布那年就已经使用,今天心血来潮,只想更新下2年未更新的BLOG,了以充数罢了.

正文:

Dotnet编译的DLL,EXE等文件,通过混淆可以一定程度保护自己的代码安全,我在此介绍自己一直使用的方式--垫片启动.

运行EXE时,先运行C++代码,再装载DotNet应用程序运行环境,然后运行DotNet程序.

本篇不涉及安全保护,代码混淆,加密等操作,只是一个运行机制模式的介绍,如何保护自己的代码安全,由你自己决定.

C++启动DotNet环境.

VC++本地代码,支持DotNet语言的几个本地函数.

ICorRuntimeHost : 运行主机CLR接口

CorBindToRuntimeEx : 运行环境绑定

_AppDomainPtr : 托管AppDomain指针

_AssemblyPtr : 托管Assembly指针

请注意,mscoree.h头文件的引用

有效使用这些对象提供的方法,可以反射加载应用程序.

#include "stdafx.h"
#include <excpt.h>
#include <windows.h>
#include <mscoree.h>
#include <assert.h>
#include <stdio.h>
#include <tchar.h>
#include <atlsafe.h>
#include <iostream>
#include <string.h>

#define RC_LENGTH                   8

void ExecuteAssembly();
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR    lpCmdLine,
int       nCmdShow)
{

ExecuteAssembly();
PostQuitMessage(0);
return 0;
}

void ExecuteAssembly()
{
//垫片方式启动托管入口
LPWSTR pszVer = L"v2.0.50727";		// .NET Fx 3.5 needs CLR 2.0
LPWSTR pszFlavor = L"svr";		//svr:多核优化处理GC, wks:总是执行单核GC处理;
ICorRuntimeHost *pClrHost = NULL;
HRESULT hr = ::CorBindToRuntimeEx(
pszVer,
pszFlavor,
STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC,
CLSID_CorRuntimeHost,
IID_ICorRuntimeHost,
(void **)&pClrHost);
pClrHost->Start(); // 启动CLR

_AppDomainPtr pDefaultDomain = NULL;
IUnknownPtr   pAppDomainPunk = NULL;

hr = pClrHost->GetDefaultDomain(&pAppDomainPunk);
hr = pAppDomainPunk->QueryInterface(__uuidof(_AppDomain),(void**) &pDefaultDomain);

//资源读取,并装载主程序依赖的引用库(第三方不能商业发布的组件,你可以考虑放在其中)
CReaderRc *rcDll = new CReaderRc(IDR_SPCLRASM1, _T("spclrasm"), pDefaultDomain);
/*
可以将你的代码作为C++的资源,一起编译成EXE
*/

//托管的主程序集
_AssemblyPtr ExeAssembly;
hr = pDefaultDomain->Load_3(*(rcDll->getByteArray()).GetSafeArrayPtr(), &ExeAssembly);
delete rcDll;
/*
rcDll->getByteArray() 是应用程序程序集文件的字节数组,由CReaderRc负责读取.
你完全可以在这个里面,采用自己的加/解密算法,操作文件.
*/

//找到入口方法,并调用执行
_MethodInfo* EntryPointInfo;
hr = ExeAssembly->get_EntryPoint(&EntryPointInfo);

_variant_t  thisPointer, ReturnValue;
CComSafeArray<BSTR> Parameters;	//main方法的参数

hr = EntryPointInfo->Invoke_3(thisPointer, *Parameters.GetSafeArrayPtr() , &ReturnValue);
}


写一段C#代码,编译成EXE.将此EXE放到上面的C++的资源中并编译C++或启动调试.

[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}


主题说明:

整个运行流程,就是将托管反射的应用改成由C++代码通过本地函数调用来实现.

其中放进资源文件的EXE或DLL,你可以使用混淆代码并加密它,然后C++读取资源时解密,并装载到程序域中.找到托管代码的入口函数就完成了.

对于C++的资源,有些工具很容易提取,如果不加密,那提取以后还是很容易看到原码的.

注意点说明:

本文并非最安全的保护,由它一个薄弱可攻击的安全漏洞,这是由于JIT决定的.可以采用C++编写JIT拦截代码,看到你运行的托管函数等信息.

所以只能从一定程度上起到保护作用.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: