一、背景

最近项目组新上项目,交付的时间比较急迫,原本好的分支管理习惯没有遵守好,于是出现下面状况:

  1. 多个小伙伴在不同的分支上开发。
  2. 原本QA环境也存在一个阻碍性的bug A
  3. 一位同事在QA环境发布了新的代码,引入了新bug B
  4. 回滚QA能修改bug B,但是对于bugA却无能为力
  5. 同时,混乱的代码管理已经导致无法确定原始发布包对应的代码版本。

最终陷入了两难的地步,既不能发布新包,回滚也无法解决问题。

好在之前了解到如何使用微软官方工具ILAsm与ILDasm对dll文件进行修改,于是开始动手实现。下面将会用示例代码讲解如何修改已经的.exe文件。

二、ILAsm与ILDasm

我们知道,.net是一个跨平台的的开发平台,其跨平台则是由其编译的中间语言(Intermediate Language, 简称IL或MSIL)实现,无论我们使用的是C#、VB.Net、还是F#或者C++, 最终都会被编译成IL,由JIT(Just In Time)编译成目标机器语言,在CLR(Commen Language Runtime, 公用语言运行时)上运行。

因此,理论上,我们可以跳过过平时使用的C#代码,直接修改IL,然后生成相应的dll或者exe文件。

那么如何查看与修改IL呢,这就是ILAsm与ILDasm的工作了。ILAsm (MSIL Assembler),用来从IL语言生成PE(Portable Executable),也就是.net中我们使用的.exe、.dll文件。ILDasm (MSIL Disassembler),则与ILAsm相反,从PE文件,生成.IL文件。那么我们可以猜到,要修改dll,我们需要先用ILDasm反编译.dll生成.il文件,再用ILAsm编译修改后的.il文件生成.dll,最终替换.dll文件。

三、使用ILDasm生成IL

先看下示例代码:

    class Program
{
static void Main(string[] args)
{
var loginResult = Login("foo", "111111");
if (loginResult)
{
Console.WriteLine("登录成功");
}
else
{
Console.WriteLine("登录失败,请重试");
}
Console.ReadLine();
}
private static bool Login(string userName, string password)
{
if (userName.Equals("johnny") && password.Equals("123456"))
{
return false;
}
return false;
}
}

显然,上述代码针对Login(string userName, string password)的调用会返回false,导致最后Console中会输出"登录失败,请重试", 我们的目的是通过直接修改.exe文件,让它返回true, Console里面输出"登录成功"。

ILDasm与ILAsm已经包含在Visual Studio发行包中中,无需另外下载安装。按如下步骤执行即可:

1. 开Developer Command Prompt for VS 2017,在里面输入命令ILDasm。

2. 在打开的IL Dasm窗口中找到需要修改的.exe文件。

3. 选择菜单 File > Dump,弹出的新窗口中点击确认,保存生成的.il文件。

整个过程如下面gif所示:

最后会生成相应的.il与.res文件。

四、修改IL

打开.il文件,会看到如下代码(节选)

  .method private hidebysig static bool  Login(string userName,
string password) cil managed
{
// Code size 43 (0x2b)
.maxstack 2
.locals init ([0] bool V_0,
[1] bool V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldstr "johnny"
IL_0007: callvirt instance bool [mscorlib]System.String::Equals(string)
IL_000c: brfalse.s IL_001b IL_000e: ldarg.1
IL_000f: ldstr "123456"
IL_0014: callvirt instance bool [mscorlib]System.String::Equals(string)
IL_0019: br.s IL_001c IL_001b: ldc.i4.0
IL_001c: stloc.0
IL_001d: ldloc.0
IL_001e: brfalse.s IL_0025 IL_0020: nop
IL_0021: ldc.i4.0
IL_0022: stloc.1
IL_0023: br.s IL_0029 IL_0025: ldc.i4.0
IL_0026: stloc.1
IL_0027: br.s IL_0029 IL_0029: ldloc.1
IL_002a: ret
} // end of method Program::Login

这个就是Login(string userName, string password)所对应的IL代码了。如果你了解IL语言,可以直接对其修改。

如果不想直接修改IL,我们可以重写一个小的示例方法,直接return true,如下:

private static bool Login()
{
return true;
}

然后使用ILDasm生成相应的IL代码,替换我们想修改的方法。最终的IL如下:

.method private hidebysig static bool  Login(string userName,
string password) cil managed
{
.maxstack 8 IL_0000: ldc.i4.1
IL_0001: ret } // end of method Program::Login

五、使用ILAsm生成exe

修改保存完.il文件以后,接下来的工作就是利用 ILAsm 让.il文件生成重新生成.exe可执行文件了,在Console中执行如下命令

ilasm ILAsmAndILDasmDemo.il /output:ILAsmAndILDasmDemo_1.exe
// 如果修改的是dll文件,需要加上参数 /dll

成功以后会生成一个ILAsmAndILDasmDemo_1.exe文件,执行这个文件,我们可以看到,现在已经显示"登录成功"了。



使用反编译工具 dotPeekI查看新生成的ILAsmAndILDasmDemo_1.exe文件,我们能够看到,Login(string userName, string password)已经直接return true了。如下图,

六、总结

其它,上面所做的事情其实也是《CLR via C#》中提到强名能够 防止代码被不怀好意的人篡改 的一个反面教材了。通过这个例子,大家应该对代码被篡改的风险也有一定的认识了,所以如果大家需要将自己的.dll(.exe)文件露给别人,最好还是打上强名,防止别人恶意篡改你的代码,导致不必要的损失。

经过这次事件,也证明了多了解下底层还是很有必要的,说不定哪天就用上了。平时再忙,也不能只限于只业务和编程语言层面,还需要对底层有一定的了解,这样才能知其然与知其所以然。

虽然此次在不修改c#代码的情况下完美解决QA的环境问题,但是这种方法也只限于小范围的改动,只试用于救急。所以给我的教训是分支管理规范才是王道,要能做到随时可发布,随时可回滚才行,这样才能完全避免再次出现这样尴尬的情况了。

如何使用ILAsm与ILDasm修改.Net exe(dll)文件的更多相关文章

  1. Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作

    Visual Studio 2017中使用正则修改部分内容   最近在项目中想实现一个小工具,需要根据类的属性<summary>的内容加上相应的[Description]特性,需要实现的效 ...

  2. C# 动态修改dll的签名 以及修改引用该dll文件的签名

    在读取RedisSessionStateProvider配置 提到用mono ceil 来修改程序集以及它的签名,里面GetPublicKey 和GetPubliKeyToken 方法里面那个字符串的 ...

  3. Delphi提取EXE,DLL文件图标

    //uses ShellAPIprocedure TForm1.Button1Click(Sender: TObject);var IconIndex:Word; h:hICON;begin Icon ...

  4. 用ildasm和ilasm对.net下的exe程序进行破解初探

    1.对ildasm和ilasm的解释和用法在msdn上有. ildasm:MSIL 反汇编程序是 MSIL 汇编程序 (Ilasm.exe) 的伙伴工具. Ildasm.exe 采用包含 Micros ...

  5. 利用 ildasm 修改被编译后DLL文件

    在开发中遇到这样一个场景,需要修改一个dll文件(.NET程序集)中某些地方的类型名称,但没有源代码,只能修改IL代码. 操作步骤如下: 1. 运行ildasm ildasm是由微软提供的.NET程序 ...

  6. 使用微软的 ilasm 和 ildasm 对. net程序进行编译和反编译

    为了保证示例的完整性,请先准备好一个 c#写的 exe 程序,或者可以使用我提供的 exe 程序也可以(很简单,为了测试这里仅生成了一个带按钮的 winform,单击按钮提示弹窗) Test WinF ...

  7. 用 ilasm 反编译、修改.net dll文件

    有些.net dll我们没有源码,如果要修改某些东西,可以用ilasm.exe反编译为il代码,修改后再编译回dll ilasm通常放在以下路径 C:\Windows\Microsoft.NET\Fr ...

  8. 如何用DELPHI编程修改外部EXE文件的版本信

    右击里面有修改 点开直接修改就可以了吧. DELPHI 里程序的版本信息怎么是灰色的,无法更改 耐心读以下说明,应该能解决你的问题,如果不能解决,请Hi我~ 如何给自己的dll文件添加版本信息呢? 首 ...

  9. 应用程序启动后修改自身EXE文件或自删除EXE文件(附VC++6.0源码)

    在CSDN论坛看到这么一个问题:如何为第三方工具加上使用限制次数?问题的答案很简单,重新做一个应用程序,将第三方程序打包进这个应用程序,启动应用程序时可以检查第三方工具的使用次数,检查通过,可运行第三 ...

随机推荐

  1. 【BZOJ2754】喵星球上的点名(AC自动机)

    [BZOJ2754]喵星球上的点名(AC自动机) 题面 BZOJ 题解 友情提示:此题请不要在cogs上提交,它的数据有毒 对于点名串构建\(AC\)自动机 然后把名字丢进去进行匹配, 大力统计一下答 ...

  2. 【BZOJ2243】【SDOI2011】染色(树链剖分,线段树)

    题面 我们也要换个花样,这回提供洛谷的题面 题解 线段树+树链剖分大水题 维护颜色段的方法很简单呀... 维护当前区间内的颜色段个数, 以及当前区间左端和右端的颜色, 合并的时候考虑是否要减一下就行了 ...

  3. Spring Boot 文件上传原理

    首先我们要知道什么是Spring Boot,这里简单说一下,Spring Boot可以看作是一个框架中的框架--->集成了各种框架,像security.jpa.data.cloud等等,它无须关 ...

  4. 八年架构师大咖首次揭秘,年薪50W秘籍!

    序言 我是土生土长的老北京人,你们肯定觉得我很有钱,为啥呢? 因为觉得我是北京户口,其实你们错了,我的房子是靠我自己买的,父母基本上没帮到我什么,当然,我也不需要吧! 我只想说,作为一名程序员,我很自 ...

  5. ubuntu安装Eclipse无图标(手动创建软件图标) —— 其他的软件也一样

    //退回根目录 cd / //进入图标存放目录 cd usr/share/applications/ //用文本编辑器打开打开eclipse的图标文件,没有会自动创建 sudo gedit eclip ...

  6. NancyFX 附录: Nuget程序包

    Nancy.Authentication.Forms 该程序包向Nancy提供标准的基于ASP.NET/IIS的表单身份验证服务. 采用这个模块启用身份验证后,可以获得标准ASP.NET表单验证方式. ...

  7. Java接口-----代理模式(Proxy)

    public static void main(String[] args) { // TODO Auto-generated method stub ProxySubject a = new Pro ...

  8. Spring事务传播机制和数据库隔离级别

    Spring事务传播机制和数据库隔离级别 转载 2010年06月26日 10:52:00 标签: spring / 数据库 / exception / token / transactions / s ...

  9. unix及Linux发展历程

    unix及Linux发展历程 版权申明:本文资料为网上收集,由本人整理而成,转载请注明 一,unix诞生: Ken Thompson肯·汤普森 -------- unix之父 在1969年到1970间 ...

  10. 11 个简单的 Java 性能调优技巧

    大多数开发人员理所当然地以为性能优化很复杂,需要大量的经验和知识.好吧,不能说这是完全错误的.优化应用程序以获得最佳性能不是一件容易的事情.但是,这并不意味着如果你不具备这些知识,就不能做任何事情.这 ...