0x00 前言
Better365官网:https://www.better365.cn/
该系列软件目前有两个付费软件是超级右键(iRightMouse)和iShot,两款软件都很好用,希望大家有条件的可以去支持正版。
0x01 定位关键点
软件默认会在界面有订购的字样,已经购买的用户可以进行恢复购买,我们可以通过这个地方抓取恢复购买的链接,也就是关键请求。
image-20230216174740996.png (434.22 KB, 下载次数: 0)
下载附件
2023-2-19 16:46 上传
image-20230216175322483.png (45.98 KB, 下载次数: 0)
下载附件
2023-2-19 16:47 上传
获取到关键请求之后就用hopper打开iRightMouse,在字符串中搜索
image-20230216175505724.png (1.16 MB, 下载次数: 0)
下载附件
2023-2-19 16:47 上传
查看引用,可以定位到[ApplePurchaseManager verifyPurchaseWithPaymentTransaction:isTestServer:Compl:]方法
image-20230216175655283.png (950.66 KB, 下载次数: 0)
下载附件
2023-2-19 16:47 上传
这个里面就是发送请求验证的逻辑了,一般下面这种情况,红框中的就是对请求返回值处理的回调函数,这里是函数名符号应该是被去掉了,所以是sub_100002aa4
image-20230216175952062.png (292.62 KB, 下载次数: 0)
下载附件
2023-2-19 16:47 上传
双击进去之后看到函数内容,就可以看到重点,一个是对status进行判断,一个是取receipt的内容进行了一些操作和判断
image-20230216180143424.png (710.66 KB, 下载次数: 0)
下载附件
2023-2-19 16:47 上传
关键就在于receipt的内容,而判断的关键在于rax的值,可以看到rax判断过了之后直接就加密写入本地了,那么关键就在于sub_10001e4ec函数了。
image-20230216180546928.png (269.24 KB, 下载次数: 0)
下载附件
2023-2-19 16:47 上传
双击进去可以看到这个函数又取了in_app和expires_date_ms
image-20230216180923939.png (608.77 KB, 下载次数: 0)
下载附件
2023-2-19 16:47 上传
结合请求的返回值看,可以得出上面的关键字的所属位置关系,当然你要是从逆向伪代码中分析也能分析出来.
{
"status":0,
"receipt":{
"in_app":[
"expires_date_ms":"1672000000000"
]
}
}
0x02 激活思路
0x03 iShot不同点
iShot在激活判断时有一些不同,可能是加了新老软件的兼容,如果expires_date_ms不存在时,会去判断product_id和purchase_date_ms。
image-20230216182810394.png (757.92 KB, 下载次数: 0)
下载附件
2023-2-19 16:47 上传
iShot的关键参数如下:
{
"status":0,
"receipt":{
"in_app":[
"expires_date_ms":"1672000000000",
"product_id":"ishotfeixuqidingyue20220212",
"purchase_date_ms":"1672000000000"
]
}
}
0x04 hook
这里有一些坑就是Objective-C中有些对象是只读形式,需要先转换为可读写的对象,才能进行替换,大家在编写时可以通过在网上搜索找到答案。
const objectForKeyedSubscript1 = ObjC.classes.NSJSONSerialization['+ JSONObjectWithData:options:error:'];
var flag1;
Interceptor.attach(objectForKeyedSubscript1.implementation,{
onLeave(retval){
let data = ObjC.Object(retval);
let key_receipt = ObjC.classes.NSString.stringWithString_('receipt');
let receipt = data.objectForKeyedSubscript_(key_receipt);
let key_in_app = ObjC.classes.NSString.stringWithString_('in_app');
let key_expires_date_ms = ObjC.classes.NSString.stringWithString_('expires_date_ms');
let key_product_id = ObjC.classes.NSString.stringWithString_('product_id');
let data_product_id = ObjC.classes.NSString.stringWithString_('ishotfeixuqidingyue20220212');
let key_purchase_date_ms = ObjC.classes.NSString.stringWithString_('purchase_date_ms');
let dict = ObjC.classes.NSMutableDictionary.alloc().init();
dict.setObject_forKey_(9999999999999,key_expires_date_ms);
dict.setObject_forKey_(9999999999999,key_purchase_date_ms);
dict.setObject_forKey_(data_product_id,key_product_id);
let info_array = ObjC.classes.NSMutableArray.alloc().init();
info_array.addObject_(dict);
let receipt1 = receipt.mutableCopy();
receipt1.setObject_forKey_(info_array,key_in_app);
let replace_data = data.mutableCopy();
replace_data.setObject_forKey_(receipt1,key_receipt);
retval.replace(replace_data);
console.log("Crack Success!")
}
})
0x05 参考
浅谈Mac应用逆向破解
Typora For Mac Crack