反编译Android App

大多数APP都对API接口进行了加密,防止第三方随意调用接口,常用的方法是,设置一个key,在调用接口来发送请求时,组合各个参数和key按照一定的规则(排序,MD5等等)生成一个用于验证的token参数,服务端接收到请求后,按照相同的规则组合参数和key去生成token,和收到的token去对比,判断请求是否是第三方伪造发送的。

但是通过抓包和反编译APP,是可以得到key和生成token的规则,来将自己伪装成官方的APP,调用API接口

下面的文章,主要是总结我自己反编译魅族天气的APP来获取API的过程。

工具

反编译class.dex获取java代码

原理:打包生成apk时,java源代码先被编译成.class文件,然后Android SDK自带的dx工具将这些.class文件转换成classes.dex,所以可以反编译classes.dex来得到java源代码

步骤

  1. 下载dex2jar.zip和jd-gui,并解压
  2. 将com.meizu.flyme.weather-2.2.1-2002001.apk重命名为com.meizu.flyme.weather-2.2.1-2002001.zip
  3. 解压com.meizu.flyme.weather-2.2.1-2002001.zip,在解压得到的目录里找到classes.dex
  4. 使用dex2jar将classes.dex反编译得到classes-dex2jar.jar
  5. 使用jd-gui查看classes-dex2jar.jar

操作截图(Mac)

image
image

image
image

注意:执行反编译指令时,可能会提示d2j_invoke.sh: Permission denied,输入sudo chmod +x d2j_invoke.sh来解决

阅读java代码

这一步要耐心,因为代码一般经过来混淆,生成很难看懂的代码,来到达保护代码的目的

通过抓包,获得了天气信息的请求

image
image

然后我观察到sign参数,在每次请求时都会发生变化,它应该就是那个用于验证的参数。

在一堆经过混淆的代码中,会需要比较多的时间,查找到生成验证参数sign的相关代码,这需要耐心。但利用搜索,可以加快查找的速度。

在jd-gui里,File->Save All Sources,将反编译的java文件保存到source文件夹,我们利用请求的url去搜索(代码里的常量字符串一般不会被混淆,利用字符串去搜索,一般都会找到有用的信息,来进一步查找


image
image

可以看到在source/com/meizu/flyme/weather/common/ad.java有拼接url的代码,这很有可能是我们需要的代码片段

在jd-gui里,打开ad.java

image
image
paramAnonymousVarArgs = "cityId=" + paramString + "&bizId=" + "aider_app" + "&timestamp=" + l + "&sign=" + ad.a(paramAnonymousVarArgs);

这应该就是我们需要的代码,可以点击ad.a,跳转到函数内部,里面的代码并不复杂。通过阅读代码,可以很容易地得到生成sign的规则(MD5(城市id+"aider_app"+时间戳+"29cc0378-3802-4470-a1e2-07ce9f34b208"))。

反编译APP获取smali代码

Android系统有自己的虚拟机Dalvik,代码编译最终不是采用的java的class,而是使用的smali。我们反编译得到的代码,jar的话可能很多地方无法正确的解释出来,如果我们反编译的是smali则可以正确的理解程序的意思。

在抓取短时预报的请求,就出现了无法解释的情况

image
image

通过搜索,最后跳转到下图的方法

image
image

这些看起来像伪代码。。。

我们可以利用apktool来反编译App,获取最终的smali代码,解决无法解释的问题

mv com.meizu.flyme.weather-2.2.1-2002001.zip com.meizu.flyme.weather-2.2.1-2002001.apk
apktool -o weather_apktool d com.meizu.flyme.weather-2.2.1-2002001.apk
image
image

切换到weather_apktool目录,smali文件夹里就是反编译得到的smali代码,我们找到刚才解释错误的文件

vim weather_apktool/smali/com/moji/mjweather/request/MJWeatherSDK.smali
image
image

上图就是代码对应的smali代码,语法有点像汇编,这里有一篇教程(android反编译-smali语法),可以先阅读一遍教程,再去阅读smali代码

利用apktool反编译apk来二次打包

看着smali代码,还是有点懵逼...有没有方法像debug一样,可以随时查看变量的值,一行一行地运行程序呢?

还真有!!!我们可以用Android Studio来动态调试smali代码!!!

我们先用usb连接手机,开启手机的开发者模式,然后打开Android Studio的Android Device Monitor,可以看到我们的手机已经连接上电脑了

image
image

但是我们没有看到程序对应的进程。。。

经过google,原来真机上,只有AndroidManifest.xml里设置有android:debuggable="true"时,ADM才会出现对应的进程。那我们要如何添加android:debuggable="true"呢?这就涉及到了apk的二次打包。

我们可以修改程序的smali代码,修改app的行为(例如去掉广告,或者游戏里面增加金币),然后重新打包成apk文件,安装到我们的手机上。看到这里,你当然会想,这样我们不就可以随意修改app了吗?当然不可能这么简单,一般大公司的app都会加入各种机制,来防止用户修改app的行为,二次打包,难以重新打包成功或者运行程序时马上崩溃。这就涉及到了如何防反编译的话题了。

我们拿之前的魅族天气来尝试进行二次打包,这种小的,不涉及到金钱的程序,防反编译的处理都比较弱

我们在之前apktool反编译smali的weather_apktool里,找到AndroidManifest.xml,加入

<application ....
    android:debuggable="true">...</application>
image
image

重新打包成apk后,还需要加上数字签名,才能安装到手机上,Android系统要求每一个Android应用程序必须要经过数字签名才能够安装到系统中,也就是说如果一个Android应用程序没有经过数字签名,是没有办法安装到系统中的!

我们使用keytool(Java数据证书的管理工具)
来生成数字签名

keytool -genkey -keystore cmd.keystore -keyalg RSA -validity 10000 -alias cmd.keystore
image
image

给二次打包的apk加上数字签名

jarsigner -verbose -keystore cmd.keystore -signedjar weather.apk weather.apk cmd.keystore

安装app

adb devices
adb -s 手机编码 install weather.apk

安装过程中,可能会出现Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE]的错误,这一般是卸载得不干净的原因,可以执行

adb shell pm list packages  # 列出手机安装的所有app包名
adb uninstall 包名

然后重新安装,安装成功后,执行

adb shell am start -D -n 包名/MainActivity  #(包名和MainActivity可以在AndroidManifest.xml找到)

在debug模式下启动App,成功了!!!

天气的自动定位问题
原因:重新打包后,APK签名文件的sha1与高德地图的key对应的sha1不符合
http://lbs.amap.com/faq/top/hot-questions/249

Android Studio动态调试smali代码

好,我们开始动态调试smali代码,先下载ideasmali,打开Android Studio,安装好ideasmali插件,选择Import project(Eclipse ADT, Gradle, etc.), 选择weather_apktool文件夹,然后一路next

image
image

选着smali文件夹,右键Mark Directory As -> Sources Root

image
image

配置远程调试的选项,选择Run-->Edit Configurations:增加一个Remote调试的调试选项,端口选择:8700

image
image

之后选择File-->Project Structure 配置JDK

image
image

查看Android Device Monitor,查看进程的端口


image
image

以调试状态启动app,并转发端口


image
image

记得关闭Android Device Monitor

下好断点之后Run-->Debug 'remote'


image
image

运行起来之后就可以单步执行,查看寄存器的值,慢慢调试了


image
image

总结

Android的反编译很有很多内容没有深入了解过,为了能更好地反编译出代码,深入了解Android系统是必要的,推荐一本书,Android软件安全与逆向分析,可以更加系统和深入的学习Android软件的反编译

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容