回顾2009至2013年的移动开发经历,除常规SDK接入外,最让我印象深刻的是深入短代计费领域的技术探索,特别是通过逆向工程破解SDK加密逻辑的过程。

短代计费的技术攻坚

在移动支付方案中,短信代收费(短代)曾是重要的支付渠道,我主导了多个短代计费系统的实现:

  1. 短信收发核心机制
    • 实现短信拦截监听:通过BroadcastReceiver捕获SMS_RECEIVED系统广播
    • 短信发送优化:处理SmsManager的分片发送和状态回调
    • 计费验证流程:建立服务端回调验证+本地短信内容匹配的双重保障
1
2
3
4
5
6
7
8
9
// 短信发送核心代码示例
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> parts = smsManager.divideMessage(encodedContent);
ArrayList<PendingIntent> sentIntents = new ArrayList<>();
for (int i = 0; i < parts.size(); i++) {
sentIntents.add(PendingIntent.getBroadcast(context, i,
new Intent(SMS_SENT_ACTION), 0));
}
smsManager.sendMultipartTextMessage(port, null, parts, sentIntents, null);
  1. 计费风控体系
    • 设备指纹识别:通过IMEI+MAC地址生成唯一设备ID
    • 频次限制:滑动窗口算法控制单设备日请求量
    • 通道熔断机制:实时监控各SP通道成功率

IDA逆向工程突破

最值得铭记的是对某支付SDK的逆向分析经历:

逆向分析过程

  1. 动态调试准备

    • 使用Xposed框架hook关键JNI方法
    • 配置IDA远程调试环境(adb forward tcp:23946 tcp:23946)
  2. 多层加密破解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 反编译发现的加密函数片段
    void __fastcall Java_com_pay_sdk_Encryptor_nativeEncrypt(
    JNIEnv *env, jobject obj, jbyteArray input) {
    jbyte* data = (*env)->GetByteArrayElements(env, input, 0);
    for(int i=0; i<len; i+=8) {
    // ARM汇编指令发现的异或加密模式
    asm volatile(
    "LD1 {v0.8b}, [%[data]]\n"
    "EOR v0.8b, v0.8b, %[key].8b\n"
    "ST1 {v0.8b}, [%[data]]\n"
    :: [data]"r"(data+i), [key]"w"(key_reg)
    );
    }
    }
  3. 跨语言调用追踪

    • Java层:通过JNI调用的参数传递规则
    • Native层:ARM汇编指令级的寄存器分析
    • 服务端:配合Charles抓包验证加密结果

技术收获

  1. 逆向推导出128位动态密钥生成算法
  2. 破解指令级优化的NEON并行加密流程
  3. 完整还原Java->JNI->ARM Assembly的调用链路

技术反思

虽然最终因商务原因未实际应用该研究成果,但这个过程让我深刻认识到:

  • 安全设计:加密方案需结合动态密钥与白盒加密
  • 逆向边界:技术探索与商业伦理的平衡之道
  • 底层价值:汇编语言知识在移动安全中的关键作用

逆向工程如同黑暗中的考古,每一行反汇编代码都是穿越技术迷雾的星火。这段经历印证了:真正的技术自信,源于知其然更知其所以然的执着探索。