首页
社区
课程
招聘
关于对steamnetworkingsockets.dll 进行逆向的思路
发表于: 2021-1-5 11:11 3092

关于对steamnetworkingsockets.dll 进行逆向的思路

2021-1-5 11:11
3092


大家过年好,
最近几个朋友在开发dota2局域网联机的软件,但是遇到了一个难题,特向大佬们请教。
dota2中,当一个用户建立房间,另一个用户进行连接的时候,dota会请求一个“证书”,验证通过后,两台电脑才能开始联机,使用软件进行转储后得到的信息如下:



cert = 080112202B39DF35AAB3E009269D5FBF57A0AC8D8059BAFA7C4E1001EE8D54062DAAEAEF2108E41494763F4001453518F75F4D35BBF95F50BA045A0A810108E41494763F40016219737465616D69643A3930313431373731303730343937383030
ca_key_id = 18220590129359924542
ca_signature = E1FA9B6E43521BDA3DA6F5C579AB10A31913AA538D6FAFE4C813CF6321E43F66D2C3D913C96A86423DC8A2A24B73F237D4E30A5BE6A85536B1E042938B1A450B


现在的问题是,我们无法还原这个加密的算法,但是dota本身是要进行验证的,目前想到的办法是对steamnetworkingsockets.dll进行逆向,将证书验证的函数修改了,或者是发送一个自签名的证书,但是这些我们都不会,希望各位大佬不吝指教,万分感谢。下面是搜到的一个相关的帖子,希望有用。







大家好,V社source游戏现在似乎使用steamnetworkingsockets.dll进行客户端/服务器通信。它需要一个“证书”,该“证书”实际上是一个已签名的协议,
由应用程序通过使用EMsgClientNetworkingCertRequest通过蒸汽向cmserver请求,并响应EMsgClientNetworkingCertRequestResponse
,游戏会发送一个appid和一个“密钥”,服务器返
回一个“证书” “,由CA签名(由ID标识)


response->body_cert.set_key_type(CMsgSteamDatagramCertificate_EKeyType_ED25519);
response->body_cert.set_key_data(msg->body.key_data());
response->body_cert.set_steam_id(connection->getSteamGlobalId());
response->body_cert.set_time_created(now);
response->body_cert.set_time_expiry(now+2*24*60*60); // 2 days
response->body_cert.set_app_id(msg->body.app_id());
 
response->body.set_ca_key_id(1234);
response->body.set_ca_signature(64 bytes signature);


证书似乎存储在userdata / steamid / config / localconfig.vdf中,在“ nettickets”部分中  ,服务器似乎可以发送任何东西,它都将被缓存,无论如何,当证书/ ca /签名被验证时,游戏服务器/客户端在steamnetworkingsockets.dll中进行连接:


char __thiscall sub_10088EF0(int this, struct_a2 *a2, struct_a3 *a3, void *a4)
{
  struct_v4 *v4; // edi@1
  bool v6; // zf@7
  int v7; // eax@9
  size_t v8; // ecx@9
  int v9; // ecx@25
  int v10; // eax@31
  int v11; // eax@38
  int v12; // ST28_4@39
  int v13; // eax@39
  HANDLE *v14; // esi@43
  int v15; // eax@46
  int v16; // ecx@49
  int v17; // edx@49
  int v18; // ecx@57
  int v19; // eax@58
  int v20; // esi@59
  int v21; // eax@59
  int v22; // eax@71
  size_t v23; // ecx@71
  char v24; // cl@75
  int v25; // edx@80
  int v26; // esi@80
  int v27; // eax@80
  int v28; // ecx@80
  char *v29; // eax@82
  signed int v30; // ecx@82
  int v31; // edx@84
  int v32; // esi@84
  int v33; // ebx@84
  int v34; // ecx@84
  int v35; // eax@85
  int v36; // eax@85
  int v37; // eax@85
  int *v38; // esi@89
  signed int v39; // ebx@89
  void *v40; // eax@90
  char *v41; // edi@93
  void *v42; // esi@93
  int v43; // eax@95
  _BYTE *v44; // ecx@95
  int i; // edi@95
  signed int v46; // ecx@97
  char *v47; // eax@97
  signed int v48; // ecx@99
  char *v49; // eax@99
  signed int v50; // ecx@101
  char *v51; // eax@101
  char v52; // [sp+4h] [bp-290h]@58
  char v53; // [sp+104h] [bp-190h]@26
  char v54; // [sp+184h] [bp-110h]@82
  char v55; // [sp+1A4h] [bp-F0h]@80
  char v56; // [sp+1C4h] [bp-D0h]@94
  char v57; // [sp+1E4h] [bp-B0h]@95
  void *v58; // [sp+1E8h] [bp-ACh]@86
  int v59; // [sp+1F8h] [bp-9Ch]@86
  int v60; // [sp+20Ch] [bp-88h]@39
  int v61; // [sp+210h] [bp-84h]@39
  int v62; // [sp+214h] [bp-80h]@38
  int v63; // [sp+218h] [bp-7Ch]@38
  int v64; // [sp+21Ch] [bp-78h]@7
  int v65; // [sp+220h] [bp-74h]@7
  int v66; // [sp+224h] [bp-70h]@7
  char v67; // [sp+228h] [bp-6Ch]@7
  int v68; // [sp+22Ch] [bp-68h]@1
  int v69; // [sp+230h] [bp-64h]@69
  int v70; // [sp+234h] [bp-60h]@69
  int v71; // [sp+238h] [bp-5Ch]@69
  char v72; // [sp+23Ch] [bp-58h]@69
  int v73; // [sp+240h] [bp-54h]@84
  int v74; // [sp+244h] [bp-50h]@84
  int v75; // [sp+248h] [bp-4Ch]@84
  int v76; // [sp+24Ch] [bp-48h]@84
  size_t v77; // [sp+250h] [bp-44h]@84
  int v78; // [sp+254h] [bp-40h]@84
  int v79; // [sp+258h] [bp-3Ch]@84
  int v80; // [sp+25Ch] [bp-38h]@84
  int v81; // [sp+260h] [bp-34h]@80
  int v82; // [sp+264h] [bp-30h]@80
  int v83; // [sp+268h] [bp-2Ch]@80
  int v84; // [sp+26Ch] [bp-28h]@80
  void *v85; // [sp+270h] [bp-24h]@84
  char *v86; // [sp+274h] [bp-20h]@84
  _BYTE *v87; // [sp+278h] [bp-1Ch]@84
  _BYTE *v88; // [sp+27Ch] [bp-18h]@84
  int v89; // [sp+280h] [bp-14h]@84
  int v90; // [sp+284h] [bp-10h]@84
  int v91; // [sp+290h] [bp-4h]@7
  char *v92; // [sp+2A4h] [bp+10h]@86
  
  v4 = (struct_v4 *)this;
  v68 = this;
  if ( *(_BYTE *)(this + 13032) )
    return 1;
  if ( !(a2->byte8 & 1) || !(a3->byte8 & 1) )
  {
    sub_1008A650(4002, "Crypto handshake missing cert or session data");
    return 0;
  }
  if ( !(unsigned __int8)sub_100C3130(a2->dword10) )
  {
    sub_1008A650(4002, "Cert failed protobuf decode");
    return 0;
  }
  v64 = 3;
  v66 = 0;
  v65 = 0;
  v67 = 0;
  v6 = v4->key_type == 1;
  v91 = 0;
  if ( !v6 )
  {
    sub_1008A650(4002, "Unsupported identity key type");
LABEL_107:
    sub_10022270(&v64);
    return 0;
  }
  v7 = v4->dword3218;
  v8 = *(_DWORD *)(v7 + 16);
  if ( *(_DWORD *)(v7 + 20) >= 0x10u )
    v7 = *(_DWORD *)v7;
  if ( !(unsigned __int8)sub_10021860((void *)v7, v8) || !(unsigned __int8)sub_10021170(&v64) )
  {
    sub_1008A650(4002, "Cert has invalid identity key");
    goto LABEL_107;
  }
  if ( v4->byte32C8 & 1 )
  {
    if ( !((v4->fields_maps >> 2) & 1) )
      sub_1001CDE0(
        (int)"Assertion Failed: m_msgCryptLocal.has_nonce()",
        0,
        "steamnetworkingsockets_connections.cpp",
        802);
    if ( !((v4->fields_maps >> 1) & 1) )
      sub_1001CDE0(
        (int)"Assertion Failed: m_msgCryptLocal.has_key_data()",
        0,
        "steamnetworkingsockets_connections.cpp",
        803);
    if ( !(v4->fields_maps & 1) )
      sub_1001CDE0(
        (int)"Assertion Failed: m_msgCryptLocal.has_key_type()",
        0,
        "steamnetworkingsockets_connections.cpp",
        804);
  }
  else
  {
    if ( !(unsigned __int8)(*(int (__thiscall **)(struct_v4 *))(v4->dword0 + 56))(v4) && dword_10271D84 >= 4 )
      sprintf(
        (char *)4,
        "We don't have cert, and unsigned certs are not supposed to be allowed here.  Continuing anyway temporarily.");
    sub_1008B330(v4);
  }
  if ( (v4->dword3210 >> 6) & 1 )
  {
    v9 = v4->app_id;
    if ( v9 != v4->dword28->dword78 )
    {
      sub_10077AE0((int)&v53, "Cert is for AppID %u instead of %u", v9, v4->dword28->dword78);
      if ( dword_10271D84 >= 4 )
        sprintf((char *)4, "Cert failure: %s\n", &v53);
    }
  }
  if ( v4->steam_id <= 0 || !((*(_DWORD *)&a2->byte8 >> 2) & 1) )
  {
    if ( !((v4->dword3210 >> 2) & 1) && dword_10271D84 >= 4 )
      sprintf((char *)4, "Cert failure: %s\n", "Cert must be bound to a SteamID.");
    if ( !((v4->dword3210 >> 6) & 1) && dword_10271D84 >= 4 )
      sprintf((char *)4, "Cert failure: %s\n", "Cert must be bound to an AppID.");
    v11 = v4->dword3220;
    v63 = v4->dword3224;
    v62 = v11;
    if ( !(unsigned __int8)sub_10087AA0(&v4->gap2C[4]) )
      goto LABEL_42;
    v60 = v4->dword3220;
    v61 = v4->dword3224;
    v12 = sub_10086E60(&v4->gap2C[4]);
    v13 = sub_10086E60(&v60);
    sub_10077AE0((int)&v53, "Cert was issued to %s, not %s", v13, v12);
    goto LABEL_40;
  }
  if ( (v4->dword34 & 0xF00000) != 0x400000 )
  {
    v10 = sub_10086E60(&v4->gap2C[4]);
    sub_10077AE0((int)&v53, "Certs restricted data center are for anon GS only.  Not %s", v10);
LABEL_40:
    if ( dword_10271D84 >= 4 )
      sprintf((char *)4, "Cert failure: %s\n", &v53);
  }
LABEL_42:
  if ( (*(_DWORD *)&a2->byte8 >> 2) & 1 )
  {
    v14 = (HANDLE *)&unk_102562E0;
    do
    {
      if ( a2->ca_key_1 == *v14 && a2->ca_key_2 == v14[1] )
      {
        v15 = a2->dword20;
        if ( *(_DWORD *)(v15 + 16) == 64 )
        {
          if ( *(_DWORD *)(v15 + 20) >= 0x10u )
            v15 = *(_DWORD *)v15;
          v16 = a2->dword10;
          v17 = *(_DWORD *)(v16 + 16);
          if ( *(_DWORD *)(v16 + 20) >= 0x10u )
            v16 = *(_DWORD *)v16;
          if ( sub_100221F0(v16, v17, (int)(v14 + 2), v15) )
            goto LABEL_57;
        }
        if ( dword_10271D84 >= 4 )
          sprintf((char *)4, "Cert failure: %s\n", "Invalid cert signature");
      }
      v14 += 6;
    }
    while ( v14 != &hEvent );
    sub_10077AE0((int)&v53, "Cert signed with key %llu; not in trusted list", a2->ca_key_1, a2->ca_key_2);
    if ( dword_10271D84 >= 4 )
      sprintf((char *)4, "Cert failure: %s\n", &v53);
LABEL_57:
    v18 = v4->dword28->dword6C;
    if ( v18 )
    {
      v20 = v4->dword323C;
      v21 = (*(int (**)(void))(*(_DWORD *)v18 + 12))();
      if ( v21 > v20 )
      {
        sub_10077AE0((int)&v53, "Cert expired %ld secs ago at %ld", v21 - v20, v20);
        if ( dword_10271D84 >= 4 )
          sprintf((char *)4, "Cert failure: %s\n", &v53);
      }
    }
    else
    {
      v19 = sub_1001D440(&v52, "Assertion Failed: %s", "No ISteamUtils?  Cannot check if cert expired!");
      sub_1001CDE0(v19, 0, "steamnetworkingsockets_connections.cpp", 899);
    }
    if ( !(unsigned __int8)(*(int (__thiscall **)(struct_v4 *))(v4->dword0 + 60))(v4) )
    {
      if ( v4->dword334C != 5 )
      {
        sub_1001CDE0(
          (int)"Assertion Failed: GetState() == k_ESteamNetworkingConnectionState_ProblemDetectedLocally",
          0,
          "steamnetworkingsockets_connections.cpp",
          920);
        sub_10022270(&v64);
        return 0;
      }
      goto LABEL_107;
    }
  }
  else if ( dword_10271D84 >= 5 )
  {
    sprintf((char *)5, "Remote host is using an unsigned cert.  Allowing connection, but it's not secure!\n");
  }
  if ( !(unsigned __int8)sub_100C3130(a3->dword10) )
  {
    sub_1008A650(4002, "Crypt info failed protobuf decode");
    goto LABEL_107;
  }
  v69 = 5;
  v71 = 0;
  v70 = 0;
  v72 = 0;
  v6 = v4->dword325C == 1;
  LOBYTE(v91) = 1;
  if ( !v6 )
  {
    sub_1008A650(4002, "Unsupported DH key type");
LABEL_105:
    sub_10022270(&v69);
    sub_10022270(&v64);
    return 0;
  }
  v22 = v4->dword3258;
  v23 = *(_DWORD *)(v22 + 16);
  if ( *(_DWORD *)(v22 + 20) >= 0x10u )
    v22 = *(_DWORD *)v22;
  if ( !(unsigned __int8)sub_10021860((void *)v22, v23) || !(unsigned __int8)sub_10021130(&v69) )
  {
    sub_1008A650(4002, "Invalid DH key");
    goto LABEL_105;
  }
  v24 = v4->byte3260;
  if ( !v24 )
    goto LABEL_112;
  if ( !dword_10264930 )
  {
LABEL_79:
    sub_1008A650(4002, "Incompatible protocol format (SNP)");
    goto LABEL_105;
  }
  if ( !v24 )
  {
LABEL_112:
    if ( dword_10264930 )
      goto LABEL_79;
  }
  LOBYTE(v91) = 2;
  sub_10021640(v4->gap3270, &v69, &v55);
  sub_10022270(v4->gap3270);
  v25 = v4->dword3268;
  v26 = v4->dword326C;
  v27 = v4->dword32A0;
  v28 = v4->dword32A4;
  v81 = v4->dword3268;
  v82 = v26;
  v83 = v27;
  v84 = v28;
  if ( (_BYTE)a4 )
  {
    v81 = v27;
    v82 = v28;
    v83 = v25;
    v84 = v26;
  }
  LOBYTE(v91) = 3;
  sub_10020940(&v81, 0x10u, &v55, 0x20u, &v54);
  v29 = &v55;
  v30 = 32;
  do
  {
    *v29++ = 0;
    --v30;
  }
  while ( v30 );
  v31 = a2->dword10;
  v32 = v4->dword32D0;
  v33 = v4->dword32B8;
  v85 = &v4->char32E9;
  v86 = &v4->char3309;
  v87 = &v4->gap330A[31];
  v88 = &v4->gap330A[47];
  v77 = 32;
  v78 = 32;
  v34 = a3->dword10;
  v89 = v4->dword50;
  v90 = v4->dword54;
  v79 = 16;
  v80 = 16;
  v73 = v31;
  v74 = v32;
  v75 = v34;
  v76 = v33;
  if ( (_BYTE)a4 )
  {
    v85 = &v4->char3309;
    v86 = &v4->char32E9;
    v87 = &v4->gap330A[47];
    v88 = &v4->gap330A[31];
    v35 = v31;
    v31 = v32;
    v77 = 32;
    v32 = v35;
    v78 = 32;
    v36 = v34;
    v79 = 16;
    v34 = v33;
    v80 = 16;
    v33 = v36;
    v73 = v31;
    v89 = v4->dword54;
    v37 = v4->dword50;
    v74 = v32;
    v75 = v34;
    v76 = v33;
    v90 = v37;
  }
  sub_1001E020(
    0,
    *(_DWORD *)(v31 + 16) + *(_DWORD *)(v32 + 16) + *(_DWORD *)(v34 + 16) + 104 + *(_DWORD *)(v33 + 16),
    0);
  LOBYTE(v91) = 4;
  sub_1001EFD0(0, 32);
  v92 = (char *)v58 + v59;
  if ( v4->dword60 < 3u )
    sub_1001EAE0(&v89, 4u);
  else
    sub_1001EAE0(&v89, 8u);
  sub_1001EAE0("Steam datagram", 0xEu);
  v38 = &v73;
  v39 = 4;
  do
  {
    v40 = (void *)*v38;
    if ( *(_DWORD *)(*v38 + 20) >= 0x10u )
      v40 = *(void **)v40;
    sub_1001EAE0(v40, *(_DWORD *)(*v38 + 16));
    ++v38;
    --v39;
  }
  while ( v39 );
  v41 = (char *)v58 + v59;
  v42 = v92;
  do
  {
    *v41 = v39 + 1;
    sub_10020940(v42, v41 - (_BYTE *)v42 + 1, &v54, 0x20u, &v56);
    memmove_0(*(&v85 + v39), &v56, *(&v77 + v39));
    v42 = v58;
    memmove_0(v58, &v56, 0x20u);
    ++v39;
  }
  while ( v39 < 4 );
  v43 = sub_100B09D0(&v57);
  v44 = v58;
  for ( i = v68; v43; --v43 )
    *v44++ = 0;
  v46 = 32;
  v47 = &v56;
  do
  {
    *v47++ = 0;
    --v46;
  }
  while ( v46 );
  *(_BYTE *)(i + 13032) = 1;
  LOBYTE(v91) = 3;
  sub_1001F470(&v57);
  v48 = 32;
  v49 = &v54;
  do
  {
    *v49++ = 0;
    --v48;
  }
  while ( v48 );
  v50 = 32;
  v51 = &v55;
  do
  {
    *v51++ = 0;
    --v50;
  }
  while ( v50 );
  sub_10022270(&v69);
  sub_10022270(&v64);
  return 1;
}

我被信任的CA证书列表或签名验证所吸引,所以由于我真的没有时间,有人已经扭转了这一点吗? 感谢您的见解!




原帖地址(请注册登录查看):https://cs.rin.ru/forum/viewtopic.php?f=20&t=85859


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-2-16 15:57 被cloverlove编辑 ,原因:
上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 12848
活跃值: (9142)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
2
经典机翻,牛头不对马嘴
2021-1-5 12:53
0
雪    币: 13
活跃值: (122)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
hzqst 经典机翻,牛头不对马嘴
不好意思,请问大佬有什么思路没?
2021-1-5 13:09
0
游客
登录 | 注册 方可回帖
返回
//