Monday, April 25, 2005

 

Some notes on DotNet decompiler - 1

1.
谈谈ILDasm的功能限制与解除

By aiasted
From http://www.cnblogs.com/aiasted/archive/2005/05/05/149639.html

首先,我在此申明,此文并不是教别人突破限制,我们只是用学习的眼光看问题

大家都知道ILDasm是。NET程序的反编译工具,它是由Microsoft提供的反编译工具。

它可以直接把。NET程序反编译为IL文件及资源文件,这样即可以非常容易的让黑客进行修改,删除强命名,修改注册码算法等等。。。并且Ilasm再次编译,得到一个正确的,可发布的程序集
并且,这个功能是其它反编译器所不能替代的功能,因为ILDasm真的太重要了。也许有的朋友能理解,有的朋友不能理解,但没关系,我们今天的重点并不是这个。

这是一件不可思议的事,让软件没有了安全保障。幸亏有了XenoCode,它有一项功能即是 Anti ILDasm 。这是一个非常棒的功能,但它是怎么做到的呢?

其实,这是ILDasm的一个限制,当你在程序中制造某个标志后,那么程序集将不可以再被ILDasm反编译,ILDasm会提示您,这个程序集已经是一个被有版权的程序集,您不可能对其反编译。呵呵,我们最可爱的ILDasm会罢工?

我曾经找过相关资料,不过没有找到有什么最简单的方法让自己的程序集变成已有版权的程序集,XenoCode有这样做,不过我不想去分析它。如果有知道的朋友,请与我交流一下

那么我们今天的任务是什么呢?就是把罢工的ILDasm拉回来,让它继续为我们工作。

OK,分析一下吧:经过短暂的分析,让我出了一身汗。。。这样的版权保护有还不如无,一定误导了很多朋友。

为什么我这样说呢?因为我发现,想让ILDasm再次工作,比想象中的简单很多,这根本就档不住任何东西。请看下面我跟踪的代码:

10042B4BD E8 8AFCFDFF CALL ildasmCr.0040B14C //报错函数
2
3
400415FC6 E8 12470100 CALL ildasm.0042A6DD //进入的主函数
5
6
70042AABD FF51 0C CALL DWORD PTR DS:[ECX+C] //判断函数
80042AAC0 3BF7 CMP ESI,EDI
90042AAC2 75 0F JNZ SHORT ildasm.0042AAD3 //关键跳转地址,改为JMP即可
100042AAC4 68 96010000 PUSH 196
110042AAC9 E8 8964FFFF CALL ildasm.00420F57
120042AACE E9 E3090000 JMP ildasm.0042B4B6
13

这已经很明显了,ILDasm只用了一个标志去阻止"已有版权"的程序集,而您只需要修改一个机器指令就可以畅通无阻的反编译任何程序集,并修改其内容再次编译

2.
ildasm.exe的/adv参数

From MSDN Magazine 2001.05 的 BugSlayer 专栏

ildasm /adv assembly.dll

添加/adv参数后,菜单中会多出几项,适用于.NET Framework 1.0 and 1.1。.NET Framework 2.0下好像所有的菜单都直接显示出来了。

3.
Net环境下的程序破解
发信人:windcbf
From: http://www.pediy.com/bbshtml/BBS5/pediy50489.htm
http://www.pediy.com/bbshtml/BBS5/pediy50488.htm

首先介绍一下.Net环境下的程序形成过程。

(1)程序员用高级OO语言(C#,VB.Net,VC.Net,Cobol,Python..)编写代码,这些代码经过
.Net编译器(比如Visual Studio.Net),编译成统一的MSIL(Microsoft Intermediate Language)。NET应用程序是以MSIL的形式出现的,只有在程序执行的时候才通过即时编译器JIT(Just-In-Time)被编译为本机代码。
(2)程序执行的时候,由JIT装入程序的MSIL,JIT同时作了很多其他的工作(装载相应的运行库,安全检测。。) 最后JIT将转化成本地机器码(EXE或者DLL)。
(3)本地机器码被装入内存,开始执行。

就是通过这几个步骤,.net实现了编程语言无关(都转化成MSIL);平台无关(执行的
时候根据本地配置,生成相应的机器码);安全性(JIT里面做了很多检测)。


作为Cracker,可以用.Net Framework SDK自带的工具进行MSIL和EXE(DLL)之间的互换:
利用FrameworkSDK\Bin\目录下的ilasm和ildasm
(1)ilasm示例:
下面的命令对 MSIL 文件 myTestFile.il 进行汇编并产生可执行文件 myTestFile.exe。
ilasm myTestFile
下面的命令对 MSIL 文件 myTestFile.il 进行汇编并产生 .dll 文件 myTestFile.dll。
ilasm myTestFile /dll
下面的命令对 MSIL 文件 myTestFile.il 进行汇编并产生 .dll 文件 myNewTestFile.dll。
ilasm myTestFile /dll /output:myNewTestFile.dll
(2)ildasm示例
下面的命令使 PE 文件 MyHello.exe 的元数据和反汇编代码显示在 Ildasm.exe 的默认 GUI 中。
ildasm myHello.exe
下面的命令对 MyFile.exe 文件进行反汇编,并将结果 MSIL 汇编程程序文本存储在 MyFile.il 文件中。

ildasm MyFile.exe /output:MyFile.il
下面的命令对 MyFile.exe 文件进行反汇编,并将结果 MSIL 汇编程序文本显示到控制台窗口中。

ildasm MyFile.exe /text
如果文件 MyApp.exe 包含嵌入的托管和非托管资源,则下面的命令将产生以下 4 个文件:MyApp.il、MyApp.res、Icons.resources 和 Message.resources:

ildasm MyApp.exe /output:MyApp.il
下面的命令对 MyFile.exe 的 MyClass 类中的 MyMethod 方法进行反汇编,并将输出显示到控制台窗口中。

ildasm /item:MyClass::MyMethod MyFile.exe /text
在上面的示例中,可能有几个具有不同签名的 MyMethod 方法。下面的命令对返回类型为 void 且带有参数 int32 和 System.string 的 MyMethod 方法进行反汇编。

ildasm /item:"MyClass::MyMethod(void(int32,class System.String))" MyFile.exe /text

通过上面分析可知,我们(Cracker)需要分析的对象就是MSIL形式的文件了

>>>MSIL: 从Hello World开始

.Net下的汇编语言(MSIL)看起来要友好的多,学编程都从Hello World开始,这里我们
同样也从一个小小的Hello World开始来逐步了解MSIL,呵呵

所需要的工具仅仅记事本就可以了,打开Notepad,输入代码:
// file:Hello.il “//“都是注释,可省去
// Author:WinHack[CCG]

//定义Assembly(EXE,DLL)
.assembly helloworld //要产生的Assembly(EXE,DLL)名称
{
.ver 1:0:0:0 //版本
}

//用.method定义方法(函数)
.method public static void main() il managed
{
.entrypoint //这里定义整个程序的入口点!
.maxstack 1 //函数所保留的栈槽数量

//导入字符串
ldstr "Hello World!!!\n"

//在控制台(Console)显示
call void [mscorlib]System.Console::WriteLine(class System.String)

ret //返回
}

将上面的文件保存成hello.il文件,打开console界面,用ilasm编译成exe。
D:\>ilasm hello.il
Microsoft (R) .NET Framework IL Assembler. Version 1.0.3705.0
Copyright (C) Microsoft Corporation 1998-2001. All rights reserved.
Assembling 'hello.il' , no listing file, to EXE --> 'hello.EXE'
Source file is ANSI

Assembled global method main
Creating PE file

Emitting members:
Global Methods: 1;
Writing PE file
Operation completed successfully

现在就可以运行程序了!
D:\>hello
Hello World!!!

这就是一个简单得不能在简单的hello world程序了,但是通过这个程序,我想大家对MSIL已经有一个大体上的印象了吧,当然.net framework是一个极其庞大的系统,MSIL里面包含了很多复杂的元素,后面我会尽力逐个介绍,不过好几天没有干活了,导师催得紧,过几天再写吧。有兴趣的发信交流,呵呵^_^

4.
http://www.remotesoft.com/salamander/index.html

Salamander is a .NET decompiler that converts executable files (.EXE or .DLL) from Intermediate Language (IL, MSIL, CIL) binary format to high-level source codes, such as C#, managed C++, Visual Basic.NET, etc. For more than 8,000 classes that have been tested, Salamander always produces equivalent and recompilable codes that are remarkably close to the original source codes.

5.
http://www.remotesoft.com/dotexplorer/

Remotesoft .NET Explorer is a generic object browser and MSIL disassembler with professional look and feel. It offers the same functionality as Microsoft ILDASM disassembler utility, plus low level viewing of metadata and PE format. Remotesoft .NET Explorer works together with our decompiler and obfuscator, and acts as a console for easy navigation and powerful code editing and printing. This tool can be used as a source code editor, and it has a powerful syntax coloring system that recognizes many popular source files, including IL, C#, C/C++, VB, ASP, JAVA, HTML, FORTRAN, PHP, etc.

6.
http://www.aisto.com/roeder/dotnet/

Reflector is a class browser for .NET components. It supports assembly and namespace views, type and member search, XML documentation, call and callee graphs, IL, Visual Basic, Delphi and C# decompiler, dependency trees, base type and derived type hierarchies and resource viewers.

Resourcer is an editor for .resources binaries and .resX XML file formats used with the .NET platform. The program allows the integration of bitmaps, icons and text strings into resource packages. Resourcer allows editing of name/string pairs, import of various kinds of data formats (bitmaps, icons, etc) and merging of resources from different sources.

7.
http://test.saurik.net/anakrino/

8.
MaxtoCode
http://www.cnblogs.com/aiasted/

9.
让Reflector的反编译不能正常工作

By midea0978
From http://www.cnblogs.com/midea0978/articles/110365.html

用过Reflector的都知道,这是一个功能非常强大的反编译工具,几乎能够将你的.net代码完全还原,并且能够立即重新
编译运行,本文提供了一个方法让Reflector的反编译不能正常工作,据研究,目前很多代码混淆工具已经使用了该技术,
为了便于理解,我将该方法姑且叫做代码顺序扰乱技术。
下面来研究一个具体的例子:
1)StrConv.cs源代码如下:

using System;
public class StrTool
{
public static void Main(String[] argv){
String s1="\ud7d1\udec3\ue5b9\ueca6";
int num=0x4308d77e;
Console.WriteLine(conv(s1,num));
}

public static string conv(string str, int num)
{
char[] chArray1 = str.ToCharArray();
for (int num1 = 0; num1 < chArray1.Length; num1++)
{
chArray1[num1] = (char)(chArray1[num1] - num);
num += 0x6fd;
}
return new string(chArray1);
}

}

运行csc strconv.cs编译运行,结果是SHA1,程序的功能是简单的字符串加密处理。
用Reflector打开strconv.exe文件,发现所有代码可以准确的反编译为c#。

2)用ildasm反编译,导出IL文件StrConv.il,打开找到conv方法的代码如下:
.method public hidebysig static string conv(string str,
int32 num) cil managed
{
// 代码大小 65 (0x41)
.maxstack 4
.locals init (char[] V_0,
int32 V_1,
string V_2)
IL_0000: ldarg.0
IL_0001: callvirt instance char[] [mscorlib]System.String::ToCharArray()
IL_0006: stloc.0
IL_0007: ldc.i4.0
IL_0008: stloc.1
IL_0009: br.s IL_0013
IL_000b: ldloc.0
IL_000c: ldloc.1
IL_000d: br IL_0027
IL_0012: stloc.1
IL_0013: ldloc.1
IL_0014: ldloc.0
IL_0015: ldlen
IL_0016: conv.i4
IL_0017: blt.s IL_000b
IL_0019: ldloc.0
IL_001a: newobj instance void [mscorlib]System.String::.ctor(char[])
IL_001f: stloc.2
IL_0020: br.s IL_003f
IL_0022: br IL_003f
IL_0027: ldloc.0
IL_0028: ldloc.1
IL_0029: ldelem.u2
IL_002a: ldarg.1
IL_002b: sub
IL_002c: conv.u2
IL_002d: stelem.i2
IL_002e: ldarg.1
IL_002f: ldc.i4 0x6fd
IL_0034: add
IL_0035: starg.s num
IL_0037: ldloc.1
IL_0038: ldc.i4.1
IL_0039: add
IL_003a: br IL_0012
IL_003f: ldloc.2
IL_0040: ret
} // end of method StrTool::conv

下面将上面的代码顺序扰乱编排如下,中间夹了几个跳转指令br
.method public hidebysig static string
conv(string str,
int32 num) cil managed
{
// 代码大小 50 (0x32)
.maxstack 4
.locals init (char[] V_0,
int32 V_1,
string V_2)
IL_0000: ldarg.0
IL_0001: callvirt instance char[] [mscorlib]System.String::ToCharArray()
IL_0006: stloc.0
IL_0007: ldc.i4.0
IL_0008: stloc.1
IL_0009: br.s IL_0021

IL_000b: ldloc.0
IL_000c: ldloc.1
//开始跳转
br IL_000d


IL_0020: stloc.1
IL_0021: ldloc.1
IL_0022: ldloc.0
IL_0023: ldlen
IL_0024: conv.i4
IL_0025: blt.s IL_000b

IL_0027: ldloc.0
IL_0028: newobj instance void [mscorlib]System.String::.ctor(char[])
IL_002d: stloc.2
IL_002e: br.s IL_0030
br IL_0030

//***移动过来的代码
IL_000d: ldloc.0
IL_000e: ldloc.1
IL_000f: ldelem.u2
IL_0010: ldarg.1
IL_0011: sub
IL_0012: conv.u2
IL_0013: stelem.i2
IL_0014: ldarg.1
IL_0015: ldc.i4 0x6fd
IL_001a: add
IL_001b: starg.s num
IL_001d: ldloc.1
IL_001e: ldc.i4.1
IL_001f: add
//***返回
br IL_0020

IL_0030: ldloc.2
IL_0031: ret
} // end of method StrTool::conv

修改完毕,保存。大家可以看到只是简单的将代码顺序移动了一下,没有其他任何改变。
用ilasm重新组装ilasm strconv.il成新的strconv.exe

3)重新运行结果正常。然后用Reflector打开strconv.exe文件,反编译conv方法为C#,这时就出现错误了。
System.InvalidOperationException: Invalid branching statement for condition expression with target offset 0027.
at _127._4(Int32 )
at _127._1(Int32 )
at _127._1(Int32 , Int32 )
at _127._1(IMethodDeclaration , IMethodBody )
at _123.VisitMethodDeclaration(IMethodDeclaration value)
at _146._1(Boolean )
不信大家可以试试!

本文只是简单演示了这种代码处理的方法,如果多次移动代码,那么要想还原就更加复杂了。
对于这种问题,Reflector在将来的版本看会不会解决,不过目前最新版本仍然不能处理该问题。

(按:简单的跳转方法而已。矛与盾的攻防正未有穷期)



<< Home

This page is powered by Blogger. Isn't yours?