Oc代码求助


#1

在Mac上使用IDA PRO7.0分析,IPA从PP助手上下载的越狱应用。

搜索关键方法,一步步看。遇到关键代码看不懂,想问问

url 是 “/cdn/user/getUserInfo”,body是如何产生的

id __cdecl -[FXUserHttpDAO getUserInfoWithUserId:succeed:fail:](FXUserHttpDAO *self, SEL a2, signed __int64 a3, id a4, id a5)
{
  id v5; // x20
  signed __int64 v6; // x22
  __int64 v7; // x24
  __int64 v8; // x19
  __int64 v9; // x1
  __int64 v10; // x21
  __int64 v11; // x0
  __int64 v12; // x20
  __int64 v13; // x1
  __int64 v14; // x0
  __int64 v15; // x21
  __int64 v16; // x1
  __int64 v17; // x1
  __int64 v18; // x19
  id result; // x0
  void **v20; // [xsp+0h] [xbp-B0h]
  __int64 v21; // [xsp+8h] [xbp-A8h]
  __int64 (__fastcall *v22)(); // [xsp+10h] [xbp-A0h]
  void *v23; // [xsp+18h] [xbp-98h]
  __int64 v24; // [xsp+20h] [xbp-90h]
  void **v25; // [xsp+28h] [xbp-88h]
  __int64 v26; // [xsp+30h] [xbp-80h]
  __int64 (__fastcall *v27)(); // [xsp+38h] [xbp-78h]
  void *v28; // [xsp+40h] [xbp-70h]
  __int64 v29; // [xsp+48h] [xbp-68h]
  __int64 v30; // [xsp+50h] [xbp-60h]
  const __CFString *v31; // [xsp+58h] [xbp-58h]
  __int64 v32; // [xsp+60h] [xbp-50h]
  __int64 v33; // [xsp+68h] [xbp-48h]

  v5 = a5;
  v6 = a3;
  v7 = __stack_chk_guard;
  v8 = objc_retain(a4, a2);
  v10 = objc_retain(v5, v9);
  v31 = CFSTR("userId");
  objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithInteger:", v6);
  v32 = objc_retainAutoreleasedReturnValue();
  objc_msgSend(&OBJC_CLASS___NSDictionary, "dictionaryWithObjects:forKeys:count:", &v32, &v31, 1LL);
  v11 = objc_retainAutoreleasedReturnValue();
  +[FXRequestInfo requestInfoWithPath:method:body:](
    &OBJC_CLASS___FXRequestInfo,
    "requestInfoWithPath:method:body:",
    CFSTR("/cdn/user/getUserInfo"),
    0LL,
    v11);
  v12 = objc_retainAutoreleasedReturnValue();
  objc_release();
  objc_release();
  v25 = _NSConcreteStackBlock;
  v26 = - -3254779904LL;
  v27 = sub_100415074;
  v28 = &unk_1016016D0;
  v14 = objc_retain(v10, v13);
  v15 = v14;
  v29 = v14;
  v30 = v8;
  v20 = _NSConcreteStackBlock;
  v21 = - -3254779904LL;
  v22 = sub_1004153F0;
  v23 = &unk_101601700;
  objc_retain(v8, v16);
  v24 = v15;
  objc_retain(v15, v17);
  +[BaseHttpDAO requestWithInfo:completeHandler:failHandler:](
    &OBJC_CLASS___BaseHttpDAO,
    "requestWithInfo:completeHandler:failHandler:",
    v12,
    &v25,
    &v20,
    _NSConcreteStackBlock,
    - -3254779904LL,
    sub_1004153F0,
    &unk_101601700,
    v15,
    _NSConcreteStackBlock,
    - -3254779904LL,
    sub_100415074,
    &unk_1016016D0,
    v29,
    v8);
  v18 = objc_retainAutoreleasedReturnValue();
  objc_release();
  objc_release();
  objc_release();
  objc_release();
  objc_release();
  result = (id)objc_release();
  if ( v7 == v33 )
    result = (id)objc_autoreleaseReturnValue(v18);
  return result;
}

#2

看下block


#3
__int64 __fastcall sub_100415074(__int64 a1, __int64 a2)
{
  __int64 v2; // x20
  void *v3; // x19
  __int64 v4; // x21
  void *v5; // x22
  __int64 v6; // x0
  __int64 v7; // x0
  void *v8; // x22
  void *v9; // x0
  int v10; // w23
  FXUserInfo *v11; // x22
  __int64 v12; // x0
  __int64 v13; // x1
  __int64 v14; // x22
  void (*v15)(void); // x8
  __int64 v16; // x0
  __int64 v17; // x0
  __int64 v18; // x0
  __int64 v20; // [xsp+0h] [xbp-70h]
  __int64 v21; // [xsp+8h] [xbp-68h]
  __int64 v22; // [xsp+10h] [xbp-60h]
  __int64 v23; // [xsp+18h] [xbp-58h]
  __int64 v24; // [xsp+20h] [xbp-50h]

  v2 = a1;
  v3 = (void *)objc_retain(a2, a2);
  if ( objc_msgSend(v3, "code") )
  {
    objc_msgSend(v3, "msg");
    v4 = objc_retainAutoreleasedReturnValue();
    v5 = objc_msgSend(v3, "code");
    v21 = NSLocalizedDescriptionKey;
    objc_msgSend(v3, "msg");
    v22 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(&OBJC_CLASS___NSDictionary, "dictionaryWithObjects:forKeys:count:", &v22, &v21, 1LL);
    v6 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(&OBJC_CLASS___NSError, "errorWithDomain:code:userInfo:", v4, v5, v6);
    objc_retainAutoreleasedReturnValue();
    objc_release();
    objc_release();
    objc_release();
    v7 = *(_QWORD *)(v2 + 32);
    if ( v7 )
      (*(void (**)(void))(v7 + 16))();
    goto LABEL_14;
  }
  objc_msgSend(v3, "data");
  v8 = (void *)objc_retainAutoreleasedReturnValue();
  v9 = objc_msgSend(&OBJC_CLASS___NSDictionary, "class");
  v10 = (unsigned __int64)objc_msgSend(v8, "isKindOfClass:", v9);
  objc_release();
  if ( v10 )
  {
    v11 = objc_msgSend(&OBJC_CLASS___FXUserInfo, "alloc");
    objc_msgSend(v3, "data");
    v12 = objc_retainAutoreleasedReturnValue();
    v20 = 0LL;
    -[FXJSONModel initWithDictionary:error:](v11, "initWithDictionary:error:", v12, &v20, 0LL);
    v14 = objc_retain(v20, v13);
    objc_release();
    if ( v14 )
    {
      v15 = *(void (**)(void))(*(_QWORD *)(v2 + 32) + 16LL);
    }
    else
    {
      v18 = *(_QWORD *)(v2 + 40);
      if ( !v18 )
      {
LABEL_13:
        objc_release();
        goto LABEL_14;
      }
      v15 = *(void (**)(void))(v18 + 16);
    }
    v15();
    goto LABEL_13;
  }
  v23 = NSLocalizedDescriptionKey;
  objc_msgSend(v3, "msg");
  v24 = objc_retainAutoreleasedReturnValue();
  objc_msgSend(&OBJC_CLASS___NSDictionary, "dictionaryWithObjects:forKeys:count:", &v24, &v23, 1LL);
  v16 = objc_retainAutoreleasedReturnValue();
  objc_msgSend(&OBJC_CLASS___NSError, "errorWithDomain:code:userInfo:", CFSTR("获取用户信息失败"), 902LL, v16);
  objc_retainAutoreleasedReturnValue();
  objc_release();
  objc_release();
  v17 = *(_QWORD *)(v2 + 32);
  if ( v17 )
    (*(void (**)(void))(v17 + 16))();
LABEL_14:
  objc_release();
  return objc_release();
}

#4

看错了,那两个是完成和失败的block,真正的body是

objc_msgSend(&OBJC_CLASS___NSDictionary, "dictionaryWithObjects:forKeys:count:", &v32, &v31, 1LL);

#5

F5生成的伪代码有问题,不过你可以根据经验和上下文大致定位到这里

结合上面的nsdictionary,你可以判断传入的body是字典{@"userId":v6},v6就是a3也就是第三个参数,因为oc本身机制的问题第一个和第二个参数都是隐式的,所以这里的a3实际上就是getUserInfoWithUserId:后面的参数


#6

body中有一个sign,我想找到sign签名的算法。然后就不知道该咋办呢


#7

你贴的部分根本没有sign哇


#8
id __cdecl -[FXRequestInfo requestBody](FXRequestInfo *self, SEL a2)
{
  FXRequestInfo *v2; // x20
  void *v3; // x0
  struct objc_object *v4; // x19
  void *v5; // x0
  void *v6; // x22
  signed __int64 v7; // x27
  void *v8; // x21
  signed __int64 v9; // x28
  __int64 v10; // x22
  __int64 v11; // x0
  void *v12; // x22
  __int64 v13; // x0
  __int64 v14; // x0
  void *v15; // x0
  void *v16; // x0
  __int64 v17; // x0
  __int64 v18; // x0
  __int64 v19; // x0
  __int64 v20; // x20
  __int64 v21; // x0
  __int64 v22; // x0
  __int64 v23; // x0
  __int64 v24; // x0
  signed __int64 v25; // x0
  __int64 v26; // x0
  signed __int64 v27; // x0
  __int64 v28; // x0
  __int64 v29; // x24
  __int64 v30; // x0
  __int64 v31; // x0
  __int64 v32; // x0
  __int64 v33; // x23
  __int64 v34; // x0
  __int64 v35; // x0
  __int64 v36; // x0

  v2 = self;
  v3 = objc_msgSend(&OBJC_CLASS___NSMutableDictionary, "alloc");
  v4 = (struct objc_object *)objc_msgSend(v3, "init");
  ((void (__cdecl *)(FXAppConfig_meta *, SEL))objc_msgSend)((FXAppConfig_meta *)&OBJC_CLASS___FXAppConfig, "appVersion");
  v5 = (void *)objc_retainAutoreleasedReturnValue();
  objc_msgSend(v5, "stringByReplacingOccurrencesOfString:withString:", CFSTR("."), &stru_101668020);
  v6 = (void *)objc_retainAutoreleasedReturnValue();
  objc_release();
  v7 = 4LL - (_QWORD)objc_msgSend(v6, "length");
  v8 = (void *)objc_retain();
  if ( v7 >= 1 )
  {
    v9 = 0LL;
    do
    {
      objc_msgSend(v8, "stringByAppendingString:", CFSTR("0"));
      objc_retainAutoreleasedReturnValue();
      objc_release();
      ++v9;
    }
    while ( v9 < v7 );
  }
  v10 = objc_retain();
  objc_release();
  objc_msgSend(v4, "setObject:forKey:", v10, CFSTR("version"));
  objc_release();
  objc_release();
  ((void (__cdecl *)(FXAppConfig_meta *, SEL))objc_msgSend)((FXAppConfig_meta *)&OBJC_CLASS___FXAppConfig, "platformId");
  v11 = objc_retainAutoreleasedReturnValue();
  objc_msgSend(v4, "setObject:forKey:", v11, CFSTR("platform"));
  objc_release();
  if ( (unsigned int)-[FXRequestInfo method](v2, "method") == 1 )
  {
    ((void (__cdecl *)(FXLoginInfo_meta *, SEL))objc_msgSend)(
      (FXLoginInfo_meta *)&OBJC_CLASS___FXLoginInfo,
      "shareUserInfo");
    v12 = (void *)objc_retainAutoreleasedReturnValue();
    if ( (unsigned int)objc_msgSend(v12, "isLoginKG") )
    {
      objc_msgSend(v12, "pid");
      v13 = objc_retainAutoreleasedReturnValue();
      objc_msgSend(v4, "setObject:forKey:", v13, CFSTR("pid"));
      objc_release();
      objc_msgSend(v12, "token");
      v14 = objc_retainAutoreleasedReturnValue();
      objc_msgSend(v4, "setObject:forKey:", v14, CFSTR("token"));
      objc_release();
      if ( v2->_isKugouLive )
      {
        objc_msgSend(v12, "kgInfo");
        v15 = (void *)objc_retainAutoreleasedReturnValue();
        v16 = objc_msgSend(v15, "userid");
        objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithInteger:", v16);
        v17 = objc_retainAutoreleasedReturnValue();
        objc_msgSend(v4, "setObject:forKey:", v17, CFSTR("kugouId"));
        objc_release();
        objc_release();
        ((void (__cdecl *)(FXAppConfig_meta *, SEL))objc_msgSend)(
          (FXAppConfig_meta *)&OBJC_CLASS___FXAppConfig,
          "channelId");
        v18 = objc_retainAutoreleasedReturnValue();
        objc_msgSend(v4, "setObject:forKey:", v18, CFSTR("channelId"));
        objc_release();
        objc_msgSend(v12, "pid");
        v19 = objc_retainAutoreleasedReturnValue();
        objc_msgSend(v4, "setObject:forKey:", v19, CFSTR("pId"));
        objc_release();
      }
    }
    else
    {
      objc_msgSend(v4, "setObject:forKey:", &stru_101668020, CFSTR("pid"));
      objc_msgSend(v4, "setObject:forKey:", &stru_101668020, CFSTR("token"));
    }
    ((void (__cdecl *)(FXAppConfig_meta *, SEL))objc_msgSend)(
      (FXAppConfig_meta *)&OBJC_CLASS___FXAppConfig,
      "channelId");
    v21 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(v4, "setObject:forKey:", v21, CFSTR("channel"));
    objc_release();
    ((void (__cdecl *)(FXAppConfig_meta *, SEL))objc_msgSend)((FXAppConfig_meta *)&OBJC_CLASS___FXAppConfig, "deviceId");
    v22 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(v4, "setObject:forKey:", v22, CFSTR("device"));
    objc_release();
    ((void (__cdecl *)(FXAppConfig_meta *, SEL))objc_msgSend)((FXAppConfig_meta *)&OBJC_CLASS___FXAppConfig, "deviceId");
    v23 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(v4, "setObject:forKey:", v23, CFSTR("uuid"));
    objc_release();
    ((void (__cdecl *)(FXAppConfig_meta *, SEL))objc_msgSend)(
      (FXAppConfig_meta *)&OBJC_CLASS___FXAppConfig,
      "currentDevice");
    v24 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(v4, "setObject:forKey:", v24, CFSTR("sysVersion"));
    objc_release();
    v25 = ((signed __int64 (__cdecl *)(FXAppConfig_meta *, SEL))objc_msgSend)(
            (FXAppConfig_meta *)&OBJC_CLASS___FXAppConfig,
            "serverTimes");
    objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithLongLong:", v25);
    v26 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(v4, "setObject:forKey:", v26, CFSTR("times"));
    objc_release();
    v27 = ((signed __int64 (__cdecl *)(FXAppConfig_meta *, SEL))objc_msgSend)(
            (FXAppConfig_meta *)&OBJC_CLASS___FXAppConfig,
            "appId");
    objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithInteger:", v27);
    v28 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(v4, "setObject:forKey:", v28, CFSTR("appid"));
    objc_release();
    ((void (__cdecl *)(FXRequestInfo *, SEL))objc_msgSend)(v2, "bodyInfo");
    v29 = objc_retainAutoreleasedReturnValue();
    objc_release();
    if ( v29 )
    {
      ((void (__cdecl *)(FXRequestInfo *, SEL))objc_msgSend)(v2, "bodyInfo");
      v30 = objc_retainAutoreleasedReturnValue();
      objc_msgSend(v4, "setValuesForKeysWithDictionary:", v30);
      objc_release();
    }
    ((void (__cdecl *)(FXRequestInfo *, SEL, id))objc_msgSend)(v2, "signWithRequestInfo:", v4);
    v31 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(v4, "setObject:forKey:", v31, CFSTR("sign"));
    v32 = objc_retain();
LABEL_17:
    v20 = v32;
    objc_release();
    objc_release();
    goto LABEL_18;
  }
  if ( !(unsigned int)-[FXRequestInfo method](v2, "method") )
  {
    ((void (__cdecl *)(FXRequestInfo *, SEL))objc_msgSend)(v2, "bodyInfo");
    v33 = objc_retainAutoreleasedReturnValue();
    objc_release();
    if ( v33 )
    {
      ((void (__cdecl *)(FXRequestInfo *, SEL))objc_msgSend)(v2, "bodyInfo");
      v34 = objc_retainAutoreleasedReturnValue();
      objc_msgSend(v4, "setValuesForKeysWithDictionary:", v34);
      objc_release();
    }
    ((void (__cdecl *)(FXRequestInfo *, SEL, id))objc_msgSend)(v2, "signWithRequestInfo:", v4);
    v35 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(v4, "setObject:forKey:", v35, CFSTR("sign"));
    ((void (__cdecl *)(FXRequestInfo *, SEL, id))objc_msgSend)(v2, "sortBodyInfoToStr:", v4);
    v36 = objc_retainAutoreleasedReturnValue();
    objc_msgSend(&OBJC_CLASS___NSString, "stringWithFormat:", CFSTR("%@"), v36);
    v32 = objc_retainAutoreleasedReturnValue();
    goto LABEL_17;
  }
  v20 = objc_retain();
LABEL_18:
  objc_release();
  return (id)objc_autoreleaseReturnValue(v20);
}

#9

看起来重点在这个方法里哇


#10

我现在不知道去哪里找,只能凭感觉


#11
id __cdecl -[FXRequestInfo signWithRequestInfo:](FXRequestInfo *self, SEL a2, id a3)
{
  FXRequestInfo *v3; // x19
  struct objc_object *v4; // x0
  __int64 v5; // x19

  v3 = self;
  ((void (__cdecl *)(FXRequestInfo *, SEL, id))objc_msgSend)(self, "sortBodyInfoToStr:", a3);
  v4 = (struct objc_object *)objc_retainAutoreleasedReturnValue();
  ((void (__cdecl *)(FXRequestInfo *, SEL, id))objc_msgSend)(v3, "signWithString:", v4);
  v5 = objc_retainAutoreleasedReturnValue();
  objc_release();
  return (id)objc_autoreleaseReturnValue(v5);
}

#12

我已经指路了你能自己解决吗,你是要我免费帮你还原算法吗? 对不起,做不到