破解到最后一步,该如果修改这个IL指令?
本帖最后由 66006630 于 2020-9-17 07:16 编辑也脱壳了
也找到关键函数了
现在就是要修改一个指令
程序是C# 写的,我使用dnspy对其进行编辑。
原始的反编译出来的方法见下图:
该方法返回了一个字符串,现在就是希望图片中的方法能返回一个空字符串。
我在dnspy里使用了“编辑方法”,但是会报错。看图
我注释掉了一个数组,并写了一个新的空数组,编译会报错。
我也尝试过把最后return 改了,但是也是报同样的错。
我进入IL指令编辑,如下:
0 0000 ldarg.0
1 0001 call uint8[] Class92/Class93::smethod_0(int32)
2 0006 stloc.0
3 0007 newobj instance void System.Text.StringBuilder::.ctor()
4 000C stloc.1
5 000D ldc.i4.0
6 000E stloc.2
7 000F br.s 41 (0046) ldloc.2
8 0011 ldc.i4.2
9 0012 newarr System.Byte
10 0017 dup
11 0018 ldc.i4.0
12 0019 ldloc.0
13 001A ldloc.2
14 001B ldelem.u1
15 001C ldc.i4 0xFF
16 0021 xor
17 0022 conv.u1
18 0023 stelem.i1
19 0024 dup
20 0025 ldc.i4.1
21 0026 ldloc.0
22 0027 ldloc.2
23 0028 ldc.i4.1
24 0029 add
25 002A ldelem.u1
26 002B ldc.i4 0xFF
27 0030 xor
28 0031 conv.u1
29 0032 stelem.i1
30 0033 stloc.3
31 0034 ldloc.1
32 0035 ldloc.3
33 0036 ldc.i4.0
34 0037 call char System.BitConverter::ToChar(uint8[], int32)
35 003C callvirt instance class System.Text.StringBuilder System.Text.StringBuilder::Append(char)
36 0041 pop
37 0042 ldloc.2
38 0043 ldc.i4.2
39 0044 add
40 0045 stloc.2
41 0046 ldloc.2
42 0047 ldloc.0
43 0048 ldlen
44 0049 conv.i4
45 004A blt.s 8 (0011) ldc.i4.2
46 004C ldloc.1
47 004D callvirt instance string System.Object::ToString()
48 0052 ret
但是实在不会,麻烦各位大佬帮忙看看,目的就是要让这个方法返回一个空字符串。
谢谢!
@66006630 出错的原因是:byte与byte进行位运算的结果是int,所以不能赋值给byte,dnSpy反编译有误,缺少必要的转换,应改为:
array ^ byte.MaxValue,
array ^ byte.MaxValue
=>
(byte)(array ^ byte.MaxValue),
(byte)(array ^ byte.MaxValue)
另外,你也不能改成 byte[] array = null; 否则array.Length将引发异常
@CrazyNut 平白添加一条ldstr指令,将导致堆栈不平衡,即使按你的方法,也应该是添加两条指令:
pop
ldstr ""
@天川天音 无言以对
解决办法:
1. C#方法:方法体只保留一句return ""; 其他全删掉
2. IL方法:在函数体开头处添加两条指令:
ldstr ""
ret
本帖最后由 SoftCracker 于 2020-9-16 23:59 编辑
howze 发表于 2020-9-16 23:51
学到了@howze @66006630 你们两个是同一个人吗? 下面这句话你们两个好像都在说,@howze把贴子编辑了,找不到了:
另外再问一下大神,为什么我直接把47行的指令改成ldstr “” 会报jit出错?按说这是直接修改,并不是凭空添加,为啥还会报错呢?
47:callvirt instance string System.Object::ToString()
该语句的堆栈行为是:
弹出一个对象(ldloc.1)并压入一个对象
ldstr "" 的堆栈行为是:
压入一个对象(而不弹出任何对象),这将导致堆栈中的ldloc.1没有弹出
细水流长 发表于 2020-9-16 20:23
把报错地方删掉就行了
关键是不知道哪里报错啊?
细水流长 发表于 2020-9-16 20:37
你用红框框起来的部分,点开,删除那行代码即可
那个点不开的。 46004C ldloc.1
47004D callvirt instance string System.Object::ToString()
480052 ret
47这句后面加一个 ldstr "" 试试。。
或者把47这句改成 ldstr ""
我也不是很熟你看着改改试试 CrazyNut 发表于 2020-9-16 20:45
46004C ldloc.1
47004D callvirt instance string System.Object::ToString()
48 ...
感谢版主,这么改可以通过,但是修改后再运行时会报错“JIT 编译器遇到内部限制”
这个是咋回事啊 本帖最后由 天川天音 于 2020-9-17 21:15 编辑
资料有误,已更正。
参考资料:
https://docs.microsoft.com/zh-cn/dotnet/api/system.text.stringbuilder?view=netcore-3.1#methods
SoftCracker 发表于 2020-9-16 23:11
@66006630 出错的原因是:byte与byte进行位运算的结果是int,所以不能赋值给byte,dnSpy反编译有误,缺少必 ...
大神!!!
真的太厉害了,我按照你的方法一下就把问题解决了,感谢!!!
页:
[1]
2