.NET Reactor代码混淆注意事项


C#开发的一个dll,在使用.NET Reactor进行代码混淆后,调用混淆后的dll发生异常,记录一下踩过的坑(自己给自己挖的,与.NET Reactor无关)

一、对象转换遇到NULL

现象

我的代码中存在要将DataTable转换为对象Object的操作,对象转换代码如下:

根据对象属性的名字进行值的转换

C# 全选
internal class Tools
    {
        public static T ConvertObject<T>(DataRow dr) where T : new()
        {
            var v = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
            List<string> _ArryColumnNames = new List<string>();
            foreach (DataColumn col in dr.Table.Columns)
            {
                _ArryColumnNames.Add(col.ColumnName);
            }
            T t = new T();
            foreach (var s in v)
            {
                var ColName = _ArryColumnNames.Where(w => String.Equals(w, s.Name, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                if (!String.IsNullOrEmpty(ColName))
                {
                    if (object.Equals(dr[ColName], DBNull.Value)) continue;
                    {
                        s.SetValue(t, dr[ColName]);
                    }
                }
            }
            return t;
        }
    }

代码中对象定义如下:

C# 全选
internal class SNDetail
{
	public string doccode { get; set; }
	public string seed { get; set; }
	public long maxid { get; set; }
	public int turns { get; set; }
}

现在如果我们用 .NET Reactor 混淆代码,那么最后得到的dll中,SNDetail 这个对象的属性会被更改名称

代码混淆原则之一,非开放public的属性更改一个名字使代码反编译后难以阅读

此时就会发现一个问题,属性被重命名了,这个时候用 Tools.ConvertObject<SNDetail>(datasn.Rows[0]) 方法转换对象就会出现问题了,

混淆后的SNDetail类代码

.NET Reactor代码混淆注意事项

解决办法

1、完善Tools.ConvertObject方法,增加一个特性,然后取特性的值,类属性中给需要转换的字段设置这个特性

2、把类设置为public,这样就不会被混淆了

public混淆后的SNDetail代码

.NET Reactor代码混淆注意事项

 

二、对象属性无法赋值

 .NET Reactor 代码混淆时 勾选了 NecroBit

.NET Reactor代码混淆注意事项

类库代码中有一个基类:

C# 全选
public abstract class ModelDocNo
{
	/// <summary>
	/// 单据标识,系统自动生成切不可重复
	/// </summary>
	public string DocCode { get; set; }

	private string _seed;
	/// <summary>
	/// 单据种子,如果为空,取DocCode
	/// </summary>
	public string seed
	{
		get
		{
			if (String.IsNullOrEmpty(_seed))
				return DocCode;
			else
				return _seed;
		}
		set
		{
			_seed = value;
		}
	}

	/// <summary>
	/// 单据名称
	/// </summary>
	public string DocName { get; set; }

	/// <summary>
	/// 单据头
	/// </summary>
	public string DocHeader { get; set; }
	/// <summary>
	/// 单据头间隔符号
	/// </summary>
	public string Separate { get; set; }

	private GenerateDocSNRule _DocType = GenerateDocSNRule.Up;
	/// <summary>
	/// 单据生成规则
	/// </summary>
	public GenerateDocSNRule DocType { get { return _DocType; } set { _DocType = value; } }

	/// <summary>
	/// 自定义生成标记
	/// </summary>
	public string CustomerSeed { get; set; }

	public string DocRule
	{
		get
		{
			string RuleType = "";
			switch (DocType)
			{
				case GenerateDocSNRule.Up:
					RuleType = "Up"; break;
				case GenerateDocSNRule.Year:
					RuleType = "Year"; break;
				case GenerateDocSNRule.Year_Month:
					RuleType = "Year-Month"; break;
				case GenerateDocSNRule.Year_Month_Day:
					RuleType = "Year-Month-dd"; break;
				case GenerateDocSNRule.Custom:
					RuleType = "Customer"; break;

			}
			return RuleType;
		}
	}


	private int _Length = 5;
	/// <summary>
	/// 单据长度
	/// </summary>
	public int Length { get { return _Length; } set { _Length = value; } }

	//bool isInit = false;
	//public void Init(DbContext dbContext)
	//{
	//    if (isInit == true) return;
	//    SqlParameter[] para = new SqlParameter[] {
	//        new SqlParameter("@DocCode", this.DocCode)
	//    };
	//    string sql = "SELECT * FROM sys_DataSN WHERE DocCode=@DocCode";
	//    DataTable dt = dbContext.Database.SqlQueryDataTable(sql, para);
	//    if (dt.Rows.Count > 0)
	//    {
	//        DocHeader = ConvertLib.ToString(dt.Rows[0]["docHeader"]);
	//        DocType = (GenerateDocSNRule)Enum.Parse(typeof(GenerateDocSNRule), ConvertLib.ToString(dt.Rows[0]["docType"]));
	//        Separate = ConvertLib.ToString(dt.Rows[0]["separate"]);
	//        Length = ConvertLib.ToInt(dt.Rows[0]["length"]);
	//    }
	//    else
	//    {
	//        string sqlInsert = "INSERT INTO sys_DataSN(docCode,docName,docHeader,separate,docType,[length]) VALUES(@DocCode,@DocName,@DocHeader,@Separate,@DocType,@Length)";
	//        SqlParameter[] pInsert = new SqlParameter[] {
	//            new SqlParameter("@DocCode",SqlDbType.VarChar,50){ Value=this.DocCode},
	//            new SqlParameter("@DocName",SqlDbType.NVarChar,50){ Value=this.DocName},
	//            new SqlParameter("@DocHeader",SqlDbType.VarChar,10){ Value=this.DocHeader??""},
	//            new SqlParameter("@Separate", SqlDbType.VarChar,2){ Value=this.Separate??""},
	//            new SqlParameter("@DocType", SqlDbType.VarChar,20){ Value=this.DocType.ToString()},
	//            new SqlParameter("@Length", SqlDbType.Int){ Value=this.Length},
	//        };
	//        dbContext.Database.ExecuteSqlCommand(sqlInsert, pInsert);
	//    }
	//    isInit = true;
	//}
}

在使用.NET Reactor进行类库代码混淆后,我们在项目中创建一个类,集成该基类

C# 全选
public class SNAPPRouterAuthorize : ModelDocNo
{
	public SNAPPRouterAuthorize()
	{
		base.DocCode = "MicroAPPRouterAuthorize";
		base.DocName = "微应用编号";
		base.DocHeader = "APP";
		base.Length = 4;
		base.DocType = GenerateDocSNRule.Custom;
	}
}

调试项目,我们会发现,不管怎么样,就是无法给基类的属性赋值

.NET Reactor代码混淆注意事项

看看基类混淆后的代码:

.NET Reactor代码混淆注意事项

通过代码我们可以发现端倪, .NET Reactor 混淆后,基类属性被直接返回null了

解惑

这里不要疑惑,先来看下 NecroBit 的解释,

NecroBit 是一种强大的保护技术,通过将方法中的 CIL 代码替换为加密代码,为您的敏感知识产权提供全面保护。 这样就不可能对您的方法源代码进行反编译/逆向工程。

再回到项目中调试,这时候,如果直接查看对象,的确看到的属性都是null,但是我们再直接查看属性值呢?a.DocCode 就能正确的显示出属性,具体原因自己体会吧,所以这个不影响项目正常运行,但是肯定会对性能有所影响的吧

.NET Reactor代码混淆注意事项

 

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
张国生
上一篇:Python对象转json字符串
下一篇:省市区数据库
评论列表

发表评论

评论内容
昵称:
关联文章

.NET Reactor代码混淆注意事项
.NET DLL加密代码混淆 Eziriz .NET Reactor
Visual Studio(VS)发布自动使用Net Reactor给生成的DLL加壳
[.Net] .NET Reactor加授权方法 .NET Reactor自定义注册机和获取机器码
混淆工具JavaScript obfuscator中文帮助文档
SQLite Database 多线程访问需要注意的问题
asp.net core 断点调试无法修改代码
.NET Core 项目调试的时候不能修改代码
C#代码编码规范手册 软件开发规范 开发指南
C# DateTime.ToString 参数使用注意
解决.Net Core3.0 修改cshtml代码之后必须重新生成才可以看到效果
.NET Core 运行时T4模板使用,T4生成代码
.NETCore动态解析Razor代码cshtml代码解析RazorEngine.NetCore
代码编辑插件使用
YESWin Winform开发框架 代码生成器使用
.NET DLL反编译 .Net脱壳利器de4dot
利用代码生成工具Database2Sharp生成ABP VNext框架项目代码
.NET MVC加载从后台加载JS代码
.NET DLL反编译 .NET Reflector
dotnet 使用 WpfAnalyzers 辅助分析 WPF 应用代码缺陷

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码