某FM密码加密分析IOS

BeginCTF2024逆向部分wp 动调发现第一个函数的作用就是将第一处加密得到的结果按小端序储存为Go中的一种大整型数据(没有位数上限 能储存多大取决于计算机)组合op[9]接下来的4个数据(大端序)并入栈。使用的是6502虚拟机 直接模拟其运行(或者分析后手画也行) 这里已经用文本编辑器替换过原来的6502指令。核心是其中的大整型取模和大整型除法 动调发现取模和除法都是对第一个函数得到的大整型进行 另一个操作数是。从64长度的表中按第二处加密得到的结果为下标取元素 最后和密文比较 猜测是换表base64。 阅读详情

某FM密码加密分析

个人感觉这个分析用的手段比较典型,所以记录下。个人感觉ios有些封装特点在逆向过程中还是要有一定的认识的,不然就真是分析半天头疼的不行了。

抓包分析可疑数据

这一部分大致说一下,大致看了以了一下,没有看到跟登录的手机号和密码相关的关键字。应该是加密了,倒是path路径有个passport-sign-mobile/v2的网址路径,不过这是后话,开始的时候没看到这里。不过个人感觉从这里入手,应该也不会太容易,不过应该也可行。

界面分析

既然抓不出来啥,我就分析下登录界面

<XMRegisterAndLoginView: 0x1308a2410; frame = (0 0; 320 460); gestureRecognizers = <NSArray: 0x1307a3dc0>; layer = <CALayer: 0x13084e910>>
   |    |    |    |    |    |    |    | <UITextField: 0x13087aa00; frame = (40 30; 240 44); text = '18104849732'; clipsToBounds = YES; opaque = NO; gestureRecognizers = <NSArray: 0x130873d00>; layer = <CALayer: 0x130894920>>
   |    |    |    |    |    |    |    |    | <UIView: 0x13099c850; frame = (0 2; 105 40); layer = <CALayer: 0x1305373d0>>
   |    |    |    |    |    |    |    |    |    | <UIButton: 0x130742b60; frame = (0 0; 80 40); opaque = NO; tag = 100; layer = <CALayer: 0x130585e80>>
   |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x130868ce0; frame = (60 13; 14 14); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1308ae3a0>>
   |    |    |    |    |    |    |    |    |    |    | <UIButtonLabel: 0x130797e60; frame = (17 10.5; 30 19.5); text = '+86'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x13058bc90>>
   |    |    |    |    |    |    |    |    |    | <UIView: 0x13092f0e0; frame = (90 10; 1 20); layer = <CALayer: 0x130958750>>
   |    |    |    |    |    |    |    |    | <UITextFieldLabel: 0x1306a4380; frame = (105 0; 135 42.5); text = '18104849732'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x130833700>>
   |    |    |    |    |    |    |    | <UITextField: 0x1309865c0; frame = (40 89; 240 44); text = 'fyg'; clipsToBounds = YES; opaque = NO; gestureRecognizers = <NSArray: 0x13088b9f0>; layer = <CALayer: 0x130556600>>
   |    |    |    |    |    |    |    |    | <UIImageView: 0x1302f5290; frame = (0 7; 30 30); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1306b43d0>>
   |    |    |    |    |    |    |    |    | <UITextFieldLabel: 0x130936840; frame = (30 0; 210 42.5); text = '●●●'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x13075aef0>>
   |    |    |    |    |    |    |    |    |    | <_UILabelContentLayer: 0x13092a690> (layer)
   |    |    |    |    |    |    |    | <UIButton: 0x130889bd0; frame = (40 148; 240 40); opaque = NO; layer = <CALayer: 0x13084ffb0>>
   |    |    |    |    |    |    |    |    | <UIButtonLabel: 0x1302f7920; frame = (104 10.5; 32 19.5); text = '登录'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x13063f460>>
   |    |    |    |    |    |    |    |    |    | <_UILabelContentLayer: 0x13058d3d0> (layer)
   |    |    |    |    |    |    |    | <UIButton: 0x1307fb070; frame = (220 194; 60 27); opaque = NO; layer = <CALayer: 0x13095da50>>
   |    |    |    |    |    |    |    |    | <UIButtonLabel: 0x1307dbbb0; frame = (0 6.5; 60 14.5); text = '忘记密码?'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x13098ae30>>
   |    |    |    |    |    |    |    |    |    | <_UILabelContentLayer: 0x13075bed0> (layer)
   |    |    |    |    |    |    |    | <UIView: 0x1309ae010; frame = (30 261; 260 20); layer = <CALayer: 0x13075c690>>
   |    |    |    |    |    |    |    |    | <UILabel: 0x1305a3600; frame = (88 0; 84 20); text = '其他方式登录'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x13091a880>>
   |    |    |    |

我这里用的工具是Frida写的一个界面的工具,为什么?因为这个东西,支持中文格式,很好用。当然如果用不惯可以用 cycript 或reveal等。
至于frida工具,可以参看我的博客ios逆向神器frida。
这里我们找到“登录”关键字,看到它所属的类XMRegisterAndLoginView。可以看到0x1308a2410是他的地址。
验证下

#cycript -p 程序名称
#[#0x1302f7920 setHidden:YES]

登录标签消失了。说明我们分析正确。

ida静态分析和动态验证

这里重点分析XMRegisterAndLoginView

-[XMRegisterAndLoginView dealloc]   __text  000000010023E5B4    000000A4            R   .   .   .   B   T   .
-[XMRegisterAndLoginView initWithFrame:]    __text  000000010023E658    000000A8            R   .   .   .   B   T   .
-[XMRegisterAndLoginView layoutSubviews]    __text  000000010023E700    000008B4            R   .   .   .   B   T   .
-[XMRegisterAndLoginView customInit]    __text  000000010023EFB4    00001C5C            R   .   .   .   B   T   .
-[XMRegisterAndLoginView resignTextfieldAllResponder]   __text  0000000100240C10    0000007C            R   .   .   .   B   T   .
-[XMRegisterAndLoginView becomeSelected]    __text  0000000100240C8C    00000080            R   .   .   .   B   T   .
-[XMRegisterAndLoginView tapPressed]    __text  0000000100240D0C    0000000C            R   .   .   .   .   T   .
-[XMRegisterAndLoginView registerButtonPressed] __text  0000000100240D18    000000B8            R   .   .   .   B   T   .
-[XMRegisterAndLoginView loginButtonPressed]    __text  0000000100240DD0    000000B8            R   .   .   .   B   T   .
-[XMRegisterAndLoginView forgetPasswordButtonPressed]   __text  0000000100240E88    000000B8            R   .   .   .   B   T   .
-[XMRegisterAndLoginView thirdPartyLoginPressed:]   __text  0000000100240F40    00000124            R   .   .   .   B   T   .
-[XMRegisterAndLoginView showLastLoginTip:] __text  0000000100241064    000001E4            R   .   .   .   B   T   .
-[XMRegisterAndLoginView updateCountryCode:]    __text  0000000100241760    000000B8            R   .   .   .   B   T   .
-[XMRegisterAndLoginView countryCode:]  __text  0000000100241818    000000B0            R   .   .   .   B   T   .
-[XMRegisterAndLoginView usernameTextField] __text  00000001002418C8    00000010            R   .   .   .   .   T   .
-[XMRegisterAndLoginView setUsernameTextField:] __text  00000001002418D8    00000014            R   .   .   .   .   T   .
-[XMRegisterAndLoginView passwordTextField] __text  00000001002418EC    00000010            R   .   .   .   .   T   .
-[XMRegisterAndLoginView setPasswordTextField:] __text  00000001002418FC    00000014            R   .   .   .   .   T   .
-[XMRegisterAndLoginView loginButton]   __text  0000000100241910    00000010            R   .   .   .   .   T   .
-[XMRegisterAndLoginView setLoginButton:]   __text  0000000100241920    00000014            R   .   .   .   .   T   .
-[XMRegisterAndLoginView forgetPasswordButton]  __text  0000000100241934    00000010            R   .   .   .   .   T   .
-[XMRegisterAndLoginView setForgetPasswordButton:]  __text  0000000100241944    00000014            R   .   .   .   .   T   .
-[XMRegisterAndLoginView delegate]  __text  0000000100241958    00000020            R   .   .   .   B   T   .
-[XMRegisterAndLoginView setDelegate:]  __text  0000000100241978    00000014            R   .   .   .   .   T   .
-[XMRegisterAndLoginView countryCodeButton] __text  000000010024198C    00000010            R   .   .   .   .   T   .
-[XMRegisterAndLoginView setCountryCodeButton:] __text  000000010024199C    00000014            R   .   .   .   .   T   .
-[XMRegisterAndLoginView .cxx_destruct] __text  00000001002419B0    0000012C            R   .   .   .   B   T   .

通过cycript lldb等各种工具,验证以上可以函数的功能。显而易见,loginButtonPressed登录按钮激发函数,passwordTextField获取密码框字符串。其他其实大概也从名字也能开出来。当然这里其实我在这走了一点弯路,因为thoes挂钩不上,我还以为分析错误了。搞了半天,但用cycript和lldb又验证了下上面一些函数才发现是正确的,这里离应该有反挂钩。反反挂钩也懒得做了,不用挂钩了。

void __cdecl -[XMRegisterAndLoginView loginButtonPressed](#928 *self, SEL a2)
{
  #928 *v2; // x19
  #927 *v3; // x0
  void *v4; // x22
  int v5; // w23
  #927 *v6; // x0
  void *v7; // x19

  v2 = self;
  objc_msgSend((void *)self, "resignTextfieldAllResponder");
  v3 = ((#927 *(__cdecl *)(#928 *, SEL))objc_msgSend)(v2, "delegate");
  v4 = (void *)objc_retainAutoreleasedReturnValue(v3);
  v5 = (unsigned __int64)objc_msgSend(v4, "respondsToSelector:", "registerAndLoginViewDidClickedLogin");
  objc_release(v4);
  if ( v5 )
  {
    v6 = ((#927 *(__cdecl *)(#928 *, SEL))objc_msgSend)(v2, "delegate");
    v7 = (void *)objc_retainAutoreleasedReturnValue(v6);
    objc_msgSend(v7, "registerAndLoginViewDidClickedLogin");
    JUMPOUT(objc_release);
  }
}

这里registerAndLoginViewDidClickedLogin属于
XMRegisterAndLoginViewController registerAndLoginViewDidClickedLogin

void __cdecl -[XMRegisterAndLoginViewController registerAndLoginViewDidClickedLogin](#4797 *self, SEL a2)
{
  #4797 *v2; // x19
  #2972 *v3; // x0
  void *v4; // x21
  void *v5; // x0
  void *v6; // x0
  void *v7; // x22
  void *v8; // x0
  __int64 v9; // x24
  #2972 *v10; // x0
  void *v11; // x20
  void *v12; // x0
  void *v13; // x0
  void *v14; // x21
  void *v15; // x0
  __int64 v16; // x22

  v2 = self;
  if ( (unsigned int)objc_msgSend((void *)self, "baseSanityCheck") )
  {
    v3 = ((#2972 *(__cdecl *)(#4797 *, SEL))objc_msgSend)(v2, "registerAndLoginInfo");
    v4 = (void *)objc_retainAutoreleasedReturnValue(v3);
    v5 = objc_msgSend(*((void **)v2 + 24), "usernameTextField");
    v6 = (void *)objc_retainAutoreleasedReturnValue(v5);
    v7 = v6;
    v8 = objc_msgSend(v6, "text");
    v9 = objc_retainAutoreleasedReturnValue(v8);
    objc_msgSend(v4, "setUsername:", v9);
    objc_release(v9);
    objc_release(v7);
    objc_release(v4);
    v10 = ((#2972 *(__cdecl *)(#4797 *, SEL))objc_msgSend)(v2, "registerAndLoginInfo");
    v11 = (void *)objc_retainAutoreleasedReturnValue(v10);
    v12 = objc_msgSend(*((void **)v2 + 24), "passwordTextField");
    v13 = (void *)objc_retainAutoreleasedReturnValue(v12);
    v14 = v13;
    v15 = objc_msgSend(v13, "text");
    v16 = objc_retainAutoreleasedReturnValue(v15);
    objc_msgSend(v11, "setLoginPassword:", v16);
    objc_release(v16);
    objc_release(v14);
    objc_release(v11);
    JUMPOUT(objc_msgSend);
  }
}

发现这里只是给一个类XMRegisterAndLoginItem赋值
根据XMRegisterAndLoginItem loginpassword调用函数找到了XMRegisterAndLoginViewController requestSecurityLogin
当然这里是通过动态lldb验证的,因为这里调用的函数并不多。

LABEL_8:
    v33 = objc_msgSend(v19, "registerAndLoginInfo");
    v34 = (void *)objc_retainAutoreleasedReturnValue(v33);
    v35 = (__int64)v34;
    v36 = objc_msgSend(v34, "username");
    v37 = objc_retainAutoreleasedReturnValue(v36);
    objc_msgSend(v26, "setObject:forKey:", v37, CFSTR("account"));
    objc_release(v37);
    v38 = v35;
  }
  else
  {
    v39 = objc_msgSend(v24, "substringFromIndex:", 1LL);
    v40 = objc_retainAutoreleasedReturnValue(v39);
    v41 = objc_msgSend(v19, "registerAndLoginInfo");
    v42 = (void *)objc_retainAutoreleasedReturnValue(v41);
    v43 = v42;
    v44 = objc_msgSend(v42, "username");
    v45 = objc_retainAutoreleasedReturnValue(v44);
    v46 = v45;
    v47 = objc_msgSend(&OBJC_CLASS___NSString, "stringWithFormat:", CFSTR("%@-%@"), v40, v45);
    v48 = objc_retainAutoreleasedReturnValue(v47);
    objc_msgSend(v26, "setObject:forKey:", v48, CFSTR("account"));
    objc_release(v48);
    objc_release(v46);
    objc_release(v43);
    v38 = v40;
  }
  objc_release(v38);
  v49 = objc_msgSend(v19, "registerAndLoginInfo");
  v50 = (void *)objc_retainAutoreleasedReturnValue(v49);
  v51 = v50;
  v52 = objc_msgSend(v50, "loginPassword");
  v53 = (void *)objc_retainAutoreleasedReturnValue(v52);
  v54 = v53;
  v55 = objc_msgSend(v53, "md5String");
  v56 = objc_retainAutoreleasedReturnValue(v55);
  objc_msgSend(v26, "setObject:forKey:", v56, CFSTR("password"));
  objc_release(v56);
  objc_release(v54);
  objc_release(v51);
  v57 = objc_msgSend(v19, "loginToken");
  v58 = objc_retainAutoreleasedReturnValue(v57);
  objc_msgSend(v26, "setObject:forKey:", v58, CFSTR("nonce"));
  objc_release(v58);
  v59 = objc_msgSend(&OBJC_CLASS___NSString, "securetyStringFromDictionary:", v26);
  v60 = (void *)objc_retainAutoreleasedReturnValue(v59);
  v61 = v60;
  v62 = objc_msgSend(v60, "lowercaseString");
  v63 = (void *)objc_retainAutoreleasedReturnValue(v62);
  v64 = v63;
  v65 = objc_msgSend(v63, "md5String");
  v66 = objc_retainAutoreleasedReturnValue(v65);
  objc_msgSend(v26, "setObject:forKey:", v66, CFSTR("signature"));
  objc_release(v66);
  objc_release(v64);
  v67 = objc_msgSend(&OBJC_CLASS___NSJSONSerialization, "dataWithJSONObject:options:error:", v26, 1LL, 0LL);
  v68 = objc_retainAutoreleasedReturnValue(v67);
  v69 = objc_msgSend(&OBJC_CLASS___NSString, "alloc");
  v70 = objc_msgSend(v69, "initWithData:encoding:", v68, 4LL);
  v71 = v70;
  v72 = objc_msgSend(&OBJC_CLASS___NSString, "RSAStringFromString:", v70);
  v73 = (void *)objc_retainAutoreleasedReturnValue(v72);
  v74 = v73;
  v75 = objc_msgSend(v73, "dataUsingEncoding:", 4LL);
  v76 = objc_retainAutoreleasedReturnValue(v75);
  objc_msgSend(v17, "setPostData:", v76);

动态 在v67 = objc_msgSend(&OBJC_CLASS___NSJSONSerialization, “dataWithJSONObject:options:error:”, v26, 1LL, 0LL);上下断点

对应的汇编

00000101042C2C                 MOV             X0, X19
__text:0000000101042C30                 BL              _objc_release
__text:0000000101042C34                 ADRP            X8, #classRef_NSJSONSerialization@PAGE
__text:0000000101042C38                 LDR             X0, [X8,#classRef_NSJSONSerialization@PAGEOFF] ; void *
__text:0000000101042C3C                 ADRP            X8, #selRef_dataWithJSONObject_options_error_@PAGE
__text:0000000101042C40                 LDR             X1, [X8,#selRef_dataWithJSONObject_options_error_@PAGEOFF] ; char *
__text:0000000101042C44                 MOV             W3, #1
__text:0000000101042C48                 MOV             X2, X24
__text:0000000101042C4C                 MOV             X4, #0
__text:0000000101042C50                 BL              _objc_msgSend
__text:0000000101042C54                 MOV             X29, X29
#subr 0x0000000101042C50

这里我用了个超级断点的工具,可以自动根据偏移计算真实地址。感兴趣的可以在我的博客里面找到。

(lldb) po $x24
{
    account = 1810484xxxx;
    nonce = "6907381121332755797@bjc|bgi|d|fj";
    password = 1aabac6d068eef6a7bad3fdf50a05cc8;
    signature = 117af45c60a1b178934d9a6631567468;
}

通过分析password是密码md5后的值,acccount是登录手机号。

到这里其实比较清晰了。
这里写图片描述

这里还有个RSAStringFromString:
跟以下这个类相关

-[XMRSAEncryptor dealloc]   __text  0000000101293154    0000007C            R   .   .   .   B   T   .
-[XMRSAEncryptor initWithCertificationName:OfType:] __text  00000001012931D0    000000AC            R   .   .   .   B   T   .
-[XMRSAEncryptor encryptWithRawString:] __text  000000010129327C    000000F0            R   .   .   .   B   T   .
-[XMRSAEncryptor getPublicKey]  __text  000000010129336C    000001CC            R   .   .   .   B   T   .
-[XMRSAEncryptor RSAEncrypotoTheData:]  __text  0000000101293538    000002D0            R   .   .   .   B   T   .
-[XMRSAEncryptor certificationName] __text  0000000101293808    00000010            R   .   .   .   .   T   .
-[XMRSAEncryptor setCertificationName:] __text  0000000101293818    00000014            R   .   .   .   .   T   .
-[XMRSAEncryptor certificationType] __text  000000010129382C    00000010            R   .   .   .   .   T   .
-[XMRSAEncryptor setCertificationType:] __text  000000010129383C    00000014            R   .   .   .   .   T   .
-[XMRSAEncryptor toBeEncryptString] __text  0000000101293850    00000010            R   .   .   .   .   T   .
-[XMRSAEncryptor setToBeEncryptString:] __text  0000000101293860    00000014            R   .   .   .   .   T   .
-[XMRSAEncryptor .cxx_destruct] __text  0000000101293874    00000054            R   .   .   .   B   T   .

这里很容易可以得到密钥等关键信息。

id __cdecl -[XMRSAEncryptor RSAEncrypotoTheData:](#5934 *self, SEL a2, id a3)
{
  id v3; // x19
  #5934 *v4; // x20
  __int64 v5; // x22
  void *v6; // x19
  void *v7; // x19
  void *v8; // x0
  void *v9; // x25
  signed int v10; // w22
  unsigned int v11; // w20
  void *v12; // x0
  __int64 v13; // x23
  __int64 v14; // x26
  unsigned __int64 v15; // x24
  __int64 v16; // x21
  char *v17; // x0
  char *v18; // x2
  void *v19; // x0
  void *v20; // x22
  int v21; // w20
  void *v22; // x0
  __int64 v23; // x0
  void *v24; // x22
  void *v25; // x20
  void *v26; // x0
  id v27; // x0
  __int64 v28; // x0
  __int64 v29; // x21
  void *v30; // x0
  __int64 v31; // x20
  struct objc_object *v33; // [xsp-90h] [xbp-90h]
  void *v34; // [xsp-78h] [xbp-78h]
  void *v35; // [xsp-70h] [xbp-70h]
  size_t v36; // [xsp-68h] [xbp-68h]

  v3 = a3;
  v4 = self;
  v5 = objc_retain(a3, a2);
  v35 = objc_msgSend((void *)v4, "getPublicKey");
  v36 = SecKeyGetBlockSize();
  v34 = malloc(v36);
  bzero(v34, v36);
  v6 = objc_msgSend(v3, "dataUsingEncoding:", 4LL);
  objc_release(v5);
  v7 = (void *)objc_retainAutoreleasedReturnValue(v6);
  v8 = objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithLong:", v36 - 11);
  v9 = (void *)objc_retainAutoreleasedReturnValue(v8);
  v10 = (unsigned __int64)objc_msgSend(v9, "intValue");
  objc_release(v9);
  v11 = vcvtpd_s64_f64((double)(unsigned __int64)objc_msgSend(v7, "length") / (double)v10);
  v12 = objc_msgSend(&OBJC_CLASS___NSMutableData, "alloc");
  v33 = (struct objc_object *)objc_msgSend(v12, "init");
  if ( (signed int)v11 >= 1 )
  {
    v13 = 0LL;
    v14 = 0LL;
    v15 = v10;
    v16 = v11;
    do
    {
      v17 = (char *)objc_msgSend(v7, "length");
      if ( v15 >= (unsigned __int64)&v17[v13] )
        v18 = &v17[v13];
      else
        v18 = (char *)v15;
      v19 = objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithLong:", v18);
      v20 = (void *)objc_retainAutoreleasedReturnValue(v19);
      v21 = (unsigned __int64)objc_msgSend(v20, "intValue");
      objc_release(v20);
      v22 = objc_msgSend(v7, "subdataWithRange:", v14, v21);
      v23 = objc_retainAutoreleasedReturnValue(v22);
      v24 = (void *)objc_retainAutorelease(v23);
      v25 = objc_msgSend(v24, "bytes");
      v26 = objc_msgSend(v24, "length");
      if ( !(unsigned int)SecKeyEncrypt(v35, 1LL, v25, v26, v34, &v36) )
        objc_msgSend(v33, "appendBytes:length:", v34, v36);
      objc_release(v24);
      v14 += v15;
      v13 -= v15;
      --v16;
    }
    while ( v16 );
  }
  if ( v34 )
    free(v34);
  if ( v35 )
    CFRelease(v35);
  v27 = ((id (__cdecl *)(#5929 *, SEL, id))objc_msgSend)((#5929 *)&OBJC_CLASS___GTMBase64, "stringByEncodingData:", v33);
  v28 = objc_retainAutoreleasedReturnValue(v27);
  v29 = v28;
  v30 = objc_msgSend(&OBJC_CLASS___NSString, "stringWithFormat:", CFSTR("%@"), v28);
  v31 = objc_retainAutoreleasedReturnValue(v30);
  objc_release(v29);
  objc_release(v33);
  objc_release(v7);
  return (id)objc_autoreleaseReturnValue(v31);
}

总结

工具太多,如果不能灵活应用,往往容易走到死路。我个人感觉,千万不能根据关键字大量的验证猜测。因为用很多相似的类和方法,但我们的目标却不在这些中。为了避免走弯路,我们的分析思路一定要清晰。发包封装的特点往往是,seturl setdata setpost requset等步骤,这些步骤可能不再同一个方法中。setpost是这些当中的关键,虽然不能直接找setpost的方法,但一定要在确定的request请求附近关注setpost.

【信息科学与工程学】计算机科学与自动化——第三篇 计算理论基础05 计算数论02 企业内部的职权滥用和利益输送往往隐藏在合法交易的表象之下,形成系统性风险。 阅读详情

相关推荐

猫耳FM机器人开发实战:Go语言与协议特性深度适配

直播机器人开发需首先理解目标平台的通信协议本质——猫耳FM并非传统视频流平台,而是基于音频+轻量互动的类IM系统,其WebSocket连接模型、弹幕批次下发、动态房管权限和礼物结算周期等特性,决定了通用直播机器人框架无法直接复用。Go语言凭借GMP调度模型、sync.Map无锁缓存、高精度time.Time及HTTP/2原生支持,天然契合猫耳FM的非均匀事件流与状态高频读取场景;结合协议逆向抓包、滑动窗口聚合、动态心跳管理与行为拟真防护等工程实践,可构建低延迟、高可用、抗风控的工业级音频社交机器人。

weixin_33858336的博客 399

NSSCTF RE [NSSRound#3 Team]jump_by_jump_revenge

找到花指令(标红) 选中按D转化为数据,再将数据改成0x90h(即nop)ida反汇编出现 jumpout(xxx) 判断是花指令。然后按P(重新分析)+F5。第一次尝试做花指令的题目。再按c转数据化为nop。写个脚本逆回去就行了。

qq_60929881的博客 747

opaque:加密的数据分析平台

安全的Apache Spark SQL Opaque是Apache Spark SQL的软件包,该软件包可使用OpenEnclave框架对DataFrames进行加密。 目的是在不受信任的云中启用对敏感数据的分析。 加密DataFrame的内容后,后续操作将在硬件区域(例如Intel SGX)中运行。 该项目基于以下NSDI 2017论文[1]。 遗忘的执行模式不包含在此版本中。 这是Opaque的Alpha预览版,但该软件仍在积极开发中。 当前具有以下限制: 与Spark群集不同,主服务器必须在受信任的环境中运行(例如,在客户端上)。 并非所有Spark SQL操作都受支持(请参阅)。 UDF必须。 计算完整性验证(NSDI文件的第4.2节)目前正在进行中。 [1]郑文婷,Ankur Dave,Jethro Beekman,Raluca Ada Popa,Joseph Go

IDA反编译的几个注意和技巧

IDA逆向程序的经验总结关于F5汇编代码不能转成c的伪代码的几个问题总结关于一些类型转换以及指针和地址的总结最可以拿来当教训的应该是 hide cast 功能1.jmpout的问题功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必...

qq_36535153的博客 1万+

Unity获取透明物体深度数据

Unity获取透明物体深度数据前言透明&景深需求模型透明度部分带透明通道图片/视频部分半透明模型获取深度的具体实现方法带透明度图片/视频获取深度的具体实现方法结束语 前言 最近在做的项目有很多奇怪的需求,甚至之前在unity里用插件写了一个类似于蓝图的行为树插件,之后有时间给大家讲一讲相关的实现方法,今天刚解决了unity里透明物体无法获得深度数据的问题。所以分享给大家。 透明&景...

可以吃的妙脆角的博客 2631

Codex Skill:AI编程助手的专项能力扩展与实战指南

在AI编程助手领域,Skill(技能)是一种标准化的能力扩展机制,它通过封装特定任务所需的指令、资源和脚本,解决AI模型在专项任务上的能力局限。其核心原理是将专业知识和工作流程模块化,让通用AI助手能够像领域专家一样执行复杂任务。从技术价值看,Skill不仅提升了代码生成的准确性,更重要的是实现了业务流程的自动化集成,如代码规范检查、API文档生成等具体场景。这种机制特别适用于需要结合内部工具链和特定业务逻辑的企业环境,能够显著提升开发效率和质量。通过安装PPT生成、SpringBoot项目创建等专项Ski

weixin_33672109的博客 413

IDA使用-2023CICSN华中赛区pwn题逆向为例

然后代码变为if (!return v1;发现在距离起始四个字节后的十六个字节都设置为0memset函数memset函数是C语言标准库中的一个用于内存操作的函数,它主要用于将某一块内存空间的内容设置为指定的值。void *s:指向要填充的内存块的指针。int c:需要设置的值,该值会被转换为无符号字符后用来设置内存块。size_t n:要设置的内存块的字节数。结果代码if (!return v1;

llovewuzhengzi的博客 1271

西门子工业物联网云平台 Insights Hub 技术白皮书

Insights Hub是西门子公司推出的工业物联网云平台,它是一个使用开放技术的基于云架构的平台,能够为制造业企业提供物联网连接、数据分析、应用开发等一系列服务。Insights Hub的设计理念是“连接、分析和运营”,即通过连接物理设备、收集数据并进行分析,来优化工业生产的运营和管理。

可爱的刘三岁的博客 3335

DLL的绑定进程和解绑定进程引起的死锁

DLL的绑定和解绑定其实操作系统做了很多的工作,资源的分配和资源的释放,我们在使用的过程中,一不小心就会中招,这里说一下我遇到的一个死锁的问题。

justin_bkdrong的专栏 4850

基于CH32X035的USB双K型热电偶温度计:硬件设计、冷端补偿与信号放大详解

本文详细介绍了基于CH32X035单片机设计USB双K型热电偶温度计的完整方案。重点解析了硬件设计中的核心挑战:如何利用精密运放GS8552-SR进行信号放大,以及采用NTC热敏电阻和查表法实现精确的冷端补偿。项目通过USB供电通信,实现了双路高精度温度测量与显示,为电子爱好者和工程师提供了实用的参考设计。

weixin_42153793的博客 160

从仿真到现实:BeamDojo双足机器人项目实战指南(附完整配置清单)

本文提供了一份基于BeamDojo项目的双足机器人从仿真训练到现实部署的完整实战指南。详细拆解了硬件选型(如宇树G1、Jetson Orin NX、Livox Mid-360)、Isaac Gym仿真环境搭建、强化学习训练技巧(如双评论家架构、课程学习)以及关键的Sim2Real迁移策略,旨在帮助开发者将前沿研究成果转化为可落地的工程实践。

hhh00的博客 877

Hacker101 iOS Hacking:文件系统基础——数据存储痕迹、沙盒结构与数据保护属性分析

**导读**:本文对应 Hacker101 免费安全课程 iOS 应用渗透系列的第二课(Filesystem Basics),聚焦于"越过 IPA 包本身"的纵深分析思路——当你想真正掌握一个 iOS 应用的行为,就必须回答它把数据写在了哪里、用什么格式存储、以及这些数据在设备锁定状态下受何种保护。读完本文,你将掌握 iOS 沙盒目录结构与各类数据存储方式的痕迹特征,理解 iOS 数据保护(Dat

gitblog_00119的博客 884

利用CANoe和CAPL实现高效CAN网关设计与仿真

本文详细介绍了如何利用CANoe和CAPL进行高效CAN网关的设计与仿真。通过搭建仿真工程、导入DBC数据库、编写CAPL脚本等步骤,手把手指导读者构建一个连接不同CAN网络的网关模型,实现报文的监听、转发与信号处理,从而在硬件开发前验证逻辑,提升汽车电子开发效率与可靠性。

weixin_29164091的博客 294

2026聚合杯决赛手机+计算机+流量分析wp

找到配置文件看一看转换一下时间考试的时候时间好像转换错了==这个是跟第五题关联的解开 Loader 和后续控制信道的 12 条 32 字节密文,得到行动摘要内容,摘要可能是 JSON、二进制 TLV 或文本配置搜索与主密钥校验值相匹配的字段先放吧。

2501_92951569的博客 305

物理信息神经网络(PINNs)在交通运输领域的应用

物理信息神经网络(PINNs)在交通运输领域的应用研究结合了数据驱动与物理模型约束,通过嵌入交通流守恒定律等物理信息,显著提升了交通状态估计与预测的精度。该技术仅需少量观测数据(流量、速度、密度等),即可实现高精度建模,尤其适用于数据稀疏场景。研究重点包括:交通状态估计与预测、参数辨识、交通控制优化等领域,同时面临计算成本高、物理模型依赖性等挑战。未来需解决大规模异构数据处理问题,以进一步推动智能交通系统发展。

qq_49609070的博客 944

基于matlab目标雷达横截面建模(附源码)

雷达系统依靠目标反射或散射来检测和识别目标。目标反射越强,雷达接收器返回的回波就越大,从而获得更高的信噪比(SNR)和更高的检测可能性。在雷达系统中,从目标反射的能量由雷达横截面(RCS)决定,定义为sigma代表RCS,R是雷达与目标之间的距离,Es是从目标反射的信号的场强,以及Ei是入射到目标上的信号的场强。通常,目标向各个方向散射能量,RCS是入射角,散射角和信号频率的函数。RCS 取决于目标的形状和构建目标的材料。用于RCS的常用单位包括平方米或dBsm。

珞瑜的博客 3083

360路由器登录协议的分析和模拟实现

本文博客地址:http://blog.youkuaiyun.com/qq1084283172/article/details/78878057 一、360路由器登录协议分析的工具配置       1. 路由器型号:360路由器P2       2. 浏览器:火狐浏览器       3. 抓包分析工具:Burp Suite 和 Wireshark 二、360路由器登录协议的分析 通过对3

Fly20141201. 的专栏 4398

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

OWASP MASTG iOS 存储安全指南:UserDefaults 明文键值存储的风险剖析与测试方法

`UserDefaults`(及其 Objective-C 别名 `NSUserDefaults`)是 iOS 应用中最常见的键值对持久化接口之一,也是移动应用安全测试(MASVS-STORAGE 类别)中重点核查的敏感数据存放位置。本文以 [MASTG-KNOW-0093](https://link.gitcode.com/i/b8aa3405ae1dc52a6535ea73603d3cf5)

gitblog_00768的博客 340

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【Go语言入门】:常量与变量(密码学版本)

Go的零值设计(如空字符串""、数字0)最初是为C程序员避免内存垃圾设计,但这也要求开发者必须显式初始化安全敏感数据。在密码学中,它暗示着“从最小单位构建安全体系”——就像每个比特都影响加密强度。:虽然Go常量在编译时确定,但在不同架构下(如32位/64位系统),保险箱:“懂了,变量是你的日常储物柜,常量是焊死的钛合金密码墙。当你要记住用户输入的密码哈希值,或者计算加密过程的中间值时,就需要。程序员:“有些数据天天变,有些规则永不改。程序员:“我想存点东西,要绝对安全。在Go语言的世界里,

墨名棋妙的博客 825

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

书侣FM-测试报告

界面: 界面的排版是否合理。 界面是否完整、是否有错别字。 界面是否简洁、美观,文字是否斜体。 点击链接之后,链接颜色是否会发生改变。 功能: 注册功能: 用户名和密码是否可以输入汉字,英文,表情,以及其他特殊字符。 用户名和密码的长度是否有限制,超过限制长度是否会有提示。 注册失败是否会有提示,是否会提示失败原因。 注册成功后是否会有提示。 注册成功后是否能跳转回主界面。 注册成功后是否能正常登陆。 登陆功能: 输入正确的用户名和密码,是否能够登陆成功。 输入错误的用户名或者密码,点击登

matilda_art的博客 286

协作传感加密密钥更新全流程详解(从触发机制到安全分发)

掌握协作传感加密的密钥更新全流程,解决动态环境中密钥安全与同步难题。涵盖触发机制、分布式协商与安全分发策略,适用于物联网、边缘计算等场景,提升系统抗攻击能力与协同效率,值得收藏。

IterStream的博客 487

MASTG-DEMO-0067 实战:使用 Frida 运行时追踪 iOS 可备份敏感文件

本文基于 OWASP MASTG 仓库中的 iOS 存储类演示案例 [MASTG-DEMO-0067](https://link.gitcode.com/i/9549c6ac6b13be5f7fccd25968443bbd),完整讲解如何用 Frida 拦截 `open` 系统调用,运行时追踪 App 写入的每一个文件路径与调用栈,从而判断哪些文件落入了会被 iCloud/iTunes 备份的目录

gitblog_00438的博客 251

IPATool:解密iOS应用商店的底层数据获取机制

IPATool是一款革命性的命令行工具,专为技术开发者和安全研究人员设计,能够直接与iOS应用商店交互,搜索并下载应用包文件(IPA文件)。这款工具通过逆向工程苹果的私有API,实现了对App Store数据层的深度访问,为自动化测试、应用分析和安全审计提供了前所未有的技术可能性。 ## 🧩 技术痛点:为何需要绕过官方限制? 在传统的iOS开发流程中,开发者只能通过Xcode或TestFli

gitblog_00380的博客 274

John the Ripper插件生态系统:10个最受欢迎的第三方扩展推荐

John the Ripper作为世界上最强大的密码恢复工具之一,其真正的威力来自于丰富的插件生态系统。这个开源密码恢复工具通过数百个第三方扩展支持各种哈希算法和加密格式,使其成为安全专家和渗透测试人员的首选工具。 ## 📊 加密文档格式插件 ### ZIP压缩文件恢复插件 ZIP格式支持是John the Ripper最受欢迎的扩展之一。[zip_fmt_plug.c](https://l

gitblog_00237的博客 448

农业物联网设备身份伪造危机(PHP认证机制深度剖析)

深入解析农业物联网PHP的设备认证机制,揭示身份伪造风险与防护策略。涵盖农田监测、温室控制等场景下的安全接入方案,采用双向加密与动态令牌技术提升可靠性。为开发者提供可落地的安全架构设计思路,值得收藏。

LearnFlow的博客 812
上一篇: fastbin3x64
下一篇: ios http数据请求小结
inquisiter
博客等级 码龄10年 374粉丝 228原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值