首页
论坛
课程
招聘
[原创]GDA使用手册
2021-3-28 13:23 16866

[原创]GDA使用手册

2021-3-28 13:23
16866

目录

简述

根据自身使用GDA的经历,进行梳理归纳,方便初学者学习使用,因自身技术水平有限,若有不当之处,盼望指正。
注:根据自身理解与时间安排,会不定时对此篇文章内容进行更新与完善
当前更新日期:2022年3月23日
涉及的GDA版本:GDA Free 4.0、GDA Free 4.0

GDA简介

GGJoy Dex Analysizer(GDA),中国第一款也是唯一一款全交互式的现代反编译器,同时也是世界上最早实现的dalvik字节码反编译器。 GDA不仅只是反编译器,同时也是一款轻便且功能强大的综合性逆向分析利器,其不依赖java且支持apk、dex、odex、oat、jar、aar、class文件的反编译, 支持python,java脚本自动化分析。

  • 功能概况:
    1.GDA提供了字符串、方法、类和成员变量的交叉引用及搜索功能、代码注释功能等等。
    2.GDA中包含多个由作者独立研究的高速分析引擎:反编译引擎、漏洞检测引擎、恶意行为检测引擎、污点传播分析引擎、反混淆引擎、apk壳检测引擎等等, 尤其是恶意行为检测引擎和污点传播引擎与反编译核心的完美融合, 大大提高了无源码逆向工程的效率。
    3.此外反编译器还提供了很多实用功能,如路径求解、 漏洞检测、隐私泄露检测、查壳、odex转dex、oat转dex、加解密算法工具、android设备内存dump等等功能
  • 官网:
    http://www.gda.wiki:9090/
  • 最新版本:
    3.91
  • GDA作者信息
    ADLab资深攻防专家,安全团队Leader、看雪智能硬件版主,KHG小组组长. 从事安全研究10年以上,长期致力于各种平台下的逆向工程、病毒分析、APT分析、攻击溯源与黑客追踪,同时对车联网安全、物联网安全、设备固件逆向、硬件调试分析等领域均有深入研究

使用技巧

集成到右键 发送到

此操作方便分析使用
在“运行”窗口或“文件管理器”的地址栏中输入如下命令,可快速定位到发送到目录

1
shell:sendto

退回到上一次访问

此操作方便分析使用,快捷键
图片描述
示例:使用快捷键Esc返回到恶意行为分析页面

简易使用

载入界面解析

简单判断被分析文件是否被加固

载入分析文件时,会显示分析主界面,若加固会有提示,或在BaseInfo模块查看
示例:

  • 加固
    图片描述
    图片描述
  • 未加固
    图片描述
    图片描述

基本信息查看

通过BaseInfo模块查看被分析文件基本情况
示例:

证书查看

常用于判断被分析目标是否合规与查询其作者或开发商

查询AndroidManifest.xml

查询此文件可查看Manifest架构情况与权限属性值定义情况,并可查看allowBackup、debuggable属性判断是否存在安全风险
示例:
动态图演示

存在漏洞的演示图片

allowBackup属性值为true或未配置allowBackup=“false”,则表示存在漏洞
漏洞成因解析

1
2
android:allowBackup 是否允许应用参与备份和恢复基础架构。如果将此属性设为 false,则永远不会为该应用执行备份或恢复,即使是采用全系统备份方法也不例外(这种备份方法通常会通过 adb 保存所有应用数据)。此属性的默认值为 true。
当allowBackup标志为true时,用户即可通过adb backup和adb restore来进行对应用数据的备份和恢复,这可能会带来一定的安全风险例如:通过此技术窃取敏感数据。

查看被分析文件所调用的API情况

可在AllAPI模块查看所调用的API,可用于分析是否存在危险行为
示例:

获取被分析文件字符串信息

根据文字判断是否存在恶意描述,进而根据这些字符串深入分析后判断是否存在恶意行为
AllStrings与AppStrings可查询字符串信息,其中AllStrings会获取该APK所有的字符串,而AppStrings只会获取APK有效类会用到的字符串

恶意行为扫描分析

使用此功能模块可简单的判断被分析文件(如.apk文件)是否存在可被攻击者恶意利用的风险项
示例:

扫描出了一些存在威胁的行为,并可查看引用此行为的对象,方便进一步进行深入分析,如看看读取了那些敏感文件:

数据流分析发现使用了android.util.log(比较敏感的方法会用特殊颜色标注方便查找)方法,简单分析为读取了错误日志文件(深入分析步骤在其它分段展示)

权限相关查看

此功能方便了解被分析应用是否存在获取敏感权限的行为,与点击要分析的模块查看具体那个模块使用,跟踪这些内容可进行简单的行为判定
示例:

调取取证信息

方便直接获取一般取证时所用的信息
功能模块:工具-APK取证分析

反编译.jar文件

功能支持说明:
节选于GDA GitHub说明
图片描述
准备:
因此功能依赖于dx工具,故需dx可正常使用。

1
2
3
4
5
6
7
8
9
10
11
12
默认情况若系统安装Android Studio则就拥有dx工具,其默认保存路径为
Windows系统:
C:\Users\用户名\AppData\Local\Android\Sdk\build-tools\版本文件夹
名称:dx.bat
方便使用,可将其添加到系统环境变量
JDK支持:我这里使用了jdk 16
dx运行报错解决:
1.查看java是否可正常使用
2.修改dx源文件
dx.bat 最后一行
原始数据:call "%java_exe%" %javaOpts% -Djava.ext.dirs="%frameworkdir%" -jar "%jarpath%" %params%
修改数据:call "%java_exe%" %javaOpts% -classpath "%frameworkdir%" -jar "%jarpath%" %params%

图片描述
注意:有些.jar文件dx是无法解析的(如其目录下的core-lambda-stubs.jar、apktool_2.4.1.jar等等##dx版本问题,可使用更新的版本试试)

 

初始使用GDA反编译.jar文件会弹出提示,选择dx路径即可。
使用演示:

深入使用

根据配置文件,排查故障

1
2
路径:C:\Users\用户名\AppData\Roaming\GDA
名称:config.dat

使用可实时更新文本状态的文件打开配置文件,如:HBuilder x
故障:当载入dx无法解析的.jar文件,在此载入会弹出选择dx路径窗口(GDA已成功解析.jar文件,会在配置文件中保存dx目录)
通过监控配置文件,会发现载入无法解析的.jar文件会引起GDA清除之前dx的路径信息,如下图对比演示:
成功解析.jar文件:
图片描述
无法解析.jar文件:
图片描述

翻译字符串功能

若Google翻译有问题,切换到有道即可
视图-环境配置
图片描述
目前无分割语句会导致翻译无变化,需手动修改
示例:
EditTextPreferenceDialogFragment
图片描述
注意:因编辑字符串限制无法超出原字符串字节长度故需妥善删减修改

1
2
3
4
5
6
原:EditTextPreferenceDialogFragment
45 64 69 74 54 65 78 74 50 72 65 66 65 72 65 6e 63 65 44 69 61 6c 6f 67 46 72 61 67 6d 65 6e 74 2e 74 65 78 74 00
翻译:编辑文本首选项对话框片段
e7 bc 96 e8 be 91 e6 96 87 e6 9c ac e9 a6 96 e9 80 89 e9 a1 b9 e5 af b9 e8 af 9d e6 a1 86 e7 89 87 e6 ae b5 2e 74 65 78 74 00 //字节超出
修改:编辑首选项对话框片段
e7 bc 96 e8 be 91 e9 a6 96 e9 80 89 e9 a1 b9 e5 af b9 e8 af 9d e6 a1 86 e7 89 87 e6 ae b5 2e 74 65 78 74 00

扩展知识

此知识方便结合GDA进行分析使用

Android Api

  • 显示网页

    1
    2
    3
    Uri uri = Uri.parse("https://bbs.pediy.com/");
    Intent it = new Intent(Intent.ACTION_VIEW,uri);
    startActivity(it);
  • 拨打电话
    直接拨打电话,需要申请权限,在AndroidManifest.xml清单文件中添加:

    1
    <uses-permission android:name="android.permission.CALL_PHONE" />
    1
    2
    3
    4
    调用拨号程序 Uri
    uri = Uri.parse("tel:号码");
    Intent it = new Intent(Intent.ACTION_DIAL, uri);
    startActivity(it);
  • 检查应用是否处于调试状态
    android.os.Debug.isDebuggerConnected();判断当前应用有没有被调试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /**
    * 执行 timeout()
    * 注意:如果处于程序调试状态和CC.DEBUG是true,
    * 两个都满足情况下,不执行超时 timeout()
    * @param cc
    */
    private void executeTimeout(CC cc) {
      if (!CC.DEBUG) {
          cc.timeout();
          return;
      }
      if (!Debug.isDebuggerConnected()) {
          cc.timeout();
      }
    }

    获取 debuggable 值的API接口

    1
    2
    3
    4
    void detectOsDebug(){
      boolean connected = android.os.Debug.isDebuggerConnected();
      Log.d(TAG, "debugger connect status:" + connected);
    }
  • 电话监听

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class PreciseCallState implements Parcelable {
      public static final int PRECISE_CALL_STATE_IDLE =           0; //通话空闲
      public static final int PRECISE_CALL_STATE_ACTIVE =         1; //正在通话
      public static final int PRECISE_CALL_STATE_HOLDING =        2; //通话挂起
      public static final int PRECISE_CALL_STATE_DIALING =        3; //拨号开始
      public static final int PRECISE_CALL_STATE_ALERTING =       4; //正在呼出
      public static final int PRECISE_CALL_STATE_INCOMING =       5; //对方来电
      public static final int PRECISE_CALL_STATE_WAITING =        6; //第三方来电等待
      public static final int PRECISE_CALL_STATE_DISCONNECTED =   7; //挂断完成
      public static final int PRECISE_CALL_STATE_DISCONNECTING =  8; //正在挂断
  • 获取手机号码
    1
    2
    3
    4
    5
    6
    7
    8
    static public String getPhone(Context p0){   
       String str = "";
       try{   
          return p0.getSystemService("phone").getLine1Number().replace("+86", str).replaceAll(" ", str);
       }catch(java.lang.Exception e-1){   
          return str;
       }   
    }
  • 获取当前位置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    static public Location c(Context p0){   
       LocationManager lSystemServi;
       Object[] objectArray;
       String sBestProvide;
       Object[] objectArray1;
       Object[] objectArray2;
       int vi = 1;
       try{   
          if ((lSystemServi = p0.getSystemService("location"))) {   
             Criteria criteria = new Criteria();
             criteria.setPowerRequirement(vi);
             criteria.setAccuracy(2);
             if ((sBestProvide = lSystemServi.getBestProvider(criteria, vi))) {   
                Location lLastKnownLo = lSystemServi.getLastKnownLocation(sBestProvide);
                objectArray1 = new Object[vi];
                objectArray1[0]=lLastKnownLo;
                c.b(e.a, "Location found: %s", objectArray1);
                return lLastKnownLo;
             }else {   
                objectArray2 = new Object[0];
                c.a(e.a, "Location Manager provider is null.", objectArray2);
             }   
          }else {   
             objectArray2 = new Object[0];
             c.a(e.a, "Location Manager is null.", objectArray2);
          }   
       }catch(java.lang.Exception e5){   
          objectArray = new Object[vi];
          objectArray[0]=e5.toString();
          c.a(e.a, "Failed to retrieve location: %s", objectArray);
       }   
       return null;

Android 中的危险权限

图片描述

参考资料

  • 《Android API 参考文档》
  • 《GDA 官方资料》
  • 《Android 取证资料》
  • 《Android 权限调用相关资料》
  • 《Android 中的危险权限表格》

未完待续

当前更新日期:2022年3月23日


[招生]科锐逆向工程师培训46期预科班将于 2023年02月09日 正式开班

最后于 2022-3-23 13:52 被梦幻的彼岸编辑 ,原因:
收藏
点赞8
打赏
分享
最新回复 (18)
雪    币: 2463
活跃值: 活跃值 (2401)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
genliese 活跃值 1 2021-3-29 14:23
2
0
下一次访问的快捷键是enter键吗?,如果是enter键,我按了enter键不会跳转到下一次访问。
雪    币: 2184
活跃值: 活跃值 (21531)
能力值: (RANK:370 )
在线值:
发帖
回帖
粉丝
梦幻的彼岸 活跃值 2 2021-3-29 15:35
3
0

按键截图:

动态演示:


雪    币: 735
活跃值: 活跃值 (2136)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
默NJ 活跃值 2021-3-29 22:35
4
0
mark
雪    币: 2463
活跃值: 活跃值 (2401)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
genliese 活跃值 1 2021-3-30 08:04
5
0
梦幻的彼岸 按键截图:动态演示:
谢谢版主,我太傻了
雪    币: 2246
活跃值: 活跃值 (840)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
任蝶飞 活跃值 2021-3-30 09:42
6
0
梦幻的彼岸 按键截图:动态演示:
这个GIF是用什么软件做的?好清晰 好流畅
雪    币: 2184
活跃值: 活跃值 (21531)
能力值: (RANK:370 )
在线值:
发帖
回帖
粉丝
梦幻的彼岸 活跃值 2 2021-3-30 13:31
7
0
ScreenToGif
https://www.screentogif.com/
雪    币: 2321
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
独钓天台 活跃值 2021-4-1 19:33
8
0
版主这个手册有点简单吧
雪    币: 2184
活跃值: 活跃值 (21531)
能力值: (RANK:370 )
在线值:
发帖
回帖
粉丝
梦幻的彼岸 活跃值 2 2021-4-2 16:28
9
0
工具比较强大简单分析就显得简单,看着难的就是分析调用深入分析了,这个后期扩充。
雪    币: 2321
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
独钓天台 活跃值 2021-4-4 06:30
10
0
梦幻的彼岸 工具比较强大简单分析就显得简单,看着难的就是分析调用深入分析了,这个后期扩充。
期待后文,感谢你的付出!
雪    币: 919
活跃值: 活跃值 (67)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
menglinxi 活跃值 2021-5-21 13:51
11
0
貌似不能直接反编译jar包.
雪    币: 2184
活跃值: 活跃值 (21531)
能力值: (RANK:370 )
在线值:
发帖
回帖
粉丝
梦幻的彼岸 活跃值 2 2021-5-21 16:58
12
0

此功能需依赖dx工具,具体步骤已在此贴更新[原创]GDA使用手册-Android安全-看雪论坛-安全社区|安全招聘|bbs.pediy.com

雪    币: 919
活跃值: 活跃值 (67)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
menglinxi 活跃值 2021-5-31 19:21
13
0

已经选择dx.bat了

雪    币: 2184
活跃值: 活跃值 (21531)
能力值: (RANK:370 )
在线值:
发帖
回帖
粉丝
梦幻的彼岸 活跃值 2 2021-6-1 10:55
14
0
看帖子说的注意说明,这是dx解析失败的原因,一般使用更新的dx版本会解决这一问题。
雪    币: 31
活跃值: 活跃值 (88)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
smartdog 活跃值 2022-1-5 10:23
15
0
能增加注释功能么。分析过程中,针对方法或者片段的注释
雪    币: 925
活跃值: 活跃值 (660)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
psych1 活跃值 2022-1-5 14:20
16
0
师傅,allowBackup为true才是有安全风险吧
雪    币: 2184
活跃值: 活跃值 (21531)
能力值: (RANK:370 )
在线值:
发帖
回帖
粉丝
梦幻的彼岸 活跃值 2 2022-1-5 14:23
17
0

16年开始已经支持注释功能



感谢指出问题,已修复

最后于 2022-1-5 14:26 被梦幻的彼岸编辑 ,原因:
雪    币: 9757
活跃值: 活跃值 (666)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
严启真 活跃值 2022-1-9 09:29
18
0
这个问题是个例吗?ctrl+h历史记录,快捷键没用?历史记录窗口打开,最小化后,偶尔无法还原或最大化,只能在任务管理器中还原窗口…

还有最小化只能单击右上角,任务栏单击图标没用…
雪    币: 2184
活跃值: 活跃值 (21531)
能力值: (RANK:370 )
在线值:
发帖
回帖
粉丝
梦幻的彼岸 活跃值 2 2022-1-10 11:18
19
0
感谢反馈bug,所描述的问题已复现,并已反馈给作者,有最新信息我更新此回复内容。
游客
登录 | 注册 方可回帖
返回