老大,我想让C#源码也有点安全,让别人也破解不了
作者:互联网
NET的清新脱俗是对于一个刚开始编程的人都受不了的诱惑。
但它总是有一个致命的问题,那就是,我不管多努力,最后结果总是别人的。
为什么这么说,NET就是源码的安全加密问题。
说到代码安全,那就非MFC与VC++之流莫属了,就问除了它能在微软上经久不衰的一代一代的传承下来就很说明这一问题,虽然门槛很高。
至于NET和VC++之间互通调试,下次找个时间整理。
然后当你某天突然对代码安全有了想法,可能是出于,你自己也想编一套程序,不想被别人轻易反编译,之后开始各种查找资料。
NET加壳,我没用过,十之八九肯定是收费广告漫天飞,你也基本不会考虑在内,自己随便一个程序,我还花钱,我傻不是?
代码混淆工具,我用过,但很繁琐,混淆后大体是将比如变量方法之类,搞成了一些很简单或者没有规则的名称,实际上反编译还是可以的,只是看起来不那么只管罢了。而且你总会有一些奇怪的代码判断混在里面,垮了动态库不知道是不是还能正常使用。
所以我最终也没考虑过这种。
然后可能来自某种渠道得知,C#和VC++的动态库可以混淆,一入侯门深似海,你会被VC++的各种骚操作所折服。
然后这种自行产生的变态需求会一直困扰着你。
NET没救了,也救不活了,所以你只能老老实实坐在这一平不到的位置上,默默的敲着代码,想着中午的饭菜和午休的躺椅,不在考虑代码安全。就让自己在躺椅上慢慢腐朽吧。
别放弃,获取我能指你一条奇怪的路,路给你了,就看你要不要自己挖个护城河。
C#会被反编译,这块你就少折腾了,还是把重心放在VC++的心上。
VC++你写方法也是能通过Depends反编译那些定义的方法。
所以你也无可奈何,当你C#被反编译后,你调用的方法也被一览无余。
偷偷告诉你一个事情,就是每个程序每次编译都会生成一个Hash值,它怎么计算出来的你不用知道,也不需要知道。这个是很重要的事情,不要忘了。
我开始举例来说明咯。
有这么一个类,要怎么写,你就怎么写,这是做什么的,就是为了获取程序编译后的exe的Hash,这个哈希不管是你改了一句代码,还是被认为修改了程序的任何信息这个hash值都会变
public class MyHash
{
private string ihash;
public string IHash
{
set { ihash = value; }
get { return ihash; }
}
~iHash()
{
IHash = "";
}
public iHash()
{
string FriendlyName = AppDomain.CurrentDomain.FriendlyName.Replace(".vshost", "");
try
{
IHash = GetHash(FriendlyName);
Console.WriteLine(IHash);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public string GetHash(string path)
{
try
{
var hash = SHA1.Create();
var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
byte[] hashByte = hash.ComputeHash(stream);
stream.Close();
return BitConverter.ToString(hashByte).Replace("-", "");
}
catch (Exception ex)
{
MessageBox.Show("error"+ex.Message);
throw;
}
}
}
这个方法你得放在Main编译的exe或者动态库都可以,指向的对象一定是自己本身的exe就行了。
也就是说当运行后或算出hash值,并且打印在Console.WriteLine方法里面
当你知道了这个值后,你就自己知道就好了。你三大姑和八大姨也不高告诉她们。她们会告诉隔壁二婶的。
我们的想法有点奇怪,要得到的东西肯定也是奇怪的。
前面不是说了和VC++联合吗,VC++它很安全,或者说相对安全。
在偷偷告诉你一件事,VC++的动态库可以直接引用C#的动态库哦,是真的。
本身呢C#调用VC++的动态库,是采用非托管(不懂的,你得自己弄明白,又不包子给我),所以实际两个模块是没任何交集的。
通常内在主程序的某个动态库都以这种方式调用
[DllImport("XXX.dll", EntryPoint = "xxFunction", CallingConvention = CallingConvention.Cdecl)]
public static extern int xxFunction(int tInfo);
而在VC++的Cpp文件也应该存在类似,就是我上面所说的,VC可以直接引用C#动态库的问题
#include "stdafx.h"
#include <iostream>
#include <string>
#using "./MyHash.dll"
using namespace MyHash;
extern "C" int xxFunction(int tInfo)
{
}
做什么呢,就是MyHash里面的Hash值以及程序都被编译好了,xxFunction在调用的时候你就校验MyHash里面的值,只是MyHash是每次一次程序就一个值,也就是你如果程序有任何编译变更,你的xxFunction的值也要跟着变更。
比如我们的exe再最后生成了一个hash值是xxxxxxxxxx-xxxxxxxxx-123(这个在MyHash的方法里可以后去到并且能够打印在Console.WriteLine里)
CPP文件就该有个通用的CheckMyHash方法
bool CheckMyHash() {
//return true;
//校验程序必须运行在主程序Win下面的程序,指定为 GUID为03d1424b-4d93-4cfe-aa7d-ddf3962fdf17
//防止Core被外部调试的直接调用
CSharp::MyHash::iHash^ iunit = gcnew CSharp::MyHash::iHash();
if (iHash->myHashValue == "xxxxxxxxx-xxxxxxxx-123") {
return true;
}
return false;
}
而且这个方法会在 这个方法里去实现
extern "C" int xxFunction(int tInfo)
{
if (!CheckMyHash())return 0;
//业务逻辑 return 1;
return 0;
}
到这里,你如果你调通了程序,应该就大概可能或许明白了我到底想干嘛,反正这个业务有点奇怪,也只能奇怪实现,为了什么目的,我的VC++不让别人调用,我的VC++是我的核心代码,我的业务我主宰,你知道了C#源码又如何,只有我自己能调用。
当然偷偷告诉你一件事情,你以为这样就防止得了别人调用不了你的VC++的方法了吗,你是兔样涂婶婆了。
破解可以绕过,CHeckMyHash的返回问题,当然前提是你的C#+VC++的程序价值有那么高,值得人家来破解。
本质上我们写的是方法,但对于汇编来说,都是判断点,只要知道判断点再哪里,改个指向跳过方法校验就行了,但这个不是没办法规避就是了,反正你要多复杂就多复杂来规避,问题是你的程序值得你怎么复杂去搞。
好了,你慢慢想,这奇怪的问题就是我要逼格很高,简单的C#无法满足我可能对源码加密的渴望,所以我……“好的,马上来,包子馅给我留着,不要有别人口水”
标签:return,C#,程序,MyHash,C++,xxFunction,源码,破解 来源: https://blog.csdn.net/jee89731/article/details/113543513