前言

几年前为了破解跑跑卡丁车安卓单机版

请输入图片描述

了解到它是用unity3D引擎开发的,而unity3D引擎则是基于跨平台的.net运行时mono来做的,因此我就开始研究C#程序的破解。为此了解到dnSpy这个逆向C#可执行程序的神器,

dnSpy.jpg

我也因此受到启发,想到把dnSpy移植到安卓平台,这样就可以随时随地破解,因此造了个破轮子droidnSpy

ic_launcher.png

思路

我首先想就是直接把dnSpy整个GUI程序移植到安卓,因为c#是跨平台的,所以只要移植mono到安卓平台(这里就用最流行的arm64平台)就可以了

深入研究后发现,dnSpy是用WPF技术开发的,而mono不支持WPF!!

mono不支持wpf.JPG

我总不能自己移植一个WPF的运行时吧

换个思路,我注意到dnSpy中的这个程序,是在命令行环境下运行的dnSpy,可以通过命令

dnSpy.console.exe.JPG

例如:

  dnSpy.Console.exe -o C:\out\path C:\some\path
      反编译目录中所有.NET文件并保存到C:\out\path
  dnSpy.Console.exe -o C:\out\path -r C:\some\path
      反编译以上目录及子目录中所有.NET 文件
  dnSpy.Console.exe -o C:\out\path C:\some\path\*.dll
      反编译目录中所有.NET的dll文件并保存到C:\out\path
  dnSpy.Console.exe --md 0x06000123 file.dll
      反编译标识为0x06000123的成员
  dnSpy.Console.exe -t system.int32 --gac-file "mscorlib, Version=4.0.0.0"
      从 mscorlib 反编译 System.Int32

既然这样我们就折衷一下,先移植dnSpy.console.exe到安卓arm64平台

因为c#程序和java一样都是跨平台的字节码,所以我只要移植mono到arm64平台

使用Linux deploy

当时我在上海带南瓜集训,没有时间用电脑,也懒得配置交叉编译环境,就干脆在我的手机上直接编译
当时的顶配手机 redmi note 4X(高通骁龙 660-arm64平台)美滋滋
绝世美机,这里就不放图了(^.^)

大家都知道安卓虽然是基于linux内核的,但是是一个阉割版的,很多linux下的东西都不能使用,比如说没有软件仓库,没有gcc,没有make

所以需要在手机上安装一个完整的linux,这个时候就需要linux deploy
简单的说,就是个linux的容器环境,利用chroot命令来在手机上运行完整的Linux发行版
具体教程百度搜索Linux depoly
附一个链接,Linux Deploy安装配置使用教程

我当时安装的是Xubuntu ports,完了可以使用ssh登录上去,也可以使用vnc或者xserver XSDL远程图形化登录上去

vnc.jpg

xserver-XSDL.jpg

网上找的图,我自己的图年代太久远就没了

软件源可以找到中科大的ports源,速度比较快

登录进Xubuntu系统,apt安装各种必要的软件后,就可以开始编译了

 $ sudo apt-get install git autoconf libtool automake build-essential gettext cmake python

编译mono-arm64

mono官网有教程

下载mono源码后make,处理各种编译错误,大概处理了8次错误后,就碰到了一个无法解决的错误

大概意思就是.net环境下的C#写的DLL文件无法编译,但是这个时候c语言写的二进制文件已经编译成功了,运行

mono/bin/mono-sgen

可以看到缺少dll文件的提示,那怎么办呢?

反正c#是跨平台的,所以在电脑上再编译一次mono,然后把编译成功的dll拷贝到手机上就行了

我真是个人才!!(^.^)

电脑上错误比较少,三下五除二就好了
到这里mono就已经移植好了,在手机linux deploy下执行

mono dnSpy.console.exe

完美运行!

使mono运行在安卓环境下

把mono直接放在安卓环境下,用终端模拟器执行

mono dnSpy.console.exe

是没有用的,会提示缺少很多库文件找不到
因为mono运行需要很多动态链接库,而安卓阉割环境下没有这些库,
一个方法是在编译mono的时候加入-static关键字进行静态编译
我这样做了后发现,还是有6个顽固的动态链接库无法静态编译

6个无法静态编译的库文件.png

那我就在安卓环境下指定ld_library这个环境变量为当前的文件夹,然后把这6个顽固的库文件拷贝到mono运行的当前文件夹中

结果还是没用,多方了解到,原来程序运行还缺少解释器interpreter,就是执行elf可执行文件的一个库

用file命令查看mono-sgen(就是mono链接到的可执行文件)

$file mono-sgen
mono-sgen: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=58bd13d372a834c72d57639b520fe25ed93d2c29, not stripped

看到没,这个/lib/ld-linux-aarch64.so.1文件在Linux环境下有,但是安卓阉割环境下没有,所以我们把这个文件从linux deploy中复制过来,但是我不想放在系统文件夹lib中,因为我的程序要做到在任何arm64手机上都能运行,所以我就把ld-linux-aarch64.so.1复制在了mono-sgen相同的文件夹下面,这样mono-sgen就要修改了

懒得重新编译,使用hex edit直接打开mono-sgen修改elf文件中的字符串,把/lib/删除即可,但是这样后面的偏移量都变了,不如将两个斜杠都转为字符

hex查看mono-sgen.png

再次file看一下

$ file mono-sgen
mono-sgen: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter llibbld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=58bd13d372a834c72d57639b520fe25ed93d2c29, not stripped

修改成功,然后将ld-linux-aarch64.so.1文件改名为llibbld-linux-aarch64.so.1放在mono-sgen同样的目录下就可以了

然后我们在安卓终端模拟器中执行mono-sgen,成功运行
执行mono-sgen dnSpy.console.exe,也成功了!!

最后就是安卓app编码啦,稍微写一下就出来了,

成品app下载(测试于红米note4x和小米4c上成功):

链接: https://pan.baidu.com/s/19WudLrcVUz5Rmo9bTWAILg 提取码: w2dq
源码目前已经更新为1.2版的,Android studio项目
http://www.github.com/q77190858/droidnSpy

1.2版的是我刚刚修改了一点点,增加了设备兼容性,增加了反编译时的动画提示,不会阻塞主线程了

动画展示:
https://m.weibo.cn/2401759795/4370502862398554

标签: none

赞赏排名 赞赏支持

已有 2 条评论

  1. 前辈,你的1.2 apk打的是debug InstantRun包,有testonly属性无法安装,且dex中无主Activity

    1. 嗯嗯,当时没有注意,你自己编译一下吧

添加新评论