66006630 发表于 2020-9-16 20:16

破解到最后一步,该如果修改这个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


但是实在不会,麻烦各位大佬帮忙看看,目的就是要让这个方法返回一个空字符串。
谢谢!

SoftCracker 发表于 2020-9-16 23:11

@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:56

本帖最后由 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

66006630 发表于 2020-9-16 20:33

细水流长 发表于 2020-9-16 20:23
把报错地方删掉就行了

关键是不知道哪里报错啊?

细水流长 发表于 2020-9-16 20:37

66006630 发表于 2020-9-16 20:39

细水流长 发表于 2020-9-16 20:37
你用红框框起来的部分,点开,删除那行代码即可

那个点不开的。

CrazyNut 发表于 2020-9-16 20:45

46004C    ldloc.1
47004D    callvirt    instance string System.Object::ToString()
480052    ret


47这句后面加一个 ldstr "" 试试。。

或者把47这句改成 ldstr ""

我也不是很熟你看着改改试试

66006630 发表于 2020-9-16 21:04

CrazyNut 发表于 2020-9-16 20:45
46004C    ldloc.1
47004D    callvirt    instance string System.Object::ToString()
48 ...

感谢版主,这么改可以通过,但是修改后再运行时会报错“JIT 编译器遇到内部限制”
这个是咋回事啊

天川天音 发表于 2020-9-16 21:46

本帖最后由 天川天音 于 2020-9-17 21:15 编辑



资料有误,已更正。
参考资料:
https://docs.microsoft.com/zh-cn/dotnet/api/system.text.stringbuilder?view=netcore-3.1#methods

66006630 发表于 2020-9-16 23:39

SoftCracker 发表于 2020-9-16 23:11
@66006630 出错的原因是:byte与byte进行位运算的结果是int,所以不能赋值给byte,dnSpy反编译有误,缺少必 ...

大神!!!
真的太厉害了,我按照你的方法一下就把问题解决了,感谢!!!
页: [1] 2
查看完整版本: 破解到最后一步,该如果修改这个IL指令?