ASeeker là một công cụ quét giao diện dịch vụ hệ thống từ mã nguồn Android, được phát triển để hỗ trợ quá trình sản xuất ứng dụng ảo hóa. Dự án đã được mã nguồn mở và có sẵn trên GitHub.
Công cụ này được tạo ra nhằm giải quyết vấn đề tương thích giữa các phiên bản Android khác nhau, từ Android 9.x đến Android 14.x. Khi ứng dụng truy cập các giao diện dịch vụ hệ thống, cần phải sửa đổi và khôi phục các tham số quan trọng, dẫn đến khối lượng công việc thích ứng lớn và dễ bỏ sót. ASeeker cho phép quét nhanh các giao diện AIDL và dịch vụ từ mã nguồn Android, đồng thời xuất kết quả theo định dạng tùy chỉnh.
Các tính năng nổi bật của ASeeker:
- Quét toàn bộ giao diện AIDL từ mã nguồn
- Hỗ trợ nhận diện kiểu dữ liệu đệ quy qua nhiều thư mục
- Hỗ trợ lớp generic, lớp nội bộ và lớp kế thừa
- Hỗ trợ danh sách cấu hình khớp
- Định dạng theo chuẩn ngôn ngữ Android
- Xuất kết quả tùy chỉnh
Cách sử dụng
# Đảm bảo aseeker.jar và thư mục res nằm cùng thư mục
# aseeker [-options]
# -p [mã phiên bản SDK] [đường dẫn mã nguồn]
$ java -jar aseeker.jar -p 33 /Users/abc/android_13.0_r13
Kết quả đầu ra được lưu trong thư mục chỉ định, bao gồm file kết quả quét và log quá trình thực thi. Nội dung file đầu ra có thể tùy chỉnh theo mẫu:
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);
public static final String sMethod_setFindAccessibilityNodeInfoResult = "setFindAccessibilityNodeInfoResult";
// 10.0 void setFindAccessibilityNodeInfosResult(List<AccessibilityNodeInfo> infos, int interactionId);
public static final String sMethod_setFindAccessibilityNodeInfosResult = "setFindAccessibilityNodeInfosResult";
}
Chi tiết triển khai
Yêu cầu nghiệp vụ
Để thực hiện ảo hóa ứng dụng, cần thích ứng các giao diện dịch vụ hệ thống có chứa tên gói, đường dẫn trong tham số, tên hàm và giá trị trả về. Trước khi truy cập, cần sửa đổi thông tin thành thông tin của ứng dụng đã cài đặt; sau khi truy cập, cần khôi phục về thông tin gốc.
Cụ thể cần:
- Quét đệ quy các tham số có kiểu
Stringchứa tên gói (ví dụ: package, pkg). - Quét đệ quy các giá trị trả về có kiểu
Stringchứa tên gói. - Quét các hàm trả về
Stringnhưng tên hàm chứa tên gói. - In ra đường dẫn cụ thể của kết quả tìm thấy.
Tiền xử lý file
Do javaparser chỉ hỗ trợ cú pháp Java cơ bản, không xử lý được các thẻ tùy chỉnh của Android, cần định dạng lại file trước khi quét:
// Từ: 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*(\\([^)]*\\))?"; // loại bỏ @Nullable, @android.app.XXX(xxx)
private static final String PATTERN_ABSTRACT = "\\)\\s*=\\s*\\d+\\s*;$"; // loại bỏ ") = ${number};"
private static final String PATTERN_BRIEF = "/\\*.*?\\*/"; // loại bỏ "/*xxx*/"
private static final String ONEWAY = "oneway ";
private static final String PARCELABLE = "parcelable ";
private static final String UNION = "union ";
Tìm kiếm lớp
Để nhận diện chính xác kiểu dữ liệu, cần tìm kiếm đệ quy theo thứ tự:
- Trong cùng thư mục hiện tại
- Trong cùng dự án
- Trong thư mục framework/base
- Trong thư mục Android SDK (cấu hình trong config.txt)
Cấu hình cá nhân hóa
1. Cấu hình toàn cục: config.txt
# Đường dẫn mã nguồn Android SDK
ANDROID_HOME=C:\Users\Administrator\AppData\Local\Android\Sdk
# Giới hạn độ sâu đệ quy để tăng hiệu suất
MAX_LEVEL=4
2. Kiểu dữ liệu bỏ qua: ignore.txt
byte
short
int
long
char
float
double
void
boolean
3. File bỏ qua: ignore-file.txt
# Bỏ qua các giao diện không cần quan tâm
RemoteServiceCallback.aidl
# Module WiFi yêu cầu quyền hệ thống
IWifiScanner.aidl
4. Kiểu dữ liệu cần khớp: match.txt
ApplicationInfo
ComponentName
PackageInfo
ActivityInfo
ServiceInfo
ProviderInfo
5. Ánh xạ file: mapping.txt
# Đổi tên file đầu ra
# ${file nguồn Android}=${file đích}
# Ví dụ:
IActivityManager=IAMS
6. Mẫu đầu ra: template.java
package android.app.os.service;
import android.app.os.base.ProxyServiceBase;
@templateFile@
public class @templateClass@ extends ProxyServiceBase {
@templateMethod@
}