(2014年二月10日翻新:微软壹度修复了Roslyn的这一个bug,详见

IL DASM反编写翻译工具

  使用C#的古人或多或少都会对微软的IL反编写翻译工具(ildasm.exe)有所认识。小编最早接触到那工具是商店同事使用他反编写翻译exe程序,进行研读和改动。感觉她照旧很强大。
  IL是微软平台上的壹门中间语言,我们常写的C#代码在编写翻译器中都会活动转换来IL,然后在由即时编写翻译器(JIT
Compiler)转化学工业机械器码,最终被CPU执行。ildasm.exe反编写翻译工具将IL汇编成可跨平台可实施的(pe)文件。可供我们询问外人代码和改动。有了他我们看待难题能够不用停留在编辑器层面,可深远中间层。

IL DASM反编写翻译工具

  使用C#的古人或多或少都会对微软的IL反编写翻译工具(ildasm.exe)有所认识。作者最早接触到那工具是商店同事使用她反编写翻译exe程序,进行研读和修改。感觉她依旧很强劲。
  IL是微软平台上的1门中间语言,大家常写的C#代码在编写翻译器中都会自行转换来IL,然后在由即时编译器(JIT
Compiler)转化学工业机械器码,最后被CPU执行。ildasm.exe反编写翻译工具将IL汇编成可跨平台可实施的(pe)文件。可供大家明白外人代码和改动。有了她大家看待难点得以不要停留在编辑器层面,可深远中间层。

C# 反编写翻译防备,

C# 编写的代码通过VS编译器生成 dll 或 exe
,很不难被一些反编写翻译工具查看到源码或对源码举办修改。
为预防代码被反编写翻译或被歪曲,我们得以拓展一定的防备措施。但无法杜绝,因为DotNet编写代码运营必须编写翻译成IL
中间语言,IL是很平整,同时也很好反编写翻译。

反编写翻译防患措施:

  • 设置项目代码反汇编属性
  • 混淆

昨天,大家用VS20一5编写翻译了博客程序中的三个顺序集并宣布上线。

VS中增加IL DASM工具

大家在安装VS同时都会活动安装ildasm工具,无需重新安装。ildasm工具打开艺术如下图:

金沙注册送58 1

笔者们也足以直接wind+福特Explorer.输入:C:\Program Files (x86)\Microsoft
SDKs\Windows\v7.0A\bin\ildasm.exe (window 7 六十七人 操作系统安装目录)
同样能够打开ildasm。
我们也足以把ildasm工具扩充到大家常用的VS中。
一.工具(Tools)–>外部工具(External Tools..)

金沙注册送58 2

2.添加内容填写对应音信。命令:C:\Program Files (x86)\Microsoft
SDKs\Windows\v7.0A\bin\ildasm.exe
(window 7 六十四位 操作系统安装目录) 。

金沙注册送58 3

已上音讯填写完毕后,在“工具”选拔卡中能找到我们刚扩充的外表工具名称(IL_DASM)。增添完毕后方可小规模试制1把。
国际惯例来段”Hello
World”。代码编写完后直接F6生成exe文件,然后工具–>IL_DASM–>确认(无需修改任何参数,暗中认可目的文件路径)。系统会弹出IL工具,大家双击Main方法。

金沙注册送58 4

此刻可以观望Main方法在IL中编写翻译的代码。感觉有个别目生不易看懂。
还有IL编译出现的三角型,正方型都以吗!

VS中增加IL DASM工具

大家在安装VS同时都会活动安装ildasm工具,无需重新安装。ildasm工具打开艺术如下图:

金沙注册送58 5

我们也足以直接wind+HummerH贰.输入:C:\Program Files (x86)\Microsoft
SDKs\Windows\v7.0A\bin\ildasm.exe (window 七 61个人 操作系统安装目录)
同样能够打开ildasm。
大家也能够把ildasm工具扩展到大家常用的VS中。
一.工具(Tools)–>外部工具(External Tools..)

金沙注册送58 6

贰.添加剧情填写对应消息。命令:C:\Program Files (x86)\Microsoft
SDKs\Windows\v7.0A\bin\ildasm.exe
(window 七 63位 操作系统安装目录) 。

金沙注册送58 7

已上新闻填写实现后,在“工具”接纳卡中能找到大家刚扩张的表面工具名称(IL_DASM)。扩展达成后能够小规模试制1把。
国际惯例来段”Hello
World”。代码编写完后平昔F陆生成exe文件,然后工具–>IL_DASM–>确认(无需修改任何参数,暗中认可指标文件路径)。系统会弹出IL工具,大家双击Main方法。

金沙注册送58 8

那儿可以观看Main方法在IL中编写翻译的代码。感觉微微面生不易看懂。
还有IL编写翻译出现的三角型,正方型都以什么!

办法一:避免 Ildasm.exe(MSIL 反汇编制程序序) 反汇编制程序序集

办法很简短在类型文件AssemblyInfo.cs中加进SuppressIldasm属性。

金沙注册送58 9

当项目中加进SuppressIldasm属性后在采用ildasm.exe反编译代码,会提醒:”受保证的模块
— 无法进展反汇编”

金沙注册送58 10

ildasm.exe 读取项目中带有 SuppressIldasm
属性就不对此程序集实行反编写翻译。但ILSyp,Reflector等反编写翻译工具针对程序集设置SuppressIldasm属性置若罔闻,壹样能够反编写翻译源码。

缺点:
可知SuppressIldasm
属性只针对ildasm.exe工具起成效,同时也能去除ildasm.exe工具的此项限制。参考:《去掉ILDasm的SuppressIldasmAttribute限制》

明天有园友反馈向大家报告,个人博客分页突显随笔列表的页面中,“上一页”“下1页”显示乱码:

IL DASM 基础

1.中文字符串编写翻译后成乱码,软件方法。图标含义

金沙注册送58 11

使用IL反编写翻译出项目代码

金沙注册送58 12

MANIFEST:是二个增大新闻列表,主要含有程序集的片段性质,如程序集名称、版本号、哈希算法等;
Democode:项目名称
德姆ocodeing.Common:命名空间
Democodeing.ICar:接口
德姆ocodeing.Program:类,首要查看存类下边包车型大巴内容。

.class 类音讯项代码:

.class private auto ansi beforefieldinit DemoCoding.Program
       extends [mscorlib]System.Object
{
} // end of class DemoCoding.Program

一).class,表示Program是八个类。并且它一连自程序集—mscorlib的System.Object类;
二)private,表示访问权限;
三)auto,表示程序的内部存款和储蓄器加载全体由CL奇骏来控制;
四)ansi,是为着在尚未托管代码与托管代码之间达成无缝转换。那里最首要指C、C++代码等;
5)before田野init,是用来标记运转库(CLKoleos)能够在静态字段方法生成后的任性时刻,来加载构造器(构造函数);

.ctor 方法代码:

.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // 代码大小       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
} // end of method Program::.ctor

1)cil managed:表示在那之中为IL代码,提醒编写翻译器编译为托管代码;
二).maxstack:表示调用构造函数.otor时期的评估堆栈(伊娃luation Stack) ;
3)  IL_0000:标记代码行开端;
四)ldarg.0:表示转发第三个分子参数,在实例方法中指的是当下实例的引用;
5)call:call壹般用来调用静态方法,因为静态方法是在编写翻译期就规定的。而那里的组织函数.otor()也是在编译期就制定的。而另一指令callvirt则象征调用实例方法,
它是在运转时规定的,因为如前述,当调用方法的继承关系时,就要相比较基类与派生类的同名函数的达成情势(virtual和new),以鲜明调用的函数所属的Method
Table;
6)ret:表示执行完结,重临;

Main() 静态方法代码:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代码大小       19 (0x13)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Hello World"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  call       string [mscorlib]System.Console::ReadLine()
  IL_0011:  pop
  IL_0012:  ret
} // end of method Program::Main

一)
hidebysig:表示当把该类作为基类,存在派生类时,此措施不被接续,同上构造函数;
二).entrypoint:指令表示CLCRUISER加载程序时,是率先从.entrypoint伊始的,即从Main方法作为程序的入口函数;
3)nop:为空该指令,首要给外部设备可能指令间隙准备时间;
四)ldstr:创造String对象变量”Hello World.” ;
伍)pop:取出栈顶的值。当大家不要求把值存入变量时行使;

IL DASM 基础

1.图标含义

金沙注册送58 13

采用IL反编写翻译出项目代码

金沙注册送58 14

MANIFEST:是一个增大音讯列表,首要含有程序集的片段个性,如程序集名称、版本号、哈希算法等;
德姆ocode:项目名称
德姆ocodeing.Common:命名空间
Democodeing.ICar:接口
德姆ocodeing.Program:类,首要查看存类上面包车型客车始末。

.class 类消息项代码:

.class private auto ansi beforefieldinit DemoCoding.Program
       extends [mscorlib]System.Object
{
} // end of class DemoCoding.Program

一).class,表示Program是二个类。并且它三番五次自程序集—mscorlib的System.Object类;
贰)private,表示访问权限;
3)auto,表示程序的内部存款和储蓄器加载全部由CLHummerH二来控制;
四)ansi,是为着在尚未托管代码与托管代码之间完成无缝转换。那里首要指C、C++代码等;
伍)before田野同志init,是用来标记运营库(CLPAJERO)能够在静态字段方法生成后的私自时刻,来加载构造器(构造函数);

.ctor 方法代码:

金沙注册送58 15

.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // 代码大小       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
} // end of method Program::.ctor

金沙注册送58 16

金沙注册送58 ,一)cil managed:表示个中为IL代码,提醒编写翻译器编写翻译为托管代码;
二).maxstack:表示调用构造函数.otor时期的评估堆栈(伊娃luation Stack) ;
3)  IL_0000:标记代码行起先;
四)ldarg.0:表示转发第壹个分子参数,在实例方法中指的是当下实例的引用;
五)call:call一般用于调用静态方法,因为静态方法是在编写翻译期就明确的。而那边的结构函数.otor()也是在编写翻译期就制订的。而另一指令callvirt则象征调用实例方法,
它是在运行时规定的,因为如前述,当调用方法的接二连三关系时,就要比较基类与派生类的同名函数的完毕格局(virtual和new),以鲜明调用的函数所属的Method
Table;
陆)ret:表示执行完结,重回;

Main() 静态方法代码:

金沙注册送58 17

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代码大小       19 (0x13)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Hello World"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  call       string [mscorlib]System.Console::ReadLine()
  IL_0011:  pop
  IL_0012:  ret
} // end of method Program::Main

金沙注册送58 18

1)
hidebysig:表示当把该类作为基类,存在派生类时,此方式不被持续,同上构造函数;
二).entrypoint:指令表示CL凯雷德加载程序时,是第三从.entrypoint开首的,即从Main方法作为程序的入口函数;
叁)nop:为空该指令,首要给外部设备也许指令间隙准备时间;
4)ldstr:创造String对象变量”Hello World.” ;
伍)pop:取出栈顶的值。当我们不须求把值存入变量时行使;

方法二:混淆

混淆原理:将VS编写翻译出的文件(exe 或
dll)通过ildasm对文本举行重命名,字符串加密,移动等方式将原始代码打乱。那种格局相比较普遍。

VS20一3 自带混淆工具:工具–>PreEmptive Dotfuscator and Analytics

金沙注册送58 19

但VS20一三自带Dotfuscator 5.5 需购销激活才能选择成套功用。近期百度提供
DotfuscatorPro 4.九 破解版版本下载。

打开 DotfuscatorPro 4.9 主界面

金沙注册送58 20

Settings->Global Options 全局配置
常用成效布局:Disable String Encryption=NO 启用字符串加密

金沙注册送58 21

慎选需混淆C#编写翻译代码(dll 或 exe)
其间Library不要勾选,不然有些类、变量等等不会搅乱;

金沙注册送58 22

Rename 重命名配置
常用成效布局: 勾选 = use enhanced overload induction 使用增强格局
重命名方案 Renaming Scheme = Unprintable
(不可打字与印刷字符,即乱码),也能够采纳别的如小写字母、大写字符、数字的办法。

金沙注册送58 23

String Encryption 字符串加密
勾选供给加密字符串文件(exe 或 dll)

金沙注册送58 24

可遵照各自须要可举行其余相关配置。(如:control flow,Output,Setting
->Build Settings,Settings –> Project Properties等)
最终生成混淆文件 Build Project。

金沙注册送58 25

Build Project 生成混淆项目错误:
Could not find a compatible version of ildasm to run on assembly
C:\Users\***bin\Debug\WindowsFormsApplication1.exe.??This
assembly was originally built with .NET Framework v4.0.30319.
Build Error.

处理办法:
ILASM_v4.0.30319 =
C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe
ILDASM_v4.0.30319 = C:\Program Files (x86)\Microsoft
SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\ildasm.exe
[设置VS版本不一致对应目录会有所扭转]

金沙注册送58 26

金沙注册送58 27

应用IL DASM 修改EXE程序代码

一.开辟IL工具,选用所要修改的EXE程序。

金沙注册送58 28

贰.文件–>转储。明确后选取另存路径,会转移一个文本:*.il 和 *.res

金沙注册送58 29

三.用记事本打开*.il修改里面包车型地铁始末:

 .method private hidebysig static void  Main(string[] args) cil managed
  {
    .entrypoint
    // 代码大小       19 (0x13)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldstr      "Hello World-[已使用il工具修改过...]"
    IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000b:  nop
    IL_000c:  call       string [mscorlib]System.Console::ReadLine()
    IL_0011:  pop
    IL_0012:  ret
  } // end of method Program::Main

四.把修改后的代码编写翻译成EXE程序。

ilasm /exe /output=C:\CK.exe /Resource=C:\Users\Ck\Desktop\coding.res C:\Users\Ck\Desktop\coding.il

金沙注册送58 30

修改就这么简单。运维修改后的EXE程序,值已修改。

金沙注册送58 31

 

选取IL DASM 修改EXE程序代码

壹.打开IL工具,选用所要修改的EXE程序。

金沙注册送58 32

二.文本–>转储。分明后选用另存路径,会扭转三个文本:*.il 和 *.res

金沙注册送58 33

3.用记事本打开*.il修改里面的始末:

金沙注册送58 34

 .method private hidebysig static void  Main(string[] args) cil managed
  {
    .entrypoint
    // 代码大小       19 (0x13)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldstr      "Hello World-[已使用il工具修改过...]"
    IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000b:  nop
    IL_000c:  call       string [mscorlib]System.Console::ReadLine()
    IL_0011:  pop
    IL_0012:  ret
  } // end of method Program::Main

金沙注册送58 35

4.把修改后的代码编写翻译成EXE程序。

ilasm /exe /output=C:\CK.exe /Resource=C:\Users\Ck\Desktop\coding.res C:\Users\Ck\Desktop\coding.il

金沙注册送58 36

修改就这么简单。运维修改后的EXE程序,值已修改。

金沙注册送58 37

混淆代码相比

未使用混淆工具,反编写翻译出的源码:

金沙注册送58 38

利用混淆工具,反编写翻译出的源码:

金沙注册送58 39

意义很强烈,极不赏心悦目出反编写翻译代码所写的实在逻辑。

缺点:
C#代码通过混淆工具生成后,扩张了无数转移进程。这使得反编写翻译工具不恐怕很直观望到源码真正逻辑。但源码代码过多变换会使软件本人运转效用下跌,甚至会现出报错情形。

反编写翻译防患, C# 编写的代码通过VS编写翻译器生成
dll 或 exe ,很不难被部分反编写翻译工具查看到源码或对源码进行改动。
为预防代码被反编写翻译…

而以此地点的“上1页”“下一页”字符串恰恰是在大家昨日公布的顺序集中定义的:

public class Pager : Control
{
    protected string PreviousText = "上一页";
    protected string NextText = "下一页";

    //...
}

可是明天我们并不曾改变那一部分代码,肯定不是我们前天代码修改引起的。

于是乎,大家改用VS201三双重编写翻译了1晃那几个程序集,更新之后,乱码立马消失。

继而,用ILSpy反编译了VS20一五所编写翻译出的主次集的IL代码之后,真相大白:

public class Pager : Control
{
    protected string PreviousText = "ÉÏÒ»Ò³";
    protected string NextText = "ÏÂÒ»Ò³";
    //...
}

本来是VS201伍所用的编写翻译器惹的祸,而以此编译器正是鼎鼎大名的 Roslyn

我们利用 Visual Studio 20一伍 时必要小心一下这几个题材。

【补充】

用ildasm查看VS20一5编写翻译出来的次序集的IL代码(乱码):

.maxstack  2
IL_0000:  ldarg.0
IL_0001:  ldstr      bytearray (C9 00 CF 00 D2 00 BB 00 D2 00 B3 00 ) 
IL_0006:  stfld      string BlogServer.Web.Controls.Pager::PreviousText
IL_000b:  ldarg.0
IL_000c:  ldstr      bytearray (CF 00 C2 00 D2 00 BB 00 D2 00 B3 00 ) 
IL_0011:  stfld      string BlogServer.Web.Controls.Pager::NextText

用ildasm查看VS二〇一一编写翻译出来的先后集的IL代码(未乱码):

.maxstack  2
IL_0000:  ldarg.0
IL_0001:  ldstr      bytearray (0A 4E 00 4E 75 98 )                               // .N.Nu.
IL_0006:  stfld      string BlogServer.Web.Controls.Pager::PreviousText
IL_000b:  ldarg.0
IL_000c:  ldstr      bytearray (0B 4E 00 4E 75 98 )                               // .N.Nu.
IL_0011:  stfld      string BlogServer.Web.Controls.Pager::NextText

【难题原因与一时解决办法】

在GitHub上交给Issue之后,从光复中查出那些难点与Roslyn检查实验文件编码的处理格局有关。

查阅出现乱码难题的.cs文件编码,发现用的是ANSI编码。于是以UTF-八编码另存该文件,然后用VS20壹5再次编写翻译,难题消除。

VS20一5 索罗德C中没那几个难题。

【GitHub上的相关链接】

*
VS20一5开辟非unicode编码的代码,在那之中变量名有普通话就不可能编写翻译的bug

* .NET compiler produces incorrect string constants in MSIL when C#
source files encoded with non-UTF-8
encoding

* VS2015 (MSBuild/14) compiler can’t detect file ecoding
correctly

* Chinese string is compiled to garbage
characters

* Roslyn can’t detect 932
encoding

相关文章

网站地图xml地图