zoukankan      html  css  js  c++  java
  • .Net反编译实战

    当你面对一个已经部署好的网站,功能,性能都非常不给力的时候,你会怎么办?

    当你尝试去了解这个网站业务逻辑,代码逻辑和数据库逻辑时却发现根本没有任何资料时你会怎么办?

    当你准备去修改这个程序却发现根本木有源代码而只有一堆堆的DLL和aspx的时候,你会怎么办?

    当你发现这个网站配置及其复杂,只有一个线上环境而且处处是坑的时候,你会怎么办?

    当你面对一个要求严格的领导,心怀一切皆有可能的思想时,准备让你对此进行优化和功能修改时,你会怎么办?

     

    重构?罢工?辞职?

    不错,是个选择!

     

    要是那样的话,就不会有这篇文章了亲。

     

    所以,只有硬着头皮干下去。。

     

    言归正传,首先介绍几款神器:

    1.Reflector ——.Net反编译工具

      我用的是8.0的破解版,支持直接运行和以VS插件形式运行,测试表示以VS插件的形式速度比较慢,容易将VS卡死,所以不推荐。

    2.Ilasm和ildasm——微软自带的编译和反编译工具

      这两款工具是Framework自带的,虽然界面不是很华丽,但是功能还是很给力的。

    3.Reflexil——一款Reflector插件

      相当给力,可以通过界面的形式对DLL中的类,方法,属性等进行修改和注入

     

    有了几款神器,下面就是如何对一个DLL进行开刀了。

     

    首先,在不清楚DLL作用的情况下,可以先通过aspx页面找一些线索。

    <%@ Page Language="C#" MasterPageFile="Template/LogonMasterPage.Master" AutoEventWireup="true" Inherits="Logon" Codebehind="Logon.aspx.cs" %>
    

     如页面顶部Inherits表示的是这个页面 定义供页继承的代码隐藏类,在DLL中搜索这个类可以找到该页面的一些后台代码逻辑。

     结合aspx的服务器控件的事件可以找到对应的实现。

     

    找到了对应的C#代码,是时候对其进行大显身手了。

    此时的需求可能有如下几个:

    1. 修改某一个变量的值(如某个SQL语句字符串)
    2. 修改某一个方法的具体实现逻辑(如修改某一个按钮点击后做的一些事情)
    3. 在原有的逻辑中,补充插入自己的新方法或程序中已有的方法。
    4. 其他未想到的需求。。

     

    下面挨个解决。

    1.修改变量的值。

    这类问题应该是最简单的一类问题,在我最初没有发现神器插件的时候,用了这样一种相对复杂的方法去做的。

     

    当时的需求是修改程序中的一个执行较慢的SQL语句,也就是改某个字符串的值。

    首先我用Reflector查看到相应的方法代码(C#代码),也就是我要修改的那个字符串所在的方法。然后在Reflector工具的上方有个下拉菜单

     

    该菜单可以查看对应该方法C#代码的IL代码,这就给我们这些看不太懂IL代码的童鞋们一些希望了。通过IL视图,我们能够查看到这个方法的IL代码是类似这样的:

     

     

    由于微软提供的工具可以支持DLL与IL代码的相互转化,那么我们就可以通过修改原始IL代码来重新生成DLL实现修改DLL的目的!那么该如何去做呢?

     

    首先打开ildasm工具,该工具所在的位置大致是:

    C:Program FilesMicrosoft SDKsWindowsv7.0Ain

     

     

    打开后将DLL文件拖进去,即可查看该DLL的一些结构:

     

     其中展开可以看到某一个方法的IL代码。

     

    通过该工具可以将DLL转储为IL代码文件,操作是:文件->转储

     

    接下来通过文本编辑器可以查看il文件,由于刚才我们已经通过Reflector定位到了某个方法的IL代码,通过搜索il代码,可以比较容易的找到。(后来又发现了一个更好的方法,由于Reflector工具和微软的工具是两款工具,生成的IL有一些细微的差别,更好的做法是通过ildasm查看到需要修改的方法的原始IL代码,再在文本编辑器里搜索)

    接下来就是修改具体的代码了,字符串啊,想改成什么就改成什么,即使我们看不太懂IL命令。

     

    修改后需要重新编译回DLL文件,这就需要请出我们的又一个神器ilasm了,这是一个需要用命令行运行的工具。运行方法是:

    //先要找到.net具体版本下的这个目录。

    cd C:WindowsMicrosoft.NETFrameworkv2.0.50727

    //执行转换操作

    ilasm c: est.il /output=c: est.dll /dll

    意思是将C盘下的test.il文件输出成test.dll文件,没有错误的话就可以成功生成。

    PS:有时候还需要将转储后的其他相关文件一起拷贝过来才能成功生成DLL。

     

     

    2.修改某一个方法的具体实现逻辑

    这个就相对有点复杂了,不同情况有不同的处理方式,需要用到一些小技巧。

    1. 修改方法体相对简单的方法。

    这种情况只需要Reflector插件就可以搞定了,因为该插件有一个给力的功能就是能以C#视图去修改某个方法的IL代码。有图有真相:

     

    在IL代码中右键 Replace all…可以打开一个C#代码编辑器:

     

     

    该编辑器中左侧是C#代码,右侧是如果编译成功会显示的IL代码。

    这个编译器有几点使用心得:

    1. 需要修改的方法,打开后默认变成空的了。所有如果是小改动,需要提前复制好代码。
    2. 代码中使用的对象除了C#基本的数据类型外,一般都需要写全限定名称。如DataTable dt就应该写成:System.Data.DataTable dt,否则不会编译通过。
    3. 对于引用了外部程序集中的对象,需要自己手工在#region " Imports "中自行添加using了哪个程序集。
    4. 基本修改后尝试点击左下角的编译按钮,如果报错的话,定位到下面的字段说明中,可以把报错的那行注释掉。
    5. 编译通过后,记得把这段代码保存起来,因为下次一旦再修改这段代码,就不用重新改了,省去了一些时间。

     

    修改后点击左侧树形目录的那个程序集,右键,save as,如果不报错,OK,搞定!

     

     

      2.修改方法体相对复杂的方法。

    对于这种修改,上述方法很可能不容易编译通过,因为牵连的东西比较多,所以……

    需要将原程序段中的方法调用,改为一个新的方法调用。(新方法如果和旧方法差异不大的话可以把旧方法进行一个“克隆”)新的方法可以是自己新建DLL中的一个方法(最好是静态方法),而且保险起见,新方法的参数类型和名称尽量和旧方法一致,便于直接修改IL。

     

    调用自己的方法,需要先将自己的DLL拖入Reflector中关联起来。然后在IL视图里找到调用旧方法的那一段(IL表格中的那一行),右键编辑,进行修改。修改时对于调用静态方法使用call指令,具体的方法可以在不同DLL中进行选择。

    如图:

     

    之后进行保存就可以了。

     

    如果是对原有方法进行的简单修改,可以采用“克隆”的方法进行操作。

    所谓克隆,就是用工具像原有dll中注入一个新的方法。

     

     

    注入方法时,输入方法名即可,确定后不会立刻看到该方法,需要将DLL保存后,重新加载才能看到。

     

    重新加载后,看到的新方法默认是Void的,而且不带任何参数,这和我们克隆的目标方法可能不太一样,所以,还需要改一下参数和返回值类型以及其他相关属性,修改的方法是比较修改法。即在克隆方法的选项卡中依次比较每一个选项,修改成和目标方法一模一样的新方法。

     

    修改新方法的各个属性。

     

    再次保存。即可克隆出一个方法签名类似的新方法。

     

    接下来就是克隆方法体了,这里还有个技巧,如果方法简单,直接通过C#视图就可以将原方法体粘贴进去,编译。

    如果方法体复杂,则需要通过之前提到的微软工具进行IL代码的移植。即,复制原方法的IL代码实现,粘贴到克隆方法的方法体中。

     

    这些操作中可能会遇到的一些注意事项:

    添加方法时的参数可参考已有方法的参数界面进行选择,其中System下的对象在microlib.dll里。

    il编译不通过可以增加Using,下面字段里不要添加自己的对象,否则无法生成dll(可以把属性用私有成员替代!)

    使用C#视图无法调用新注入的函数时,可以先克隆一个原有函数(函数头一样的),然后再使用IL视图的Edit功能把旧方法换成克隆后的方法。最后再修改克隆后的实现。

    每次增加新方法,需要更新关联的DLL

    Clone方法头可以使用reflecxil工具,克隆复杂的方法体,可以使用微软IL工具,查看到具体的方法的IL代码,复制。然后用文本编辑器找到Clone的方法体,粘贴。重新编译。

     

     此外还可以尝试修改类成员的访问权限,如改成public,注入其他成员等。

     

    除了在DLL中下手调用新的方法,还可以直接通过aspx页面进行修改。

    步骤大概是:

    1. 准备一个需要调用的方法(自己的DLL中)
    2. 在aspx页面头添加对自己dll的引用
    3. 实例化自己dll的类的一个对象
    4. 调用自己的方法(页面级调用)
    5. 页面级输出一些结果(如表格数据之类)

     具体的操作是:

     

  • 相关阅读:
    纪念一下Jerry
    在中信66楼微软Offic参加讲座
    关于地理信息信息点数据采集一些方法
    简单的C#进行图片操作
    PHP访问C#建立的Webservice
    搜索引擎一:介绍
    介绍一况挺好用的Javascript编辑器(带项目)
    服务器不支持WebResource.axd的特殊处理
    Daily Web Words
    php psr 编码规范(PSR[04])
  • 原文地址:https://www.cnblogs.com/dannywang/p/3262092.html
Copyright © 2011-2022 走看看