This article mainly introduces the application proficiency of some work, and traces the stack to see whether to do some other operations, etc.:
Packet capture:
signature is an encrypted value;
First go up the trace, down the stack and encrypt
Let's base64 the results to see if the results are consistent to determine whether the base64 is magically changed
Verify that base64 is standard;
According to the stack just now, follow
0x101115468 /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!+[RSA encryptData:withKeyRef:isSign:]
0x101115ae0 /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!+[RSA encryptData:publicKey:]
0x101115a28 /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!+[RSA encryptString:publicKey:]
0x10108a8ac /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!-[YDRequest getSignatureWithReqId:]
0x10108a6b0 /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!-[YDRequest updateParametersForGet:reqid:]
0x10108aaf4 /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!-[YDRequest initWithURLString:parameters:method:]
0x10108e300 /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!-[HpEngineRequest initWithURLString:parameters:method:]
0x101047544 /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!-[HpEngine refreshNewsListOfKeyword:sinceIndex:]
0x101a17858 /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!-[HpNewsListDataProvider userRefreshLatestData:]
0x1017be2ac /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!-[YDNewsListView userRefreshData:]
0x101a235bc /var/containers/Bundle/Application/9580891A-98B0-4F3F-9938-D794221B5B4D/yidian.app/yidian!-[YDNLViewModel didFinishLoadingLocalData:]
0x101a166f0 yidian!0x16ae6f0 (0x1016ae6f0)
0x232360a38 libdispatch.dylib!_dispatch_call_block_and_release
0x2323617d4 libdispatch.dylib!_dispatch_client_callout
0x23230f008 libdispatch.dylib!_dispatch_main_queue_callback_4CF V A R I A N T VARIANT VARIANTmp
0x2328b4b20 CoreFoundation!CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE
Let's hook it again: encryptData:withKeyRef:isSign:
frida -UF -l hook.js directly attached to the app
var initWithMethod = ObjC.classes.RSA['+ encryptData:withKeyRef:isSign:'];
Interceptor.attach(initWithMethod.implementation, {
onEnter: function (args) {
// console.log('initWithMethod called from:\n' +
// Thread.backtrace(this.context, Backtracer.ACCURATE)
// .map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log("args[2]: ", ObjC.Object(args[2]));
console.log("args[3]: ", hexdump(args[3]));
console.log("args[4]: ", args[4]);
}, onLeave: function (retval) {
console.log('Base64Encode() this.args1 onLeave:', hexdump(retval));
}
});
bool a5 is 0, which is false, go directly
At this time, I understand that this place is the place where the stack and encryption are traced at the beginning above.
Let's look up according to the stack:
Seeing here is also doing rsa and then base64, no other operations
Let's hook it up:
var initWithMethod = ObjC.classes.RSA['+ encryptString:publicKey:'];
Interceptor.attach(initWithMethod.implementation, {
onEnter: function (args) {
// console.log('initWithMethod called from:\n' +
// Thread.backtrace(this.context, Backtracer.ACCURATE)
// .map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log("args[2]: ", ObjC.Object(args[2]));
console.log("args[3]: ", ObjC.Object(args[3]));
console.log("args[4]: ",hexdump(args[4]));
}, onLeave: function (retval) {
console.log('Base64Encode() this.args1 onLeave:', ObjC.Object(retval));
}
});
I'll go, won't I just come out right now?
The value that needs to be encrypted: "pro6.4.0.00njbh2wlr_1685327378963_38033100"
input parameters splicing appid, cv, platform, reqid, version
The secret key and public key are also out.
No problem, call it a day!