C#两种⽅式反编译修改源码(dnspy,ildasmilasm)
⼀:背景
1. 讲故事
周五下午运营反馈了⼀个紧急bug,说客户那边⼀个信息列表打不开,急需解决,附带的⽇志⽂件也发过来了,看了下⽇志⼤概是这样的:
⽇期:2020-11-13 12:25:45,923 线程ID:[3924] ⽇志级别:INFO 错误类:xxx property:[(null)] - 错误描述:应⽤程序出现了未捕获的异常,Message:该字符串未被识别为有效的 DateTime。; StackTrace:  在 System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
在 System.(DataTable table, ValueType type, Object constant, Boolean fParseQuotes)
在 System.Data.ExpressionParser.Parse()
在 System.(DataTable table, String expression, Type type)
在 System.(DataTable table, String filterExpression, String sort, DataViewRowState recordStates)
在 System.Data.DataTable.Select(String filterExpression)
从异常信息可以看到,⼤概就是 DataTable.Select 的时候抛出了异常,通过调⽤堆栈追查了下代码⼤概是这样的。
public Task<DataTable> QueryDataTable()
{
var dt = new DataTable();
dt.Columns.Add(new DataColumn("SendTime"));
dt.Rows.Add(dt.NewRow()["SendTime"] = "2020/11/14");
var where = $" SendTime < #{DateTime.Now.ToString()}#";
var query = dt.Select(where).CopyToDataTable();
}
⼤坑就在这⾥,绝⼤多数时候过滤 DataTable 可以采⽤这样的写法 : SendTime < #2020/11/5#,但是客户在新加坡,全英⽂操作系统,⽽且时间格
式也不知道设置成啥样了,我估计时间格式包含了类似的 #,正好⼜遇到了前后缀 # ,拆分上就出错了,导致了经典的该字符串未被识别为有效的DateTime 异常被抛出。
这个 bug 改起来还是很简单的,将 # 换成 ' 即可,也就是: SendTime < '2020/11/5',如果⼀切顺利的话,⽂章就应该到此为⽌了,可恰恰上天捉
弄,因为是紧急bug,研发⽼⼤ & 项⽬实施都请假了,我⼀个⼈还真搞不定,也不知道给了客户哪⼀个 release 版,不想节外⽣枝,为了先解决这
个问题,我想到了⼀个好办法,反编译修改,这是代价最⼩的,也能最快的搞定。
⼆:使⽤ dnspy 反编译修改代码
1. 使⽤ dnspy 的编辑⽅法模式
为了更好的理解通过 dnspy 修改,先来聊⼀聊 dnspy 最便捷的修改 dll 的⽅式:编辑⽅法,这种⽅式⾮常⽅便,⽆需理解 IL 代码,为了演⽰,我举⼀个简单的加法运算。
static void Main(string[] args)
{
var i = 10;
var j = 20;
Console.WriteLine($"{i}+{j}={i + j}");
Console.ReadLine();
}
接下来将 var i= 10 改成 var i=100 的步骤为:
右键编辑⽅法
弹框修改 var i=10 -> var i=100
点击右下⾓编译
Ctrl + Shift + S 全部保存
弹出框中选择确定
截图⼤概如下:
最后 bin ⽬录下的 exe 就被成功修改了,双击之后就能看到你的成果啦!
,果然搞定了,是不是太简单了?感觉做这种反编译⼀点门槛都没有,哈哈,真的没有门槛吗?
不信的话,我举⼀个异步⽅法的例⼦:
class Program
{
static void Main(string[] args)
{
var query = QueryDataTable().Result;
Console.WriteLine(JsonConvert.SerializeObject(query));
Console.ReadLine();
}
static async Task<DataTable> QueryDataTable()
{
tabletablevar dt = new DataTable();
dt.Columns.Add(new DataColumn("SendTime"));
dt.Rows.Add(dt.NewRow()["SendTime"] = "2020/11/14");
var where = $" SendTime < #{DateTime.Now.ToString()}#";
Console.Write(where + "\t");
var task = await Task.Run(() => { return dt.Select(where).CopyToDataTable(); });
return task;
}
}
接下来反编译⼀下:
我去,⿇烦了,从图中可以看出两点信息:
异步⽅法会⽣成状态机,⽤ C# 模式看反编译的代码,那些⾃动⽣成的状态机类看都看不到,谈何修改⽐如你能到: var where = $" SendTime < #{DateTime.Now.ToString()}#"; 吗?
从 <QueryDataTable>d__1 类的命名格式: <QueryDataTable>d__ 来看,你点击编译按钮肯定是过不了编译器的。
⽽恰恰我遇到的就是这种情况,太坑爹了。。。所以说,不碰 IL 在实际反编译中是不可能的。
2. 使⽤ dnspy 的编辑IL指令模式
dnspy 中除了编辑⽅法外,还可以使⽤编辑IL指令,这功能就强⼤了,接下来看看怎么处理呢?操作步骤如下:
在 dnspy 中将 C# 切换到 IL 视图
到需要修改的类的 IL 代码处,右键选择编辑IL指令
编辑完成之后,点击确定
⼤概截图如下:
然后双击执⾏ exe ,可以看到已经修改成功了。
不过这⾥有⼀个吐糟的地⽅就是,这次bug我需要修改的地⽅有多处,⽽编辑IL指令的窗⼝中并没有搜索功能,这就尴尬了,处理起来⾮常⿇烦!三:使⽤ ildasm & ilasm 反编译修改代码
1. 介绍
这⼀对还是蛮有意思的,ildasm ⽤于查看 dll 中的 il 代码, ilasm ⽤于将 il 编译成 dll,所以两者配合使⽤挺好的。
ildasm 路径:C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8
ilasm 路径:C:\Windows\Microsoft.NET\Framework64\v4.0.
2. 使⽤ ildasm 导出 il⽂件
打开 ildasm,点击 '⽂件' -> '转储' ⽣成 il ⽂件,这⾥我指定名称为 my.il,接下来就可以在 my.il 中将 # 改成 ' ,如下图:
3. 使⽤ ilasm 编译 il ⽂件
使⽤ ilasm 将 my.il 重新⽣成 即可。
E:\net5\ConsoleApp2\ConsoleApp2\bin\Debug>ilasm my.s / /exe
Microsoft (R) .NET Framework IL Assembler. Version 4.8.3752.0
Copyright (c) Microsoft Corporation. All rights reserved.
Assembling 'my.il' to EXE --> ''
Source file is UTF-8
Assembled method ConsoleApp2.Program?<>c__DisplayClass1_0::.ctor
Assembled method ConsoleApp2.Program?<>c__DisplayClass1_0::<QueryDataTable>b__0
Assembled method ConsoleApp2.Program?<QueryDataTable>d__1::.ctor
Assembled method ConsoleApp2.Program?<QueryDataTable>d__1::MoveNext
Assembled method ConsoleApp2.Program?<QueryDataTable>d__1::SetStateMachine
Assembled method ConsoleApp2.Program::Main
Assembled method ConsoleApp2.Program::QueryDataTable
Assembled method ConsoleApp2.Program::.ctor
Assembling 'my.res' to EXE --> ''
Source file is UNICODE
Creating PE file
Emitting classes:
Class 1:    ConsoleApp2.Program
Class 2:    ConsoleApp2.Program?>c__DisplayClass1_0
Class 3:    ConsoleApp2.Program?QueryDataTable>d__1
Emitting fields and methods:
Global
Class 1 Methods: 3;
Class 2 Fields: 2;  Methods: 2;
Class 3 Fields: 6;  Methods: 3;
Resolving local member refs: 44 -> 44 defs, 0 refs, 0 unresolved
Emitting events and properties:
Global
Class 1
Class 2
Class 3
Method Implementations (total): 2
Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved
Writing PE file
Operation completed successfully
E:\net5\ConsoleApp2\ConsoleApp2\bin\Debug>ilasm my.s / /exe
Microsoft (R) .NET Framework IL Assembler. Version 4.8.3752.0
Copyright (c) Microsoft Corporation. All rights reserved.
Assembling 'my.il' to EXE --> ''
Source file is UTF-8
Assembled method ConsoleApp2.Program?<>c__DisplayClass1_0::.ctor
Assembled method ConsoleApp2.Program?<>c__DisplayClass1_0::<QueryDataTable>b__0
Assembled method ConsoleApp2.Program?<QueryDataTable>d__1::.ctor
Assembled method ConsoleApp2.Program?<QueryDataTable>d__1::MoveNext
Assembled method ConsoleApp2.Program?<QueryDataTable>d__1::SetStateMachine
Assembled method ConsoleApp2.Program::Main
Assembled method ConsoleApp2.Program::QueryDataTable
Assembled method ConsoleApp2.Program::.ctor
Assembling 'my.res' to EXE --> ''
Source file is UNICODE
Creating PE file
Emitting classes:
Class 1:    ConsoleApp2.Program
Class 2:    ConsoleApp2.Program?>c__DisplayClass1_0
Class 3:    ConsoleApp2.Program?QueryDataTable>d__1
Emitting fields and methods:
Global
Class 1 Methods: 3;
Class 2 Fields: 2;  Methods: 2;
Class 3 Fields: 6;  Methods: 3;
Resolving local member refs: 44 -> 44 defs, 0 refs, 0 unresolved
Emitting events and properties:
Global
Class 1
Class 2
Class 3
Method Implementations (total): 2
Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved
Writing PE file
Operation completed successfully
可以看到,最后编译成 exe 成功,双击 可以看到最新的成果。
四:总结
本篇介绍了两种修改 dll 的⽅式,其实实操起来我感觉 ildasm & ilasm 的⽅式更灵活⼀点,如果⼤家有更好的反编译修改的⽅式,欢迎留⾔讨论哈!以上就是C# 两种⽅式反编译修改源码(dnspy,ildasm & ilasm)的详细内容,更多关于c# 反编译修改源码的资料请关注其它相关⽂章!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。