目录 简述
根据自身使用GDA的经历,进行梳理归纳,方便初学者学习使用,因自身技术水平有限,若有不当之处,盼望指正。 注:根据自身理解与时间安排,会不定时对此篇文章内容进行更新与完善 当前更新日期:2023年5月17日 GDA版本:4.0.6
GDA使用手册:案例篇
https://bbs.kanxue.com/thread-278222.htm
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/
最新版本: 4.0.6
GDA作者信息 ADLab资深攻防专家,安全团队Leader、看雪智能硬件版主,KHG小组组长. 从事安全研究10年以上,长期致力于各种平台下的逆向工程、病毒分析、APT分析、攻击溯源与黑客追踪,同时对车联网安全、物联网安全、设备固件逆向、硬件调试分析等领域均有深入研究
使用技巧
集成到右键 发送到
此操作方便分析使用 在“运行”窗口或“文件管理器”的地址栏中输入如下命令,可快速定位到发送到目录
退回到上一次访问
此操作方便分析使用,快捷键 示例:使用快捷键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 中的危险权限表格》
未完待续
当前更新日期:2023年5月17日
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2023-8-25 11:22
被梦幻的彼岸编辑
,原因: