首页
社区
课程
招聘
[原创]Blowfish 解密 静态分析和动态调试流程记录
发表于: 2026-3-8 15:15 916

[原创]Blowfish 解密 静态分析和动态调试流程记录

2026-3-8 15:15
916

在仿真途中遇到了一个 DSPLib.py 文件,每次仿真都会加载一次,开头明摆着写着 VPICRYPTV2 ;要是它放在内部加载,恐怕也不会注意到,放在用户可见的目录中加载,这有些引发好奇心了,于是看看到底从哪里加载到源码的。下面记一下查找解密位置的流程:

首先,是个 .py,加载后是 module,先看看加载流程,发现了一个内置库 vpi_tc_internal

它没有 __file__ 字段,说明其是内置或故意隐藏的,应该嵌入在解释器内部;先观察执行效果,它使用 check_header 方法检查数据头部,另一个 init_module 方法从 module spec 加载,解密并初始化这一模块,这是 spec 的结构:

不过,spec 被初始化后,已经编译为字节码了,没有 __source__ 字段:

劫持 exec 会导致相关的 scipy 组件初始化出错,看起来没有很好的方法,并且无法保留注释等内容,接下来看下究竟是哪里进行了解密。

仿真由界面调用启动,界面程序为 pde.exe,命令行仿真程序为 ptcl.exe,在 System Informer 下可以看到创建的进程:

IDA 静态分析 ptcl.exe,搜索 VPICRYPTV2,寻找到一个字符串,发现字符串初始化结构:

这是一个字符串对象的初始化过程,atexit 是销毁逻辑,初始化时将固定位置的字符串复制到这一对象的数据区,IDA 中暂时标注为 VPICRYPTV2_string 对象;

接下来,寻找对象引用,按 x 找交叉引用,能够找到两个主要使用点,有一个较短,再向上找引用是 check_header 的逻辑,显然,并无解密逻辑;另一个伪代码较长,后续流程较为复杂,应该是要排查的内容:

上来就是一个字符串比较,清晰明了,进入这一分支的是解密流程,跳过压缩文件相关的逻辑,要看的是 VPICRYPTV2 解密逻辑:

排查这些步骤中的函数,标注了 get_VPICRYPTV2_key_string,其内部逻辑执行了混淆的 blowfish 秘钥构建,密钥是由 off_141A4A5E8 位置的三个字符串交叉生成的,这三个原始字符串似乎是开发人员随手复制的,例如 Error: no file existing,重新混合组合成二进制秘钥字符串,下面是偏移处的数据:

不过,这里的逻辑有些难以辨识,这一 get_VPICRYPTV2_key_string 函数给了一个明确的返回值,考虑直接动态调试查看秘钥情况。

由于 ptcl.exepde.exe 界面程序创建进程,先调试 pde.exe,断点设置在创建进程相关接口:

ptcl.exe 相关的执行停止在 CreateProcessW,对于 CreateProcessW 有六个参数:

在 x64 调用约定中,前 4 个参数在寄存器(RCX, RDX, R8, R9),后面的参数在栈上。

RDX 指针位置的数据的确是 ptcl.exe 相关的命令行指令,从 System Informer 可以看到环境变量和运行参数,使用 x64dbg.exe 启动 ptcl.exe 开始调试:

x64dbg 跳过 pde.exeCreateProcessW 进程创建,IDA 内找到 ptcl.exe 的断点在 ret 之前:

例如 .text:0000000141240966 地址,由于 IDA 静态时默认起始地址 0x140000000,对应的实际运行时断点位置为 ptcl.exe + 0x14124F5D2 - 0x140000000

x64dbg 下 Ctrl+Gx64dbg.exe 中导航到这一地址位置设置断点,F9 继续运行 ptcl.exepde.exe 使二者正常完成初始化 HTTP 通信,开始读取文件和解密(bp fopen 会无法初始化,还是需要手动设用户段的断点):

停止在 00007FF7A9D90966 (IDA内0x141240956附近),RAX 内部地址为 000000FEC42FE638,是函数返回的目标字符串对象指针,RAX 内存镜像 dump 000000FEC42FE638

前 8 字节为 50 B9 FC 43 D2 02 00 00,转换成地址是:0x000002D243FCB950,这是数据指针;偏移 16 字节(+0x10)处为 52 00 00 00 00 00 00 00,十六进制 0x52 = 十进制 82,说明 Blowfish 算法使用的密钥长度是 82 字节。

去数据区寻找秘钥 dump 0x000002D243FCB950

可以看到秘钥为

69r114o114:32n111 102i108e32e120i115t105n10380r111f105l101 98a10068i115k32f117l108

看起来仍然是混淆的,这并不是个好现象,不过秘钥指针传递到了 v24,一定是被后续使用到。

继续静态分析,看后续代码 blowfish_start_decryptv24 传递给函数第四个参数,函数内 a4 就是这一秘钥字符串:

sub_14123DBC0 使用 a4 字符串赋值给了 v13v13 在下一个 blowfish_decrypt_init 函数中被处理为 Blowfish 解密需要的 S-Box 和 P-Array,存入a1 + 0x68(104)a1 + 0x24(32)

之后 blowfish_crypt_exec 使用了 a1 中储存的 S-Box 和 P-Array,进行分块解密,返回值 v11 为数据长度,这是最终解密操作的核心:

数据写入到前面申请的地址空间 v12 = (void *)operator new(*a3 - 4);v12 作为第五个参数传递到函数中:

因此,在上一级函数 blowfish_start_decrypt动态调试,返回 v12 前打一个断点,读取 v12(R12) 即为解密后的数据,a1(RDI) + 0x68a1(RDI) + 0x20 的两个偏置位置则为 S-Box 和 P-Array 数据,现在继续动态调试:

停止在 00007FF7A9D9F6F6,对应 IDA 的 .text:000000014124F6F6,做内存转储 dump R12,直接报错解密后数据即可。

查看对应的 RDI + 0x20RDI + 0x68 地址位置的 S-Box 和 P-Array,RDI + 0x20 可以直接转储,18 个 P-Array 秘钥连续储存,RDI + 0x68 的 S-Box 数据是字符串对象,同理找到其数据区地址 0x000000FEC42FE760

获取数据区内容 dump 0x000000FEC42FE760

有了 S-Box 和 P-Array,也可以手动做 Blowfish ECB 解码获取数据

这样就能离线解码出目标文件了:

总之这一代码库的加密部分,使用 Blowfish ECB 已经是加密的老一辈了,而且代码库也没有更多的做混淆或检测;寻找解密部分还算顺利,这次就说到这吧

[2026-03-07 13:36:28] vpi_tc_internal info:
 
  Type: <class 'module'>
 
  Dir: ['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'check_header', 'eval_expr', 'get_param_expr_type', 'get_param_value', 'init_module']
 
  __name__: vpi_tc_internal
[2026-03-07 13:36:28] vpi_tc_internal info:
 
  Type: <class 'module'>
 
  Dir: ['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'check_header', 'eval_expr', 'get_param_expr_type', 'get_param_value', 'init_module']
 
  __name__: vpi_tc_internal
[2026-03-07 13:36:28] spec info:
 
  Type: <class '_frozen_importlib.ModuleSpec'>
 
  Dir: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_cached', '_set_fileattr', 'cached', 'has_location', 'loader', 'loader_state', 'name', 'origin', 'parent', 'submodule_search_locations']
 
  __module__: _frozen_importlib
[2026-03-07 13:36:28] spec info:
 
  Type: <class '_frozen_importlib.ModuleSpec'>
 
  Dir: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_cached', '_set_fileattr', 'cached', 'has_location', 'loader', 'loader_state', 'name', 'origin', 'parent', 'submodule_search_locations']
 
  __module__: _frozen_importlib
[2026-03-07 12:50:20] Source exec info:
 
  Type: <class 'code'>
 
  Dir: ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
[2026-03-07 12:50:20] Source exec info:
 
  Type: <class 'code'>
 
  Dir: ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
"C:\Program Files\VPI\VPIdesignSuite 11.1\simeng\bin\x64\ptcl.exe" -port 7801 -id 1 -dir "C:\Users\zsig\AppData\Local\Temp\VPIDS111\jobs\6" -x
"C:\Program Files\VPI\VPIdesignSuite 11.1\simeng\bin\x64\ptcl.exe" -port 7801 -id 1 -dir "C:\Users\zsig\AppData\Local\Temp\VPIDS111\jobs\6" -x
int sub_140021720()
{
  sub_14123DE40((__int64)&VPICRYPTV2_string, "VPICRYPTV2");
  return atexit(sub_1416A3850);
}
int sub_140021720()
{
  sub_14123DE40((__int64)&VPICRYPTV2_string, "VPICRYPTV2");
  return atexit(sub_1416A3850);
}
if ( (unsigned int)compare_string_objects(v60, &VPICRYPTV1_string)
  && (unsigned int)compare_string_objects(v60, &VPICRYPTV2_string) )
if ( (unsigned int)compare_string_objects(v60, &VPICRYPTV1_string)
  && (unsigned int)compare_string_objects(v60, &VPICRYPTV2_string) )
v50 = 0;
v62 = 16;
v63 = 8;
v64 = 5;
v65 = 56;
v66 = 16;
v67 = (void *)operator new(saturated_mul(0x12u, 4u));
Block = (void *)operator new(4096);
sub_1412404B0(v69, &off_141A4A5E8);
v52 = v57;
v24 = get_VPICRYPTV2_key_string(v69, v57, &off_141A4A5E8);
v25 = (char *)blowfish_start_decrypt(pExceptionObject, v53, &v46, v24);
v50 = v25;
j_j_free_0(Block);
j_j_free_0(v67);
sub_14124D840(a1, v25, (unsigned int)v46, &v47);
v26 = (int)v47;
v27 = v46 - v47;
v46 -= v47;
v50 = 0;
v62 = 16;
v63 = 8;
v64 = 5;
v65 = 56;
v66 = 16;
v67 = (void *)operator new(saturated_mul(0x12u, 4u));
Block = (void *)operator new(4096);
sub_1412404B0(v69, &off_141A4A5E8);
v52 = v57;
v24 = get_VPICRYPTV2_key_string(v69, v57, &off_141A4A5E8);
v25 = (char *)blowfish_start_decrypt(pExceptionObject, v53, &v46, v24);
v50 = v25;
j_j_free_0(Block);
j_j_free_0(v67);
sub_14124D840(a1, v25, (unsigned int)v46, &v47);
v26 = (int)v47;
v27 = v46 - v47;
v46 -= v47;
.rdata:0000000141A4A5E8 off_141A4A5E8   dq offset aErrorNoFileExi
.rdata:0000000141A4A5E8                                         ; DATA XREF: sub_140E5A0E0:loc_140E5A12D↑o
.rdata:0000000141A4A5E8                                         ; sub_1411D3970:loc_1411D39DE↑o ...
.rdata:0000000141A4A5E8                                         ; "Error: no file existing"
.rdata:0000000141A4A5F0                 dq offset aProfileBad   ; "Profile bad"
.rdata:0000000141A4A5F8                 dq offset aDiskFull     ; "Disk full"
.rdata:0000000141A4A600 aErrorNoFileExi db 'Error: no file existing',0
.rdata:0000000141A4A600                                         ; DATA XREF: .rdata:off_141A4A5E8↑o
.rdata:0000000141A4A618 aProfileBad     db 'Profile bad',0      ; DATA XREF: .rdata:0000000141A4A5F0↑o
.rdata:0000000141A4A624                 align 8
.rdata:0000000141A4A628 aDiskFull       db 'Disk full',0        ; DATA XREF: .rdata:0000000141A4A5F8↑o
.rdata:0000000141A4A632                 align 8
.rdata:0000000141A4A5E8 off_141A4A5E8   dq offset aErrorNoFileExi
.rdata:0000000141A4A5E8                                         ; DATA XREF: sub_140E5A0E0:loc_140E5A12D↑o
.rdata:0000000141A4A5E8                                         ; sub_1411D3970:loc_1411D39DE↑o ...
.rdata:0000000141A4A5E8                                         ; "Error: no file existing"
.rdata:0000000141A4A5F0                 dq offset aProfileBad   ; "Profile bad"
.rdata:0000000141A4A5F8                 dq offset aDiskFull     ; "Disk full"
.rdata:0000000141A4A600 aErrorNoFileExi db 'Error: no file existing',0
.rdata:0000000141A4A600                                         ; DATA XREF: .rdata:off_141A4A5E8↑o
.rdata:0000000141A4A618 aProfileBad     db 'Profile bad',0      ; DATA XREF: .rdata:0000000141A4A5F0↑o
.rdata:0000000141A4A624                 align 8
.rdata:0000000141A4A628 aDiskFull       db 'Disk full',0        ; DATA XREF: .rdata:0000000141A4A5F8↑o
.rdata:0000000141A4A632                 align 8
$env:BNROOT = "C:\Program Files\VPI\VPIdesignSuite 11.1\simeng"
$env:HOME = "C:\Users\zsig"
$env:PTCL_GPU_SETTINGS = "0:4294836224"
$env:PTCL_PYTHON_ENGINE = "C:\ProgramData\VPI\VPIpython\x64\pyenvs\0\Scripts\python37.dll"
$env:PTDS_HOME = "C:\Program Files\VPI\VPIdesignSuite 11.1\"
$env:PTOLEMY = "C:\Program Files\VPI\VPIdesignSuite 11.1\simeng\ptolemy"
$env:PYTHONHOME = "C:\ProgramData\VPI\VPIpython\x64\pyenvs\0"
$env:PYTHONPATH = ""
$env:TMM_DATA = "C:\Users\zsig\AppData\Local\Temp\VPIDS111"
$env:TMM_LOGDIR = "C:\Users\zsig\AppData\Local\Temp\VPIDS111\log"
$env:TMP = "C:\Users\zsig\AppData\Local\Temp"
$env:USERNAME = "zsig"
$env:USERPROFILE = "C:\Users\zsig"
 
Start-Process "D:\U-WindowsUserData\TmpData\x64dbg\release\x64\x64dbg.exe" -ArgumentList @(
    '"C:\Program Files\VPI\VPIdesignSuite 11.1\simeng\bin\x64\ptcl.exe"',
    '--',
    '-port 7802',
    '-id 1',
    '-dir "C:\Users\zsig\AppData\Local\Temp\VPIDS111\jobs\2"',
    '-x'
)
$env:BNROOT = "C:\Program Files\VPI\VPIdesignSuite 11.1\simeng"
$env:HOME = "C:\Users\zsig"
$env:PTCL_GPU_SETTINGS = "0:4294836224"
$env:PTCL_PYTHON_ENGINE = "C:\ProgramData\VPI\VPIpython\x64\pyenvs\0\Scripts\python37.dll"
$env:PTDS_HOME = "C:\Program Files\VPI\VPIdesignSuite 11.1\"
$env:PTOLEMY = "C:\Program Files\VPI\VPIdesignSuite 11.1\simeng\ptolemy"
$env:PYTHONHOME = "C:\ProgramData\VPI\VPIpython\x64\pyenvs\0"
$env:PYTHONPATH = ""
$env:TMM_DATA = "C:\Users\zsig\AppData\Local\Temp\VPIDS111"
$env:TMM_LOGDIR = "C:\Users\zsig\AppData\Local\Temp\VPIDS111\log"
$env:TMP = "C:\Users\zsig\AppData\Local\Temp"
$env:USERNAME = "zsig"
$env:USERPROFILE = "C:\Users\zsig"
 
Start-Process "D:\U-WindowsUserData\TmpData\x64dbg\release\x64\x64dbg.exe" -ArgumentList @(
    '"C:\Program Files\VPI\VPIdesignSuite 11.1\simeng\bin\x64\ptcl.exe"',
    '--',
    '-port 7802',
    '-id 1',
    '-dir "C:\Users\zsig\AppData\Local\Temp\VPIDS111\jobs\2"',
    '-x'
)
// Hidden C++ exception states: #wind=3
void *__fastcall blowfish_start_decrypt(_DWORD *a1, __int64 a2, _DWORD *a3, void *a4)
{
  int v8; // edi
  __int64 i; // rax
  int v10; // edx
  int v11; // ecx
  void *v12; // r14
  __int64 v13; // rax
  int v14; // eax
  size_t v15; // rbx
  void *v16; // rdi
  void *v18; // [rsp+30h] [rbp-A8h]
  _BYTE v19[32]; // [rsp+48h] [rbp-90h] BYREF
  _BYTE v20[32]; // [rsp+68h] [rbp-70h] BYREF
  void *v21; // [rsp+88h] [rbp-50h]
 
  v21 = a4;
  v8 = 0;
  for ( i = 0; i < 4; ++i )
  {
    v10 = *(char *)(i + a2);
    v11 = v10 + 256;
    if ( v10 >= 0 )
      v11 = *(char *)(i + a2);
    v8 += v11;
    if ( i < 3 )
      v8 <<= 8;
  }
  v12 = (void *)operator new(*a3 - 4);
  v18 = (void *)sub_14123DBC0(v19, a4);
  v13 = sub_14123DBC0(v20, v18);
  blowfish_decrypt_init(a1, v13);
  sub_14123E010(v18);
  *a1 = 1;
  v14 = blowfish_crypt_exec((_DWORD)a1, a2, 4, *a3 - 4, (__int64)v12, 0);
  *a3 = v8;
  if ( v8 == v14 )
  {
    sub_14123E010(a4);
    return v12;
  }
  else
  {
    v15 = v8;
    v16 = (void *)operator new(v8);
    memcpy(v16, v12, v15);
    j_j_free_0(v12);
    sub_14123E010(a4);
    return v16;
  }
}
// Hidden C++ exception states: #wind=3
void *__fastcall blowfish_start_decrypt(_DWORD *a1, __int64 a2, _DWORD *a3, void *a4)
{
  int v8; // edi
  __int64 i; // rax
  int v10; // edx
  int v11; // ecx
  void *v12; // r14
  __int64 v13; // rax
  int v14; // eax
  size_t v15; // rbx
  void *v16; // rdi
  void *v18; // [rsp+30h] [rbp-A8h]
  _BYTE v19[32]; // [rsp+48h] [rbp-90h] BYREF
  _BYTE v20[32]; // [rsp+68h] [rbp-70h] BYREF
  void *v21; // [rsp+88h] [rbp-50h]
 
  v21 = a4;
  v8 = 0;
  for ( i = 0; i < 4; ++i )
  {
    v10 = *(char *)(i + a2);
    v11 = v10 + 256;
    if ( v10 >= 0 )
      v11 = *(char *)(i + a2);
    v8 += v11;
    if ( i < 3 )
      v8 <<= 8;
  }
  v12 = (void *)operator new(*a3 - 4);
  v18 = (void *)sub_14123DBC0(v19, a4);
  v13 = sub_14123DBC0(v20, v18);
  blowfish_decrypt_init(a1, v13);
  sub_14123E010(v18);
  *a1 = 1;
  v14 = blowfish_crypt_exec((_DWORD)a1, a2, 4, *a3 - 4, (__int64)v12, 0);
  *a3 = v8;
  if ( v8 == v14 )
  {
    sub_14123E010(a4);
    return v12;
  }
  else
  {
    v15 = v8;
    v16 = (void *)operator new(v8);
    memcpy(v16, v12, v15);
    j_j_free_0(v12);
    sub_14123E010(a4);
    return v16;
  }
}
void __fastcall blowfish_decrypt_init(__int64 a1, _QWORD *a2)
{
  _OWORD *v3; // rax
  _OWORD *v4; // rcx
  __int64 v5; // rdi
  __int64 v6; // rdx
  _OWORD *v7; // rax
  _OWORD *v8; // rcx
  __int64 v9; // rdx
  _OWORD *v10; // rax
  _OWORD *v11; // rcx
  __int64 v12; // rdx
  _OWORD *v13; // rax
  _OWORD *v14; // rcx
  __int64 v15; // rdx
  int v16; // edx
  int v17; // r8d
  __int64 v18; // rsi
  int v19; // esi
  int v20; // ebp
  __int64 v21; // rax
  int v22; // r14d
  int v23; // r15d
  int v24; // r12d
  __int64 v25; // rax
  int v26; // r11d
  unsigned __int64 v27; // rdx
  __int64 v28; // r10
  _QWORD *v29; // rsi
  unsigned __int64 v30; // rbp
  int v31; // ecx
  int v32; // edx
  int v33; // r8d
  int v34; // edx
  int v35; // r9d
  int v36; // edx
  int v37; // ecx
  int v38; // esi
  int v39; // r14d
  __int64 v40; // rbp
  __int64 v41; // r13
  int v42; // r13d
  __int64 v43; // rax
  _DWORD *v44; // rdx
  int v45; // [rsp+30h] [rbp-78h] BYREF
  int v46; // [rsp+34h] [rbp-74h]
  int v47; // [rsp+38h] [rbp-70h]
  _QWORD *v48; // [rsp+40h] [rbp-68h]
  unsigned __int64 v49; // [rsp+48h] [rbp-60h]
  void *v50; // [rsp+50h] [rbp-58h]
  __int64 v51; // [rsp+58h] [rbp-50h]
  _QWORD *v52; // [rsp+60h] [rbp-48h]
 
  v51 = -2;
  v50 = a2;
  v52 = a2;
  if ( a2[3] < 0x10u )
    v48 = a2;
  else
    v48 = (_QWORD *)*a2;
  v49 = a2[2];
  v3 = *(_OWORD **)(a1 + 104);
  v4 = &unk_141A6C0D0;
  v5 = 8;
  v6 = 8;
  do
  {
    *v3 = *v4;
    v3[1] = v4[1];
    v3[2] = v4[2];
    v3[3] = v4[3];
    v3[4] = v4[4];
    v3[5] = v4[5];
    v3[6] = v4[6];
    v3 += 8;
    *(v3 - 1) = v4[7];
    v4 += 8;
    --v6;
  }
  while ( v6 );
  v7 = (_OWORD *)(*(_QWORD *)(a1 + 104) + 1024LL);
  v8 = &unk_141A6C4D0;
  v9 = 8;
  do
  {
    *v7 = *v8;
    v7[1] = v8[1];
    v7[2] = v8[2];
    v7[3] = v8[3];
    v7[4] = v8[4];
    v7[5] = v8[5];
    v7[6] = v8[6];
    v7 += 8;
    *(v7 - 1) = v8[7];
    v8 += 8;
    --v9;
  }
  while ( v9 );
  v10 = (_OWORD *)(*(_QWORD *)(a1 + 104) + 2048LL);
  v11 = &unk_141A6C8D0;
  v12 = 8;
  do
  {
    *v10 = *v11;
    v10[1] = v11[1];
    v10[2] = v11[2];
    v10[3] = v11[3];
    v10[4] = v11[4];
    v10[5] = v11[5];
    v10[6] = v11[6];
    v10 += 8;
    *(v10 - 1) = v11[7];
    v11 += 8;
    --v12;
  }
  while ( v12 );
  v13 = (_OWORD *)(*(_QWORD *)(a1 + 104) + 3072LL);
  v14 = &unk_141A6CCD0;
  v15 = 8;
  do
  {
    *v13 = *v14;
    v13[1] = v14[1];
    v13[2] = v14[2];
    v13[3] = v14[3];
    v13[4] = v14[4];
    v13[5] = v14[5];
    v13[6] = v14[6];
    v13 += 8;
    *(v13 - 1) = v14[7];
    v14 += 8;
    --v15;
  }
  while ( v15 );
  memcpy(*(void **)(a1 + 24), &unk_141A6C080, 4LL * (*(_DWORD *)(a1 + 20) + 2));
  v16 = 0;
  v45 = 0;
  v17 = 0;
  v46 = 0;
  v18 = 10;
  while ( 1 )
  {
    blowfish_encrypt(a1, v16, v17, (unsigned int)&v45, 0);
    if ( !--v18 )
      break;
    v17 = v46;
    v16 = v45;
  }
  v19 = v46;
  v20 = v45;
  if ( v45 != -1426174275 || v46 != 651634172 )
  {
    v21 = sub_14002CE50(std::cout, "Blowfish: Self Test 1 failed: encrypt^10(0) =");
    std::ostream::operator<<(v21, sub_14002DE00);
  }
  v47 = 9;
  v22 = 9;
  while ( 1 )
  {
    blowfish_decrypt(a1, v20, v19, (unsigned int)&v45, 0);
    if ( --v22 < 0 )
      break;
    v19 = v46;
    v20 = v45;
  }
  v23 = v46;
  v24 = v45;
  if ( v45 || v46 )
  {
    v25 = sub_14002CE50(std::cout, "Blowfish: Self Test 1 failed: decrypt^10(encrypt^10(0)) = ");
    std::ostream::operator<<(v25, sub_14002DE00);
  }
  v26 = 0;
  LODWORD(v27) = 0;
  if ( *(_DWORD *)(a1 + 20) + 2 > 0 )
  {
    v28 = 0;
    v29 = v48;
    v30 = v49;
    do
    {
      v31 = *((unsigned __int8 *)v29 + (int)v27);
      v32 = ((int)v27 + 1) % v30;
      v33 = (v31 << 8) | *((unsigned __int8 *)v29 + v32);
      v34 = (v32 + 1) % v30;
      v35 = (v33 << 8) | *((unsigned __int8 *)v29 + v34);
      v36 = (v34 + 1) % v30;
      v37 = (v35 << 8) | *((unsigned __int8 *)v29 + v36);
      v27 = (v36 + 1) % v30;
      *(_DWORD *)(v28 + *(_QWORD *)(a1 + 24)) ^= v37;
      ++v26;
      v28 += 4;
    }
    while ( v26 < *(_DWORD *)(a1 + 20) + 2 );
  }
  blowfish_encrypt(a1, 0, 0, *(_QWORD *)(a1 + 24), 0);
  v38 = 2;
  v39 = 2;
  if ( *(_DWORD *)(a1 + 20) + 2 > 2 )
  {
    v40 = 8;
    do
    {
      blowfish_encrypt(
        a1,
        *(_DWORD *)(*(_QWORD *)(a1 + 24) + v40 - 8),
        *(_DWORD *)(*(_QWORD *)(a1 + 24) + v40 - 4),
        *(_QWORD *)(a1 + 24),
        v39);
      v39 += 2;
      v40 += 8;
    }
    while ( v39 < *(_DWORD *)(a1 + 20) + 2 );
  }
  blowfish_encrypt(
    a1,
    *(_DWORD *)(*(_QWORD *)(a1 + 24) + 4LL * *(int *)(a1 + 20)),
    *(_DWORD *)(*(_QWORD *)(a1 + 24) + 4LL * (*(_DWORD *)(a1 + 20) + 1)),
    *(_QWORD *)(a1 + 104),
    0);
  do
  {
    blowfish_encrypt(
      a1,
      *(_DWORD *)(v5 + *(_QWORD *)(a1 + 104) - 8),
      *(_DWORD *)(v5 + *(_QWORD *)(a1 + 104) - 4),
      *(_QWORD *)(a1 + 104),
      v38);
    v38 += 2;
    v5 += 8;
  }
  while ( v38 < 1024 );
  v41 = 10;
  while ( 1 )
  {
    blowfish_encrypt(a1, v24, v23, (unsigned int)&v45, 0);
    if ( !--v41 )
      break;
    v23 = v46;
    v24 = v45;
  }
  v42 = v47;
  do
  {
    blowfish_decrypt(a1, v45, v46, (unsigned int)&v45, 0);
    --v42;
  }
  while ( v42 >= 0 );
  if ( v45 || v46 )
  {
    v43 = sub_14002CE50(std::cout, "Blowfish: Self Test 2 failed: decrypt^10(encrypt^10(0)) = ");
    std::ostream::operator<<(v43, sub_14002DE00);
  }
  if ( *(_DWORD *)(a1 + 20) == *(_DWORD *)(a1 + 4) )
  {
    v44 = *(_DWORD **)(a1 + 24);
    *(_DWORD *)(a1 + 32) = *v44;
    *(_DWORD *)(a1 + 36) = v44[1];
    *(_DWORD *)(a1 + 40) = v44[2];
    *(_DWORD *)(a1 + 44) = v44[3];
    *(_DWORD *)(a1 + 48) = v44[4];
    *(_DWORD *)(a1 + 52) = v44[5];
    *(_DWORD *)(a1 + 56) = v44[6];
    *(_DWORD *)(a1 + 60) = v44[7];
    *(_DWORD *)(a1 + 64) = v44[8];
    *(_DWORD *)(a1 + 68) = v44[9];
    *(_DWORD *)(a1 + 72) = v44[10];
    *(_DWORD *)(a1 + 76) = v44[11];
    *(_DWORD *)(a1 + 80) = v44[12];
    *(_DWORD *)(a1 + 84) = v44[13];
    *(_DWORD *)(a1 + 88) = v44[14];
    *(_DWORD *)(a1 + 92) = v44[15];
    *(_DWORD *)(a1 + 96) = v44[16];
    *(_DWORD *)(a1 + 100) = v44[17];
  }
  sub_14123E010(v50);
}
void __fastcall blowfish_decrypt_init(__int64 a1, _QWORD *a2)
{
  _OWORD *v3; // rax
  _OWORD *v4; // rcx
  __int64 v5; // rdi
  __int64 v6; // rdx
  _OWORD *v7; // rax
  _OWORD *v8; // rcx
  __int64 v9; // rdx
  _OWORD *v10; // rax
  _OWORD *v11; // rcx
  __int64 v12; // rdx
  _OWORD *v13; // rax
  _OWORD *v14; // rcx
  __int64 v15; // rdx
  int v16; // edx
  int v17; // r8d
  __int64 v18; // rsi
  int v19; // esi
  int v20; // ebp
  __int64 v21; // rax
  int v22; // r14d
  int v23; // r15d
  int v24; // r12d
  __int64 v25; // rax
  int v26; // r11d
  unsigned __int64 v27; // rdx
  __int64 v28; // r10
  _QWORD *v29; // rsi
  unsigned __int64 v30; // rbp
  int v31; // ecx
  int v32; // edx
  int v33; // r8d
  int v34; // edx
  int v35; // r9d
  int v36; // edx
  int v37; // ecx
  int v38; // esi
  int v39; // r14d
  __int64 v40; // rbp
  __int64 v41; // r13
  int v42; // r13d
  __int64 v43; // rax
  _DWORD *v44; // rdx
  int v45; // [rsp+30h] [rbp-78h] BYREF
  int v46; // [rsp+34h] [rbp-74h]
  int v47; // [rsp+38h] [rbp-70h]
  _QWORD *v48; // [rsp+40h] [rbp-68h]
  unsigned __int64 v49; // [rsp+48h] [rbp-60h]
  void *v50; // [rsp+50h] [rbp-58h]
  __int64 v51; // [rsp+58h] [rbp-50h]
  _QWORD *v52; // [rsp+60h] [rbp-48h]
 
  v51 = -2;
  v50 = a2;
  v52 = a2;
  if ( a2[3] < 0x10u )
    v48 = a2;
  else
    v48 = (_QWORD *)*a2;
  v49 = a2[2];
  v3 = *(_OWORD **)(a1 + 104);
  v4 = &unk_141A6C0D0;
  v5 = 8;
  v6 = 8;
  do
  {
    *v3 = *v4;
    v3[1] = v4[1];
    v3[2] = v4[2];
    v3[3] = v4[3];
    v3[4] = v4[4];
    v3[5] = v4[5];
    v3[6] = v4[6];
    v3 += 8;
    *(v3 - 1) = v4[7];
    v4 += 8;
    --v6;
  }
  while ( v6 );
  v7 = (_OWORD *)(*(_QWORD *)(a1 + 104) + 1024LL);
  v8 = &unk_141A6C4D0;
  v9 = 8;
  do
  {
    *v7 = *v8;
    v7[1] = v8[1];
    v7[2] = v8[2];
    v7[3] = v8[3];
    v7[4] = v8[4];
    v7[5] = v8[5];
    v7[6] = v8[6];
    v7 += 8;
    *(v7 - 1) = v8[7];
    v8 += 8;
    --v9;
  }
  while ( v9 );
  v10 = (_OWORD *)(*(_QWORD *)(a1 + 104) + 2048LL);
  v11 = &unk_141A6C8D0;
  v12 = 8;
  do
  {
    *v10 = *v11;
    v10[1] = v11[1];
    v10[2] = v11[2];
    v10[3] = v11[3];
    v10[4] = v11[4];
    v10[5] = v11[5];
    v10[6] = v11[6];
    v10 += 8;
    *(v10 - 1) = v11[7];
    v11 += 8;
    --v12;
  }
  while ( v12 );
  v13 = (_OWORD *)(*(_QWORD *)(a1 + 104) + 3072LL);
  v14 = &unk_141A6CCD0;
  v15 = 8;
  do
  {
    *v13 = *v14;
    v13[1] = v14[1];
    v13[2] = v14[2];
    v13[3] = v14[3];
    v13[4] = v14[4];
    v13[5] = v14[5];
    v13[6] = v14[6];
    v13 += 8;
    *(v13 - 1) = v14[7];
    v14 += 8;
    --v15;
  }
  while ( v15 );
  memcpy(*(void **)(a1 + 24), &unk_141A6C080, 4LL * (*(_DWORD *)(a1 + 20) + 2));
  v16 = 0;
  v45 = 0;
  v17 = 0;
  v46 = 0;
  v18 = 10;
  while ( 1 )
  {
    blowfish_encrypt(a1, v16, v17, (unsigned int)&v45, 0);
    if ( !--v18 )
      break;
    v17 = v46;
    v16 = v45;
  }
  v19 = v46;
  v20 = v45;

传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 3
支持
分享
最新回复 (1)
雪    币: 155
活跃值: (4296)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享 !学习。
2026-3-9 15:40
0
游客
登录 | 注册 方可回帖
返回