记一次通过反编译恢复Android代码的经历(一)

152 阅读3分钟

起因

最近在维护公司一老项目,发现客户使用的包的版本号比git上高不少,这意味着该项目代码可能没有提交,顿时心中一凉,因为负责这个项目的同事已经离职,电脑也已经被回收,所以想找到这个项目文件是不可能了,那只能去尝试恢复这部分代码了,下面记录一下我的操作过程,以供参考。

过程

注意:下面的操作都在windows环境下进行,linux和mac用户自行替换相关命令,原理是一样的

1.准备apk文件

  • 首先需要找到你要恢复的版本对应的apk文件,最好是未开启混淆的版本(比如debug包),不然很难操作
  • 然后使用当前项目文件重新打包一个和上述版本一致的包(打包参数一致,比如都是debug包,相同渠道,目的是排除不必要的差异)

2.提取jar文件

将apk中的dex文件转为jar文件,这一步需要借助dex2jar这个工具,使用也是非常简单

d2j-dex2jar.cmd .\xxx.apk

之后会在当前目录生成一个jar文件(支持multiple dex)

两个apk都要提取

3.从jar文件中提取出自己项目包名下的代码

jar文件可以直接用解压软件打开,找到自己包名下的代码后直接拖出来即可,这一步的目的是排除依赖的三方代码的影响,只关注自己的项目代码。

提取后的代码文件夹,可以使用jar命令打包成jar文件,首先进入到要打包的文件夹根目录,执行下面命令

jar.exe cvf xxx.jar *

4.比对jar文件差异

通过上面的步骤操作,我们已经得到了两个只包含我们自己项目代码的jar文件,接下来需要使用jarcomp这个工具比对下代码差异,这个工具是一个jar文件,使用方法如下,a.jar b.jar是需要比对的jar文件

java -jar jarcomp.jar a.jar b.jar

执行后你会得到一个如下图所示的弹框

微信截图_20230420134842.png

黄色部分是两个文件之间的差异,有了这个差异性列表之后,我们就可以去替换代码了

5.代码替换

首先需要打开你要恢复的这个版本的jar文件,这一步我们使用jadx,下载后,找到jadx-gui.bat这个文件,运行它,之后你需要配置下,将调试信息关掉,否则代码中将会有调试信息的注释

方法如下:文件->首选项

image.png

打开jar文件后,你就可以按照步骤4中拿到的差异性列表来找到对应的文件,然后将内容替换到你的项目中,这是一个非常考验耐心和细心的活,慢慢来

这里需要说明下,由于代码是反编译的,所以代码中的常量都是直接显示的,比如

  • setVisibility(View.GONE)反编译后就是setVisibility(8)

  • getSystemService(Context.AUDIO_SERVICE)反编译后就是getSystemService("audio")

等等 不影响运行,但是这样肯定没法维护,所以要自己替换回来

经过上面的操作后,代码部分基本就替换完成了,剩下的就是资源部分,改天抽空再写下吧。。