2025/1/21训练

ollvm

收集信息

无壳,elf文件,64位

拖入ida64,一看先是被吓了一跳

这么多流程,结合题目名字,我一开始认为这道题是ollvm平坦化混淆,第一反应是去olllvm平坦化

ollvm去平坦化

argc符号执行

Miasm符号执行

代码直接分析

 

 v124 = 0;
   v123 = argc;
   v122 = argv;
   if ( argc == 2 )
   {
     if ( strlen(v122[1]) == 38 )
     {
       i = 0;
       j = 0;
       __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::__gmp_expr(v119, 1LL);
       __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::__gmp_expr(v118);
       v22 = v116;
       do
       {
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::__gmp_expr(v22);
         v22 += 16;
       }
       while ( v22 != v117 );
       v115 = 0;
       for ( i = 0; ; ++i )
       {
         v21 = i;
         if ( v21 >= strlen(v122[1]) )
           break;
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=(v119, 1LL);
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=(v118, (unsigned int)(v122[1][i] - v115));
         for ( j = 0; j < 5; ++j )
         {
           v114[0] = operator*<__mpz_struct [1],__mpz_struct [1],__mpz_struct [1],__mpz_struct [1]>(v119, v118);
           v114[1] = v3;
           __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=<__mpz_struct [1],__gmp_binary_expr<__gmp_expr<__mpz_struct [1],__mpz_struct [1]>,__gmp_expr<__mpz_struct [1],__mpz_struct [1]>,__gmp_binary_multiplies>>(
             v119,
             v114);
         }
         v113[0] = operator%<__mpz_struct [1],__mpz_struct [1]>(v119, 323LL);
         v113[1] = v4;
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=<__mpz_struct [1],__gmp_binary_expr<__gmp_expr<__mpz_struct [1],__mpz_struct [1]>,long,__gmp_binary_modulus>>(
           &v116[i],
           v113);
       }
       v20 = (__int64 *)v111;
       do
       {
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::__gmp_expr(v20);
         v20 += 2;
       }
       while ( v20 != &v112 );
       v109[0] = operator-<__mpz_struct [1],__mpz_struct [1]>(v116, 0LL);
       v109[1] = v5;
       v6 = strlen(v122[1]);
       v110[0] = operator+<__mpz_struct [1],__gmp_binary_expr<__gmp_expr<__mpz_struct [1],__mpz_struct [1]>,long,__gmp_binary_minus>>(
                   v109,
                   v6);
       v110[1] = v7;
       __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=<__mpz_struct [1],__gmp_binary_expr<__gmp_expr<__mpz_struct [1],__gmp_binary_expr<__gmp_expr<__mpz_struct [1],__mpz_struct [1]>,long,__gmp_binary_minus>>,unsigned long,__gmp_binary_plus>>(
         v111,
         v110);
       for ( i = 1; ; ++i )
       {
         v19 = i;
         if ( v19 >= strlen(v122[1]) )
           break;
         v108[0] = operator+<__mpz_struct [1],__mpz_struct [1],__mpz_struct [1],__mpz_struct [1]>(&v116[i], &v116[i - 1]);
         v108[1] = v8;
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=<__mpz_struct [1],__gmp_binary_expr<__gmp_expr<__mpz_struct [1],__mpz_struct [1]>,__gmp_expr<__mpz_struct [1],__mpz_struct [1]>,__gmp_binary_plus>>(
           &v111[i],
           v108);
       }
       v18 = (__int64 *)v107;
       do
       {
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::__gmp_expr(v18);
         v18 += 2;
       }
       while ( v18 != v108 );
       std::allocator<char>::allocator(v105);
       std::string::basic_string(

1. 输入验证

 if (argc == 2) {
     if (strlen(INPUT[1]) == 38) {
         ...
     }
 }
  • 要求程序的参数数量为 2,并且输入的字符串长度为 38。

  • 如果不满足条件,程序将不会继续执行。


2. 初始化

 oo2::MemsetQuantum_Test((oo2 *)v119, (const unsigned __int8 *)1);
 __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::__gmp_expr((__int64)v118);
  • 使用 GMP 大数库,初始化变量 v119v118

  • oo2::MemsetQuantum_Test 可能是某种自定义初始化函数,给定默认值 1


3. 核心循环

 for (i = 0; i < strlen(INPUT[1]); ++i) {
     __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=(v119, 1LL);
     __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=(v118, (unsigned int)(INPUT[1][i] - v115));
     
     for (j = 0; j < 5; ++j) {
         v114[0] = operator*<...>(v119, (size_t)v118); // v119 = v119 * v118
         rcs::analytics::Event::operator=(v119, v114);
     }
     
     v113[0] = operator%<...>(v119, 323LL); // v113[0] = v119 % 323
     __gmp_expr<...>::operator=(&v116[i], v113); // 保存结果到 v116[i]
 }
  • 每个字符(

     INPUT[1][i]

    )经过以下数学运算:

    1. 初始化 v119 = 1

    2. 将字符减去一个偏移量 v115,结果存入 v118

    3. 计算字符的 5 次幂:v119 = (INPUT[1][i] - v115)^5

    4. 将结果取模 323,存入 v116[i]

此循环的作用是将输入的每个字符转化为一个与其相关的数值,便于后续验证。


4. 结果验证

 for (i = 1; i < strlen(INPUT[1]); ++i) {
     v108[0] = operator+<...>(&v116[i], &v116[i - 1]); // v116[i] + v116[i - 1]
     __gmp_expr<...>::operator=(&v111[i], v108); // 保存结果到 v111[i]
 }
  • 计算数组 v116 中相邻元素的和,并存入 v111

  • 这可能是对转换后的值再进行一次处理,以增加难度。

 

中间部分是一堆大数的赋值和比较

 

  for ( i = 38; i < 0x64; ++i )
       {
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::__gmp_expr(v24, 4267316LL, 0LL);
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=(&v63[16 * i], v24);
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v24);
       }
       for ( i = 0; ; ++i )
       {
         v16 = i;
         if ( v16 >= strlen(v122[1]) )
           break;
         encrypt(v23, &v111[i], v101, v102);
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=(&v107[i], v23);
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v23);
         if ( (operator!=<__mpz_struct [1],__mpz_struct [1],__mpz_struct [1],__mpz_struct [1]>(&v107[i], &v63[16 * i]) & 1) != 0 )
         {
           v15 = std::operator<<<std::char_traits<char>>(&_bss_start, (unsigned int)"wrong flag.");
           std::ostream::operator<<(v15, (unsigned int)&std::endl<char,std::char_traits<char>>);
           v124 = 0;
           goto LABEL_31;
         }
       }
       v14 = std::operator<<<std::char_traits<char>>(&_bss_start, (unsigned int)"bingo!");
       std::ostream::operator<<(v14, (unsigned int)&std::endl<char,std::char_traits<char>>);
       v124 = 0;
 LABEL_31:
       v13 = v101;
       do
       {
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v13 - 16);
         v13 -= 16;
       }
       while ( v13 != v63 );
       __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v101);
       __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v102);
       std::string::~string(v104);
       std::string::~string(v106);
       v12 = v108;
       do
       {
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v12 - 2);
         v12 -= 2;
       }
       while ( v12 != (__int64 *)v107 );
       v11 = &v112;
       do
       {
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v11 - 2);
         v11 -= 2;
       }
       while ( v11 != (__int64 *)v111 );
       v10 = v117;
       do
         __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(--v10);
       while ( v10 != v116 );
       __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v118);
       __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v119);
     }
     else
     {
       v124 = 0;
       printf("flag require 38 chars");
     }
   }
   else
   {
     v124 = 0;
     printf("Command line parameter error.");
   }
   return v124;
 }

第一个 for 循环

 for ( i = 38; i < 0x64; ++i )
 {
     __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::__gmp_expr(v24, 4267316LL, 0LL);
     __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=(&v63[16 * i], v24);
     __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v24);
 }
  1. 功能

    • 该循环从索引 38 开始到 0x64(即 100),对每个 i 生成一个 GMP 表达式并赋值到 v63 的相应位置。

  2. 过程

    • v24 被初始化为值 4267316

    • v24 的值赋值给 v6316 * i 偏移处。

    • 销毁 v24 对象。

  3. 目的

    • 初始化 v63 的特定区域,可能是用于后续比较的参考值。


第二个 for 循环

 cpp复制编辑for ( i = 0; ; ++i )
 {
     v16 = i;
     if ( v16 >= strlen(v122[1]) )
         break;
     encrypt(v23, &v111[i], v101, v102);
     __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::operator=(&v107[i], v23);
     __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v23);
     if ( (operator!=<__mpz_struct [1],__mpz_struct [1],__mpz_struct [1],__mpz_struct [1]>(&v107[i], &v63[16 * i]) & 1) != 0 )
     {
         v15 = std::operator<<<std::char_traits<char>>(&_bss_start, (unsigned int)"wrong flag.");
         std::ostream::operator<<(v15, (unsigned int)&std::endl<char,std::char_traits<char>>);
         v124 = 0;
         goto LABEL_31;
     }
 }
  1. 功能

    • 遍历输入字符串的每个字符,并对其执行加密操作。

    • 将加密结果与之前的初始化值 v63 的对应部分进行比较。

  2. 过程

    • v16 是循环索引,逐个字符处理 v122[1](输入字符串)。

    • 调用 encrypt 函数对输入字符串的当前字符进行加密,结果存储在 v23

    • v23 的值赋值到 v107[i]

    • 如果 v107[i]v63[16 * i] 不相等,表示当前字符错误,打印 "wrong flag." 并跳转到清理代码块。

  3. 目的

    • 核心功能是校验输入字符串的每个字符是否正确。

    • 如果某个字符不正确,会立即退出循环并提示错误。


校验成功的情况

 cpp复制编辑v14 = std::operator<<<std::char_traits<char>>(&_bss_start, (unsigned int)"bingo!");
 std::ostream::operator<<(v14, (unsigned int)&std::endl<char,std::char_traits<char>>);
 v124 = 0;
  • 如果所有字符都通过校验,打印 "bingo!" 表示输入正确。


清理代码块

 cpp复制编辑do
 {
     __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::~__gmp_expr(v13 - 16);
     v13 -= 16;
 } while ( v13 != v63 );
  1. 功能

    • 销毁 GMP 对象,释放动态分配的内存。

    • 遍历多个动态数组,包括 v63v107v111 等,依次销毁其内部的 GMP 表达式对象。

  2. 目的

    • 避免内存泄漏,完成程序清理工作。


输入长度检查

 cpp复制编辑else
 {
     v124 = 0;
     printf("flag require 38 chars");
 }
  • 如果输入字符串长度不足 38 个字符,打印提示 "flag require 38 chars"


命令行参数错误

 cpp复制编辑else
 {
     v124 = 0;
     printf("Command line parameter error.");
 }
  • 如果命令行参数数量不符合要求,打印提示 "Command line parameter error."

encrypt函数分析

   __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::__gmp_expr(a1);
   mpz_t = __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::get_mpz_t(a1);
   v7 = __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::get_mpz_t(a2);
   v6 = __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::get_mpz_t(a3);
   v5 = __gmp_expr<__mpz_struct [1],__mpz_struct [1]>::get_mpz_t(a4);
   __gmpz_powm(mpz_t, v7, v6, v5);
   return a1;

result=(base^exp)mod mod

其中:

  • result 存储在 a1 中。

  • basea2 的值。

  • expa3 的值。

  • moda4 的值。

RSA

函数逻辑简化整理

 assert len(flag) == 38
 v120 = [pow(i, 5, 323) for i in flag]
 v114 = v120[38] + [v120[i-1]+v120[i] for i in range(1, 38)]
 for i,v in enumerate(v114):
     if pow(v,e,n) != v63[i]:
         break
 else:
     print("OK")

 

 

 

 

脚本

 #
 '''
 assert len(flag) == 38
 v120 = [pow(i, 5, 323) for i in flag]
 v114 = v120[38] + [v120[i-1]+v120[i] for i in range(1, 38)]
 for i,v in enumerate(v114):
     if pow(v,e,n) != v63[i]:
         break
 else:
     print("OK")
 '''
 v63 = [
 ......这个数据在原程序里,一共38个大大大的数......
 ]
  
  
 n = 102651473104605400881443209436335207143364593902607831104659513254775518923447923418776053184964127417292310751110954018379230925038183526950825957076822861193097601598650310458833168757490447855063621089262488908245458996608300475771810218545021100532975095664160301297355685288040601637561442455179633110079846710134322730324284152857852000538712290118985202146945804609486282114958343308956178741452118058076488074220293303425550534104695916297651437260840156614208398265649572936591070707149727591261946573549966777759067945870542262596595729532884877741113485459644140649532472144766397594354234108576755815917168003359597993072007662182342629809152936969421895552780144527391604982975657819198048361600023456702313892160810273481932944137974282216381637292972896247123735265111606267014480229602366343234386044792316318028789845062796141719269577108623503432313385433912012680162134432871999515572195678215741149038561107783321860080221501590006190270380869307116405522430479782169008415898242325411271043447827685653357582905940740125675545255630155684164945409286389585255976330122263610987012875989116119004168237430091958750377684385918076049811463810026787681970329875350154256541485562299929744955216059064911687028831046268556619196694147338675484825249402694136964225868844636091765013673567792490217775308571769318669397501731133181116010571526812759760618304461298242712032781458409426120142005834592865613957784145176085762288081896026523415885624361265385011667667343515890459493297688753
 e = 41609
  
 t = [0]*38
 for i in range(38):
     for j in range(323*2):
         k = pow(j,e,n)
         if k == v63[i]:
             t[i] = j 
             break
 print(t)            
 #t = [85,335,338,235,410,512,529,423,267,327,370,232,188,170,169,192,239,179,179,300,356,394,336,212,196,355,471,459,437,448,506,472,256,134,318,317,265,188]
 tab = [pow(i,5,323) for i in range(0x7f)]
 for i in range(0x20,0x7f):
     v = pow(i, 5, 323)
     if v<t[1]:
         r = [0]*38
         r[0] = v 
         for j in range(1,38):
             r[j] = t[j]-r[j-1]
             if r[j]<0 or (r[j] not in tab):
                 break
         else:
             flag = [tab.index(k) for k in r]
             print(bytes(flag))
 #QCTF{5Ym4aOEww2NcZcvUPOWKYMnPaqPywR2m}           

 

RSA解密部分

Python复制

 t = [0]*38
 for i in range(38):
     for j in range(323*2):
         k = pow(j, e, n)
         if k == v63[i]:
             t[i] = j 
             break
  • 这段代码的目的是对v63中的每个值进行RSA解密。

  • v63是一个长度为38的列表,每个元素是一个大整数。

  • n是RSA的模数,e是公钥指数。

  • 程序通过暴力尝试j的值(范围是0646,即323*2),计算pow(j, e, n),直到找到一个j使得pow(j, e, n) == v63[i]

  • 如果找到这样的j,则将j存入t[i]

2. 差分序列还原部分

Python复制

 tab = [pow(i, 5, 323) for i in range(0x7f)]
 for i in range(0x20, 0x7f):
     v = pow(i, 5, 323)
     if v < t[1]:
         r = [0]*38
         r[0] = v 
         for j in range(1, 38):
             r[j] = t[j] - r[j-1]
             if r[j] < 0 or (r[j] not in tab):
                 break
         else:
             flag = [tab.index(k) for k in r]
             print(bytes(flag))
  • 这部分代码的目的是还原一个差分序列。

  • tab是一个预计算的表,包含00x7f(即127)的所有数的五次方模323的结果。

  • 程序尝试从0x200x7f的所有可能的起始值i,计算pow(i, 5, 323),并将其作为差分序列的第一个值r[0]

  • 然后通过差分公式r[j] = t[j] - r[j-1]逐步还原整个序列。

  • 如果某个r[j]小于0或者不在tab中,则中断当前尝试。

  • 如果成功还原整个序列,则通过tab.index(k)将每个r[j]映射回原始值,并将这些值转换为字节,最终输出flag

 

动态插桩法()pintools

 

 

 import subprocess
 import time
 ​
 st_time = time.time()
 l = 38
 table="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 now = 5
 flag = "QCTF{"+"*"*33
 prev_cnt = 11718047
 while(1):
     if(now>=37):
         break
     for x in table:
         cmd = '../../../pin -t obj-intel64/inscount0.so -o ollvm.log -- ./ollvm '+\
             flag[:now]+x+flag[now+1:]+\
                 '; cat ./ollvm.log'
         output = subprocess.check_output(cmd,shell=True,stderr=subprocess.PIPE) 
         now_cnt = int(output.split(b'\n')[1].split()[1].decode())
         # print(now_cnt)
         if(now_cnt-prev_cnt>=1000000):
             print(f"[+] RIGHT!        {x}")
             flag = flag[:now]+x+flag[now+1:]
             now += 1
             prev_cnt = now_cnt
             break
     else:
         print("[+] ERROR !")
 ​
 print(f'[+] Done!\ntime: {time.time()-st_time}')
 print(f'\n[+]{flag}\n')
 ​

代码功能概述

  1. 目标: 通过逐字符尝试,利用指令执行计数的变化(inscount0.so 插桩工具生成),判断每个字符是否正确,从而逐步还原正确的 flag

  2. 假设:

    • 如果尝试的字符是正确的,则程序的行为会发生显著变化(比如指令执行数增加)。

    • 如果字符错误,则指令执行数的变化幅度较小或不符合预期。


核心逻辑

  1. 初始化:

    • st_time 记录破解过程的开始时间。

    • l = 38 表示 flag 的总长度。

    • table 包含所有可能的字符(数字 + 大小写字母)。

    • flag 初始化为 QCTF{ 开头,后跟 33 个 * 作为占位符。

    • prev_cnt 初始为指令执行计数的基准值,手动设置为 11718047

  2. 字符破解:

    • 外层循环:

      按顺序破解每一位字符。

      • now 表示当前正在破解的字符位置(初始为 5)。

    • 内层循环:

      遍历

       table

      中所有可能的字符,逐一尝试。

      • 调用 Pin 工具运行目标程序,输入当前尝试的 flag

      • 读取插桩工具生成的日志 ollvm.log,提取指令执行计数。

      • 判断当前字符是否正确:

        • 如果指令执行计数相比上一次增加超过 1,000,000,则认为当前字符正确,更新 flag

        • 否则继续尝试下一个字符。

  3. 结束条件:

    • 如果所有字符(now >= 37)破解完毕,结束循环。

  4. 输出:

    • 打印破解完成所用时间。

    • 输出最终破解的 flag


改进建议

  1. 优化字符表:

    • 如果有部分字符范围已知,可以缩小 table 的范围,减少尝试次数。

  2. 动态调整 prev_cnt

    • prev_cnt 是手动设置的基准值。若破解多个不同程序,可动态获取基准值代替硬编码。

  3. 增加错误处理:

    • 目前对于异常(如 subprocess 调用失败或日志解析失败)未处理,可增加捕获和重试机制。

  4. 减少系统调用开销:

    • 如果 Pin 或目标程序运行较慢,可以通过优化插桩工具或程序逻辑提高效率。


运行结果(示例)

如果 flagQCTF{1234...},程序会逐步输出每一位正确字符。例如:

 css复制编辑[+] RIGHT!        Q
 [+] RIGHT!        C
 [+] RIGHT!        T
 [+] RIGHT!        F
 ...
 [+] Done!
 time: 62.384
 [+] QCTF{correct_flag}

这段代码是一个典型的基于动态分析的爆破工具,主要依赖程序行为差异(如指令计数)来判断输入的正确性,非常适合用于破解具有复杂混淆的程序。

 

Q2384729

QC24333

QCTF{ }

您说:

逐行分析

 

ChatGPT 说:

ChatGPT

以下是代码的逐行分析和功能说明:


 python复制编辑import subprocess
 import time
  • 功能:

    导入所需的模块。

    • subprocess: 用于执行系统命令(这里运行 Pin 工具)。

    • time: 用于记录破解开始和结束时间,计算耗时。


 python
 ​
 ​
 复制编辑
 st_time = time.time()
  • 功能: 记录破解开始时间,用于后续计算破解总耗时。


 python
 ​
 ​
 复制编辑
 l = 38
  • 功能: 定义 flag 的长度为 38。这个长度是从目标程序分析中得出的。


 python
 ​
 ​
 复制编辑
 table="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  • 功能: 定义所有可能的字符集合,包括数字、大写字母、小写字母。这是每个位置可能的字符候选集合。


 python复制编辑now = 5
 flag = "QCTF{"+"*"*33
 prev_cnt = 11718047
  • 功能:

    1. now: 表示当前正在破解的字符位置,初始为 5(跳过 QCTF{)。

    2. flag: 初始化 flagQCTF{ 开头,后面用 * 占位符代替未知字符。

    3. prev_cnt: 初始指令执行计数,用于后续判断当前字符是否正确。这个值是从初始运行或分析结果中获取的。


 python复制编辑while(1):
     if(now >= 37):
         break
  • 功能:

    • 无限循环,直到破解到第 37 位(从 0 开始计数,即破解完成第 38 个字符)。

    • 出口条件: now >= 37,即所有字符已破解完成。


 python
 ​
 ​
 复制编辑
     for x in table:
  • 功能: 遍历 table 中所有可能的字符,逐一尝试插入到当前待破解的位置 now


 python复制编辑        cmd = '../../../pin -t obj-intel64/inscount0.so -o ollvm.log -- ./ollvm '+\
             flag[:now]+x+flag[now+1:]+\
                 '; cat ./ollvm.log'
  • 功能:

    1. 构造系统命令,调用 Pin 工具对目标程序进行插桩分析。

      • ../../../pin: Pin 工具路径。

      • -t obj-intel64/inscount0.so: 使用 inscount0.so 插桩工具,记录程序运行的指令计数。

      • -o ollvm.log: 将指令计数的结果输出到 ollvm.log

      • -- ./ollvm <flag>: 执行目标程序 ollvm,传入当前猜测的 flag

    2. 拼接当前尝试的

       flag

      • flag[:now]: 已破解的部分。

      • x: 当前尝试的字符。

      • flag[now+1:]: 未破解部分(保持原样)。

    3. ; cat ./ollvm.log: 读取生成的日志文件。


 python
 ​
 ​
 复制编辑
         output = subprocess.check_output(cmd,shell=True,stderr=subprocess.PIPE)
  • 功能:

    执行系统命令

     cmd

    ,并捕获其输出。

    • shell=True: 允许在 shell 环境中执行命令。

    • stderr=subprocess.PIPE: 捕获命令的标准错误输出。


 python
 ​
 ​
 复制编辑
         now_cnt = int(output.split(b'\n')[1].split()[1].decode())
  • 功能:

    1. 解析

       ollvm.log

      日志中的指令计数。

      • output.split(b'\n')[1]: 获取日志中包含指令计数的第二行。

      • .split()[1]: 提取指令计数值。

      • .decode(): 将字节流解码为字符串。

      • int(): 转换为整数。

    2. 将当前的指令计数存储到 now_cnt


 python复制编辑        if(now_cnt-prev_cnt >= 1000000):
             print(f"[+] RIGHT!        {x}")
             flag = flag[:now]+x+flag[now+1:]
             now += 1
             prev_cnt = now_cnt
             break
  • 功能:

    判断当前尝试的字符

     x

    是否正确。

    1. 如果指令计数的增长量(now_cnt - prev_cnt)超过 1,000,000,说明 x 是正确的。

    2. 输出当前正确字符。

    3. 更新

       flag

      • flag[:now] + x + flag[now+1:]: 替换当前位置 now 的占位符为正确字符 x

    4. 更新 now 指针,移动到下一个字符。

    5. 更新 prev_cnt 为当前指令计数,作为下一次比较的基准。

    6. 使用 break 跳出内层循环。


 python复制编辑    else:
         print("[+] ERROR !")
  • 功能: 如果 table 中所有字符尝试完毕仍未找到正确字符,则输出错误提示。


 python复制编辑print(f'[+] Done!\ntime: {time.time()-st_time}')
 print(f'\n[+]{flag}\n')
  • 功能:

    1. 输出破解完成的提示。

    2. 计算并显示总耗时:time.time() - st_time

    3. 打印最终破解完成的 flag

 

dates_test y_test pred_test 2024/9/3 88.33333333 112.5269743 2024/9/3 88.33333333 87.66773838 2024/9/8 108.1818182 101.305023 2024/9/9 115.4545455 95.94628989 2024/9/13 44 50.22694321 2024/9/18 80 83.50581792 2024/9/28 75 72.03481818 2024/9/29 100 70.63235275 2024/10/2 74.16666667 60.0974857 2024/10/5 102.7272727 93.70316775 2024/10/11 130.9090909 90.89599003 2024/10/11 130.9090909 106.1278653 2024/10/13 63.75 70.22797207 2024/10/15 86.66666667 84.94518368 2024/10/16 71.66666667 67.6315823 2024/10/17 35.5 41.12031575 2024/10/22 37.5 41.03879175 2024/10/24 75.83333333 75.25111555 2024/10/26 56.66666667 59.38398062 2024/10/27 67.5 77.832346 2024/10/30 78.33333333 74.74345001 2024/11/1 71.66666667 74.42641864 2024/11/1 71.66666667 79.26579196 2024/11/3 107.5 95.54370557 2024/11/5 55 88.56740098 2024/11/5 55 63.31681544 2024/11/7 70.83333333 69.54550807 2024/11/8 52.5 70.67583166 2024/11/9 50.5 65.56271868 2024/11/11 61.66666667 67.35173834 2024/11/13 66.66666667 67.28262989 2024/11/14 69.16666667 74.95588283 2024/11/16 62.5 67.71457132 2024/11/20 31.25 39.891552 2024/11/21 56.25 53.22487241 2024/11/21 56.25 45.76253479 2024/11/22 67.5 55.73400985 2024/11/22 67.5 71.83695125 2024/11/29 60 63.5601233 2024/12/3 121.25 123.4305079 2024/12/3 121.25 85.3482925 2024/12/4 78.75 118.7901925 2024/12/5 48.57142857 76.99301816 2024/12/5 48.57142857 56.97048272 2024/12/6 50 55.87833305 2024/12/9 63.75 76.94141229 2024/12/11 90 91.33542966 2024/12/11 90 86.81876617 2024/12/12 105 88.86386619 2024/12/12 105 83.2873992 2024/12/28 44 52.28276036 2024/12/29 73.75 71.47314109 2024/12/31 145 113.5592608 2025/1/2 174.2857143 155.6452639 2025/1/3 204 167.5981065 2025/1/4 157.1428571 132.7838937 2025/1/5 75 92.49745297 2025/1/6 77.5 91.45886457 2025/1/10 44.28571429 54.07822402 2025/1/10 44.28571429 49.77849383 2025/1/11 78.75 78.33945264 2025/1/12 81.25 73.83615932 2025/1/13 106.25 80.49762555 2025/1/20 151.4285714 135.5365602 2025/1/21 133.75 129.3701745 2025/1/22 135 129.7498376 2025/1/24 91.25 146.2574101 2025/1/27 55 71.19681257 2025/1/28 62.5 66.08731135 2025/2/1 67.5 70.55055278 2025/2/2 58.75 66.17282227 2025/2/5 58.75 88.25618868 2025/2/8 39 77.09680956 2025/2/9 45.71428571 52.59000634 2025/2/15 86.25 82.55732834 2025/2/16 82.5 80.47600523 2025/2/19 63.75 77.20241091 2025/2/23 116.25 86.20812499 2025/2/24 120 99.71647402 2025/2/28 76.25 62.48392691 2025/3/3 28 49.58835197 2025/3/4 42.85714286 31.03968392 2025/3/5 48.57142857 57.86928852 2025/3/6 72.5 63.13378784 2025/3/7 80 78.53474335 2025/3/9 80 74.8908945 2025/3/9 80 86.4381764 2025/3/11 65 68.92648547 2025/3/15 42.5 47.87104828 2025/3/17 54.16666667 55.10420056 2025/3/19 70 71.56898471 2025/3/21 75.83333333 77.01770667 2025/3/24 70 74.56893424 2025/3/29 70 76.79240723 2025/4/1 71 80.49636367 2025/4/2 81.66666667 81.90300111 2025/4/5 84.16666667 78.87172554 2025/4/6 97.5 94.27099108 2025/4/7 84.16666667 89.69045916 2025/4/14 98 95.76669915 2025/4/21 42 110.7547733 2025/4/23 81.66666667 57.57965373 2025/4/24 61.5 83.89232336 2025/4/26 91.66666667 84.27197067 2025/4/27 58.33333333 63.2359425 2025/4/28 95 60.21913102 2025/4/30 68.33333333 73.17850563 2025/5/1 80.83333333 82.36145101 2025/5/2 86.66666667 83.28253032 2025/5/3 80.83333333 86.81863008 2025/5/4 103.6363636 98.15885845 2025/5/7 135.5 95.10256211 2025/5/7 135.5 116.0233971 2025/5/10 50 56.54042179 2025/5/15 50.83333333 56.13208029 2025/5/19 80 80.8703101 2025/5/21 55.83333333 57.59769333 2025/5/22 38.5 42.78308838 2025/5/22 38.5 63.21934594 2025/5/24 80.83333333 73.79815518 2025/5/25 123.6363636 79.32403802 2025/5/27 97.5 105.5559785 2025/5/28 64.16666667 69.09375382 2025/5/31 33.5 70.82817578 2025/5/31 33.5 34.23426147 2025/6/1 43 37.87608647 2025/6/11 65.83333333 40.92472477 2025/6/14 44.5 71.85373194 2025/6/15 67.5 47.3552771 2025/6/16 80.83333333 76.67770933 2025/6/18 40.5 56.99440466 2025/6/21 52.5 50.26688877 2025/6/24 67.5 70.07672005 2025/6/25 85.83333333 83.64304008 2025/6/26 48 47.23009884 2025/6/26 48 82.14277947 2025/6/27 27.5 32.65747275 2025/6/29 33 38.08214866 2025/7/2 40.5 41.67411208 2025/7/3 41.5 41.41264814 2025/7/4 62.5 42.44601331 2025/7/6 89.16666667 68.117607 2025/7/10 48 50.34278214 2025/7/12 38.5 54.11489636 2025/7/13 61.66666667 68.58124235 2025/7/14 57.5 74.65653795 2025/7/15 63.33333333 61.39286753 2025/7/16 61.66666667 61.32914242 2025/7/18 89.16666667 84.7154233 2025/7/19 109.0909091 85.33932655 2025/7/21 44.5 50.99408325 2025/7/23 47 67.89049979 2025/7/24 70.83333333 72.41964472 2025/7/24 70.83333333 65.9840856 2025/7/28 41.5 44.27687112 2025/7/31 68.33333333 67.99134975 2025/8/1 58.33333333 57.32271191 2025/8/2 66.66666667 72.74851308 2025/8/2 66.66666667 59.6210798 2025/8/3 85 83.60732756 2025/8/3 85 78.78748701 2025/8/8 48 60.12853279 2025/8/17 67.5 46.09111409 2025/8/18 55 71.52011334 2025/8/21 43.5 42.50301084 2025/8/26 95 96.08207568 2025/8/27 80 95.63145426 2025/8/28 85 71.81423784 2025/9/1 60 47.52937251 2025/9/3 74.16666667 68.18375631 2025/9/4 68.33333333 70.05693039 2025/9/5 73.33333333 70.05693039 2025/9/5 73.33333333 71.04672543 2025/9/21 32 35.85595145 2025/9/23 29.5 48.00505558 2025/9/25 25.5 33.71126822 2025/9/25 25.5 35.91251939 2025/9/29 32.5 37.6947908 观察以上预测结果,按照月、天对结果进行分析总结,
11-27
2024/1/1 123.75 141.44978233067818 2024/1/7 168.571428571429 164.58807061400717 2024/1/7 168.571428571429 88.90894227150248 2024/1/14 205 149.4715770893992 2024/1/16 52.5 136.41907987248615 2024/1/17 38.75 48.555230155374 2024/1/28 88.75 98.74711815669839 2024/2/2 32.857142857142904 50.54266038039505 2024/2/2 32.857142857142904 51.77056225639738 2024/2/5 82.5 97.3466728624111 2024/2/6 95 77.28656265637308 2024/2/7 110 82.90365797321212 2024/2/8 120 107.29023222927522 2024/2/10 151.428571428571 112.40124095463952 2024/2/11 116.25 121.88067651092562 2024/2/18 47.99999999999999 56.003677776515694 2024/2/19 67.5 55.847826096774526 2024/2/20 26.5 74.12894162493086 2024/2/22 47.1428571428572 50.037483558704345 2024/2/23 57.5 58.72629260822178 2024/2/23 57.5 59.90278324034665 2024/2/25 85 71.33576752872008 2024/2/28 122.5 108.9989900963616 2024/3/11 85 84.32848045698128 2024/3/16 100 75.57018610879334 2024/3/22 65 64.63852076852191 2024/3/24 36 62.39492082209007 2024/3/25 41 45.1101102285979 2024/3/28 56.6666666666667 66.59210042370242 2024/3/31 87.5 85.55500914218962 2024/4/1 54.16666666666671 51.4276556700062 2024/4/3 75 36.78731342930887 2024/4/3 75 73.76915442987828 2024/4/6 49.49999999999999 57.76058767045256 2024/4/7 56.25 59.90187152601827 2024/4/10 50.83333333333331 57.4928560934163 2024/4/11 63.75 51.59536811040737 2024/4/14 66.6666666666667 74.62430391378464 2024/4/16 44 49.86779586148121 2024/4/21 91.6666666666667 80.99920808671243 2024/4/25 94 95.1916784497183 2024/4/25 94 101.6468276165237 2024/4/26 123.636363636364 101.54226255724868 2024/5/1 47.1428571428572 58.50932702270208 2024/5/2 68.3333333333333 64.01621832767732 2024/5/4 40.5 53.42829426027681 2024/5/11 63 79.31938023373458 2024/5/13 123.636363636364 109.90295137443077 2024/5/14 121.818181818182 103.38721464003619 2024/5/22 50.83333333333331 55.79412608640662 2024/5/23 77.5 80.42939479500879 2024/5/27 73.3333333333333 71.32283060586244 2024/6/3 96.6666666666667 88.01209786222385 2024/6/9 68.3333333333333 108.56864781513396 2024/6/11 83.3333333333333 48.55482492203493 2024/6/13 110 88.15962441453412 2024/6/14 122.727272727273 107.61549578817458 2024/6/27 46.50000000000001 44.078713021115306 2024/6/29 33 26.44193350991658 2024/7/1 42 52.59867325205077 2024/7/3 44.5 89.82048738852457 2024/7/4 39 52.19653144726541 2024/7/5 47.99999999999999 48.08958368353323 2024/7/9 49 57.59646598524163 2024/7/9 49 53.60283014788386 2024/7/11 63.3333333333333 66.97868019503072 2024/7/17 53.3333333333333 63.34636274774507 2024/7/19 41.5 42.89947272348277 2024/7/21 64.1666666666667 66.09878524599225 2024/7/22 66.6666666666667 65.00890057786901 2024/7/26 45.00000000000001 71.21665897622492 2024/7/28 40.5 44.13470403198099 2024/8/1 44.5 47.583181504691126 2024/8/2 45.00000000000001 47.583181504691126 2024/8/2 45.00000000000001 46.9087841595428 2024/8/3 51.6666666666667 45.23014594969053 2024/8/4 55.8333333333333 58.65054857410897 2024/8/6 68.3333333333333 54.60578952020746 2024/8/9 62.5 65.85809400034259 2024/8/10 75.8333333333333 71.9206795742283 2024/8/11 94.1666666666667 70.96740036589514 2024/8/15 90 80.34604289750527 2024/8/18 90 94.47656346062271 2024/8/22 81.6666666666667 86.53461449155253 2024/8/22 81.6666666666667 108.27781523932805 2024/8/23 65.8333333333333 82.53817106629121 2024/9/3 88.3333333333333 113.16247944014161 2024/9/3 88.3333333333333 88.23748357200765 2024/9/8 108.181818181818 101.89782847813537 2024/9/9 115.454545454545 96.45857559537323 2024/9/13 44 50.29448003948117 2024/9/18 80 83.8067648044246 2024/9/28 75 72.56515720406895 2024/9/29 100 70.64652960614046 2024/10/2 74.1666666666667 60.570719215034764 2024/10/5 102.727272727273 93.99401752385478 2024/10/11 130.909090909091 91.43861631520019 2024/10/11 130.909090909091 107.36748520058795 2024/10/13 63.75 70.11378396004059 2024/10/15 86.6666666666667 85.31855469197326 2024/10/16 71.6666666666667 67.85859636969488 2024/10/17 35.5 40.568489434724526 2024/10/22 37.5 41.13715300481026 2024/10/24 75.8333333333333 75.07703363794025 2024/10/26 56.6666666666667 59.31423576916348 2024/10/27 67.5 77.72187997314686 2024/10/30 78.3333333333333 74.72658701406004 2024/11/1 71.6666666666667 74.32719194724612 2024/11/1 71.6666666666667 78.99471579045824 2024/11/3 107.5 96.12724021398316 2024/11/5 55 88.70741079334934 2024/11/5 55 63.17230961245132 2024/11/7 70.8333333333333 69.40951088280127 2024/11/8 52.5 70.58982172647461 2024/11/9 50.5 65.39850926077335 2024/11/11 61.6666666666667 67.08648185133565 2024/11/13 66.6666666666667 67.06290561067581 2024/11/14 69.1666666666667 74.92724767621056 2024/11/16 62.5 67.72309837940713 2024/11/20 31.25 39.791267230677306 2024/11/21 56.25 53.09328772113596 2024/11/21 56.25 45.96954038585586 2024/11/22 67.5 55.89475640940251 2024/11/22 67.5 72.07171621764438 2024/11/29 60 63.75168781309595 2024/12/3 121.25 123.51751061089429 2024/12/3 121.25 85.35092998366582 2024/12/4 78.75 118.96571575050625 2024/12/5 48.5714285714286 77.23522342869911 2024/12/5 48.5714285714286 56.760071551348034 2024/12/6 50.00000000000001 55.67542260586588 2024/12/9 63.75 77.29555462085865 2024/12/11 90 91.88546031226497 2024/12/11 90 87.43060672017323 2024/12/12 105 89.23105190131274 2024/12/12 105 83.14521582557892 2024/12/28 44 51.14349839579385 2024/12/29 73.75 70.82581380052193 2024/12/31 145 113.7323729139217 2025/1/2 174.285714285714 158.40406690058774 2025/1/3 204 168.67990876026008 2025/1/4 157.142857142857 131.7945723625761 2025/1/5 75 92.88837622077833 2025/1/6 77.5 90.9308700022185 2025/1/10 44.28571428571429 53.946620996090516 2025/1/10 44.28571428571429 49.57827863490396 2025/1/11 78.75 78.29644384995049 2025/1/12 81.25 73.87610905688891 2025/1/13 106.25 80.38639509127034 2025/1/20 151.428571428571 136.6081186621433 2025/1/21 133.75 129.94744729140956 2025/1/22 135 130.24655227366316 2025/1/24 91.25 146.3767752344893 2025/1/27 55 71.46727057951108 2025/1/28 62.5 66.31463541778702 2025/2/1 67.5 71.37098161035166 2025/2/2 58.75 66.17426845 2025/2/5 58.75 88.75667212785046 2025/2/8 39 77.88252871091174 2025/2/9 45.7142857142857 52.18881850959389 2025/2/15 86.25 82.4133355641056 2025/2/16 82.5 80.27288373068554 2025/2/19 63.75 77.16937696990621 2025/2/23 116.25 86.76096912509652 2025/2/24 120 100.18931943988112 2025/2/28 76.25 62.27437528664383 2025/3/3 28 49.49588667705353 2025/3/4 42.857142857142904 31.204205454247344 2025/3/5 48.5714285714286 57.89927257633713 2025/3/6 72.5 63.413358717767835 2025/3/7 80 78.92374488524504 2025/3/9 80 74.84065901246376 2025/3/9 80 86.94889436125919 2025/3/11 65 68.96484811264284 2025/3/15 42.5 47.68307768671133 2025/3/17 54.16666666666671 54.844184083948534 2025/3/19 70 71.32317723530358 2025/3/21 75.8333333333333 76.9746305766928 2025/3/24 70 74.65521786082064 2025/3/29 70 77.40180710328875 2025/4/1 71 80.57870505575087 2025/4/2 81.6666666666667 81.99531424941331 2025/4/5 84.1666666666667 78.8368811413689 2025/4/6 97.5 94.72271732958869 2025/4/7 84.1666666666667 89.88488096255729 2025/4/14 98 95.67823824552184 2025/4/21 42 111.53290689851633 2025/4/23 81.6666666666667 57.141737161191365 2025/4/24 61.5 83.99447487776038 2025/4/26 91.6666666666667 84.24149848760464 2025/4/27 58.3333333333333 62.870282372247104 2025/4/28 95 59.83136943842301 2025/4/30 68.3333333333333 73.1449341049362 2025/5/1 80.8333333333333 82.50448713333525 2025/5/2 86.6666666666667 83.55990976104009 2025/5/3 80.8333333333333 87.13972460673028 2025/5/4 103.636363636364 98.5090122230891 2025/5/7 135.5 94.65732498676186 2025/5/7 135.5 118.08517354632647 2025/5/10 50.00000000000001 56.534837994279506 2025/5/15 50.83333333333331 55.91271636914875 2025/5/19 80 80.8946332197781 2025/5/21 55.8333333333333 57.6135692788171 2025/5/22 38.5 42.75042106739687 2025/5/22 38.5 63.47590727436925 2025/5/24 80.8333333333333 73.64128586482872 2025/5/25 123.636363636364 79.50115966335561 2025/5/27 97.5 106.27753198307643 2025/5/28 64.1666666666667 69.30680223618985 2025/5/31 33.5 70.81933813357111 2025/5/31 33.5 34.34381152519421 2025/6/1 43 38.11541438169796 2025/6/11 65.8333333333333 40.703264716877996 2025/6/14 44.5 71.8059471813712 2025/6/15 67.5 47.3519258804609 2025/6/16 80.8333333333333 76.75751861199961 2025/6/18 40.5 56.99724051629258 2025/6/21 52.5 50.91048391171709 2025/6/24 67.5 70.32261502977192 2025/6/25 85.8333333333333 83.64395823861886 2025/6/26 47.99999999999999 47.11187595527804 2025/6/26 47.99999999999999 82.26586779001731 2025/6/27 27.5 32.61973525719978 2025/6/29 33 38.471384454153934 2025/7/2 40.5 41.8137903149492 2025/7/3 41.5 41.55174601833187 2025/7/4 62.5 42.555910187138494 2025/7/6 89.1666666666667 67.94355289605272 2025/7/10 47.99999999999999 50.420961530730615 2025/7/12 38.5 53.933623933134314 2025/7/13 61.6666666666667 68.87604276458451 2025/7/14 57.5 75.07816532 2025/7/15 63.3333333333333 61.27539132564982 2025/7/16 61.6666666666667 61.2199272323314 2025/7/18 89.1666666666667 85.1940043760954 2025/7/19 109.090909090909 85.80104582479294 2025/7/21 44.5 51.048631974115125 2025/7/23 47 68.68200192813825 2025/7/24 70.8333333333333 72.70514810854169 2025/7/24 70.8333333333333 66.72884559566981 2025/7/28 41.5 44.24787044978878 2025/7/31 68.3333333333333 68.10199967482542 2025/8/1 58.3333333333333 57.21891596330586 2025/8/2 66.6666666666667 73.0065068273534 2025/8/2 66.6666666666667 59.566026288096104 2025/8/3 85 83.71691559565357 2025/8/3 85 79.21006390845372 2025/8/8 47.99999999999999 60.629516790631705 2025/8/17 67.5 46.08474692761816 2025/8/18 55 71.73300540615286 2025/8/21 43.5 42.74603613157312 2025/8/26 95 96.662891741162 2025/8/27 80 96.21714056534087 2025/8/28 85 72.027393057495 2025/9/1 60 47.6061644310276 2025/9/3 74.1666666666667 68.11991657351632 2025/9/4 68.3333333333333 70.02119887103083 2025/9/5 73.3333333333333 70.02119887103083 2025/9/5 73.3333333333333 70.89262161791024 2025/9/21 32 35.474220745225495 2025/9/23 29.5 47.931426661999886 2025/9/25 25.5 33.93622542134888 2025/9/25 25.5 36.402784316544256 2025/9/29 32.5 37.61827081824134 列名依次为时间、真实值、预测值,对以上预测结果进行分析
11-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值