如果有人可以提供建议或为我提供指导,我将非常感激。谢谢。
#1 楼
有一个名为Reflexil for Reflector的插件,可以很轻松地修补.NET二进制文件。Reflexil是一个程序集编辑器,可作为Red Gate的Reflector和Telerik的JustDecompile的插件运行。 Reflexil使用Jb Evain编写的Mono.Cecil
,并且能够操纵IL代码并将修改后的程序集保存到磁盘。 Reflexil还支持C#/ VB.NET代码注入。
我最近在博客上举了一个例子。
评论
不错的文章。我认为Reflexil绝对是完成工作的最简单方法,但也知道如何做其他方法也很好。
– 4r4r4r
13年6月16日在1:41
#2 楼
考虑以下.NET 4.5控制台应用程序:using System;
namespace ReversingMSIL101
{
class Program
{
static void Main(string[] args) {
if (args.Length > 0 && args[0] == "Secret")
Authenticated();
else
Anonymous();
}
private static void Authenticated() {
Console.WriteLine("Gold for the people!");
}
private static void Anonymous() {
Console.WriteLine("Give them copper ...");
}
}
}
编译并打开Ildasm。我们将从加载可执行文件(文件->打开)开始。完成后:将其转储(文件->转储)。 Ildasm会显示一个充满复选框的漂亮对话框,因为我们需要尽可能多的信息,请检查所有内容!先前生成的转储。我们对
if
语句特别感兴趣,因为它控制所提供的密码是否正确;请注意,您可以使用生成的注释轻松找到它。我们将继续看最后一个。长话短说:如果第一个参数不是字符串
"Secret"
,我们将转到该分支并结束于IL_0027
:因此,我们将对最后一条指令进行一些微调,然后将其替换为brfalse.s
:保存文件并打开外壳,导航至包含IL转储的文件夹,然后发出ilasm ReversingMSIL101.il
以便将转储重新组装为可执行文件! br /> //000009: if (args.Length > 0 && args[0] == "Secret")
IL_0001: /* 02 | */ ldarg.0
IL_0002: /* 8E | */ ldlen
IL_0003: /* 69 | */ conv.i4
IL_0004: /* 16 | */ ldc.i4.0
IL_0005: /* 31 | 12 */ ble.s IL_0019
IL_0007: /* 02 | */ ldarg.0
IL_0008: /* 16 | */ ldc.i4.0
IL_0009: /* 9A | */ ldelem.ref
IL_000a: /* 72 | (70)000001 */ ldstr "Secret" /* 70000001 */
IL_000f: /* 28 | (0A)000011 */ call bool [mscorlib/*23000001*/]System.String/*01000013*/::op_Equality(string, string) /* 0A000011 */
IL_0014: /* 16 | */ ldc.i4.0
IL_0015: /* FE01 | */ ceq
IL_0017: /* 2B | 01 */ br.s IL_001a
IL_0019: /* 17 | */ ldc.i4.1
IL_001a: /* 00 | */ nop
IL_001b: /* 0A | */ stloc.0
IL_001c: /* 06 | */ ldloc.0
IL_001d: /* 2D | 08 */ brtrue.s IL_0027
评论
很棒的教程!感谢您抽出宝贵的时间来编写它。我最终在resources.infosecinstitute.com/…上使用了字节码图表。从那里开始,这是一个奇怪的方案,但是您可以重建ILDasm.exe中显示的字节序列,并在十六进制编辑器中搜索它们并进行更改,但是如果未将它们更改为可接受的字节,则会使程序混乱。仍然没有接到正确打no电话的电话,将继续搜索。疯狂的在这些.net程序中,您仅能查看裸露的源代码!
– 4r4r4r
13年6月14日在23:19
好吧,CALL指令是0x28 + <4个字节的令牌>,因此您必须总共NOP(0x00)5个字节。
– dna
2013年6月14日23:43
经过一些测试,我发现根据调用的不同,您不能仅对5个调用字节本身进行nop。您必须先获得ldloc和stloc调用,否则必须执行args推送,尤其是如果函数看起来像.net中的Test(test1,test2(test3))。Testing()时,尤其如此。我不太喜欢这种中介语言。我也想知道如何在Olly中进行动态分析,我对此不太了解,并且我认为修补cmp / jnz会比这容易。
– 4r4r4r
13年6月16日在1:39
有道理,我完全忘记提及展开堆栈。好吧,我从来没有在Olly中做到这一点,但是当他将MSIL方法编译为本地指令时,您将不得不发现JIT。可能不那么聪明,因为您会失去便携性和时间,但这应该很有趣:)
– dna
13年6月16日在9:53
Reflexil会自动处理某种类型的签名例程,MS放置在其中以防止在更改此类字节时也需要寻址的补丁。
– 4r4r4r
13年6月16日在21:49
#3 楼
尽管dna的答案很好并且得到了很好的解释,但是对于现实世界中的可执行文件来说,这通常是不切实际的,除非它们非常简单和简短。转储某些东西,更改它并“重新编译”是容易出错的,尤其是在混淆的程序集等中。我建议您下载Reflexil,它是Reflector插件:您可以看到函数的IL您正在通过Reflector进行查看,以非常简单的方式更改需要更改的任何内容,然后仅保存修改后的exe。因为您不是从头开始转储和重建程序,所以这样不容易出错。同样,您可以通过这种方式将任何东西注入到程序集中,无论是类,新方法还是结构。
评论
OP要求提供一个清晰的示例,在这种精确的情况下,依靠汇编程序更不会出错!由于将在组装过程中检测到错误。注入部分很有趣,我通常依靠Cecil(mono-project.com/Cecil),因为它是开源的,可以让您在程序集中添加/删除/修改任何内容并保存修补的内容!
– dna
2013年6月15日9:19
提醒一下,Reflexil不仅适用于Reflector,而且还适用于ILSpy(开源)和JustDecompile。
–JoséTomásTocino
16 Dec 16'在12:53
评论
更具体地说,我想在try块内修补一个调用。 Ildasm.exe报告IL_0039的地址(在CFF中不对应)有点离题,但在不混淆程序集的情况下通常要做的是:使用ildasm来反汇编程序集,根据需要修改IL,然后使用ilasm重新组装。
是的,听起来不错。无法找到任何教程或无法从Ildasm.exe进行修改,请您多解释一下吗?
另外,我正尝试打个电话。有问题的字节是2885。我知道28字节表示“呼叫”。我尝试将它们更改为00,我认为该语言是NOP(通常为90字节),但它搞砸了。
我让您知道如何自己拨打电话!