因为手头需要使用一个第三方类库,网络上又找不到它的可用的版本,于是只好自己动手。这个类库使用了Dotfuscator 加密,用.NET Reflector加载程序集,

看到的字符串是乱码,如下面的代码例子所示:

internal class Program
{
// Methods
private static void Main(string[] args)
{
int num2 = 4;
try
{
List<string> expressionStack_51_0;
string expressionStack_51_1;
List<string> expressionStack_3C_0;
string expressionStack_3C_1;
int expressionStack_12_0 = 1;
if (expressionStack_12_0 == 0)
{
}
string exePath = args[0];
List<string> list = ReadAllUserStrings(exePath);
if (CS$<>9__CachedAnonymousMethodDelegate1 != null)
{
expressionStack_51_1 = exePath + b("䱡ၣṥᱧ", num2);
expressionStack_51_0 = list;
goto Label_0051;
}
else
{
expressionStack_3C_1 = exePath + b("䱡ၣṥᱧ", num2);
expressionStack_3C_0 = list;
}
string expressionStack_3E_1 = expressionStack_3C_1;
List<string> expressionStack_3E_0 = expressionStack_3C_0;
CS$<>9__CachedAnonymousMethodDelegate1 = str => CSStringConverter.Convert(str);
expressionStack_51_1 = expressionStack_3E_1;
expressionStack_51_0 = expressionStack_3E_0;
Label_0051:
File.WriteAllLines(expressionStack_51_1, expressionStack_51_0.Select<string, string>(CS$<>9__CachedAnonymousMethodDelegate1));
Console.WriteLine(b("੡ୣብݧᱩͫ䁭幯山味", num2));
}
catch (Exception exception)
{
Console.WriteLine(b("❡ᱣե൧ᩩᡫݭὯᱱ乳噵", num2) + exception.ToString());
Console.WriteLine(b("ቡᙣͥ᭧ᥩ䱫཭偯ᥱᅳཱུ噷呹剻", num2));
Console.ReadKey();
}
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

初步判断是应用了字符串混淆技术。网上可以找到的一个反加密的算法,代码如下所示

static string GetString(string source, int salt)
{
int index = 0;
char[] data = source.ToCharArray();
salt += 0xe74d6d7; // This const data generated by dotfuscator
while (index < data.Length)
{
char key = data[index];
byte low = (byte)((key & '\x00ff') ^ salt++);
byte high = (byte)((key >> 8) ^ salt++);
data[index] = (char)((low << 8 | high));
index++;
}
return string.Intern(new string(data));
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }套用一下这个方法,没有解密成功,得到的仍然是乱码。如果你有读过我昨天发布的文章”字符串混淆技术在.NET程序保护中的应用及如何解密被混淆的字符串“,就相当于我已经解决了这个问题。但是,我想把这个思路解释一下,以至不忘。

第一个知识点是关于多模块。现在Visual Studio编译生成的程序集,一个程序集只能有一个模块,但是用命令行的CSC可以生成有多个模块的程序集文件。因为C#中不能给模块添加全局方法,也不能添加全局变量,但是MSIL可以做到这一点。MSIL可以添加完全不依赖于任何类型的全局方法。下面的代码演示了如何添加全局方法和全局变量:

.assembly extern mscorlib { auto }
.assembly MyApp {}
.module MyApp.exe .namespace MyApp
{
.class public auto ansi Program extends [mscorlib]System.Object
{
.method private static void Main(string[] args)
{
.entrypoint call void Test()
ret
}
}
} .field assembly static int32 x .method private hidebysig specialname rtspecialname static void .cctor()
{
ldc.i4 1234
stsfld int32 x
ret
} .method public static void Test()
{
ldsfld int32 x
call void [mscorlib]System.Console::WriteLine(int32)
ret
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

MSDN论坛中有一个关于如何调用模块中的方法的,地址是的http://social.msdn.microsoft.com/Forums/vstudio/en-US/8a48f5bb-08c3-4d80-b5fc-56cb359fca94/call-a-global-function-using-c-emit

那么,如何调用这个全局方法呢,请参看下面的代码:

Assembly assembly = Assembly.LoadFile(file);
MethodInfo methodInfo = assembly.GetModules()[0].GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)[0];
object result = methodInfo.Invoke(null, new object[] {allUserString, key});

 

用.NET Reflector加载程序集,可以看到,模块下面有一个静态方法

 

于是,要借助于MSIL的知识才可以做到生产多模块的程序集,来看一下Dotfuscator的日志文件:

Backed up existing renaming map file G:\CLR\Source\ExtractExeNetStrings\bin\Debug\Dotfuscated\Map.xml to G:\CLR\Source\ExtractExeNetStrings\bin\Debug\Dotfuscated\Map.1.xml

Loading Assemblies...

Running C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\x64\ildasm.exe /OUT=C:\Users\Administrator\AppData\Local\Temp\~Extract.0\ExtractExeNetStrings.exe.il /TEXT /NOBAR /RAWEH /QUOTEALLNAMES /UTF8 /FORWARD G:\CLR\Source\ExtractExeNetStrings\bin\Debug\ExtractExeNetStrings.exe

Processing instrumentation attributes...

Analyzing Markup...

Removal is disabled

Linking is disabled

Analyzing Code...

Renaming...

Encrypting Strings...

Updating Markup...

Writing map file to G:\CLR\Source\ExtractExeNetStrings\bin\Debug\Dotfuscated\Map.xml

Writing Assemblies...

Running C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe /OUTPUT=C:\Users\Administrator\Desktop\CPP\ExtractExeNetStrings.exe /nologo /quiet /resource=C:\Users\Administrator\AppData\Local\Temp\~Extract.0\ExtractExeNetStrings.exe.res  C:\Users\Administrator\AppData\Local\Temp\~Extract.0\ExtractExeNetStrings.exe.il

Build Finished.

 

可以看到一点,它先用ildasm把程序集文件反编译成源代码,把得到的IL源代码经过修改后,再编译成执行文件。

Dotfuscator本身也是用.NET语言开发的,要修改程序集文件,目前常见的技术是调用MONO.Cecil开源类库,以面向对象的方法直接修改.NET程序集。

一个有趣的现象是,Dotfuscator本身却不用字符串混淆技术加密,原因可能是性能。经过混淆的字符串在被调用时,要解密,性能上有损失。如果有几百个,

上千个字符串都要被解密,这样要耗费很多资源。

如上图所示,Dotfuscator 4.9本身的程序集没有使用字符串混淆技术。

 

第三个知识点是关于如何搜索一个程序集中的字符串。这要理解PE文件结构,可直接参考源代码对照理解。

源代码下载: http://files.cnblogs.com/JamesLi2015/ExtractExeNetStrings.zip

最后,我把它集成到一起,做一个通用的程序界面,用来解密混淆过的程序集。

代码不复杂,点击按钮,打开程序集文件:

private void btnOpen_Click(object sender, EventArgs e)
{
OpenFileDialog dlg=new OpenFileDialog();
dlg.Filter = "All File (*.*)|*.*|Library File (*.dll)|*.dll|Application File(*.exe)|*.exe";
if (dlg.ShowDialog() != DialogResult.OK)
return; OpenLibrayFile(dlg.FileName);
}
 
 

接着是分解程序集中的字符串,把到提取到一个List<string> ,调用上面的methodIn.Invoke即可解密。

有一个缺陷是对有密匙(key)的字符串,多数时候会有乱码,因为所传入的key不一样,解密时需要的key不同,无法做到自动化解密,需要手工调整key的值。

这篇文章中被加密的代码,我使用的是Dotfuscator 版本号是4.9.6005.29054。

 

源代码下载: http://files.cnblogs.com/JamesLi2015/ExtractExeNetStrings.zip

字符串反混淆实战 Dotfuscator 4.9 字符串加密技术应对策略的更多相关文章

  1. 字符串混淆技术应用 设计一个字符串混淆程序 可混淆.NET程序集中的字符串

    关于字符串的研究,目前已经有两篇. 原理篇:字符串混淆技术在.NET程序保护中的应用及如何解密被混淆的字符串  实践篇:字符串反混淆实战 Dotfuscator 4.9 字符串加密技术应对策略 今天来 ...

  2. pojg2744找一个最长的字符串x,使得对于已经给出的字符串中的任意一个y,x或者是y的子串,或者x中的字符反序之后得到的新字符串是y的子串。

    http://poj.grids.cn/practice/2744 描述现在有一些由英文字符组成的大小写敏感的字符串,你的任务是找到一个最长的字符串x,使得对于已经给出的字符串中的任意一个y,x或者是 ...

  3. 前端总结·基础篇·JS(二)数组深拷贝、去重以及字符串反序和数组(Array)

    目录 这是<前端总结·基础篇·JS>系列的第二篇,主要总结一下JS数组的使用.技巧以及常用方法. 一.数组使用 1.1 定义数组 1.2 使用数组 1.3 类型检测 二.常用技巧 2.1 ...

  4. 编写一个类,其中包含一个排序的方法Sort(),当传入的是一串整数,就按照从小到大的顺序输出,如果传入的是一个字符串,就将字符串反序输出。

    namespace test2 { class Program { /// <summary> /// 编写一个类,其中包含一个排序的方法Sort(),当传入的是一串整数,就按照从小到大的 ...

  5. 几种常见的JavaScript混淆和反混淆工具分析实战

    几种常见的JavaScript混淆和反混淆工具分析实战 xiaix2016-03-05+8共1195751人围观 ,发现 5 个不明物体WEB安全 信息安全常被描述成一场军备竞赛,白帽与黑帽,渗透测试 ...

  6. mysql下的将多个字段名的值复制到另一个字段名中(批量更新数据)字符串拼接cancat实战例子

    mysql下的将多个字段名的值复制到另一个字段名中(批量更新数据)mysql字符串拼接cancat实战例子: mysql update set 多个字段相加,如果是数字相加可以直接用+号(注:hund ...

  7. ES6中的模板字符串---反引号``

    在react中,反引号``有特殊的含义. 如MDN中所述,模板字符串(Template literals)允许嵌入表达式,并且支持多行字符串和字符串插补特性.基本语法为以下几种: 其中第一行为最基本用 ...

  8. 字符串函数(strcpy字符串拷,strcmp字符串比较,strstr字符串查找,strDelChar字符串删除字符,strrev字符串反序,memmove拷贝内存块,strlen字符串长度)

    1.strcpy字符串拷贝拷贝pStrSource到pStrDest,并返回pStrDest地址(源和目标位置重叠情况除外) char *strcpy(char *pStrDest, const ch ...

  9. 技术分享:几种常见的JavaScript混淆和反混淆工具分析实战【转】

    信息安全常被描述成一场军备竞赛,白帽与黑帽,渗透测试者与黑客,善与恶,本文将聚焦这场永无止境决斗中的一个小点. HTML5 & JS 应用中充满着对输入进行验证/注入的问题,需要开发人员始终保 ...

随机推荐

  1. XHTML标签的嵌套规则分析

    在 XHTML 的语言里,我们都知道:ul 标签包含着 li.dl 标签包含着 dt 和 dd——这些固定标签的嵌套规则十分明确.但是,还有许多标签是独立的,它们没有被捆绑在一起,比如 h1.div. ...

  2. 关于unity3D的学习感想

    在老师布置团队项目后组长确定项目是做游戏是,我才接触的Unity3D游戏引擎. 因为一开始我没有接触过这类软件,更没有用过.所以作为一个新手,做好的办 法实在网上找教程.网上说Unity3D是由Uni ...

  3. 基于AWS的云服务架构最佳实践

    ZZ from: http://blog.csdn.net/wireless_com/article/details/43305701 近年来,对于打造高度可扩展的应用程序,软件架构师们挖掘了若干相关 ...

  4. MG--滚动的视觉差效果

    #几句代码完成tableView滚动的视觉差 - 效果图 (失帧严重)![](http://upload-images.jianshu.io/upload_images/1429890-f2c8577 ...

  5. java中super的两种用法

    通过用static来定义方法或成员,为我们编程提供了某种便利,从某种程度上可以说它类似于C语言中的全局函数和全局变量.但是,并不是说有了这种便利,你便可以随处使用,如果那样的话,你便需要认真考虑一下自 ...

  6. hdu 5795

    A Simple Nim Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  7. I2C VHDL程序

    http://blog.sina.com.cn/s/blog_9bd80b7601012o9y.html library ieee ; use ieee.std_logic_1164.all ; us ...

  8. Ubuntu 16.04 下使用Xampp

    Ubuntu 16.04 下使用Xampp 什么是Xampp? XAMPP(Apache+MySQL+PHP+PERL) 是一个功能强大的建站集成软件包.这个软件包原来的名字是 LAMPP,但是为了避 ...

  9. UI进阶

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  10. 【Visual Lisp】图元选择集专题

    图元选择集专题;;★★★01.选择集操作★★★(setq ss (ssadd));;创建一个空选择集(ssadd (car(entsel)) ss);;将点取的图元添加到ss选择集中,可以不用setq ...