Mac IDA动态调试Android应用dump dex

前言

由于本人使用的是Mac来做开发,并且最近要做逆向相关,苦于网上多数教程都是Win的,没办法只有到处搜集资料和自己踩坑,摸着石头过河。这里分享一下Mac来做的整个过程。目标,IDA动态调试,dump dex脱壳。
脱壳的话,目前两种方法,一种动态调试,一种xposed,当前为动态调试学习

环境:
macOS 10.14.1
root过后的手机 htc 4.4.2
IDA 7.0 附送地址
IDA mac 高版本崩溃解决适配
mprop 设置手机所有应用为可调试 下载地址

精简方案

1、 copy 启动 Android server

  1. 上传IDA调试服务器地址:IDAPro70\dbgsrv\android_server
  2. cmd进入到该目录下: IDAPro70\dbgsrv
  3. 导入IDA调试服务器:adb push android_server /data/local/tmp
  4. adb shell 以su启动(手机要求root)
  5. cd到/data/local/tmp下:chmod 777 android_server
  6. ./android_server(如果失败重启手机)

2、 root手机使用mprop设置ro.debuggable为1

adb push xxx/mprop /data/local/tmp/mprop
adb shell su
chmod 755 /data/local/tmp/mprop
data/local/tmp/mprop
setprop ro.debuggable 1
/data/local/tmp/mprop -r

3、 转发ida端口 开启adb应用调试

adb forward tcp:23946 tcp:23946
adb shell am start -D -n 包名/包名对应启动Activity

4、 ida attach到应用进程 打断点

打开IDA设置好process options 地址127.0.0.1 端口23946
Ida -》debugger -》attach process
选择对应应用进程
选择libdvm.so
找到dvmDexFileOpenPartial 计算偏移量
下断点

5、 jdb连接应用

连接jdb(两种方式)
1、通过ddms(如果占用8700 ps查看 kill杀掉 重来)
2、命令
adb shell ps | xxx 找到对应app的进程号
adb forward tcp:8700 jdwp:进程号
jdb -connect com.sun.jdi.SocketAttach:port=8700,hostname=localhost

6 IDA开启调试

启动ida F9 开始进行调试

大致原理

通过IDA的动态调试系统库libdvm.so的dvmDexFileOpenPartial方法,来寻找内存中的dex段地址,然后进行dump,最终达到脱壳的目的。
(4.4前后的不同java虚拟机类型,所以这里用的是4.4.2的手机,系统库为libdvm,如果是之后的便是libart,调试方法为openMemory)

详细过程

看似原理很简单,但是会遇到许多的问题和坑,每个都能卡你半天,所以这里分享给大家一些细节东西,望君莫要重蹈覆辙。

1、 copy 启动 Android server
  1. 上传IDA调试服务器地址:IDAPro70\dbgsrv\android_server
  2. cmd进入到该目录下: IDAPro70\dbgsrv
  3. 导入IDA调试服务器:adb push android_server /data/local/tmp
  4. adb shell 以su启动(手机要求root)
  5. cd到/data/local/tmp下:chmod 777 android_server
  6. ./android_server(如果失败重启手机)
找到android server

这里启动之后 可以看到IDA Android 32-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017
注意:这里32-bit的话,你打开IDA就用32位的打开 不然就是64位的

2、 root手机使用mprop设置ro.debuggable为1

adb push xxx/mprop /data/local/tmp/mprop
adb shell su
chmod 755 /data/local/tmp/mprop
data/local/tmp/mprop
setprop ro.debuggable 1
/data/local/tmp/mprop -r

使用getprop ro.debuggable 就可以查看是否修改成功

有时候遇到

android_server Address already in use

可以杀掉进程重来

进入adb shell
ps | grep android_server
kill -s 9 进程号
重新启动android_server

注意:手机每次重启都要重复此操作,都要重新设置debuggable为1,有时候手机会无意重启,注意。

3、 转发ida端口 开启adb应用调试

adb forward tcp:23946 tcp:23946
adb shell am start -D -n 包名/包名对应启动Activity


这里转发了之后可以使用lsof -i:23946来查看如果有Listen则说明转发成功
接着调用adb 调试命令 填好对应包名和启动的Activity注入调试

这里提供一下 查询启动页的方法
adb shell dumpsys activity top 启动app之后查看现在的Activity信息可以拿到包名
然后
adb shell dumpsys package 包名
就可以查询一下有action MAIN的Activity,一般类似为SplashActivity

注入调试,手机上就有等待调试的弹框了。

4、 ida attach到应用进程 打断点

打开IDA设置好process options 地址127.0.0.1 端口23946
Ida -》debugger -》attach process
选择对应应用进程
选择libdvm.so
找到dvmDexFileOpenPartial 计算偏移量
下断点

这里我们使用的是32位的IDA打开,一般要开两个,一个为了静态分析so(也就是找到libdvm.so的对应的dexFileOpen函数地址,后面要做寻找断点用);另外一个是拿来调试用的。

首先,需要获取libdvm.so,一般是在手机的/system/lib/ 下面

adb pull /system/lib/libdvm.so /users/jafir/desktop/
直接pull到电脑上来,然后IDA打开

IDA
这里可以看到地址为0004BB10

0004BB10这个地址就是dexFileOpen函数在libdvm.so中的偏移地址,后面我们打断点的时候,需要在整个内存中去寻找到真正的dexFileOpen的地址。
原理就是 找到libdvm.so在内存中的首地址,然后加上这里的偏移地址,就可以得到libdvm.so中的dexFileOpen的地址。
好,这就是静态分析获取地址。

然后,再打开一个,File->New Instance,选择 GO
Debugger->Attach->Remote ArmLinux/Android


填好地址,不用密码
选中目标进程
然后就变成了这样

接下来就ctrl+s找到libdvm.so然后查看,它在内存中的首地址,计算偏移量


4152D000就是它的地址

计算一下偏移量 4152D000+ 0004BB10 = 41578b10,按G,进行地址跳转

地址跳转

打上断点



ok

PS:有些人是 这种图,右键切换为text

5、 jdb连接应用

连接jdb(两种方式)
1、通过ddms(如果占用8700 ps查看 kill杀掉 重来)
2、命令
(-- adb shell ps | xxx 找到对应app的进程号
-- adb forward tcp:8700 jdwp:进程号)
jdb -connect com.sun.jdi.SocketAttach:port=8700,hostname=localhost

最简单的打开ddms,它是在你Android sdk/tools下面的monitor
然后jdb -connect com.sun.jdi.SocketAttach:port=8700,hostname=localhost

(base) Jafir:~ jafir$ jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700
设置未捕获的java.lang.Throwable
设置延迟的未捕获的java.lang.Throwable
正在初始化jdb...
>

如果打开DDMS报8700被占用了,lsof -i :端口号查看,然后kill -s 9 进程号杀掉,重来

(base) Jafir:~ jafir$ lsof -i:8700
COMMAND   PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
monitor 31587 jafir  121u  IPv6 0x8c41b253ec7cd357      0t0  TCP localhost:8700 (LISTEN)
(base) Jafir:~ jafir$ kill -s 9 31587 

如果不用ddms,也可以用命令,来连接jdb

 adb shell ps | xxx包名 找到对应app的进程号
 adb forward tcp:8700 jdwp:进程号
 jdb -connect com.sun.jdi.SocketAttach:port=8700,hostname=localhost

6 IDA开启调试

启动ida F9 开始进行调试

点击绿色启动按钮,就可以了,这时候按道理,手机的debug等待框也消失了,进入调试状态。


ok

ddms的灯变成绿色,然后断点断在了libc上头,就成功了
之后便是一路F9,回车。F9,回车
直到我们的断点处。
注意断点,向下执行,不要超过BL,过了PUSH就可以了


注意

到断点处,如果成功的话,就可以从General registers里面看到变量值。


image.png
static main(void){
    auto fp, dex_addr,end_addr;
    //打开或创建一个文件
    fp = fopen("/users/jafir/desktop/dump.dex", "wb");
    end_addr = r0+r1;
    for ( dex_addr = r0; dex_addr < end_addr;    end_addr ++ ){
      //按字节将其dump到本地文件中
      fputc(Byte(dex_addr), fp);
    }
}

File->Script Command可以创建脚本命令


过一会就可以看到桌面上dump.dex文件了。

后面还会遇到很多坑:
遇到这个点 pass

命令相关分享

进程相关:

ps A 查看所有
ps a 显示同一终端下的所有程序
lsof -i:xxx 查看端口进程信息
kill -9 xxxx 杀死某个进程

逆向相关命令:

cat 查看
cat /proc/xxxpid/maps 查看xxx进程的lib库文件(一般需要root才能查看)
echo touch 写内容到文件中
echo 内容 >> 文件路径 (如果有文件就追加 没有就创建)
echo 内容 >文件路径 (如果有文件就清空写入 没有就创建)
adb shell dumpsys activity top
adb shell dumpsys package [packagename]
adb shell dumpsys meminfo xxxx com.cctv4g.cctvmobiletv
adb shell dumpsys dainfo xxx
adb shell screencap -p xxx路径
adb install -t xxx 以测试包的类型安装

查看当前的activity:

1、adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'
2、adb shell dumpsys activity | grep -i run

查看权限的命令:

ls -alf 查看文件及其权限
ls -a 可以查看包含隐藏文件
ls 查看

查看keystore的信息摘要 sha1

keytool -list -keystore keystore

jadx-gui:

jadx-gui xxx.jar/xxxx.dex/xxx.apk
配置好环境变量

Dx:

dx --dex --output=HelloWorld.dex HelloWorld.class
把class文件编译成dex

执行dex文件

1、生成dex文件(可以直接从apk中解压出来,也可以从jar利用dx命令生成)
2、然后adb push xxx.dex xxx到手机中去
3、adb shell
4、dalvikvm -cp xxx.dex com.jafir.signprotect.Main(主类)

后记

本人也是刚入手,小白一个,摸索着石头过河,请教过很多大神,但是不管怎么说还是要自己动手,踩坑,尝试,无数次尝试。
这里只进行到dump dex,其实后面还有很多的操作,比如什么指令抽取的要还原啊,还要过滤反调试等的。

我只是用了自己的没有反调试的apk来过了一遍手,而后在想要脱壳的时候,却遇到了更多的问题,总之,初来乍到,还要继续学习和探索,有志同道合者,希望相互交流。

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

推荐阅读更多精彩内容

  • Android开发中我们有时候需要借助一些命令帮助更好的高效率定位解决问题,本文就来介绍一些可能有些隐藏的而却非常...
    passiontim阅读 1,426评论 0 4
  • 妈妈又在给我上开学第一课 跳出田字格 随手挥霍大把的青春吧 写大字,办大报 将孩子体换成颜真卿体 愿意潦草结束一生...
    倩何人换取阅读 152评论 0 1
  • 这种喜欢就像是惯性,有多喜欢,惯性就有多大,刹车的时候用力太猛会犯错,用力太轻,刹车会太慢。路上碰见其他人会因为惯...
    馋_6ac7阅读 185评论 0 0
  • 夜深了,我拖着干涩的双眼斜靠在老旧的皮革沙发上,注视着长长的银色丝线尽头的红心卡片在昏黄的灯光下趁着风翩翩摇摆。刚...
    蝉鸣夏阅读 295评论 0 1