首页
社区
课程
招聘
[原创]关于某宝手表版本 apk 逆向分析过程
发表于: 2025-5-29 16:32 2496

[原创]关于某宝手表版本 apk 逆向分析过程

2025-5-29 16:32
2496

1、apktool_2.4.1.jar--用于反编和打包apk

2、jadx-gui-1.4.5--用于查看 apk 反编译源码,方便快速导出查找

3、Linux环境安装 zipalign 、apksigner--用于对齐和重新签名

1、反编后,啥也不改,直接再打包回 apk,z4 对齐并签名后安装失败,错误原因为

提示 so 未对齐,试了很多方法一直不都行,后来验证了下发现这货根本不是so,而是 jar 文件,这一招正是为了防止反编的手段。

file libsgmain.so: Java archive data (JAR)

将重打包后的 apk 再解压开,强制 so 不压缩,然后再进行对齐和签名即可,完整指令步骤如下

最终得到的 aligned.apk 就可以成功安装

先将 apk 通过 apktool 反编出来备用,一会方便修改 smali 代码
然后在 jadx-gui 中打开 apk,打开工程后,点击文件保存将所有代码保存出来,然后 cp 到 linux 下,这样方便快速查找关键词
比如界面显示未授权的设备,可以通过 grep 未授权 ./ -nir 快速搜索到具体位置,然后在 jadx-gui 中快速定位代码位置。

1、com.a.a.a.a.a.booleanValue() 为 false 则直接忽略检查,可能是为了测试模式留的
2、为 true,则检查指定包名的apk对应的 SHA-256 签名值是否和固定值相等,一致则认为设备已授权

看到蓝牙绑定时报错 log 如下

对应代码为先获取 BluetoothManager getAdapter 通过 getAddress 方法获取 mac,

取不到则再进行反射调用,调用时抛出权限异常

Caused by: java.lang.SecurityException: Need LOCAL_MAC_ADDRESS permission: Neither user 10032 nor current process has android.permission.LOCAL_MAC_ADDRESS.

高版本安卓此权限必须是系统 app 才能拥有,可以修改 smali 代码直接走下面的 Secure 查询 bluetooth_address 即可

扫码绑定后本地开始生成付款条码

调用对应 so 生成条码

本文内容仅用于技术研究与学习交流目的,不涉及任何商业用途。
文中所提及的技术手段、工具使用及分析过程均基于开源或公开信息进行探讨,不代表鼓励或支持任何非法行为。
若您使用相关技术从事违法行为,后果自负,与本文作者无关。
如有侵权,联系删文。

反编指令
java -jar apktool_2.4.1.jar d .\test.apk -o test       
 
打包指令
java -jar apktool_2.4.1.jar b test -o testPack.apk
反编指令
java -jar apktool_2.4.1.jar d .\test.apk -o test       
 
打包指令
java -jar apktool_2.4.1.jar b test -o testPack.apk
D NativeLibraryHelper: Library 'libsgmain.so' is not page-aligned - will not be able to open it directly from apk.
W NativeHelper: Failure copying native libraries [errorCode=-2]
D NativeLibraryHelper: Library 'libsgmain.so' is not page-aligned - will not be able to open it directly from apk.
W NativeHelper: Failure copying native libraries [errorCode=-2]
java -jar apktool_2.4.1.jar b .\test -o unsigned.apk
 
然后再到 linux 环境下处理
 
unzip unsigned.apk -d apk_unpacked/
 
cd apk_unpacked/
 
zip -r -0 ../repack-unsigned.apk *
 
zipalign -f -v -p 4 repack-unsigned.apk aligned.apk
 
apksigner  sign --ks test.jks --ks-key-alias xxxx  -ks-pass pass:xxxx  ./aligned.apk
java -jar apktool_2.4.1.jar b .\test -o unsigned.apk
 
然后再到 linux 环境下处理
 
unzip unsigned.apk -d apk_unpacked/
 
cd apk_unpacked/
 
zip -r -0 ../repack-unsigned.apk *
 
zipalign -f -v -p 4 repack-unsigned.apk aligned.apk
 
apksigner  sign --ks test.jks --ks-key-alias xxxx  -ks-pass pass:xxxx  ./aligned.apk
private void c() {
    if (com.xpay.watch.utils.a.a(this)) {
        getWindow().addFlags(128);
        setContentView(com.xpay.watch.utils.g.a(this, R.layout.activity_watch_main));
        com.xpay.android.watchsdk.g.a().g();
        if (!com.xpay.android.watchsdk.l.a().e()) {
            com.xpay.android.watchsdk.g.a().a(com.xpay.watch.utils.h.a(), com.xpay.watch.utils.h.b(), null);
            try {
                com.xpay.android.watchsdk.ble.d.a().f();
            } catch (Throwable th) {
                com.xpay.android.phone.inside.log.api.b.a(th);
            }
            this.a.postDelayed(this.h, 200L);
            com.xpay.android.watchsdk.l.a().l();
        } else {
            d();
            this.a.postDelayed(this.i, 200L);
        }
    } else {
        DialogUtil.a aVar = new DialogUtil.a(this);
        aVar.a(DialogUtil.DialogType.SINGLE_BUTTON);
        aVar.a(getString(R.string.dlg_authorization_check_failed_title));
        aVar.b(getString(R.string.dlg_authorization_check_failed_tips));
        aVar.c("c-" + com.xpay.watch.utils.h.a() + " m-" + Build.MODEL);
        aVar.a(new h(this));
        DialogUtil.a(aVar);
    }
     
public static boolean a(Context context) {
    if (com.a.a.a.a.a.booleanValue()) {
        String[] split = h.f().split(",");
        String[] split2 = h.e().split(",");
        if (split2 == null || split2.length <= 0) {
            return false;
        }
        for (int i = 0; i < split2.length; i++) {
            Log.w("xpay_watch", "packageName |" + split2[i]);
            if (a(context, split2[i], split)) {
                return true;
            }
        }
        return false;
    }
    return true;
}
 
private static boolean a(Context context, String str, String[] strArr) {
    List<String> a2 = a(context, str);
    if (a2 == null || a2.size() <= 0) {
        return false;
    }
    for (String str2 : strArr) {
        String trim = str2.trim();
        Log.w("xpay_watch", str + " " + a2.get(0).toUpperCase() + trim.toUpperCase());
        if (TextUtils.equals(a2.get(0).toUpperCase(), trim.toUpperCase())) {
            return true;
        }
    }
    return false;
}
 
private static List<String> a(Context context, String str) {
    try {
        PackageInfo packageInfo = context.getPackageManager().getPackageInfo(str, 64);
        if (packageInfo != null) {
            Signature[] signatureArr = packageInfo.signatures;
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            ArrayList arrayList = new ArrayList();
            for (Signature signature : signatureArr) {
                byte[] digest = messageDigest.digest(signature.toByteArray());
                StringBuilder sb = new StringBuilder((digest.length * 3) - 1);
                int length = digest.length - 1;
                for (int i = 0; i <= length; i++) {
                    byte b = digest[i];
                    sb.append(a[(b & 240) >> 4]);
                    sb.append(a[b & 15]);
                    if (i < length) {
                        sb.append(':');
                    }
                }
                String sb2 = sb.toString();
                arrayList.add(sb2);
                com.xpay.android.phone.inside.log.api.b.a("package |" + str + "| fingerprint: " + sb2);
                Log.w("xpay_watch", "package |" + str + "| fingerprint: " + sb2);
            }
            return arrayList;
        }
        return null;
    } catch (Throwable th) {
        th.printStackTrace();
        return null;
    }
}
private void c() {
    if (com.xpay.watch.utils.a.a(this)) {
        getWindow().addFlags(128);
        setContentView(com.xpay.watch.utils.g.a(this, R.layout.activity_watch_main));
        com.xpay.android.watchsdk.g.a().g();
        if (!com.xpay.android.watchsdk.l.a().e()) {
            com.xpay.android.watchsdk.g.a().a(com.xpay.watch.utils.h.a(), com.xpay.watch.utils.h.b(), null);
            try {
                com.xpay.android.watchsdk.ble.d.a().f();
            } catch (Throwable th) {
                com.xpay.android.phone.inside.log.api.b.a(th);
            }
            this.a.postDelayed(this.h, 200L);
            com.xpay.android.watchsdk.l.a().l();
        } else {
            d();
            this.a.postDelayed(this.i, 200L);
        }
    } else {
        DialogUtil.a aVar = new DialogUtil.a(this);
        aVar.a(DialogUtil.DialogType.SINGLE_BUTTON);
        aVar.a(getString(R.string.dlg_authorization_check_failed_title));
        aVar.b(getString(R.string.dlg_authorization_check_failed_tips));
        aVar.c("c-" + com.xpay.watch.utils.h.a() + " m-" + Build.MODEL);
        aVar.a(new h(this));
        DialogUtil.a(aVar);
    }
     
public static boolean a(Context context) {
    if (com.a.a.a.a.a.booleanValue()) {
        String[] split = h.f().split(",");
        String[] split2 = h.e().split(",");
        if (split2 == null || split2.length <= 0) {
            return false;
        }
        for (int i = 0; i < split2.length; i++) {
            Log.w("xpay_watch", "packageName |" + split2[i]);
            if (a(context, split2[i], split)) {
                return true;
            }
        }
        return false;
    }
    return true;
}
 
private static boolean a(Context context, String str, String[] strArr) {
    List<String> a2 = a(context, str);
    if (a2 == null || a2.size() <= 0) {
        return false;
    }
    for (String str2 : strArr) {
        String trim = str2.trim();
        Log.w("xpay_watch", str + " " + a2.get(0).toUpperCase() + trim.toUpperCase());
        if (TextUtils.equals(a2.get(0).toUpperCase(), trim.toUpperCase())) {
            return true;
        }
    }
    return false;
}
 
private static List<String> a(Context context, String str) {
    try {
        PackageInfo packageInfo = context.getPackageManager().getPackageInfo(str, 64);
        if (packageInfo != null) {
            Signature[] signatureArr = packageInfo.signatures;
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            ArrayList arrayList = new ArrayList();
            for (Signature signature : signatureArr) {
                byte[] digest = messageDigest.digest(signature.toByteArray());
                StringBuilder sb = new StringBuilder((digest.length * 3) - 1);
                int length = digest.length - 1;
                for (int i = 0; i <= length; i++) {
                    byte b = digest[i];
                    sb.append(a[(b & 240) >> 4]);
                    sb.append(a[b & 15]);
                    if (i < length) {
                        sb.append(':');
                    }
                }
                String sb2 = sb.toString();
                arrayList.add(sb2);
                com.xpay.android.phone.inside.log.api.b.a("package |" + str + "| fingerprint: " + sb2);
                Log.w("xpay_watch", "package |" + str + "| fingerprint: " + sb2);
            }
            return arrayList;
        }
        return null;
    } catch (Throwable th) {
        th.printStackTrace();
        return null;
    }
}
14:05:57.870 9853  BluetoothGattServer      D  onServiceAdded() - handle=40 uuid=00003802-0000-1000-8000-00805f9b34fb status=0
14:05:57.874 9853  BluetoothGattServer      W  Unhandled exception in callback
                                               java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toUpperCase()' on a null object reference
                                                   at com.xpay.android.watchsdk.ble.d.b(SourceFile:542)
                                                   at com.xpay.android.watchsdk.ble.d.a(SourceFile:44)
                                                   at com.xpay.android.watchsdk.ble.d$a.onServiceAdded(SourceFile:441)
                                                   at android.bluetooth.BluetoothGattServer$1.onServiceAdded(BluetoothGattServer.java:136)
                                                   at android.bluetooth.IBluetoothGattServerCallback$Stub.onTransact(IBluetoothGattServerCallback.java:85)
                                                   at android.os.Binder.execTransact(Binder.java:723)
14:06:13.725 9853  zygote                   I  Debugger is no longer active
14:05:57.870 9853  BluetoothGattServer      D  onServiceAdded() - handle=40 uuid=00003802-0000-1000-8000-00805f9b34fb status=0
14:05:57.874 9853  BluetoothGattServer      W  Unhandled exception in callback
                                               java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toUpperCase()' on a null object reference
                                                   at com.xpay.android.watchsdk.ble.d.b(SourceFile:542)
                                                   at com.xpay.android.watchsdk.ble.d.a(SourceFile:44)
                                                   at com.xpay.android.watchsdk.ble.d$a.onServiceAdded(SourceFile:441)
                                                   at android.bluetooth.BluetoothGattServer$1.onServiceAdded(BluetoothGattServer.java:136)
                                                   at android.bluetooth.IBluetoothGattServerCallback$Stub.onTransact(IBluetoothGattServerCallback.java:85)
                                                   at android.os.Binder.execTransact(Binder.java:723)
14:06:13.725 9853  zygote                   I  Debugger is no longer active
public String b() {
        if (this.k == null) {
            if (this.h == null) {
                this.h = (BluetoothManager) this.c.getSystemService("bluetooth");
                if (this.h == null) {
                    com.xpay.android.phone.inside.log.api.b.b("Unable to initialize BluetoothManager.");
                    return null;
                }
            }
            this.i = this.h.getAdapter();
            if (this.i == null) {
                com.xpay.android.phone.inside.log.api.b.b("Unable to obtain a BluetoothAdapter.");
                return null;
            }
            this.k = this.i.getAddress();
            if (TextUtils.isEmpty(this.k) || this.k.endsWith("00:00:00:00:00")) {
                try {
                    this.k = a(this.i);
                } catch (Throwable th) {
                    com.xpay.android.phone.inside.log.api.b.a(th);
                }
            }
            if (TextUtils.isEmpty(this.k) || this.k.endsWith("00:00:00:00:00")) {
                try {
                    this.k = Settings.Secure.getString(this.c.getContentResolver(), "bluetooth_address");
                } catch (Throwable th2) {
                    com.xpay.android.phone.inside.log.api.b.a(th2);
                }
            }
            com.xpay.android.phone.inside.log.api.b.a("ServerAddress:" + this.k);
        }
        return this.k;
    }
     
    private static String a(BluetoothAdapter bluetoothAdapter) {
        Object obj;
        try {
            Field declaredField = BluetoothAdapter.class.getDeclaredField("mService");
            declaredField.setAccessible(true);
            obj = declaredField.get(bluetoothAdapter);
        } catch (Throwable th) {
            com.xpay.android.phone.inside.log.api.b.a(th);
        }
        if (obj == null) {
            return null;
        }
        Method declaredMethod = obj.getClass().getDeclaredMethod("getAddress", new Class[0]);
        declaredMethod.setAccessible(true);
        Object invoke = declaredMethod.invoke(obj, new Object[0]);
        if (invoke != null && (invoke instanceof String)) {
            return (String) invoke;
        }
        return null;
    }
public String b() {
        if (this.k == null) {
            if (this.h == null) {
                this.h = (BluetoothManager) this.c.getSystemService("bluetooth");
                if (this.h == null) {
                    com.xpay.android.phone.inside.log.api.b.b("Unable to initialize BluetoothManager.");
                    return null;

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 82
支持
分享
最新回复 (34)
雪    币: 163
活跃值: (2778)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
不错哟,分析的手表软件
2025-5-29 17:39
0
雪    币: 5164
活跃值: (4755)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
66
2025-5-29 20:25
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2025-5-30 00:45
0
雪    币: 1837
活跃值: (3680)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
666
2025-5-30 22:19
0
雪    币: 129
活跃值: (130)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习一下
2025-5-31 13:28
0
雪    币: 252
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
666
2025-5-31 16:50
0
雪    币: 544
活跃值: (628)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习一下
2025-5-31 20:09
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
66
2025-5-31 20:42
0
雪    币: 1593
活跃值: (1599)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
回复学学
2025-6-1 03:38
0
雪    币: 4464
活跃值: (1296)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
1
2025-6-1 15:18
0
雪    币: 87
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
qweeeeeeeeeeeeeeeeeee
2025-6-2 10:24
0
雪    币: 2096
活跃值: (2350)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
好像很牛逼 的样子
2025-6-2 10:39
0
雪    币: 2096
活跃值: (2350)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
这手表的APP 怎么弄出来 ?
2025-6-2 10:42
0
雪    币: 30
活跃值: (1735)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
666
2025-6-3 08:35
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
6
2025-6-3 09:43
0
雪    币: 13
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
6
2025-6-3 14:41
0
雪    币: 3223
活跃值: (1133)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
18
6
2025-6-3 14:46
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
1
2025-6-3 14:50
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
1
2025-6-3 16:50
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
66
2025-6-4 09:41
0
雪    币: 519
活跃值: (206)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
感谢分享
2025-6-4 09:42
0
雪    币: 84
活跃值: (2563)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
1
2025-6-4 14:45
0
雪    币: 1749
活跃值: (1645)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
1
2025-6-4 14:46
0
雪    币: 369
活跃值: (221)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
25
666
2025-6-4 16:51
0
游客
登录 | 注册 方可回帖
返回