ios逆向分析进阶之关键字加密还原

AI辅助iOS逆向算法分析:从目标定位到验证还原的完整方法 在移动应用安全领域,逆向工程是理解客户端逻辑、剖析接口参数生成机制的核心手段。而面对大型商业App的二进制文件,类名混淆、加密复杂、汇编代码冗长等问题,常让分析者陷入效率困境。借助AI大模型,可显著加速静态定位、伪代码还原、算法特征识别等重复性工作,但需警惕其“幻觉”风险。本文从逆向分析的基本概念出发,介绍如何通过抓包定位、静态工具(如Ghidra、otool)与动态调试(Frida)结合,构建“目标定义→静态定位→AI辅助阅读→动态验证→算法还原”的闭环流程。同时,文章给出了实用的Prompt模板与验证策 阅读详情

ios逆向分析进阶之关键字加密还原

衔接上一篇博客,这一片自主逆向了一个较坑的算法,感觉基本入门了:

  • 文中使用工具:
  • IDA,Xcode(主要用来静态分析代码)
  • theos lldb debugserver(动态跟踪函数参数返回值)
  • mac自带的日志查看工具(这里找了很多日志工具,感觉还是mac自带的控制台比较好用)
  • ssh连接手机
  • frida分析应用结构
  • charles(http截取)

回顾流程

  • 本次逆向重在总结思路,所以就不给出app名称。静态分析花费时间较长,相信一般都是这样。当然如果经验多了,关键字猜的准一点,分析时间会大大缩短。本次分析从一个基本对app默认规则了解较少的视角来分析,确保逆向思路准确或接近准确。过程尽量还原分析过程和流程。
  • 砸壳过程其实显示是没有加密,但dump头文件却很奇怪,一度以为dump不出头文件,也是后来发现,app目录下就有。不过个人觉得,只要app没加密,头文件其实不重要了。我们直接反编译搜索就行了,当然前提是思路要清晰。

charles抓包

POST /rest/user/thirdPlatformLogin?appver=5.4.4.297&did=BDF77B98-E3CD-4C99-BA77-EA75EE21FC77&c=PP&ver=5.4&sys=ios9.3.2&mod=iPhone6%2C1&net=%E4%B8%AD%E5%9B%BD%E8%81%94%E9%80%9A_5 HTTP/1.1
Host: api.gifshow.com
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
X-REQUESTID: 7603933
Accept: application/json
User-Agent: kwai-ios
Accept-Language: zh-Hans-CN;q=1
Content-Length: 580
Accept-Encoding: gzip, deflate

access_token=2.001azZhGohp7gC7c212d77790PBR_H&client_key=56c3713c&country_code=cn&language=zh-Hans-CN%3Bq%3D1&open_id=6140757656&platform=sina2.0&raw=1511322475686&secret=dyUsRMKNXHmsDwmC3cIq%2FdhlAlreWTMlgW9iGIt63lGd06FI5uJNP3Mt0N6X19n8I90zJIYC6MW54GRWq2qr7Zz6ztpybrQg8J05hNDWL2ADNGPTnTPP0Z%2FDdxJ2Yjlhmse4lFAHNj7mlsNY1J6m52tE9E9c%2BBkR1K6OaCr69iiBKPFjciq%2BWSOTU17SXnWl6pJR80FAJ%2BgnBXkCiIvAaEs5Y%2BNRgvAbxdxFd6LOnrfLguX6%2F75nMIdIIR5P%2BfjTqjM3Ux%2FAGlTxHG4OhKnTSNV%2F%2BRUwkMi0naooCdnZ6uMrSRA7Kw5EedS1z4n0efCQ6xtYSYHglxJOastX%2BmKevQ%3D%3D&sig=e162bc6fe6b588027938ab497fd33dd9


access_token    2.001azZhGohp7gC7c212d77790PBR_H
client_key  56c3713c
country_code    cn
language    zh-Hans-CN;q=1
open_id 6140757656
platform    sina2.0
raw 1511322475686
secret  dyUsRMKNXHmsDwmC3cIq/dhlAlreWTMlgW9iGIt63lGd06FI5uJNP3Mt0N6X19n8I90zJIYC6MW54GRWq2qr7Zz6ztpybrQg8J05hNDWL2ADNGPTnTPP0Z/DdxJ2Yjlhmse4lFAHNj7mlsNY1J6m52tE9E9c+BkR1K6OaCr69iiBKPFjciq+WSOTU17SXnWl6pJR80FAJ+gnBXkCiIvAaEs5Y+NRgvAbxdxFd6LOnrfLguX6/75nMIdIIR5P+fjTqjM3Ux/AGlTxHG4OhKnTSNV/+RUwkMi0naooCdnZ6uMrSRA7Kw5EedS1z4n0efCQ6xtYSYHglxJOastX+mKevQ==
sig e162bc6fe6b588027938ab497fd33dd9
  • 我们这里同样分析secret关键字,这里分析过程其实不重要了,其实也不能说不重要。我们在程序中搜索secret,发现和secret相关的字段比较多,这里其实也用到了猜测的方法。我们根据直觉和认识寻找,但是都比较坑,就不说了。其实到后来才知道,我们应该搜索KS开头的类,这个主程序代码类库命名的主要方式。因为这两个字母是app中文拼音的两个开头字母,刚开始有点找不着北。总之,最后没有找到相关的。
    这时候峰回路转,我们需要改变搜索规则。考虑是否可以搜索api.gifshow.com网址,但发现往这个地址发的数据很多,不现实。但发现这里这个路径/rest/user/thirdPlatformLogin?只有这个包里利用这条路径。经过搜索。我们发现apipath这个字符串里包含了/rest/user/thirdPlatformLogin?。搜索引用。其实在这里又花了点时间,发现IDA不是特别会用。因为它这个引用会跳到一个object的结构里,然后又包含了这个apipath,而且直接找引用根本找不到。
    apipath位置
  • 原因是object c调用规则,它采用了obj_msgsend()消息机制传输字符串来寻找对应的结构和方法,是所以我们直接找引用分本没有。好吧。

  • 这里就掉坑里,我放弃了正确的方法,转到分析界面寻找按钮响应事件去了。

-><_UIWebViewScrollView: 0x12fbeaa00; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = H; gestureRecognizers = <NSArray: 0x130ac0820>; layer = <CALayer: 0x130a41b30>; contentOffset: {0, -64}; contentSize: {320, 504}>
--><UIWebView: 0x130ebf310; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x130e2d8c0>>
---><WBSDKWebView: 0x1312a9510; frame = (0 0; 320 568); opaque = NO; autoresize = W+H; layer = <CALayer: 0x12f7fa190>>
----><UIView: 0x12f5f4fb0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x12f799f20>>
-----><WBSDKAuthorizeWebViewController: 0x13114df20>
------><UIViewControllerWrapperView: 0x131040c50; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x130d0cb30>>
-------><UINavigationTransitionView: 0x130aade80; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x130ac5a70>>
--------><UILayoutContainerView: 0x130a4cbd0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x131039dd0>; layer = <CALayer: 0x1310c71b0>>
---------><UINavigationController: 0x12fbd5000>
----------><KSNavigationController: 0x12fbd8200>
-----------><KSRevealSideViewController: 0x13085e630>
------------><UITransitionView: 0x130a24210; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x130d550a0>>
-------------><UIWindow: 0x12f5a1850; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x12f5e19b0>; layer = <UIWindowLayer: 0x12f5e0fe0>>
--------------><UIApplication: 0x12f58cb30>
---------------><AppDelegate: 0x12f599c60>
  • 这里显示的微博登录的一个界面,坑的是,管理按钮的根本不是本地的界面,而是weibo的sdk接口。我找了半天没找到响应时间在那。理论上应该能找到,但我在congtroller里面找半天后来果断放弃,回到了原来的路上。

IDA静态分析和各种动态分析

  • 其实这里静态分析,其实这里就走到正途上。但前面确实花了不少时间,很是纠结。IDA上有一个神奇的界面,叫鱼眼视图,开始不知道是用来干啥的,看起来很怪,后来发现很强大。
    鱼眼视图
    走到了正途我们就捡紧要的说了
    sel_apipath
    sub_1001AB000
    KSLoginService loginWithContext:(id)arg1
    id __cdecl -[KSPhoneLoginService processLoginResponse:context:](KSPhoneLoginService *self, SEL a2, id a3, id a4)  //
    sel_processLoginResponse
    sub_1001AB2B0
    KSLoginService loginWithContext                           KSLoginManager login

    sub_1003596AC
    id __cdecl -[KSPhoneLoginService processLoginResponse:context:](KSPhoneLoginService *self, SEL a2, id a3, id a4)
  • 经过跳转引用和鱼眼视图的不断切换,我们发现了程序的主要逻辑。apipath 通过sub_1001AB000通过KSLoginService loginWithContext引用。然后回溯到了[KSPhoneLoginService processLoginResponse:context:]。之后又回到了KSLoginService loginWithContex,只不过中间变成经过sub_1001AB2B0。
    这个时候要动态分析了,
    分别挂钩KSLoginService loginWithContext
    KSPhoneLoginService processLoginResponse:context:
%hook KSLoginService
- (void *)loginWithContext:(void *)arg1{
    NSString *string=@"hkms loginWithContext::arg1:";
    NSString *stringcombine=[[NSString alloc] initWithFormat:@"%@,%@",string,arg1];
    %log(stringcombine);
    string=[[NSString alloc] initWithFormat:@"%@,%@",@"hkms ::self-value",self];
    %log(string);
    void* result=%orig;//(arg1 ,arg2,arg3);
    string=[[NSString alloc] initWithFormat:@"%@,%@",@"hkms ::result-value",result];
    %log(string);
    return result;
}
%end
  • 只剩成功的这一段了,反正经过日志分析,我们发现 KSPhoneLoginService processLoginResponse:context:没有进来。我们loginWithContext似乎和这个关键字相关。
    为了验证我们的猜想,我们lldb跟进。
    image list -o -f
    找到模块地址基地址
    br s -a 基地址+IDA分析偏移
    下断

我们发现sub_1001AB000函数dataTaskWithRequest:cancellationToken执行后,我们的关键请求立马会被发送。

        id __fastcall sub_1001AB000(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8, struct objc_object *a9)

           v29 = +[KSUHTTPTaskManager defaultTaskManager](&OBJC_CLASS___KSUHTTPTaskManager, "defaultTaskManager");
    v30 = (void *)objc_retainAutoreleasedReturnValue(v29);
    v31 = objc_msgSend(v28, "token");
    v32 = objc_retainAutoreleasedReturnValue(v31);
    v33 = v32;
    v34 = objc_msgSend(v30, "dataTaskWithRequest:cancellationToken:", v22, v32);
    v15 = (KSApiDotGifShowHTTPClient *)objc_retainAutoreleasedReturnValue(v34);

到这里已经比较近了。但还需要很多分析。应为这里传经来的都是类.

    _text:00000001001AB1E0                 BL              _objc_msgSend
__text:00000001001AB1E4                 MOV             X29, X29
__text:00000001001AB1E8                 BL              _objc_retainAutoreleasedReturnValue
__text:00000001001AB1EC                 MOV             X25, X0
__text:00000001001AB1F0                 ADRP            X8, #selRef_dataTaskWithRequest_cancellationToken_@PAGE
__text:00000001001AB1F4                 LDR             X1, [X8,#selRef_dataTaskWithRequest_cancellationToken_@PAGEOFF] ; char *
__text:00000001001AB1F8                 MOV             X0, X24 ; void *
__text:00000001001AB1FC                 MOV             X2, X21
__text:00000001001AB200                 MOV             X3, X25
__text:00000001001AB204                 BL              _objc_msgSend
__text:00000001001AB208                 MOV             X29, X29
__text:00000001001AB20C                 BL              _objc_retainAutoreleasedReturnValue

挂钩得到了传经来的类,细节不说了,跟上面一样

%hook KSUHTTPTaskManager//这个管理器参数一就是KSUPOSTHTTPRequest 参数二BFCancellationToken
- (void*)dataTaskWithRequest:(void*)arg1 cancellationToken:(void*)arg2{
  • 经过了一大段分析,我们跟进了一步。但这里我用lldb动态把这个函数给跟了一遍,最后自己都醉了。
    应为这一段不和静态分析的代码的执行过程完全一样,虽然找到了地方,参数也相似,但有很多跳转就像山上的猴子,简直是乱跳,没有逻辑。

最后放弃了全盘动态跟踪的想法,这也就是arm汇编和x86汇编的区别吧。

  • 其实这里有点思路不清晰了,KSUPOSTHTTPRequest 知识发送请求的操作,我们的数据很有可能在这之前就完成,最后回到了sub_1001AB000
id __fastcall sub_1001AB000(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8, struct objc_object *a9)
{
  __int64 v9; // x22
  void *v10; // x19
  void *v11; // x0
  struct objc_object *v12; // x0
  struct objc_object *v13; // x21
  id v14; // x0
  KSApiDotGifShowHTTPClient *v15; // x22
  __int64 v16; // x0
  void *v17; // x0
  __int64 v18; // x20
  void *v19; // x0
  __int64 v20; // x21
  void *v21; // x0
  void *v22; // x21
  void *v23; // x0
  __int64 v24; // x23
  void *v25; // x0
  __int64 v26; // x22
  id v27; // x0
  void *v28; // x23
  id v29; // x0
  void *v30; // x24
  void *v31; // x0
  __int64 v32; // x0
  __int64 v33; // x25
  void *v34; // x0
  SEL v35; // x1
  id v36; // x2
  unsigned __int64 v37; // x3
  id v38; // x4
  id v39; // x5
  id v40; // x6
  id v41; // x7

  v9 = a1;
  v10 = (void *)objc_retain(a2, a2);
  if ( (unsigned int)objc_msgSend(v10, "isFaulted") )
  {
    v11 = objc_msgSend(v10, "error");
    v12 = (struct objc_object *)objc_retainAutoreleasedReturnValue(v11);
    v13 = v12;
    v14 = ((id (__cdecl *)(BFTask_meta *, SEL, id))objc_msgSend)(
            (BFTask_meta *)&OBJC_CLASS___BFTask,
            "taskWithError:",
            v12);
    v15 = (KSApiDotGifShowHTTPClient *)objc_retainAutoreleasedReturnValue(v14);
    v16 = (__int64)v13;
  }
  else
  {
    v17 = objc_msgSend(*(void **)(v9 + 32), "paramsFromContext:", *(_QWORD *)(v9 + 40));
    v18 = objc_retainAutoreleasedReturnValue(v17);
    if ( (unsigned int)objc_msgSend(*(void **)(v9 + 32), "needAppendTimestampSecret") )
    {
      v19 = objc_msgSend(*(void **)(v9 + 32), "_paramsWithTimestampSecret:", v18);
      v20 = objc_retainAutoreleasedReturnValue(v19);
      objc_release(v18);
      v18 = v20;
    }
    v21 = objc_msgSend(*(void **)(v9 + 32), "request");
    v22 = (void *)objc_retainAutoreleasedReturnValue(v21);
    v23 = objc_msgSend(*(void **)(v9 + 32), "apiPath");
    v24 = objc_retainAutoreleasedReturnValue(v23);
    objc_msgSend(v22, "setPath:", v24);
    objc_release(v24);
    objc_msgSend(v22, "setBodyParameter:", v18);
    objc_msgSend(*(void **)(v9 + 32), "additionSetupRequest:context:", v22, *(_QWORD *)(v9 + 40));
    v25 = objc_msgSend(*(void **)(v9 + 32), "_transformResponseObjectBlock");
    v26 = objc_retainAutoreleasedReturnValue(v25);
    objc_msgSend(v22, "setTransformResponseObject:", v26);
    objc_release(v26);
    v27 = ((id (__cdecl *)(BFCancellationTokenSource_meta *, SEL))objc_msgSend)(
            (BFCancellationTokenSource_meta *)&OBJC_CLASS___BFCancellationTokenSource,
            "cancellationTokenSource");
    v28 = (void *)objc_retainAutoreleasedReturnValue(v27);
    v29 = ((id (__cdecl *)(KSUHTTPTaskManager_meta *, SEL))objc_msgSend)(
            (KSUHTTPTaskManager_meta *)&OBJC_CLASS___KSUHTTPTaskManager,
            "defaultTaskManager");
    v30 = (void *)objc_retainAutoreleasedReturnValue(v29);
    v31 = objc_msgSend(v28, "token");
    v32 = objc_retainAutoreleasedReturnValue(v31);
    v33 = v32;
    v34 = objc_msgSend(v30, "dataTaskWithRequest:cancellationToken:", v22, v32);
    v15 = (KSApiDotGifShowHTTPClient *)objc_retainAutoreleasedReturnValue(v34);
    objc_release(v33);
    objc_release(v30);
    objc_release(v28);
    objc_release(v22);
    v16 = v18;
  }
  objc_release(v16);
  objc_release(v10);
  return objc_autoreleaseReturnValue(v15, v35, v36, v37, v38, v39, v40, v41, a9);
}

这段代码比较长,但是也比较重要,就全贴吧。
明显这里是加密关键:KSLoginService _paramsWithTimestampSecret。进去

id __cdecl -[KSLoginService _paramsWithTimestampSecret:](KSLoginService *self, SEL selm, id instr)
{
  void *v3; // x19
  void *datastr; // x0
  void *datastr0; // x21
  double ident0; // d0   我猜测这里是采用datastr溢出的方式的到ident0
  void *raw0; // x0
  __int64 raw; // x20
  void *secret0; // x0
  __int64 secret; // x21
  KSApiDotGifShowHTTPClient *instr_encode; // x22
  SEL instr_encode0; // x1
  id instr_encode1; // x2
  unsigned __int64 diguisign; // x3
  id diguisign0; // x4
  id v16; // x5
  id base64result; // x6
  id base64result0; // x7
  struct objc_object *v20; // [xsp+40h] [xbp+10h]

  v3 = objc_msgSend(instr, "mutableCopy");   //id __cdecl -[VKAccessToken mutableCopy](VKAccessToken *self, SEL selm)

  datastr = objc_msgSend(&OBJC_CLASS___NSDate, "date");
  datastr0 = (void *)objc_retainAutoreleasedReturnValue(datastr);
  objc_msgSend(datastr0, "timeIntervalSince1970");
  //ident0不知是什么,突然出现这么个值,raw还不定时的变化
  raw0 = objc_msgSend(&OBJC_CLASS___NSString, "stringWithFormat:", CFSTR("%ld"), (signed __int64)(ident0 * 1000.0));//拼接字符串,这里就一个,就是个类型转换
  raw = objc_retainAutoreleasedReturnValue(raw0);
  objc_release(datastr0);
  secret0 = objc_msgSend(&OBJC_CLASS___UIDevice, "getSignatureStr:", raw);
  //经过测试这里已经完成了secret字符串的加密

}

secret0 = objc_msgSend(&OBJC_CLASS___UIDevice, “getSignatureStr:”, raw);
//经过测试这里已经完成了secret字符串的加密



    id __cdecl +[UIDevice getSignatureStr:](UIDevice_meta *self, SEL selm, id instr)
{
  UIDevice_meta *v3; // x20
  struct objc_object *weiRSA; // x0
  __int64 weiRSA0; // x19
  __int64 ident0; // x1
  __int64 num0; // x21
  KSUTaskMetaData *ksutaskmetadata; // x0
  KSUTaskMetaData *ksutaskmetadata0; // x22
  signed __int64 ident1; // x2
  const __CFString *weiRSA1; // x20
  struct objc_object *weiRSA2; // x20
  __int64 num; // [xsp+8h] [xbp-38h]

  v3 = self;
  num = 0LL;
  weiRSA = +[KSRSAUtil getSignatureStr:identifier:error:](
         &OBJC_CLASS___KSRSAUtil,
         "getSignatureStr:identifier:error:",
         instr,
         CFSTR("kKSDefaultSecurityIdentifier"),
         &num);
  weiRSA0 = objc_retainAutoreleasedReturnValue(weiRSA);
  num0 = objc_retain(num, ident0);
  ksutaskmetadata = objc_msgSend(&OBJC_CLASS___KSUTaskMetaData, "alloc");
  ksutaskmetadata0 = objc_msgSend(ksutaskmetadata, "init");
  -[KSUTaskMetaData setAction:](ksutaskmetadata0, "setAction:", 41LL);
  -[KSUTaskMetaData setStatus:](ksutaskmetadata0, "setStatus:", 1LL);
  objc_msgSend((void *)v3, "taskMetaData:addErrorInfo:", ksutaskmetadata0, num0);
  if ( weiRSA0 )
    ident1 = 7LL;
  else
    ident1 = 8LL;
  if ( weiRSA0 )
    weiRSA1 = (const __CFString *)weiRSA0;
  else
    weiRSA1 = &stru_1024ident740;
  -[KSUTaskMetaData setStatus:](ksutaskmetadata0, "setStatus:", ident1);
  objc_release(num0);
  weiRSA2 = (struct objc_object *)objc_retainAutoreleaseReturnValue(weiRSA1);
  objc_release(ksutaskmetadata0);
  objc_release(weiRSA0);
  return weiRSA2;
}

weiRSA = +[KSRSAUtil getSignatureStr:identifier:error:](
&OBJC_CLASS___KSRSAUtil,
“getSignatureStr:identifier:error:”,
instr,
CFSTR(“kKSDefaultSecurityIdentifier”),
&num);
这里的结果就是secret
我们把这几个函数可以都挂一下,发现,返回值都是secret.
但最核心的是这个。


id __cdecl +[KSRSAUtil getSignatureStr:identifier:error:](KSRSAUtil_meta *self, SEL selm, id instr, id ident, id *a5)
{
  id *errostr; // x21
  id ident0; // x20
  KSRSAUtil_meta *selfobj; // x22
  void *instr_selm; // x19
  __int64 v9; // x1
  void *ident1; // x20
  void *instr_encode; // x0
  __int64 instr_encode0; // x0
  __int64 instr_encode1; // x23
  void *diguisign; // x0
  void *diguisign0; // x21
  void *NSSv; // x22
  void *base64result; // x0
  __int64 base64result0; // x23
  KSApiDotGifShowHTTPClient *base64result1; // x22
  void *v20; // x0
  __int64 v21; // x0
  SEL v22; // x1
  id v23; // x2
  unsigned __int64 v24; // x3
  id v25; // x4
  id v26; // x5
  id v27; // x6
  id v28; // x7
  struct objc_object *v30; // [xsp+40h] [xbp+10h]

  errostr = a5;
  ident0 = ident;   //这是一个字符串"KKSDefaultSecurityIdentifier"      

  selfobj = self;
  instr_selm = (void *)objc_retain(instr, selm);//这个选择子还是getSignatureStr,要么输入还是这么个类,要么其他的类也是这个方法,看了下其他类没有这个方法
  //这个instr为raw,为一串变化的字符串,目测跟时间有关,产生于上一层



  ident1 = (void *)objc_retain(ident0, v9);
  if ( objc_msgSend(ident1, "length") )//计算字节长度
  {
    instr_encode = objc_msgSend(instr_selm, "dataUsingEncoding:", 4LL);//静态调用本方法
    instr_encode0 = objc_retainAutoreleasedReturnValue(instr_encode);
    instr_encode1 = instr_encode0;
    diguisign = objc_msgSend(selfobj, "getSignature:identifier:error:", instr_encode0, ident1, errostr);
    diguisign0 = (void *)objc_retainAutoreleasedReturnValue(diguisign);
    objc_release(instr_encode1);
    if ( diguisign0 )
    {
        //这几个函数都是NSString里的库函数,也就是说,本地函数到此调用结束
      NSSv = objc_msgSend(&OBJC_CLASS___NSString, "alloc");
      base64result = objc_msgSend(diguisign0, "base64EncodedDataWithOptions:", 0LL);//NSData
      base64result0 = objc_retainAutoreleasedReturnValue(base64result);
      base64result1 = (KSApiDotGifShowHTTPClient *)objc_msgSend(NSSv, "initWithData:encoding:", base64result0, 4LL);//NNString
      objc_release(base64result0);
    }
    else
    {
      base64result1 = 0LL;
    }
    objc_release(diguisign0);
  }
  else if ( errostr )
  {
    v20 = objc_msgSend(selfobj, "errorWithErrorType:", 3001LL);//错误类型,不用管
    v21 = objc_retainAutoreleasedReturnValue(v20);
    base64result1 = 0LL;
    *errostr = (id)objc_autorelease(v21);
  }
  else
  {
    base64result1 = 0LL;
  }
  objc_release(ident1);
  objc_release(instr_selm);
  return objc_autoreleaseReturnValue(base64result1, v22, v23, v24, v25, v26, v27, v28, v30);
}

函数名中有RSA,我还以为跟RSA相关。但根本没啥关系。

(1)加密要用公钥 (n,e)
m必须是整数(字符串可以取ascii值或unicode值),且m必须小于n。
所谓”加密”,就是算出下式的c:
  m的e次方 ≡ c (mod n)
例如:公钥是 (3233, 17),鲍勃的m假设是65,那么可以算出下面的等式:
  6517 ≡ 2790 (mod 3233)
于是,c等于2790。
(2)解密要用私钥(n,d)
拿到2790以后,就用私钥(3233, 2753) 进行解密。
  cd ≡ m (mod n)
也就是说,c的d次方除以n的余数为m。现在,c等于2790,私钥是(3233, 2753)
  2790的2753次方 ≡ 65 (mod 3233)

因为里面就是base64加密,可见代码注释。
我们把这几个函数验证下。


%hook KSLoginService
- (void*)_paramsWithTimestampSecret:(void*)arg1{
    NSString *string=@"hkms _paramsWithTimestampSecret::arg1:";
    NSString *stringcombine=[[NSString alloc] initWithFormat:@"%@,%@",string,arg1];
    //NSString * match=@"^((?!rest/user).)*$"
    //[NSPredicate predcateWithFormate:arg1,match]
    //%log(stringcombine);

    string=[[NSString alloc] initWithFormat:@"%@,%@",@"hkm::self-value",self];
    stringcombine=[[NSString alloc] initWithFormat:@"%@,%@",stringcombine,string];
    //%log(stringcombine);

    void* result=%orig;//(arg1 ,arg2,arg3);
    string=[[NSString alloc] initWithFormat:@"%@,%@",@"hkm::result-value",result];
    stringcombine=[[NSString alloc] initWithFormat:@"%@,%@",stringcombine,string];
    %log(stringcombine);

    return result;
}
%end

%hook UIDevice
//这里的返回值已经是sercret关键字加密后的形式了
/*dp7RIvaOm/20vyL0eYCUqZP5los9YTlAPT/a0Bv6jlQfq2m3KfX9KuI/nEu771FIRLaxCvkaGA7++rXoU4dY
R0iPpYbXqMdU2kpRIgrPlCZHgC6I14UxaRbQ1JBJNqUqLGCzYDNWyBywurLFapIjfFy8857iYQ8WNIP9KmZX4W
ysTgfnmJBO2ltVkYZaUAP7ljdlritTSQ5R7qGAmwYlj1Vw1W6NWSlRTJAhIPaIRRw8jsBTdRELpEdwAoTX+EeW
jsEPTNbyaCOkNYcBsZcBiI4sFdVCvSRfigVxaZdYN+1oJdiksp8OOxyyDe6VAir15wf+1gcpVIiP7/fUxk0r5Q==
*/
+ (void*)getSignatureStr:(void*)arg1{
    NSString *string=@"hkms getSignatureStr::arg1:";
    NSString *stringcombine=[[NSString alloc] initWithFormat:@"%@,%@",string,arg1];

    string=[[NSString alloc] initWithFormat:@"%@,%@",@"hkm::self-value:",self];
    stringcombine=[[NSString alloc] initWithFormat:@"%@,%@",stringcombine,string];
    //%log(stringcombine);

    void* result=%orig;//(arg1 ,arg2,arg3);
    string=[[NSString alloc] initWithFormat:@"%@,%@",@"hkm::result-value:",result];
    stringcombine=[[NSString alloc] initWithFormat:@"%@,%@",stringcombine,string];
    %log(stringcombine);

    return result;
}
%end

日志跟踪结果


10:13:59.000000 +0800   com_kwai_gif     [1;36m[kuaishouhook] [m[0;36mTweak.xm:169[m [0;30;46mDEBUG:[m +[<KSRSAUtil: 0x102a4c270> getSignatureStr:0x160722db0 identifier:0x10257dcc0 error:0x16fd4a618]: hkms KSRSAUtil getSignatureStr::arg1:,1511579639518,hkms getSignatureStr::arg2:,kKSDefaultSecurityIdentifier,hkm::self-value:,KSRSAUtil,
hkm::result-value:,RXyOXL3s1QvkStBtDFO65BRIkuak5pz6t/EQMRhEmy/htpBnHNdCykZYmy7xWXecJ+znh8/4CEsc/48yJepfDMJyvfwsZLb/lXLZBdQmo/irCCrCbHfxsosnD7WUg7kapj1sRcUdx7R6SCi9pPgopebo21Ag2MtRDqnVjt3HzQvaKZIukGD5mb1DGi0ZpDFRbRX7pLKKZbihupvEYkxsTqL36pKWgs50b8y56zyQlNI43Ts3LD27RYTnJLGjTCRrSMX9kakVtAIeHI+EQoIPiajtJa+MA74MvynCMh1FMXkv0xhj0+rY1T5Iu4TZIFYSHLjwzjEC40TPDVP4vB3frA==

10:13:59.000000 +0800   com_kwai_gif     [1;36m[kuaishouhook] [m[0;36mTweak.xm:121[m [0;30;46mDEBUG:[m +[<UIDevice: 0x1a1e546a8> getSignatureStr:0x160722db0]: hkms getSignatureStr::arg1:,1511579639518,hkm::self-value:,
UIDevice,hkm::result-value:,RXyOXL3s1QvkStBtDFO65BRIkuak5pz6t/EQMRhEmy/htpBnHNdCykZYmy7xWXecJ+znh8/4CEsc/48yJepfDMJyvfwsZLb/lXLZBdQmo/irCCrCbHfxsosnD7WUg7kapj1sRcUdx7R6SCi9pPgopebo21Ag2MtRDqnVjt3HzQvaKZIukGD5mb1DGi0ZpDFRbRX7pLKKZbihupvEYkxsTqL36pKWgs50b8y56zyQlNI43Ts3LD27RYTnJLGjTCRrSMX9kakVtAIeHI+EQoIPiajtJa+MA74MvynCMh1FMXkv0xhj0+rY1T5Iu4TZIFYSHLjwzjEC40TPDVP4vB3frA==



10:15:35.000000 +0800   com_kwai_gif     [1;36m[kuaishouhook] [m[0;36mTweak.xm:169[m [0;30;46mDEBUG:[m +[<KSRSAUtil: 0x102a4c270> getSignatureStr:0x1604bbc70 identifier:0x10257dcc0 error:0x16fd4a0f8]: 
hkms KSRSAUtil getSignatureStr::arg1:1511579735417
hkms getSignatureStr::arg2:kKSDefaultSecurityIdentifier
hkm::self-value:KSRSAUtil
hkm::resultvalue:qCdZPHdPQx/KW/jsJv6QVJcR4blEMlKWlOAYFtharNFuWuKjlkbiGoaCKrKUsFrewK3K6CJA0wX0UVBb/61A9lqulSX5IpxoARUCGO4YoLksWVAX2Gv4cDguPlWHIBkbMLKQm21RKKCADXf8NOQRQuLITYsulnOozxQvhHdeI3jbt1LzdKz/GbG7os3jdN9kRCZtxXe3f6gE5ejNq5ILjQPubATLeOoTiVI60HBO6Iq+j7YNHVf80Brixme/Q/NgJWKIvziBOxQ89EPhUEnyMgPVkH/Vqd9bvDKnXT21NZwAvrQwGv8heVp5ttzrqrswx1cfU8O52Lu6BuFxj96N6w==



10:15:35.000000 +0800   com_kwai_gif     [1;36m[kuaishouhook] [m[0;36mTweak.xm:121[m [0;30;46mDEBUG:[m +[<UIDevice: 0x1a1e546a8> getSignatureStr:0x1604bbc70]: 
hkms getSignatureStr::arg1:1511579735417
hkm::self-value:UIDevice
hkm::result-value:qCdZPHdPQx/KW/jsJv6QVJcR4blEMlKWlOAYFtharNFuWuKjlkbiGoaCKrKUsFrewK3K6CJA0wX0UVBb/61A9lqulSX5IpxoARUCGO4YoLksWVAX2Gv4cDguPlWHIBkbMLKQm21RKKCADXf8NOQRQuLITYsulnOozxQvhHdeI3jbt1LzdKz/GbG7os3jdN9kRCZtxXe3f6gE5ejNq5ILjQPubATLeOoTiVI60HBO6Iq+j7YNHVf80Brixme/Q/NgJWKIvziBOxQ89EPhUEnyMgPVkH/Vqd9bvDKnXT21NZwAvrQwGv8heVp5ttzrqrswx1cfU8O52Lu6BuFxj96N6w==

11:15:35.000000 +0800   com_kwai_gif     [1;36m[kuaishouhook] [m[0;36mTweak.xm:97[m [0;30;46mDEBUG:[m -[<KSLoginService: 0x1607618c0> _paramsWithTimestampSecret:0x1606d1da0]: hkms _paramsWithTimestampSecret::arg1:,{
        "access_token" = "2.001azZhGohp7gC7c212d77790PBR_H";
        "open_id" = 6140757656;
        platform = "sina2.0";
    },hkm::self-value,<KSThirdPartyLoginService: 0x1607618c0>,hkm::result-value,{
        "access_token" = "2.001azZhGohp7gC7c212d77790PBR_H";
        "open_id" = 6140757656;
        platform = "sina2.0";
        raw = 1511579735417;
        secret = "qCdZPHdPQx/KW/jsJv6QVJcR4blEMlKWlOAYFtharNFuWuKjlkbiGoaCKrKUsFrewK3K6CJA0wX0UVBb/61A9lqulSX5IpxoARUCGO4YoLksWVAX2Gv4cDguPlWHIBkbMLKQm21RKKCADXf8NOQRQuLITYsulnOozxQvhHdeI3jbt1LzdKz/GbG7os3jdN9kRCZtxXe3f6gE5ejNq5ILjQPubATLeOoTiVI60HBO6Iq+j7YNHVf80Brixme/Q/NgJWKIvziBOxQ89EPhUEnyMgPVkH/Vqd9bvDKnXT21NZwAvrQwGv8heVp5ttzrqrswx1cfU8O52Lu6BuFxj96N6w==";
    }

突然发现把关键信息泄露了,算了,给细心的同学点福利吧。

总结

  • 日志这东西以前不用,想在用了发现。挂钩的结果一定要标准清楚,用来在日志中方便查找。否则一片混乱,就真找不到北了。
  • 分析过程中关键字可能不只一个,一般类似secret、password、username.道理相同。实在找不到可以看下路径里有没有特异性的字符。总之,就是要能找到这个地方,其他人应用较少。
  • 一般找到引用后有两个问题:
    1.找到大致位置后不能定位。
    2.引用位置太多,基本看不完。
  • 这时候除了利用鱼眼视图要注意两点:
    1.动态调试前一定要理清思路,把参数传递和数据发送的动作分开来思考。因为这符合模块设计的思路。
    2.挂钩和动态调试结合,静态分析的结果很多有片面性,如果lldb完全照着跟,很容掉坑里。分析要重点关注流程,不能一位分析汇编代码。
  • 以上总结纯属个人意见,如果异议,欢迎留言。

本次实验纯属研究为目的,如有不妥请联系本人。

移动安全-IOS逆向第三天——实战HOOK RSA/DES加密 一、车联网APP加密破解 APP抓包发现有加密 1、首先使用frida-ios-dump下文件之后,找到Ipa中的match-O可执行文件 2、脱入ida中、直接搜索rsa xxx函数 3、使用frida-trace ios-trace脚本进行Hook查看是否调用,发现没有命中Hook函数 4、再次搜索rsa发现如下,使用相同方法进行验证 5、发现没有调用 6、继续搜索 7、发现命中加密函数,trace BKRSA类下encrypt关键字的函数 8、如下是objec 阅读详情

相关推荐

APP逆向实战:从抓包到算法还原的全流程技术解析

在移动应用安全与协议分析领域,逆向工程是理解应用内部工作机制、分析通信协议及数据处理逻辑的核心技术。其基本原理是通过动静结合的分析方法,由外而内探查应用行为。动态分析借助抓包工具(如Charles、Burp Suite)监控网络流量,获取接口与数据线索;静态分析则利用反编译工具(如Jadx、IDA Pro)深入代码层,还原业务逻辑与算法实现。二者交叉验证,能高效定位关键代码与加密逻辑。这项技术的核心价值在于,它使开发者与安全研究人员能够深入理解应用的安全机制、协议设计,并用于合法的安全评估、兼容性开发或学习

weixin_42525738的博客 717

ios六种常见加密方式总结

ios六种常见加密方式总结

u013712343的博客 3399

逆向分析SM4加密接口:从抓包到Python解密实战

在数据安全传输领域,对称加密算法是保障信息机密性的核心技术之一。其原理是使用相同的密钥进行加密和解密,确保只有授权方能够访问原始数据。这类算法在保护API接口数据、实现安全通信方面具有重要价值,广泛应用于金融、政务及各类对数据安全有严格要求的行业场景。本文聚焦于国密算法SM4,这是一种自主设计的分组密码标准,与AES类似但采用不同的S盒和密钥扩展方式。通过结合网络抓包、代码分析与黑盒测试等逆向工程方法,我们将深入探讨如何识别加密模式、定位密钥与初始向量,并最终在Python环境中使用gmssl库实现完整的解

weixin_34254464的博客 788

iOS逆向之旅(进阶篇) — 代码注入

延伸 做过游戏外挂的人都知道,代码注入通常是通过这工具去注入的进行测试的【当然还有劫持注入等等其他注入方式】 通常这种测试注入的方式有两种 一种是直接注入汇编代码 【这种方式只能用在简单测试。在iPhone中,我们可以通过LLDB、Cycript直接注入OC原生语言进行测试,这种方式更加简单粗暴。其实我们平时调试多多少少都会用过LLDB,或许你已经会了不少】 一种是注入一个.dll的动态库...

weixin_34008805的博客 763

环境准备:逆向分析工具链搭建与配置

上周排查一个ZLibrary的接口调用问题,明明参数都对,却总是返回签名错误。抓包看到请求里带了个_sign字段,每次都在变,显然客户端做了加密或签名。这种时候,光靠Charles抓包已经不够用了,得把真机或模拟器里的代码扒出来看看它到底怎么算的。今天就把我平时逆向分析移动端接口的这套工具链整理出来,都是实战中攒下来的配置,未必最全,但绝对够用。

ZXSXJ的博客 983

API签名逆向分析实战:从抓包到算法还原的完整指南

在移动应用和Web服务中,API签名(Sign)是一种核心的安全校验机制,用于验证请求的合法性与完整性。其基本原理是客户端将请求参数按特定规则排序拼接后,使用密钥通过哈希算法(如MD5、SHA系列)生成唯一签名,服务器端以相同逻辑验签。这项技术对于保障数据传输安全、防止请求篡改具有重要价值,广泛应用于用户认证、支付、数据接口等场景。理解签名机制不仅是学习API安全设计的切入点,也是进行合规接口测试、自动化脚本开发的基础。本文以典型的移动端签名场景为例,系统阐述通过抓包观察、静态反编译、动态Hook等逆向工程

weixin_34185512的博客 449

【iOS逆向】小陈手牵手带你看懂iOS伪代码

上一篇文章带大家简单的入门了iOS开发,本文以上篇文章的二进制文件为例,带大家如何在IDA Pro里看懂iOS的伪代码。

小陈的技术博客 1626

iOS应用安全之代码混淆设计篇

iOS应用安全随着各种事件的曝出,越来越受到重视。那针对iOS应用安全方面能做点什么呢?如何让我们开发的应用更安全一点呢?要知道如何才能安全,就要了解iOS应用怎么就不安全了呢?现在随着越狱技术的提高和各种工具的完善,使得逆向分析一款iOS应用变成了一个轻而易举的事情。因此,要使的iOS应用更安全,那就从逆向工程的各个阶段进行层层阻拦。当然,这个只是增加逆向到难度而已~。

zm53373581的专栏 7598

iOS逆向之旅(进阶篇) — 工具(LLDB)

简介 LLDB是个开源的内置于XCode的调试工具,给我们平时开发调试带来很大的便利,同时它对我们逆向分析别人的APP同样有很大的帮助。 LLDB的使用其实看LLDB官方文档就可以了 这篇文章我就把常用的指令列举出来,方便日后查阅 断点操作 【为C函数下断点】 $b set -n "C函数名" 【为OC方法下断点】 $b set -n "-[OC类 方法名:]" 【遍历整个项目中,为所有同名的所...

weixin_33698043的博客 216

FT601Q芯片深度解析:从USB3.0引脚定义到FPGA FIFO协议实战选型

本文深入解析FT601Q芯片在USB3.0接口设计与FPGA协议栈开发中的应用,详细介绍了USB3.0引脚定义、FT601Q芯片架构、245同步FIFO模式及硬件设计要点,帮助工程师实现高速数据传输系统。

weixin_30607659的博客 447

SARscape的DInSAR全流程-以西安市隋大兴唐长安城遗址为例

通过DInSAR对西安市隋大兴唐长安城遗址开展的年度周期性监测,发现成因是地质内部构造断裂带活动所导致的地面产生物理空间上的形变,而地面的沉降与抬升是直接影响城市发展与文化遗产保护最为常见的缓变型不可逆地质灾害。西安市地处汾渭断陷盆地中部,受临潼-长安断裂带影响,导致区域内构造活动较为强烈。由于早年西安市地表水资源匮乏,从上世纪50年代末开始大量开采地下水资源以满足城市人口不断扩张的需求,从而导致地下承压含水层水位急速下降,形成多个局部沉降中心(八里村、西工大、电子城等)。

2301_77687129的博客 5815

【iOS逆向与安全】DTRpcClient 抓包和代码分析记录

【代码】【iOS逆向与安全】DTRpcClient 抓包和代码分析记录。

六桥风月IT随笔 917

Windows Server 2012 R2虚拟机安装全攻略:从镜像选择到网络配置一步到位

本文提供Windows Server 2012 R2虚拟机安装全攻略,涵盖从镜像选择到网络配置的完整流程。详细讲解在Oracle VM VirtualBox中的安装步骤、TCP/IP网络设置、系统优化及常见问题解决方案,帮助用户快速搭建可立即投入使用的服务器环境。特别适合IT初学者和系统管理员学习传统服务器应用的部署与配置。

weixin_28363123的博客 538

ios逆向某幸咖啡 抓包+脱壳+frida-trace+ida分析

本文分析了某幸咖啡iOS端(v5.4.20)的接口加密机制。通过SSLKillSwitch绕过SSL Pinning抓包,定位到核心加密类LNAESRequestSerializer。研究发现q参数采用AES-ECB模式加密,密钥通过frida hook获取;sign参数由cid、q、t、uid拼接后经MD5特殊处理生成。与小程序版相比,iOS端加密逻辑更复杂,直接hook标准加密方法无效。文章详细介绍了从抓包、反编译到参数逆向的全过程,为类似应用的逆向分析提供了参考思路。

weixin_59616601的博客 1812

快速理解OSI七层模型(举例理解,数据传输过程,深入理解OSI七层模型)

我们需要了解互联网的本质是一系列的网络协议,这个协议就叫做OSI协议(开放系统互联(Open System Interconnection)),它是由ISO(国际标准化组织)定义的。 需要注意,随着时代的发展,OSI已经被TCP/IP 4层模型淘汰,在当今世界上并没有大规模的使用。 那么对于OSI,人们按照功能不同,分工不同,人为的将OSI的分为七层。实际上这七层是并不存在的,也就是说没有这些概念,而我们今天提到的七层概念,只是人为的划分而已。目的只是为了让大家更好地理解这些都是用来做什么的。

CN_TangZheng的博客 3万+

198、影像系统设计评审流程:从需求评审到 EVT、DVT、PVT 各阶段的关注重点

本文详细介绍了影像系统从需求评审到EVT、DVT、PVT各阶段的设计评审流程及关键点。作者通过实际案例(如IMX766模组偏紫问题)强调硬件工艺的重要性,指出影像系统是功能定义与物理实现的反复拉锯过程。文章分阶段解析:需求评审需将模糊需求转化为物理参数;架构评审要明确接口定义和时序约束;EVT阶段重点关注模组一致性和基础链路;DVT阶段需平衡算法调优与硬件验证;PVT阶段则以量产一致性为核心。最后提出建立"边界条件确认表"和"健康度看板"等实用建议,强调工程师需具备从表象追溯硬件根源的物理直觉。全文贯穿实战

sundong_81的博客 218

关于某ios app登录关键字加密分析

关于某ios app登录关键字加密分析 学逆向到现在,本来以为可以找个大神带一下,不过一路做来基本是在自学。还有好多东西不知到如何下手,世界上本来就是学无止境,找到自己需要的我觉得更关键。学了两周的ios逆向,顺便总结下:需要工具: 越狱iPhone cydia *openssh和socat IDA或者HOPPER dis 个人感觉这两个工具虽然目的一样,但用起来还是差别还是很大。HP动不动就卡的

inquisiter 2508

游戏大厂状态同步与帧同步技术全解析——让虚拟世界万物协同的“时间齿轮”

本文深入解析了大厂游戏开发中的两种核心同步技术:状态同步和帧同步。状态同步适合大型MMO和FPS游戏,由服务端计算并广播世界状态;帧同步则通过统一操作输入实现MOBA和RTS游戏的绝对公平。文章详细比较了两者的差异、适用场景和底层实现原理,并揭秘了《王者荣耀》《PUBG》等热门游戏的同步机制。同时探讨了本地预测、延迟补偿、防作弊等关键技术,以及未来AI和云游戏带来的同步新挑战,为开发者提供了全面的技术参考和实践指南。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 920

iOS应用逆向工程:加密字段分析与算法还原

移动应用安全中的加密技术是保护数据传输的核心机制,常见如MD5、AES等算法通过对关键字段(如sign签名、Authorization令牌)进行加密校验来确保API调用安全。其原理涉及参数拼接、哈希运算及对称加密等基础密码学方法,在iOS逆向工程中,通过IDA Pro静态分析与Frida动态调试相结合,可有效还原加密逻辑。本文以实际案例展示了如何破解包含动态随机数(nonceStr)和时效验证的签名体系,以及设备标识(phoneName)的生成规则,为安全研究人员提供了一套完整的逆向工程方法论。

weixin_42525738的博客 203

Cost-effective Attention Reuse across Multi-turn Conversations in Large Language Model Serving

通过多回合对话与人类互动是大型语言模型(LLM)的一个基本特征。然而,由于需要重复计算历史token的密钥值(KV)缓存,用于执行多回合会话的现有LLM服务引擎效率低下,从而导致高服务成本。为了解决这个问题,本文提出了AttentionStore,这是一种新的注意力机制,可以在多回合对话中重用KV缓存(即注意力重用),显著降低重复计算开销。AttentionStore维护一个分层的KV缓存系统,该系统利用经济高效的内存/存储介质为所有请求保存KV缓存。

c_cpp_csharp的专栏 394

python实现DoIP基本通信(收发报文)

python实现DoIP基本通信(收发报文)

天赐好车的博客 898

Frida实战:逆向分析APP加密与证书绑定防护

在移动应用安全领域,逆向工程是理解应用内部逻辑、分析数据流与通信协议的核心技术。其基本原理是通过静态与动态分析相结合的方法,解析应用代码与运行时行为。这项技术的核心价值在于帮助安全研究人员、开发人员深入理解应用工作机制,识别潜在漏洞,并用于安全评估与协议研究。在实际应用场景中,常需应对代码混淆、加密算法和反调试机制等防护措施。以Frida这一动态插桩工具为例,它允许在应用运行时注入脚本,实时监控和修改函数行为,成为突破防护的关键。本文聚焦于使用Frida解决两个典型难题:绕过HTTPS证书绑定(SSL Pi

weixin_30681121的博客 410

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

oc代码混淆_iOS原生应用与SDK马甲包安全之代码混淆的设计实现

iOS应用安全随着各种事件的曝出,越来越受到重视。那针对iOS应用安全方面能做点什么呢?如何让我们开发的应用更安全一点呢?要知道如何才能安全,就要了解iOS应用怎么就不安全了呢?现在随着越狱技术的提高和各种工具的完善,使得逆向分析一款iOS应用变成了一个轻而易举的事情。因此,要使的iOS应用更安全,那就从逆向工程的各个阶段进行层层阻拦。当然,这个只是增加逆向到难度而已~。iOS应用逆向分析分为静态...

weixin_39607865的博客 418

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

逆向分析微信 iOS 版的登录验证码功能(基于 iPad 协议 859)

本文详细分析了微信iPad协议(版本859)的登录流程,特别是验证码请求的触发逻辑、数据包内容及关键字段的逆向解析方法。文章首先解释了选择iPad协议的原因,包括其清晰的协议逻辑和独立的登录流程。接着,介绍了抓包准备和protobuf数据包的获取方法,推荐使用Frida、BurpSuite等工具进行动态Hook和解密。文章还详细解析了验证码请求接口的识别与字段结构,并提供了逆向工程工具和技巧的详细说明,如Frida动态Hook和IDA静态分析。最后,文章通过伪代码演示了如何构造验证码请求数据包,并发送到微信

2401_86201935的博客 4234

美团iOS逆向工程分析

Tech:美团iOS逆向工程分析 by ChenQi 《Tech:美团Android逆向工程分析》,九个月前曾经对美团Android App做过一次简单拆包分析,主要是了解美团MRN工程结构的实现,以及观察各业务线的模块设计划分和代码量占比情况。并未具体分析源码逻辑实现。 最近QIN同学对美团iOS App做了一次更加详细的逆向分析。 [转载] 原地址:https://chenqi.app/Meituan-iOS-Reverse-Engineering/ 原作者:ChenQi 静态分析 美团App i

qq_43739446的博客 4019

iOS逆向基础砸壳原理(2)

开发者提交给Appstore发布的App,都经过FairPlay作为版权保护而加密,这样可以保证机器上跑的应用是苹果审核过的,也可以管理软件授权,起到DRM...

寻找改变未来的算法 879
上一篇: 关于某ios app登录关键字加密分析
下一篇: lldb python 脚本扩展之超级断点增强版
inquisiter
博客等级 码龄10年 374粉丝 228原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值