记录自己一次xenocode反混淆实践

需要用到的工具有

  1. https://down.52pojie.cn/Tools/PEtools/PE.Tools.v1.9.762.2018.zip
  2. ildasm
  3. https://down.52pojie.cn/Tools/NET/ILSpy_Master_2.3.1.1855_Binaries.zip
  4. DOBSTR 很老的一个工具.在<加密与解密 第三版>随书光盘里面才有 下载地址 https://download.csdn.net/download/gqhyz/3203429 在目录 /chap09/工具/反混淆/ 下

第一个方法: 用PEtools选择 exe 进程 右键dump full 可以得到一个新的exe文件 拖入 ILSpy后 可以看到逻辑代码
但是字符串还是处于混淆状态.
第二个方法: 用ILDSAM将被混淆的程序集反编译为IL文件,反编译时只改变编码为Unicode,其他不变,用DOBSTR打开这个IL文件,并选择保存位置,点击 “反混淆”,程序将生成反混淆后的IL文件.(注意:打开dobstr后 选择一下指定方法 选择程序集就使用dobstr同目录的decode.dll 请使用全路径) 其他不改. 注释选项选择不注释.
生成反混淆后的IL文件后.使用windows 系统下.NET目录(例如:C:\Windows\Microsoft.NET\Framework\v2.0.50727)的ilasm重新将il文件编译为dll或者exe 命令如下:

ilasm /exe /output=d:\server\iltoexe_server.exe d:\server\server1.il

这时候将 iltoexe_server.exe 拖入ILSpy, 有惊喜.
但是也不一定全部过程都成功. dobstr反混淆 和 ilasm重新编译过程中都会有可能出现错误.

之前的代码
这里写图片描述

之后的代码
这里写图片描述

一些具体细节

通过反编译 dobstr的源代码可以看到它直接从il文件中读取bytearray类型的字符串 然后导入解密函数进行解密.可能由于程序的多样性,dobstr 的解密算法已经硬编码在内部了. 遇到dobstr出错的时候,可以自己提取il里面的bytearray自己手工解密
以下是使用ILDSAM 反编译后获取的IL中间语音代码片段:

      IL_0470:  ldstr      bytearray (17 68 32 6F 1E 76 28 7D 2A 84 F5 8A 15 92 12 99 ) // .h2o.v(}*.......
      IL_0475:  ldc.i4     0xff167c3

其中 ldstr是已经混淆过了的字符串
ldc.i4 是一个整数 用于参与反混淆过程

附上反混淆解密方法:

		public string cc381ffa3ede662f(string e4115acdf4fbfccc, int 211566702b710682)
		{
			char[] array = e4115acdf4fbfccc.ToCharArray();
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = (char)((int)array[i] - 211566702b710682);
				211566702b710682 += 1789;
			}
			return new string(array);
		}

反混淆过程如下:
首先拿到ldstr 字符串 17 68 32 6F 1E 76 28 7D 2A 84 F5 8A 15 92 12 99
4位一组.两两对调.用\u进行拼接,得到新的字符串:\u6817\u6f32\u761e\u7d28\u842a\u8af5\u9215\u9912
再拿出ldc.i4 0xff167c3 进行16进制转换10进制 得到整数 267478979 再传入上面的反混淆函数.即可得到想要的字符串.

这里写图片描述

以下是我自己写的一个demo C#的解密代码

        static void Main(string[] args)
        {
			string strOrgStr = "\u6817\u6f32\u761e\u7d28\u842a\u8af5\u9215\u9912";
			char[] array = strOrgStr.ToCharArray();

			int ccc = 267478979;
			for (int i = 0; i < array.Length; i++){
				char b = (char)((int)array[i] - ccc);
				ccc += 1789;
				Console.Write(b);
			}
            Console.Write("\r\nPress any key to continue....");
            Console.Read();
        }

这里写图片描述

这个是dobstr 调用自己写的程序集来解密,dobstr 程序还有一些问题.

// ConsoleApplication3.Form1
public string Decrypt(string str, int radix)
{
	string result;
	try
	{
		Assembly assembly = Assembly.LoadFrom(this.indll.Text);
		Type type = assembly.GetType(this.Namespace.Text);
		object[] array = new object[]
		{
			str,
			radix
		};
		Type[] array2 = new Type[array.Length];
		for (int i = 0; i < array.Length; i++)
		{
			array2[i] = array[i].GetType();
		}
		BindingFlags bindingFlags = 24;
		MethodInfo method = type.GetMethod(this.Method.Text, bindingFlags, null, array2, null);
		object obj = method.Invoke(null, array);
		result = obj.ToString();
	}
	catch
	{
		this.OutPut.AppendText("错误:解密字符串失败!\r\n");
		this.OutPut.AppendText("请检查调用的解密方法是否正确!\r\n");
		this.OutPut.AppendText("\r\n");
		this.bTest = false;
		result = "";
	}
	return result;
}

这个是硬编码了的解密函数

// ConsoleApplication3.Form1
public string Decrypt(string strOrgStr, string strRadix)
{
	string text = strOrgStr.Replace(" ", "");
	text = text.Trim();
	int num = text.get_Length() / 4;
	int[] array = new int[num];
	char[] array2 = new char[num];
	for (int i = 0; i < num; i++)
	{
		string text2 = text.Substring(4 * i + 2, 2) + text.Substring(4 * i, 2);
		array[i] = int.Parse(text2, 515);
		array2[i] = (char)array[i];
	}
	string text3 = new string(array2);
	text3.Trim();
	int radix = int.Parse(strRadix, 515);
	string text4 = this.Decrypt(text3, radix);
	text4 = text4.Trim();
	string text5 = text4;
	byte[] bytes = Encoding.get_Unicode().GetBytes(text4);
	text4 = Form1.HexTest.ToHexString(bytes);
	text4 = text4.Trim();
	string text6 = "";
	for (int j = 0; j < text4.get_Length() / 2; j++)
	{
		string text2 = text4.Substring(j * 2, 2) + ' ';
		text6 += text2;
	}
	text6 += ')';
	if (this.BaStyle.Checked)
	{
		text6 = text6 + "   //" + text5;
	}
	return text6;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值