freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

【ASeeker】Android 源码捞针,服务接口扫描神器
iofomo 2024-06-20 12:52:06 258203

ASeeker是一个Android源码应用系统服务接口扫描工具。

image

项目已开源:

☞ Github ☜

如果您也喜欢 ASeeker,别忘了给我们点个星。

说明

ASeeker项目是我们在做虚拟化分身产品( 『 空壳 』)过程中的内部开发工具,目的是为了提升Android系统各版本适配效率。由于产品需支持Android 9.x ~ Android 14.x,需在应用访问所有的系统服务接口时,将我们关心的参数进行修正和还原。

这导致每个系统版本适配的工作量巨大,且很容易遗漏。因此我们开发了这个源码接口扫描工具,可以快速从Android源码中搜索我们需要的AIDL接口和服务,并安装定制的格式输出。

感谢开源项目com.github.javaparser,因为它的存在才让ASeeker成为可能,这也是我们开源ASeeker的动力。

ASeeker的特点:

  • 完整源码AIDL接口扫描。

  • 支持多目录关联递归类型查找识别。

  • 支持泛型类,内部类和继承类递归查找。

  • 支持匹配配置名单。

  • 支持Android代码语言规范格式化。

  • 支持查找结果的定制输出。

如何使用

# 确保 asseker.jar 和 res 在同一目录下
# aseeker [-options]
#   -p [SDK version code] [source code path]
$ java -jar aseeker.jar -p 33 /Users/abc/android_13.0_r13

输出结果目录:(包含扫描结果和执行过程日志)

image

输出文件内容:(可自定义输出内容格式)

package android.app.os.service;

import android.app.os.base.ProxyServiceBase;

// source code: /frameworks/base/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
public class IAccessibilityInteractionConnectionCallback extends ProxyServiceBase {

    // 10.0 void setFindAccessibilityNodeInfoResult(AccessibilityNodeInfo info, int interactionId);// argument: AccessibilityNodeInfo:info -> CharSequence::mPackageName
    public static final String sMethod_setFindAccessibilityNodeInfoResult = "setFindAccessibilityNodeInfoResult";
    // 10.0 void setFindAccessibilityNodeInfosResult(List<AccessibilityNodeInfo> infos, int interactionId);// argument: List<AccessibilityNodeInfo>:infos -> CharSequence::mPackageName
    public static final String sMethod_setFindAccessibilityNodeInfosResult = "setFindAccessibilityNodeInfosResult";

}

功能实现

需求

为了实现应用虚拟化,我们需要将应用与系统服务接口通信中包含包名,路径的参数,函数名和返回值的接口进行适配。在访问之前需要修正为安装应用的信息,访问结果需要还原为原应用的信息。

因此,我们需要:

  1. 递归查找参数中包含类型为String的名字含包名的接口,如:packagepkg等。

    void func(String pkg);
    void func(ComponentName cn);// 因为ComponentName中有成员:mPackageName
    
  2. 递归查找返回值中包含类型为String的名字含包名的接口,如:packagepkg等。

    ComponentName getComponentName();
    
  3. 查找返回值为String但是函数名包含包名的接口。

    String getPackageName();
    
  4. 打印输出找到的具体路径。

    // 11.0 boolean enterPictureInPictureMode(IBinder token, PictureInPictureParams params);// argument: PictureInPictureParams:params -> List<RemoteAction>::mUserActions -> PendingIntent::mActionIntent
        public static final String sMethod_enterPictureInPictureMode = "enterPictureInPictureMode";
    

文件预处理

由于javaparser只支持基础的Java类语言规范,对于Android平台定制标签,关键字等不支持,所以需要对目标文件先进行格式化处理,去除这些属性。

// @from: com.ifms.cmpt.aseeker.AidlFormator.java

Pattern.compile("(?<![\\w])IN\\s+([a-zA-Z_])"),
Pattern.compile("(?<![\\w])in\\s+([a-zA-Z_])"),
Pattern.compile("(?<![\\w])OUT\\s+([a-zA-Z_])"),
Pattern.compile("(?<![\\w])out\\s+([a-zA-Z_])"),
Pattern.compile("(?<![\\w])INOUT\\s+([a-zA-Z_])"),
Pattern.compile("(?<![\\w])inout\\s+([a-zA-Z_])"),

private static final String PATTERN_AT = "@\\w[\\w.]*\\s*(\\([^)]*\\))?"; // rm @Nullable, @android.app.XXX(xxx)
private static final String PATTERN_ABSTRACT = "\\)\\s*=\\s*\\d+\\s*;$";// rm ") = ${number};"
private static final String PATTERN_BRIEF = "/\\*.*?\\*/";// rm "/*xxx*/"
private static final String ONEWAY = "oneway ";
private static final String PARCELABLE = "parcelable ";
private static final String UNION = "union ";

类查找

为了可以准确识别类型,需要完整的查找到参数类型。

  1. 当前同目录下查找。

  2. 当前同工程目录下查找。

  3. framework/base目录下查找。

  4. Android SDK目录下查找(可在config.txt中配置ANDROID_HOME路径)。

个性化配置

1. 全局配置:config.txt

# 配置Android SDK源码路径
ANDROID_HOME=C:\Users\Administrator\AppData\Local\Android\Sdk
# 配置最大递归访问深度,提升效率
MAX_LEVEL=4

2. 忽略类型:ignore.txt

byte
short
int
long
char
float
double
void
boolean

3. 忽略文件:ignore-file.txt

忽略明确不需要关注的接口类,这样不会出现在结果中。

# 系统服务使用
RemoteServiceCallback.aidl

# 系统WiFi管理模块,需要系统权限
IWifiScanner.aidl

4. 匹配类型:match.txt

ApplicationInfo
ComponentName
PackageInfo
ActivityInfo
ServiceInfo
ProviderInfo

5. 文件映射:mapping.txt

可以定制输出结果文件名。

# rename out file
# ${Android source file}=${target file}
# such as:
IActivityManager=IAMS

6. 输出模板:template.java

定制输出模板可以更好的和我们工程的代码融合,易于代码和结果对比。

package android.app.os.service;

import android.app.os.base.ProxyServiceBase;

@templateFile@
public class @templateClass@ extends ProxyServiceBase {

    @templateMethod@

}
# 系统安全 # 数据安全 # Android # Android开发 # 源码分析
本文为 iofomo 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
iofomo LV.5
数字锋芒(全网同名),开源,探索,分享,赋能。
  • 18 文章数
  • 4 关注者
DeepSeek文档合集
2025-03-07
【Abyss】Android平台BPF和SECCOMP的SVC指令拦截
2025-01-23
分身应用还谈个人隐私?
2024-11-21