放心分发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头文件的引用
有效使用这些对象提供的方法,可以反射加载应用程序.
写一段C#代码,编译成EXE.将此EXE放到上面的C++的资源中并编译C++或启动调试.
主题说明:
整个运行流程,就是将托管反射的应用改成由C++代码通过本地函数调用来实现.
其中放进资源文件的EXE或DLL,你可以使用混淆代码并加密它,然后C++读取资源时解密,并装载到程序域中.找到托管代码的入口函数就完成了.
对于C++的资源,有些工具很容易提取,如果不加密,那提取以后还是很容易看到原码的.
注意点说明:
本文并非最安全的保护,由它一个薄弱可攻击的安全漏洞,这是由于JIT决定的.可以采用C++编写JIT拦截代码,看到你运行的托管函数等信息.
所以只能从一定程度上起到保护作用.
文章的技巧在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拦截代码,看到你运行的托管函数等信息.
所以只能从一定程度上起到保护作用.
相关文章推荐
- 独立设计师如何有效保护自己的基本利益
- 如何有效的保护自己的手机被盗?
- 模仿CIFAR-10数据集制作自己的数据集(亲测有效)
- 600万密码泄露之后,我们该如何保护自己的密码?
- 保护自己免受敌人子弹通过防弹背心
- 决不做“肉鸡” 从零开始保护自己的系统
- 【时间管理】有效的管理自己的时间才能超越自己
- 让自己放心
- 自己的程序编程变成windows可以运行的.exe文件----py2exe
- java程序调用exe文件和调用自己打的jar包或其他外部jar包
- 还是自己写的东西比较放心
- 开发者要懂得保护自己眼睛
- 怎么在劣势保护自己和保存实力
- 如何保护自己开发的软件
- ERP顾问出差遇险记(一).恶脸也能保护自己
- 【女人在爱裡要懂得保护自己!三个…
- 程序员如何保护自己?
- 进行有效的时间管理----实践自己的人生目标和美好理想
- 【超实用】黑客来袭,如何保护自己?
- 如何使用Android Studio把自己的Android library分发到jCenter和Maven Central