xkang 发表于 2018-11-23 15:29

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 = ?????;
# } ]







MrScotch 发表于 2018-11-23 17:26

好文,坏处在于 公开之后 就会和谐 :)

kanxue2018 发表于 2019-1-6 21:36


多谢分享
学习了

别管我了行 发表于 2022-5-5 02:46

youxigx 发表于 2022-5-5 23:04

[快捷回复]-学破解防逆向,知进攻懂防守!

Cerolluo 发表于 2022-12-14 09:14

谢谢楼主分享,学习学习!

曾经沧海 发表于 2023-1-20 21:25

感谢分享宝贵经验

一生逍遥 发表于 2023-2-4 22:19

给大牛点个赞,教程很nice!
页: [1]
查看完整版本: IOS WeChat & Frida 逆向(二)