IOS WeChat & Frida 逆向(二)
这个拖得有点久了主要最近比较忙 过一段时间就要去foreign了 调试机不在身边 所以今天先帖实现代码以及几个主要函数 图文可能只有文字了图是帖不了了看情况明天或者后天再补充教程中部分敏感内容已用????代替可能有人会说我按照你的教程走,最后报错了或者根本没有实现功能之类的,那么请看我随后要说的话。不是所有的教程都是面向小白,照葫芦画瓢,葫芦没有了瓢也就不复存在,请多思考,如果您觉得看着本文章,头晕并且伴随着恶心不适,请立马点击❌,谢谢合作
声明:本文所发布的逆向分析文章,仅限用于学习和研究软件安全的目的。全体用户必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。学习逆向分析技术是为了更好的完善软件可能存在的不安全因素,提升软件安全意识。不得将上述内容私自传播、销售或者其他任何非法用途!否则,一切后果请自行自负!
主要函数:1.消息函数
-://OC伪码
void -(void * self, void * _cmd, void * arg2, void * arg3) {//arg2为用户名字,arg3=包含红包类型等一系列参数
r7 = (sp - 0x14) + 0xc;
sp = sp - 0x34;
r8 = self;
r11 = ;
CMP(r11, 0x0);
r10 = ;
if (r10 == 0x0) {
r1 = @selector(logWithLevel:module:errorCode:file:line:func:format:);
r0 = @class(iConsole);
r6 = "/Users/gydevgydev/Desktop/hudson/workspace/release_appstore_6.7.3/WeChatKernel/Message/MessageMgr.mm";
r3 = "Msg";
asm{ strd r5, r2, };
r2 = 0x4;
objc_msgSend(r0, r1, r2);
}
else {
r6 = [ init];
;
;
r4 = [ retain];//这里就是构造字典供后面使用
;
;
r3 = r6;
r1 = @selector(performSelectorOnMainThread:withObject:waitUntilDone:);
r2 = @selector(MainThreadNotifyToExt:);
objc_msgSend(r8, r1, r2);
;
}
;
loc_2db4174(r11, r1, r2, r3);
return;
}
2.红包参数函数
-:void -(void * self, void * _cmd, void * arg2) {//agr2为我们需要的红包参数,里面包含除了timingIdentifier之外所需的所有参数
loc_e0bad8(self + *0x3b320d8, arg2);
return;
}
3.开红包函数-:void -(void * self, void * _cmd, void * arg2) {
sub_1c0d198();
return;
}
4.红包合法验证函数(timingIdentifier)-:void -(void * self, void * _cmd, void * arg2, void * arg3) {//timingIdentifier==arg2,agr2为NSData 我们需要把它转化为NSString 在使用Json解析为对象取值
r7 = (sp - 0x14) + 0xc;
sp = sp - 0x1a4;
stack = self;
r5 = loc_1c0d1a8(arg2, _cmd, arg2, arg3, stack);
sub_1c0d198();
r4 = loc_1c0d1a0();
sub_1c0d198();
r6 = loc_1c0d1a0();
r0 = r4;
r4 = r5;
loc_1c0d19c(r0);
stack = @selector(alloc);
sub_1c0d198();
stack = sub_1c0d198();
sub_1c0d198();
r7 = r7;
loc_1c0d1a0();
asm{ strd r1, r2, };
sub_1c0d198();
r5 = loc_1c0d1a0();
r10 = sub_1c0d198();
sub_1c0d198();
r7 = r7;
r6 = loc_1c0d1a0();
stack = r5;
if (r5 == 0x0) {
r8 = 0x3b24800;
s0 = "/Users/gydevgydev/Desktop/hudson/workspace/release_appstore_6.7.3/WCBiz/WCRedEnvelopes/Model/WCRedEnvelopesLogicMgr.mm";
asm{ strd r5, r2, };
sub_1c0d198();
sub_1c0d198();
r7 = r7;
stack = loc_1c0d1a0();
}
r11 = @selector(platRet);
stack = r4;
if (sub_1c0d198() != 0x0) {
stack = r6;
sub_1c0d198();
sub_1c0d198();
r5 = loc_1c0d1a0();
sub_1c0d198();
loc_1c0d19c(r5);
r5 = @selector(platMsg);
sub_1c0d198();
r7 = r7;
r4 = loc_1c0d1a0();
sub_1c0d198();
r0 = r4;
r4 = stack;
loc_1c0d19c(r0);
if (r10 == 0x0) {
r10 = sub_1c0d198();
}
sub_1c0d198();
r7 = r7;
r11 = loc_1c0d1a0();
loc_1c0d19c(stack);
}
else {
r11 = r6;
}
if (r10 == 0x0) {
r8 = stack;
stack = @selector(objectForKey:);
sub_1c0d198();
r7 = r7;
r5 = loc_1c0d1a0();
r10 = @selector(intValue);
r6 = sub_1c0d198();
loc_1c0d19c(r5);
if (r6 != 0x0) {
sub_1c0d198();
r5 = loc_1c0d1a0();
r10 = sub_1c0d198();
loc_1c0d19c(r5);
sub_1c0d198();
r7 = r7;
r5 = loc_1c0d1a0();
loc_1c0d19c(r11);
r11 = r5;
}
else {
r10 = 0x0;
}
}
r5 = @selector(length);
r0 = sub_1c0d198();
if ((r10 != 0x0) && (r0 == 0x0)) {
r6 = @selector(platMsg);
sub_1c0d198();
r7 = r7;
r8 = r4;
r4 = loc_1c0d1a0();
r5 = sub_1c0d198();
loc_1c0d19c(r4);
if (r5 != 0x0) {
sub_1c0d198();
r7 = r7;
r5 = loc_1c0d1a0();
loc_1c0d19c(r11);
}
else {
r5 = r11;
}
}
else {
r5 = r11;
}
r8 = r10;
stack = @selector(numberWithUnsignedInt:);
sub_1c0d198();
r7 = r7;
r4 = loc_1c0d1a0();
r11 = stack;
r10 = @selector(safeSetObject:forKey:);
sub_1c0d198();
loc_1c0d19c(r4);
stack = r5;
sub_1c0d198();
r4 = @class(iConsole);
stack = @selector(cgiCmdid);
sub_1c0d198();
r1 = @selector(logWithLevel:module:errorCode:file:line:func:format:);
asm{ strd r0, r2, };
stack = 0x0;
sub_1c0d198();
r4 = @selector(objectForKey:);
sub_1c0d198();
r7 = r7;
r6 = loc_1c0d1a0();
r5 = @selector(intValue);
stack = sub_1c0d198();
loc_1c0d19c(r6);
if (sub_1c0d198() <= 0x3) {
sub_1c0d198();
r8 = loc_1c0d1a0();
sub_1c0d198();
sub_1c0d198();
r6 = loc_1c0d1a0();
sub_1c0d198();
sub_1c0d198();
r5 = loc_1c0d1a0();
sub_1c0d198();
r4 = loc_1c0d1a0();
sub_1c0d198();
loc_1c0d19c(r4);
loc_1c0d19c(r5);
loc_1c0d19c(r6);
stack = sub_1c0d198();
sub_1c0d198();
r10 = loc_1c0d1a0();
sub_1c0d198();
sub_1c0d198();
r4 = loc_1c0d1a0();
sub_1c0d198();
r7 = r7;
r6 = loc_1c0d1a0();
stack = r8;
r11 = sub_1c0d198();
loc_1c0d19c(r6);
loc_1c0d19c(r4);
loc_1c0d19c(r10);
loc_1c0e864(0x2f4b, 0x0);
loc_1c0d19c(r8);
r0 = 0x2c77986;
asm{ ldrd r8, sl, };
r0 = r0 + 0xeace7a;
r4 = stack;
}
else {
stack = r10;
r0 = stack | r8;
if (r0 != 0x0) {
r10 = stack;
sub_1c0d198();
stack = loc_1c0d1a0();
sub_1c0d198();
r6 = loc_1c0d1a0();
r11 = sub_1c0d198();
loc_1c0d19c(r6);
sub_1c0d198();
r8 = loc_1c0d1a0();
sub_1c0d198();
r5 = loc_1c0d1a0();
sub_1c0d198();
r7 = r7;
r6 = loc_1c0d1a0();
sub_1c0d198();
loc_1c0d19c(r6);
sub_1c0d198();
sub_1c0d198();
stack = r5;
r11 = sub_1c0d198();
loc_1c0d19c(r5);
r4 = r10;
loc_1c0d19c(r8);
loc_1c0d19c(stack);
r0 = 0x2c77856;
asm{ ldrd r8, sl, };
r0 = r0 + 0xeacfaa;
}
else {
r10 = sp + 0x38;
r4 = stack;
r11 = 0x0;
asm{ ldm.w sl, {r1, r8, sl} };
r0 = 0x3b24800;
}
}
sub_1c0d198();
r7 = r7;
r6 = loc_1c0d1a0();
sub_1c0d198();
sub_1c0d198();
sub_1c0d198();
sub_1c0d198();
r4 = stack;
r0 = sub_1c0d198();
if (r0 > 0xa) goto loc_ead116;
loc_ead020:
goto *0xead024;
loc_ead03a:
if (r11 == 0x0) {
sub_1c0d198();
r4 = loc_1c0d1a0();
sub_1c0d198();
loc_1c0d19c(r4);
}
stack = 0x3179d4d;
r4 = @selector(OnQueryRedEnvelopesUserInfo:Error:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r0 = __NSConcreteStackBlock;
r1 = 0x0;
r2 = 0x354f678;
asm{ strd r1, sb, };
stack = loc_1c0d1a8(r6, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
sub_1c0d298();
loc_1c0d19c(stack);
loc_1c0d19c(stack);
r4 = stack;
goto loc_ead56a;
loc_ead56a:
loc_1c0d19c(r6);
loc_1c0d19c(r11);
loc_1c0d19c(stack);
loc_1c0d19c(stack);
loc_1c0d19c(r8);
loc_1c0d19c(stack);
loc_1c0d19c(r10);
loc_1c0d19c(r4);
return;
loc_ead176:
stack = 0x3179d4d;
r4 = @selector(OnGenRedEnvelopesPayRequest:Error:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r1 = 0x0;
r0 = __NSConcreteStackBlock;
r2 = 0x354f690;
asm{ strd r1, sb, };
stack = loc_1c0d1a8(stack, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
r4 = stack;
sub_1c0d298();
loc_1c0d19c(stack);
goto loc_ead566;
loc_ead566:
loc_1c0d19c();
goto loc_ead56a;
loc_ead1e4:
stack = 0x3179d4d;
r4 = @selector(OnSendShareRedEnvelopesoRequest:Error:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r0 = __NSConcreteStackBlock;
r1 = 0x0;
r2 = 0x354f6c0;
asm{ strd r1, sb, };
stack = loc_1c0d1a8(r6, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
r4 = stack;
sub_1c0d298();
loc_1c0d19c(stack);
goto loc_ead566;
loc_ead252:
stack = 0x3179d4d;
r4 = @selector(OnReceiverQueryRedEnvelopesRequest:Error:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r0 = __NSConcreteStackBlock;
r1 = 0x0;
r2 = 0x354f6d8;
asm{ strd r1, sb, };
stack = loc_1c0d1a8(r6, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
r4 = stack;
sub_1c0d298();
loc_1c0d19c(stack);
goto loc_ead566;
loc_ead2c0:
stack = 0x3179d4d;
sub_1c0d198();
r2 = 0x3b24434;
r3 = 0xead701;
r4 = @selector(OnOpenRedEnvelopesRequest:Error:);
r1 = sp + 0xe4;
r5 = *r2;
asm{ stm.w r1, {r0, r3} };
stack = loc_1c0d1a8(r6, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
r4 = stack;
sub_1c0d298();
loc_1c0d19c(stack);
goto loc_ead566;
loc_ead342:
stack = 0x3179d4d;
r4 = @selector(OnQueryRedEnvelopesDetailRequest:Error:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r0 = __NSConcreteStackBlock;
r1 = 0x0;
r2 = 0x354f708;
asm{ strd r1, sb, };
stack = loc_1c0d1a8(r6, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
r4 = stack;
sub_1c0d298();
loc_1c0d19c(stack);
goto loc_ead566;
loc_ead3b0:
stack = 0x3179d4d;
r4 = @selector(OnQueryUserSendOrReceiveRedEnveloperListRequest:Error:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r0 = __NSConcreteStackBlock;
r1 = 0x0;
r2 = 0x354f720;
asm{ strd r1, sb, };
stack = loc_1c0d1a8(r6, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
r4 = stack;
sub_1c0d298();
loc_1c0d19c(stack);
goto loc_ead566;
loc_ead41e:
stack = 0x3179d4d;
r4 = @selector(OnClearserSendOrReceiveRedEnveloperListRequest:Error:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r0 = __NSConcreteStackBlock;
r1 = 0x0;
r2 = 0x354f738;
asm{ strd r1, sb, };
stack = loc_1c0d1a8(r6, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
r4 = stack;
sub_1c0d298();
loc_1c0d19c(stack);
goto loc_ead566;
loc_ead48c:
stack = 0x3179d4d;
r4 = @selector(OnThanksForRedEnvelopesRequest:Error:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r0 = __NSConcreteStackBlock;
r1 = 0x0;
r2 = 0x354f750;
asm{ strd r1, sb, };
stack = loc_1c0d1a8(r6, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
r4 = stack;
sub_1c0d298();
loc_1c0d19c(stack);
goto loc_ead566;
loc_ead4fa:
stack = 0x3179d4d;
r4 = @selector(OnGenH5RedEnvelopesPayRequest:Error:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r0 = __NSConcreteStackBlock;
r1 = 0x0;
r2 = 0x354f6a8;
asm{ strd r1, sb, };
stack = loc_1c0d1a8(r6, r1, r2, r3, stack, stack);
stack = loc_1c0d1a8(r11);
r4 = stack;
sub_1c0d298();
loc_1c0d19c(stack);
goto loc_ead566;
loc_ead116:
stack = 0x3179d4d;
r4 = @selector(OnWCRedEnvelopesBaseRequestCommonError:HongbaoCmdType:);
r3 = 0xc2000000;
r5 = __objc_proto_WCRedEnvelopesLogicMgrExt_protocol;
r1 = 0x0;
r0 = __NSConcreteStackBlock;
r2 = 0x354f768;
asm{ strd r1, sb, };
r0 = loc_1c0d1a8(stack, r1, r2, r3, stack, stack);
stack = r0;
r4 = stack;
sub_1c0d298();
goto loc_ead566;
}
实现代码:import frida
import sys
session = frida.get_usb_device().attach(88906)
script_string = """
if (ObjC.available)
{
try
{
var sessionUserName;
var timingIdentifier;
var receiver_dict = ObjC.classes.NSMutableDictionary.alloc().init();
var openred_dict = ObjC.classes.NSMutableDictionary.alloc().init();
var className = "CMessageMgr";
var funcName = "- AsyncOnAddMsg:MsgWrap:";
var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]');
console.log("[*] Class Name: " + className);
console.log("[*] Method Name: " + funcName);
Interceptor.attach(hook.implementation, {
onEnter: function(args) {
var arg2 = new ObjC.Object(args);
console.log("AsyncOnAddMsgArg2:"+ arg2.toString());
var obj = new ObjC.Object(args);
console.log("AsyncOnAddMsgArg3:"+ obj.toString());
var str = obj.toString();
type = str.split(", ");
if(type.indexOf("type=49")!=-1){
console.log("Successful!!");
console.log("receiver_dict:"+ receiver_dict);
console.log("openred_dict:"+ openred_dict);
//在这里你可以通过红包类型为49 直接调用openRed函数达到自动抢红包
};
},
onLeave: function(retval) {
string_value = ObjC.classes.NSString.stringWithString_(retval);
console.log("Mgrretval:"+string_value+" type:"+typeof string_value);
}
});
var arr;
var url;
var originalUrl
var className = "WCPayInfoItem";
var funcName = "- setM_c2cNativeUrl:";
var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]');
console.log("[*] Class Name: " + className);
console.log("[*] Method Name: " + funcName);
Interceptor.attach(hook.implementation, {
onEnter: function(args) {
var arg2 = new ObjC.Object(args);
//console.log("setM_c2cNativeUrl:"+ arg2.toString());
originalUrl = arg2.toString();
url = arg2.toString();
var num=url.indexOf("?")
url=url.substr(num+1); //取得所有参数
arr=url.split("&"); //各个参数放到数组里
//console.log(arr);
for(var i=0;i < arr.length;i++){
num=arr.indexOf("="); //num=7,9,6,12,3,4
if(num>0){
name=arr.substring(0,num);
value=arr.substr(num+1);
this=value;
}
};
//构建NSDictionary
receiver_dict.setObject_forKey_(0,"agreeDuty");
receiver_dict.setObject_forKey_(1,"inWay");
receiver_dict.setObject_forKey_(this["channelid"],"channelId");
receiver_dict.setObject_forKey_(this["msgtype"],"msgType");
receiver_dict.setObject_forKey_(originalUrl,"nativeUrl");
receiver_dict.setObject_forKey_(this["sendid"],"sendId");
openred_dict.setObject_forKey_("http://wx.qlogo.cn/?????","headImg");
openred_dict.setObject_forKey_("XXX","nickName");
openred_dict.setObject_forKey_(originalUrl,"nativeUrl");
openred_dict.setObject_forKey_(this["channelid"],"channelId");
openred_dict.setObject_forKey_(this["msgtype"],"msgType");
openred_dict.setObject_forKey_(this["sendid"],"sendId");
openred_dict.setObject_forKey_(this["sendusername"],"sessionUserName");
},
onLeave: function(retval) {
console.log("Finished!");
}
});
var className = "WCRedEnvelopesLogicMgr";
var funcName = "- OnWCToHongbaoCommonResponse:Request:";
var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]');
console.log("[*] Class Name: " + className);
console.log("[*] Method Name: " + funcName);
Interceptor.attach(hook.implementation, {
onEnter: function(args) {
var arg2 = new ObjC.Object(args);
//NSData转换为NSString
console.log("OnWCToHongbaoCommonResponse:"+ Memory.readUtf8String(arg2.retText().buffer().bytes(),arg2.retText().buffer().length()));
//将json字符串转换成json对象
var obj = JSON.parse(Memory.readUtf8String(arg2.retText().buffer().bytes(),arg2.retText().buffer().length()));
console.log(obj.timingIdentifier);
timingIdentifier = obj.timingIdentifier;
openred_dict.setObject_forKey_(timingIdentifier,"timingIdentifier");
if(timingIdentifier!=null){
console.log("OpenRed");
var OpenRedEnvelopesRequest = ObjC.classes.WCRedEnvelopesLogicMgr.alloc().init();
OpenRedEnvelopesRequest["- OpenRedEnvelopesRequest:"](openred_dict);
};
},
onLeave: function(retval) {
console.log("Finished!");
}
});
}
catch(err)
{
console.log("[!] Exception2: " + err.message);
}
}
else
{
console.log("Objective-C Runtime is not available!");
}
"""
script = session.create_script(script_string)
def on_message(message, data):
if message['type'] == 'error':
print("[!] " + message['stack'])
elif message['type'] == 'send':
print(" " + message['payload'])
else:
print(message)
script.on('message', on_message)
script.load()
sys.stdin.read()
# 红包参数:
# [<WCRedEnvelopesLogicMgr: 0x171030740> OpenRedEnvelopesRequest:{
# channelId = 1;
# headImg = "http://wx.qlogo.cn/????";
# msgType = 1;
# nativeUrl = "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=10000394012018&sendusername=?????&ver=6&sign=????";
# nickName = "????";
# sendId = 10000394012018102;
# sessionUserName = ?????;
# timingIdentifier = ?????;
# } ]
好文,坏处在于 公开之后 就会和谐 :)
多谢分享
学习了 [快捷回复]-学破解防逆向,知进攻懂防守! 谢谢楼主分享,学习学习! 感谢分享宝贵经验 给大牛点个赞,教程很nice!
页:
[1]