.Net反编译实战
原文:.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#代码,是时候对其进行大显身手了。
此时的需求可能有如下几个:
- 修改某一个变量的值(如某个SQL语句字符串)
- 修改某一个方法的具体实现逻辑(如修改某一个按钮点击后做的一些事情)
- 在原有的逻辑中,补充插入自己的新方法或程序中已有的方法。
- 其他未想到的需求。。
下面挨个解决。
1.修改变量的值。
这类问题应该是最简单的一类问题,在我最初没有发现神器插件的时候,用了这样一种相对复杂的方法去做的。
当时的需求是修改程序中的一个执行较慢的SQL语句,也就是改某个字符串的值。
首先我用Reflector查看到相应的方法代码(C#代码),也就是我要修改的那个字符串所在的方法。然后在Reflector工具的上方有个下拉菜单
该菜单可以查看对应该方法C#代码的IL代码,这就给我们这些看不太懂IL代码的童鞋们一些希望了。通过IL视图,我们能够查看到这个方法的IL代码是类似这样的:
由于微软提供的工具可以支持DLL与IL代码的相互转化,那么我们就可以通过修改原始IL代码来重新生成DLL实现修改DLL的目的!那么该如何去做呢?
首先打开ildasm工具,该工具所在的位置大致是:
C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin
打开后将DLL文件拖进去,即可查看该DLL的一些结构:
其中展开可以看到某一个方法的IL代码。
通过该工具可以将DLL转储为IL代码文件,操作是:文件->转储
接下来通过文本编辑器可以查看il文件,由于刚才我们已经通过Reflector定位到了某个方法的IL代码,通过搜索il代码,可以比较容易的找到。(后来又发现了一个更好的方法,由于Reflector工具和微软的工具是两款工具,生成的IL有一些细微的差别,更好的做法是通过ildasm查看到需要修改的方法的原始IL代码,再在文本编辑器里搜索)
接下来就是修改具体的代码了,字符串啊,想改成什么就改成什么,即使我们看不太懂IL命令。
修改后需要重新编译回DLL文件,这就需要请出我们的又一个神器ilasm了,这是一个需要用命令行运行的工具。运行方法是:
//先要找到.net具体版本下的这个目录。
cd C:\Windows\Microsoft.NET\Framework\v2.0.50727
//执行转换操作
ilasm c:\test.il /output=c:\test.dll /dll
意思是将C盘下的test.il文件输出成test.dll文件,没有错误的话就可以成功生成。
PS:有时候还需要将转储后的其他相关文件一起拷贝过来才能成功生成DLL。
2.修改某一个方法的具体实现逻辑
这个就相对有点复杂了,不同情况有不同的处理方式,需要用到一些小技巧。
- 修改方法体相对简单的方法。
这种情况只需要Reflector插件就可以搞定了,因为该插件有一个给力的功能就是能以C#视图去修改某个方法的IL代码。有图有真相:
在IL代码中右键 Replace all…可以打开一个C#代码编辑器:
该编辑器中左侧是C#代码,右侧是如果编译成功会显示的IL代码。
这个编译器有几点使用心得:
- 需要修改的方法,打开后默认变成空的了。所有如果是小改动,需要提前复制好代码。
- 代码中使用的对象除了C#基本的数据类型外,一般都需要写全限定名称。如DataTable dt就应该写成:System.Data.DataTable dt,否则不会编译通过。
- 对于引用了外部程序集中的对象,需要自己手工在#region " Imports "中自行添加using了哪个程序集。
- 基本修改后尝试点击左下角的编译按钮,如果报错的话,定位到下面的字段说明中,可以把报错的那行注释掉。
- 编译通过后,记得把这段代码保存起来,因为下次一旦再修改这段代码,就不用重新改了,省去了一些时间。
修改后点击左侧树形目录的那个程序集,右键,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页面进行修改。
步骤大概是:
- 准备一个需要调用的方法(自己的DLL中)
- 在aspx页面头添加对自己dll的引用
- 实例化自己dll的类的一个对象
- 调用自己的方法(页面级调用)
- 页面级输出一些结果(如表格数据之类)
具体的操作是:
.Net反编译实战的更多相关文章
- 设计模式课程 设计模式精讲 8-8 单例设计模式-Enum枚举单例、原理源码解析以及反编译实战
1 课堂解析 2 代码演练 2.1 枚举类单例解决序列化破坏demo 2.2 枚举类单例解决序列化破坏原理 2.3 枚举类单例解决反射攻击demo 2.4 枚举类单例解决反射攻击原理 3 jad的使用 ...
- java7(1)——反编译深入理解增强的switch(读字节命令实战)
[本文介绍] 本文主要讲java_7 的改进switch的底层实现.反编译一个使用带String的switch的demo并一步步解析反编译出来的字节命令,从编译的角度解读switch的底层实现. [正 ...
- 一次.NET项目反编译的实战经验(WinForm)
最近由于业务需求,需要对一个老项目进行功能调整.但是项目的源代码已经找不到了.所以只能尝试对项目行进反编译. 一.反编译工具的选择 提到.NET的反编译,第一个想到的就是大名鼎鼎的Reflector. ...
- Android 应用程序的反编译
1.ApkTool工具 安装ApkTool工具,该工具可以解码得到资源文件,但不能得到Java源文件.安装环境:需要安装JRE1.61> 到http://code.google.com/p/an ...
- 【转】反编译获取任何微信小程序源码(完)
一.前言最近在学习微信小程序开发,半个月学习下来,很想实战一下踩踩坑,于是就仿写了一个阿里妈妈淘宝客小程序的前端实现,过程一言难尽,差不多两周时间过去了,发现小程序的坑远比想象的要多的多!!在实际练手 ...
- class-dump 反编译私有的库和应用
一.下载并安装class-dump 下载class-dump-3.5.dmg 点击下载 下载完成以后双击.dmg的文件,将里面的class-dump拷贝到/usr/local/bin 设置权限chm ...
- 反编译.NET工程
工具: 1. .Net Reflector 2. 远程桌面 步骤: 1. 远程桌面连接到服务器 IP,port,user,pwd 2. 打开 IIS 这里面就是所部属的网 ...
- 将JAR包反编译,修改后重新打包(转)
将JAR包反编译,修改后重新打包(转) 在学习和开发JAVA项目中,我们经常会用到第三方提供的一些jar.使用这些第三方工具包,可以提高我们开发的效率,缩短开发的时间.有的第三方工具,提供具体的 ...
- 反编译apk
一.反编译Apk得到Java源代码 首先要下载两个工具:dex2jar和JD-GUI 前者是将apk中的classes.dex转化成Jar文件,而JD-GUI是一个反编译工具,可以直接查看Jar包的源 ...
随机推荐
- python学习笔记--for循环
推荐一个学习语言的网站:http://www.codecademy.com 有教程,可以边学边写,蛮不错的. for循环: 1.for loops allow us to iterate throug ...
- docker 现实---中小企业docker环境结构(五)
docker对于中小企业,设定paas他没有足够的能量,没有必要为,个人二手sandbox实用性和小点.我个人觉得,中小企业可以使用docker要规范发展.测试.生产环境. 他画了一个简单的图表: d ...
- android选择和裁剪图像拍摄的图像
转载请注明出处:http://blog.csdn.net/allen315410/article/details/39994913 近期从曾经的项目中扒下来一个经常使用的模块.在这里有必要记录一下的. ...
- ES6箭头函数和它的作用域
原文来自我的前端博客: http://www.hacke2.cn/arrow-functions-and-their-scope/ http://es6rocks.com/2014/10/arrow- ...
- MySQL在大数据Limit使用
它已被用于Oracle一世.但今天,很惊讶,MySQL在对数量级的性能,甚至差距如此之大不同的顺序相同的功能. 看看表ibmng(id,title,info) 只要 id key 指数title ...
- Portal.MVC
Portal.MVC Portal.MVC 简介 项目是基于MVC4+EF,带有角色,权限,用户中心及账户相关(登录,注册,修改密码,找回密码等)等基本功能.参考的开源项目nopcommerce,这是 ...
- 怎样配置nginx同一时候执行不同版本号的php-fpm
在/usr/local/php/etc/php-fpm.conf里找到 listen = 127.0.0.1:9000 将port9000改动为9001 在对应的nginx配置里也做相同的port改动
- Android实战技术:IPC方式简介教程
非实时,通知性的方式 第一种方式就是Intent,Intent可以非常方便的通讯,但是它是非实时的,无法进行实时的像函数调用那样的实时的通讯. 实时的函数调用 但是IPC的根本目的还是为了实现函数的调 ...
- easyui LinkButton
http://www.zi-han.net/case/easyui/menu&button.html
- 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)
写在前面: Java SE5 提供了一种新的类型 Java的枚举类型,关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能 ...