首页
社区
课程
招聘
[原创]2025 KCTF 第二题 初窥门径
发表于: 2025-8-16 21:18 4666

[原创]2025 KCTF 第二题 初窥门径

2025-8-16 21:18
4666

首先注意到题目中有几个位置通过修改栈顶后ret来进行跳转:

捋清楚逻辑后,可以在ida里面将多余的指令patch掉,如下:


之后函数sub_701280就可以正常反编译了:

其中的几个函数的作用分别是判断质数、求平方根和判断一个数是否被拆为两质数之积:

回到最关键的验证函数sub_701280,借助大模型的帮助,思路是将问题建模为三维网格上的路径搜索问题

编写解题代码:

编译运行后,得到flag:



byte __cdecl sub_701280(const char *str_input)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  p = str_input;
  if ( str_input )
  {
    len = strlen(str_input);
    index = 0;
    v4 = 0;
    y = 0;
    len2 = len;
    z_last = 0;
    y_last = 0;
    x_last = 0;
    v15 = 0;
    v13 = 0;
    if ( len > 0 )
    {
      while ( 1 )
      {
        chr = p[v4];
        while ( arr_0toz[index] != chr )
        {
          if ( arr_0toz[index + 1] == chr )
          {
            ++index;
            break;
          }
          if ( arr_0toz[index + 2] == chr )
          {
            index += 2;
            break;
          }
          if ( arr_0toz[index + 3] == chr )
          {
            index += 3;
            break;
          }
          if ( arr_0toz[index + 4] == chr )
          {
            index += 4;
            break;
          }
          if ( arr_0toz[index + 5] == chr )
          {
            index += 5;
            break;
          }
          index += 6;
          if ( index >= 36 )
            return 0;
        }
        if ( index >= 36 )
          break;
        if ( index >= 12 )
          z = (index >= 24) + 1;
        else
          z = 0;
        if ( (v4 & 1) != 0 )
        {
          v10 = v15 + 1;
          x = index % 12;
          v15 = v10;
          if ( v10 == 1 && dword_703020[80 * z + 10 * z + 10 * y + x] != 0x2C0E )
            return 0;
          v9 = v13;
          if ( v13 == len2 - 1 && dword_703020[80 * z + 10 * z + 10 * y + x] != 0x1FB2 )
            return 0;
          if ( v10 > 1 )
          {
            if ( v13 < len2
              && (!semiprime_factorize(dword_703020[80 * z + 10 * z + 10 * y + x], &v19, &v20)
               || v19 < 2
               || v20 < 2
               || v19 == v20)
              || abs32(x - x_last) + abs32(y - y_last) + abs32(z - z_last) != 1 )
            {
              return 0;
            }
            v9 = v13;
          }
          x_last = x;
          y_last = y;
          z_last = z;
          if ( v9 == len2 - 1 && dword_703020[80 * z + 10 * z + 10 * y + x] == 0x1FB2 )
            return 1;
          len = len2;
        }
        else
        {
          y = index % 12;
          v9 = v13;
        }
        v12 = v9 + 1;
        v13 = v12;
        if ( v12 >= len )
          return 0;
        p = str_input;
        v4 = v12;
        index = 0;
      }
    }
  }
  return 0;
}
char __cdecl is_prime(int a1)
{
  int v2; // esi
  int v3; // ecx

  if ( a1 < 2 )
    return 0;
  v2 = 2;
  v3 = (int)square_root((double)a1);
  if ( v3 >= 2 )
  {
    while ( a1 % v2 )
    {
      if ( ++v2 > v3 )
        return 1;
    }
    return 0;
  }
  return 1;
}
double __cdecl square_root(double a1)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  result = 0.0;
  if ( a1 > 0.0 )
  {
    if ( 1.0 == a1 )
    {
      return 1.0;
    }
    else
    {
      v2 = 0;
      v3 = a1 * 0.5;
      do
      {
        v4 = (v3 + a1 / v3) * 0.5;
        v5 = v4 - v3;
        if ( v5 < 0.0 )
          v5 = -v5;
        v6 = v5;
        v7 = v4;
        v8 = v6;
        if ( v4 < 0.0 )
          v4 = -v4;
        v9 = v4 * 0.0000001;
        v10 = v9 < v8;
        v11 = v9 == v8;
        v3 = v7;
        if ( !v10 && !v11 )
          break;
        v12 = (v7 + a1 / v7) * 0.5;
        v13 = v12 - v7;
        if ( v13 < 0.0 )
          v13 = -v13;
        v14 = v13;
        v15 = v12;
        v16 = v14;
        if ( v12 < 0.0 )
          v12 = -v12;
        v17 = v12 * 0.0000001;
        v18 = v17 < v16;
        v19 = v17 == v16;
        v3 = v15;
        if ( !v18 && !v19 )
          break;
        v20 = (v15 + a1 / v15) * 0.5;
        v21 = v20 - v15;
        if ( v21 < 0.0 )
          v21 = -v21;
        v22 = v21;
        v23 = v20;
        v24 = v22;
        if ( v20 < 0.0 )
          v20 = -v20;
        v25 = v20 * 0.0000001;
        v26 = v25 < v24;
        v27 = v25 == v24;
        v3 = v23;
        if ( !v26 && !v27 )
          break;
        v28 = (v23 + a1 / v23) * 0.5;
        v29 = v28 - v23;
        if ( v29 < 0.0 )
          v29 = -v29;
        v30 = v29;
        v31 = v28;
        v32 = v30;
        if ( v28 < 0.0 )
          v28 = -v28;
        v33 = v28 * 0.0000001;
        v34 = v33 < v32;
        v35 = v33 == v32;
        v3 = v31;
        if ( !v34 && !v35 )
          break;
        v36 = (v31 + a1 / v31) * 0.5;
        v37 = v36 - v31;
        if ( v37 < 0.0 )
          v37 = -v37;
        v38 = v37;
        v39 = v36;
        v40 = v38;
        if ( v36 < 0.0 )
          v36 = -v36;
        v41 = v36 * 0.0000001;
        v42 = v41 < v40;
        v43 = v41 == v40;
        v3 = v39;
        if ( !v42 && !v43 )
          break;
        v2 += 5;
      }
      while ( v2 < 50 );
      return v3;
    }
  }
  return result;
}
char __cdecl semiprime_factorize(int n, int *p, int *q)
{
  int v4; // edi
  int v5; // ecx
  int v6; // esi
  int v7; // ecx
  int v9; // [esp+1Ch] [ebp-4h]
  int na; // [esp+24h] [ebp+4h]

  if ( n < 4 )
    return 0;
  v4 = 2;
  v9 = 2;
  v5 = (int)square_root((double)n);
  na = v5;
  if ( v5 < 2 )
    return 0;
  while ( 1 )
  {
    if ( n % v4 || v4 < 2 )
      goto LABEL_10;
    v6 = 2;
    v7 = (int)square_root((double)v9);
    if ( v7 >= 2 )
    {
      while ( v4 % v6 )
      {
        if ( ++v6 > v7 )
          goto LABEL_8;
      }
      goto LABEL_9;
    }
LABEL_8:
    if ( is_prime(n / v4) )
      break;
LABEL_9:
    v5 = na;
LABEL_10:
    v9 = ++v4;
    if ( v4 > v5 )
      return 0;
  }
  if ( p )
    *p = v4;
  if ( q )
    *q = n / v4;
  return 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <vector>
#include <tuple>
#include <algorithm>

// 已有函数声明
double __cdecl square_root(double a1);
char __cdecl is_prime(int a1);
char __cdecl semiprime_factorize(int n, int* p, int* q);
char __cdecl test(const char* str_input);

int main() {
    // 复制test函数中的字符映射数组(0-35对应字符)
    unsigned char arr_0toz[40] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 
        0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 
        0x77, 0x78, 0x79, 0x7A, 0x00, 0x00, 0x00, 0x00
    };
    
    // 复制test函数中的值数组(272个元素)
    unsigned int dword_703020[272] = {
        0x00002C0E, 0x00001312, 0x00007F44, 0x00004C2B, 0x00000966, 0x00001E12, 0x00001263, 0x00001828, 
        0x000031A1, 0x000052AE, 0x00001DC6, 0x00004019, 0x00003D89, 0x0000614D, 0x00001A4A, 0x00003A24, 
        0x00005406, 0x00000E61, 0x00000658, 0x00000D4C, 0x00005423, 0x00004860, 0x00007988, 0x00001FA3, 
        0x0000705B, 0x00004464, 0x000063EF, 0x0000403E, 0x000050CB, 0x00001676, 0x00005132, 0x000068B5, 
        0x00004A38, 0x00006FF5, 0x0000189B, 0x0000170B, 0x00002704, 0x000020ED, 0x00004938, 0x000047F6, 
        0x00007512, 0x00005196, 0x00002B7C, 0x00004A50, 0x00002E54, 0x00006FBE, 0x00003532, 0x00007B54, 
        0x00000ABD, 0x00002889, 0x000056C0, 0x0000323B, 0x00003698, 0x000031CF, 0x0000435A, 0x000075FA, 
        0x00000A2B, 0x0000200B, 0x000045ED, 0x0000163F, 0x00002554, 0x000062BB, 0x00003393, 0x00002A31, 
        0x00002956, 0x00003004, 0x00003684, 0x00003DEE, 0x000047AC, 0x00002267, 0x0000629E, 0x00001E93, 
        0x00007943, 0x0000661B, 0x00007FB4, 0x0000255A, 0x00003D37, 0x00001804, 0x000069E1, 0x0000312C, 
        0x00003999, 0x0000293F, 0x00002F0E, 0x0000743A, 0x00000117, 0x000064CD, 0x00007C76, 0x00005CBF, 
        0x00006AB0, 0x00000585, 0x00006CFC, 0x00003CE6, 0x00006FAB, 0x00000F81, 0x0000511C, 0x000024E4, 
        0x00000785, 0x00005AEB, 0x00002977, 0x00000BFB, 0x000055F8, 0x00000039, 0x000029DD, 0x00004987, 
        0x0000133B, 0x00005E2F, 0x00007F4D, 0x00006497, 0x000062C2, 0x00003774, 0x00001826, 0x0000078C, 
        0x000020BB, 0x00005473, 0x000068B6, 0x000027FB, 0x00007321, 0x00001B0E, 0x00006280, 0x000054E2, 
        0x00005133, 0x000061E7, 0x00002F6B, 0x00005AE2, 0x00001B09, 0x000064BB, 0x0000071B, 0x00006272, 
        0x0000453F, 0x000022BD, 0x00000D68, 0x000052A9, 0x00003116, 0x000019AD, 0x000028F6, 0x0000141E, 
        0x00006B10, 0x000032AC, 0x00002394, 0x0000353D, 0x00006A40, 0x00000697, 0x0000080E, 0x00006883, 
        0x00004297, 0x0000175D, 0x00000B3A, 0x00004584, 0x00004FB8, 0x000055D2, 0x00002592, 0x00005F99, 
        0x00005986, 0x00005A84, 0x000071A3, 0x00003975, 0x00000525, 0x00003E15, 0x00000823, 0x000012D7, 
        0x000078EF, 0x0000636B, 0x0000471A, 0x0000531C, 0x000023F8, 0x000038D7, 0x00007E64, 0x000018DB, 
        0x0000344E, 0x00005655, 0x00001C69, 0x00000EE8, 0x0000023C, 0x000025C8, 0x00000684, 0x0000776D, 
        0x00000B65, 0x00007855, 0x0000602D, 0x0000277E, 0x000060AC, 0x00001885, 0x00006E40, 0x00003EEC, 
        0x0000175C, 0x00000D2B, 0x00004F2E, 0x00000645, 0x00006C70, 0x0000457D, 0x00005CD8, 0x00002B12, 
        0x0000011C, 0x00007AAD, 0x00002E5E, 0x000037CB, 0x00005CF8, 0x00005C48, 0x0000648F, 0x00003841, 
        0x00006344, 0x00007F63, 0x000005C2, 0x00000BE2, 0x0000717A, 0x00007317, 0x0000711A, 0x00004344, 
        0x00000319, 0x0000756E, 0x00002F5E, 0x00006EF2, 0x000023B0, 0x00001ED5, 0x00005A1B, 0x00005FFF, 
        0x00007494, 0x00005C4C, 0x00007D2C, 0x00002C51, 0x00004BE4, 0x00005197, 0x00002384, 0x000064DD, 
        0x000062E9, 0x00005019, 0x0000447E, 0x00001DA1, 0x000070B3, 0x00005B03, 0x000017BC, 0x00004ED4, 
        0x00003E1F, 0x000026F8, 0x00002AF2, 0x00007B64, 0x00004634, 0x000069D9, 0x0000075A, 0x0000344B, 
        0x000027D0, 0x00000C9C, 0x0000385E, 0x00002496, 0x00005635, 0x000057AA, 0x000044A8, 0x000062AF, 
        0x000065E7, 0x00003284, 0x00007A73, 0x00001CCF, 0x000025F4, 0x00005DCD, 0x00005CDE, 0x0000109B, 
        0x00007890, 0x000045CF, 0x00005FEF, 0x00004ABB, 0x00000026, 0x0000047D, 0x00006121, 0x00003A42, 
        0x00005519, 0x000032AF, 0x00002096, 0x000018E7, 0x00004181, 0x00001FB2, 0x00000000, 0x00000000
    };

    // 定义网格范围:x,y ∈ [0,11], z ∈ [0,2]
    const int GRID_SIZE = 12;
    const int Z_LEVELS = 3;
    
    // 访问标记和前驱记录
    bool visited[GRID_SIZE][GRID_SIZE][Z_LEVELS] = {false};
    std::tuple<int, int, int> prev[GRID_SIZE][GRID_SIZE][Z_LEVELS];
    
    // 6个移动方向 (dx, dy, dz)
    const int directions[6][3] = {
        {1, 0, 0}, {-1, 0, 0}, 
        {0, 1, 0}, {0, -1, 0},
        {0, 0, 1}, {0, 0, -1}
    };
    
    // BFS队列
    std::queue<std::tuple<int, int, int>> q;
    
    // 步骤1: 遍历整个网格,寻找所有值为0x2C0E的点作为起点
    bool found_start = false;
    for (int z = 0; z < Z_LEVELS; ++z) {
        for (int y = 0; y < GRID_SIZE; ++y) {
            for (int x = 0; x < GRID_SIZE; ++x) {
                int index = 90 * z + 10 * y + x;
                if (index >= 272) continue;  // 超出数组范围
                
                // 检查值是否为0x2C0E (11278)
                if (dword_703020[index] == 0x2C0E) {
                    if (!visited[x][y][z]) {
                        visited[x][y][z] = true;
                        // 使用(-1,-1,-1)表示起点,避免与(0,0,0)混淆
                        prev[x][y][z] = std::make_tuple(-1, -1, -1);
                        q.push(std::make_tuple(x, y, z));
                        found_start = true;
                    }
                }
            }
        }
    }
    
    // 无有效起点
    if (!found_start) {
        printf("No valid starting point found. Checking grid...\n");
        // 调试:打印所有值为0x2C0E的点
        for (int z = 0; z < Z_LEVELS; ++z) {
            for (int y = 0; y < GRID_SIZE; ++y) {
                for (int x = 0; x < GRID_SIZE; ++x) {
                    int index = 90 * z + 10 * y + x;
                    if (index < 272 && dword_703020[index] == 0x2C0E) {
                        printf("Found start point at (x=%d, y=%d, z=%d) index=%d\n", x, y, z, index);
                    }
                }
            }
        }
        return 1;
    }

    // 步骤2: BFS搜索路径
    while (!q.empty()) {
        // 获取队首元素
        std::tuple<int, int, int> point = q.front();
        q.pop();
        
        // 提取坐标
        int x = std::get<0>(point);
        int y = std::get<1>(point);
        int z = std::get<2>(point);
        
        // 检查6个邻居
        for (int i = 0; i < 6; ++i) {
            int nx = x + directions[i][0];
            int ny = y + directions[i][1];
            int nz = z + directions[i][2];
            
            // 检查邻居是否在网格内
            if (nx < 0 || nx >= GRID_SIZE || ny < 0 || ny >= GRID_SIZE || nz < 0 || nz >= Z_LEVELS)
                continue;
            
            // 计算邻居的数组索引
            int index = 90 * nz + 10 * ny + nx;
            if (index >= 272) continue;  // 超出数组范围
            
            unsigned int value = dword_703020[index];
            
            // 情况1: 找到终点(值必须为0x1FB2)
            if (value == 0x1FB2) {
                // 回溯路径(从终点到第一个点)
                std::vector<std::tuple<int, int, int>> path;
                path.push_back(std::make_tuple(nx, ny, nz));  // 终点
                
                // 回溯:当前点 -> 第一个点
                std::tuple<int, int, int> cur = std::make_tuple(x, y, z);
                while (true) {
                    path.push_back(cur);
                    int cx = std::get<0>(cur);
                    int cy = std::get<1>(cur);
                    int cz = std::get<2>(cur);
                    
                    // 检查是否到达起点
                    std::tuple<int, int, int> next = prev[cx][cy][cz];
                    if (std::get<0>(next) == -1 && std::get<1>(next) == -1 && std::get<2>(next) == -1) {
                        break;
                    }
                    
                    cur = next;
                }
                
                // 反转路径:第一个点 -> 终点
                std::reverse(path.begin(), path.end());
                
                // 构建字符串:模拟test函数的字符查找逻辑
                char result[1000] = {0};  // 足够大的缓冲区
                int pos = 0;
                
                for (size_t i = 0; i < path.size(); ++i) {
                    int px = std::get<0>(path[i]);
                    int py = std::get<1>(path[i]);
                    int pz = std::get<2>(path[i]);
                    
                    // 1. 处理 y_char (偶数位置)
                    int target_char_y = arr_0toz[py];
                    int y_index = 0;
                    while (true) {
                        if (arr_0toz[y_index] == target_char_y) break;
                        if (arr_0toz[y_index + 1] == target_char_y) { y_index++; break; }
                        if (arr_0toz[y_index + 2] == target_char_y) { y_index += 2; break; }
                        if (arr_0toz[y_index + 3] == target_char_y) { y_index += 3; break; }
                        if (arr_0toz[y_index + 4] == target_char_y) { y_index += 4; break; }
                        if (arr_0toz[y_index + 5] == target_char_y) { y_index += 5; break; }
                        y_index += 6;
                        if (y_index >= 36) {
                            printf("Error: y_char not found in arr_0toz\n");
                            return 1;
                        }
                    }
                    result[pos++] = arr_0toz[y_index];
                    
                    // 2. 处理 x_char (奇数位置)
                    int target_char_x = arr_0toz[px + 12 * pz];
                    int x_index = 0;
                    while (true) {
                        if (arr_0toz[x_index] == target_char_x) break;
                        if (arr_0toz[x_index + 1] == target_char_x) { x_index++; break; }
                        if (arr_0toz[x_index + 2] == target_char_x) { x_index += 2; break; }
                        if (arr_0toz[x_index + 3] == target_char_x) { x_index += 3; break; }
                        if (arr_0toz[x_index + 4] == target_char_x) { x_index += 4; break; }
                        if (arr_0toz[x_index + 5] == target_char_x) { x_index += 5; break; }
                        x_index += 6;
                        if (x_index >= 36) {
                            printf("Error: x_char not found in arr_0toz\n");
                            return 1;
                        }
                    }
                    result[pos++] = arr_0toz[x_index];
                }
                result[pos] = '\0';
                
                // 验证并输出
                printf("Found valid string: %s\n", result);
                
                // 详细调试信息
                printf("Path details:\n");
                for (size_t i = 0; i < path.size(); ++i) {
                    int px = std::get<0>(path[i]);
                    int py = std::get<1>(path[i]);
                    int pz = std::get<2>(path[i]);
                    int index = 90 * pz + 10 * py + px;
                    unsigned int value = (index < 272) ? dword_703020[index] : 0xFFFFFFFF;
                    
                    printf("  Point %zu: (x=%d, y=%d, z=%d) index=%d value=0x%04X", 
                           i, px, py, pz, index, value);
                    
                    if (i > 0) {
                        int prev_x = std::get<0>(path[i-1]);
                        int prev_y = std::get<1>(path[i-1]);
                        int prev_z = std::get<2>(path[i-1]);
                        int dist = abs(px - prev_x) + abs(py - prev_y) + abs(pz - prev_z);
                        printf(" dist=%d", dist);
                    }
                    
                    if (i == 0) {
                        printf(" (start)");
                    } else if (i == path.size() - 1) {
                        printf(" (end)");
                    } else {
                        int p_val, q_val;
                        if (semiprime_factorize((int)value, &p_val, &q_val) && p_val != q_val) {
                            printf(" semi-prime: %d*%d", p_val, q_val);
                        } else {
                            printf(" NOT semi-prime");
                        }
                    }
                    printf("\n");
                }
                
                if (test(result)) {
                    printf("Verification passed.\n");
                    return 0;
                } else {
                    printf("Verification failed.\n");
                }
            }
            
            // 情况2: 检查中间点(必须是半质数)
            if (value < 4) continue;  // 半质数要求至少4
            
            int p_val, q_val;
            if (semiprime_factorize((int)value, &p_val, &q_val) && p_val != q_val) {
                // 未访问则加入队列
                if (!visited[nx][ny][nz]) {
                    visited[nx][ny][nz] = true;
                    prev[nx][ny][nz] = std::make_tuple(x, y, z);
                    q.push(std::make_tuple(nx, ny, nz));
                }
            }
        }
    }
    
    printf("No valid path found.\n");
    return 1;
}

// 以下为已有函数实现(保持不变)
double __cdecl square_root(double a1)
{
    double result; // st7
    int v2; // ecx
    double v3; // st5
    double v4; // st1
    double v5; // st2
    double v6; // rt2
    double v7; // st2
    double v8; // st5
    double v9; // st1
    bool v10; // c0
    bool v11; // c3
    double v12; // st1
    double v13; // st2
    double v14; // rt1
    double v15; // st2
    double v16; // st5
    double v17; // st1
    bool v18; // c0
    bool v19; // c3
    double v20; // st1
    double v21; // st2
    double v22; // rt0
    double v23; // st2
    double v24; // st5
    double v25; // st1
    bool v26; // c0
    bool v27; // c3
    double v28; // st1
    double v29; // st2
    double v30; // rtt
    double v31; // st2
    double v32; // st5
    double v33; // st1
    bool v34; // c0
    bool v35; // c3
    double v36; // st1
    double v37; // st2
    double v38; // rt2
    double v39; // st2
    double v40; // st5
    double v41; // st1
    bool v42; // c0
    bool v43; // c3

    result = 0.0;
    if (a1 > 0.0)
    {
        if (1.0 == a1)
        {
            return 1.0;
        }
        else
        {
            v2 = 0;
            v3 = a1 * 0.5;
            do
            {
                v4 = (v3 + a1 / v3) * 0.5;
                v5 = v4 - v3;
                if (v5 < 0.0)
                    v5 = -v5;
                v6 = v5;
                v7 = v4;
                v8 = v6;
                if (v4 < 0.0)
                    v4 = -v4;
                v9 = v4 * 0.0000001;
                v10 = v9 < v8;
                v11 = v9 == v8;
                v3 = v7;
                if (!v10 && !v11)
                    break;
                v12 = (v7 + a1 / v7) * 0.5;
                v13 = v12 - v7;
                if (v13 < 0.0)
                    v13 = -v13;
                v14 = v13;
                v15 = v12;
                v16 = v14;
                if (v12 < 0.0)
                    v12 = -v12;
                v17 = v12 * 0.0000001;
                v18 = v17 < v16;
                v19 = v17 == v16;
                v3 = v15;
                if (!v18 && !v19)
                    break;
                v20 = (v15 + a1 / v15) * 0.5;
                v21 = v20 - v15;
                if (v21 < 0.0)
                    v21 = -v21;
                v22 = v21;
                v23 = v20;
                v24 = v22;
                if (v20 < 0.0)
                    v20 = -v20;
                v25 = v20 * 0.0000001;
                v26 = v25 < v24;
                v27 = v25 == v24;
                v3 = v23;
                if (!v26 && !v27)
                    break;
                v28 = (v23 + a1 / v23) * 0.5;
                v29 = v28 - v23;
                if (v29 < 0.0)
                    v29 = -v29;
                v30 = v29;
                v31 = v28;
                v32 = v30;
                if (v28 < 0.0)
                    v28 = -v28;
                v33 = v28 * 0.0000001;
                v34 = v33 < v32;
                v35 = v33 == v32;
                v3 = v31;
                if (!v34 && !v35)
                    break;
                v36 = (v31 + a1 / v31) * 0.5;
                v37 = v36 - v31;
                if (v37 < 0.0)
                    v37 = -v37;
                v38 = v37;
                v39 = v36;
                v40 = v38;
                if (v36 < 0.0)
                    v36 = -v36;
                v41 = v36 * 0.0000001;
                v42 = v41 < v40;
                v43 = v41 == v40;
                v3 = v39;
                if (!v42 && !v43)
                    break;
                v2 += 5;
            } while (v2 < 50);
            return v3;
        }
    }
    return result;
}

char __cdecl is_prime(int a1)
{
  int v2; // esi
  int v3; // ecx

  if ( a1 < 2 )
    return 0;
  v2 = 2;
  v3 = (int)square_root((double)a1);
  if ( v3 >= 2 )
  {
    while ( a1 % v2 )
    {
      if ( ++v2 > v3 )
        return 1;
    }
    return 0;
  }
  return 1;
}

char __cdecl semiprime_factorize(int n, int* p, int* q)
{
    int v4; // edi
    int v5; // ecx
    int v6; // esi
    int v7; // ecx
    int v9; // [esp+1Ch] [ebp-4h]
    int na; // [esp+24h] [ebp+4h]

    if (n < 4)
        return 0;
    v4 = 2;
    v9 = 2;
    v5 = (int)square_root((double)n);
    na = v5;
    if (v5 < 2)
        return 0;
    while (1)
    {
        if (n % v4 || v4 < 2)
            goto LABEL_10;
        v6 = 2;
        v7 = (int)square_root((double)v9);
        if (v7 >= 2)
        {
            while (v4 % v6)
            {
                if (++v6 > v7)
                    goto LABEL_8;
            }
            goto LABEL_9;
        }
    LABEL_8:
        if (is_prime(n / v4))
            break;
    LABEL_9:
        v5 = na;
    LABEL_10:
        v9 = ++v4;
        if (v4 > v5)
            return 0;
    }
    if (p)
        *p = v4;
    if (q)
        *q = n / v4;
    return 1;
}

char __cdecl test(const char* str_input)
{
    const char* p; // esi
    int len; // edi
    int index; // ecx
    int v4; // edx
    int y; // ebx
    char chr; // al
    int z; // esi
    int v9; // ecx
    int v10; // edx
    int x; // edi
    int v12; // ecx
    int v13; // [esp+10h] [ebp-20h]
    int len2; // [esp+14h] [ebp-1Ch]
    int v15; // [esp+18h] [ebp-18h]
    int x_last; // [esp+1Ch] [ebp-14h]
    int y_last; // [esp+20h] [ebp-10h]
    int z_last; // [esp+24h] [ebp-Ch]
    int v19; // [esp+28h] [ebp-8h] BYREF
    int v20; // [esp+2Ch] [ebp-4h] BYREF
    unsigned char arr_0toz[40] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 
        0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 
        0x77, 0x78, 0x79, 0x7A, 0x00, 0x00, 0x00, 0x00
    };
    unsigned int dword_703020[272] = {
        0x00002C0E, 0x00001312, 0x00007F44, 0x00004C2B, 0x00000966, 0x00001E12, 0x00001263, 0x00001828, 
        0x000031A1, 0x000052AE, 0x00001DC6, 0x00004019, 0x00003D89, 0x0000614D, 0x00001A4A, 0x00003A24, 
        0x00005406, 0x00000E61, 0x00000658, 0x00000D4C, 0x00005423, 0x00004860, 0x00007988, 0x00001FA3, 
        0x0000705B, 0x00004464, 0x000063EF, 0x0000403E, 0x000050CB, 0x00001676, 0x00005132, 0x000068B5, 
        0x00004A38, 0x00006FF5, 0x0000189B, 0x0000170B, 0x00002704, 0x000020ED, 0x00004938, 0x000047F6, 
        0x00007512, 0x00005196, 0x00002B7C, 0x00004A50, 0x00002E54, 0x00006FBE, 0x00003532, 0x00007B54, 
        0x00000ABD, 0x00002889, 0x000056C0, 0x0000323B, 0x00003698, 0x000031CF, 0x0000435A, 0x000075FA, 
        0x00000A2B, 0x0000200B, 0x000045ED, 0x0000163F, 0x00002554, 0x000062BB, 0x00003393, 0x00002A31, 
        0x00002956, 0x00003004, 0x00003684, 0x00003DEE, 0x000047AC, 0x00002267, 0x0000629E, 0x00001E93, 
        0x00007943, 0x0000661B, 0x00007FB4, 0x0000255A, 0x00003D37, 0x00001804, 0x000069E1, 0x0000312C, 
        0x00003999, 0x0000293F, 0x00002F0E, 0x0000743A, 0x00000117, 0x000064CD, 0x00007C76, 0x00005CBF, 
        0x00006AB0, 0x00000585, 0x00006CFC, 0x00003CE6, 0x00006FAB, 0x00000F81, 0x0000511C, 0x000024E4, 
        0x00000785, 0x00005AEB, 0x00002977, 0x00000BFB, 0x000055F8, 0x00000039, 0x000029DD, 0x00004987, 
        0x0000133B, 0x00005E2F, 0x00007F4D, 0x00006497, 0x000062C2, 0x00003774, 0x00001826, 0x0000078C, 
        0x000020BB, 0x00005473, 0x000068B6, 0x000027FB, 0x00007321, 0x00001B0E, 0x00006280, 0x000054E2, 
        0x00005133, 0x000061E7, 0x00002F6B, 0x00005AE2, 0x00001B09, 0x000064BB, 0x0000071B, 0x00006272, 
        0x0000453F, 0x000022BD, 0x00000D68, 0x000052A9, 0x00003116, 0x000019AD, 0x000028F6, 0x0000141E, 
        0x00006B10, 0x000032AC, 0x00002394, 0x0000353D, 0x00006A40, 0x00000697, 0x0000080E, 0x00006883, 
        0x00004297, 0x0000175D, 0x00000B3A, 0x00004584, 0x00004FB8, 0x000055D2, 0x00002592, 0x00005F99, 
        0x00005986, 0x00005A84, 0x000071A3, 0x00003975, 0x00000525, 0x00003E15, 0x00000823, 0x000012D7, 
        0x000078EF, 0x0000636B, 0x0000471A, 0x0000531C, 0x000023F8, 0x000038D7, 0x00007E64, 0x000018DB, 
        0x0000344E, 0x00005655, 0x00001C69, 0x00000EE8, 0x0000023C, 0x000025C8, 0x00000684, 0x0000776D, 
        0x00000B65, 0x00007855, 0x0000602D, 0x0000277E, 0x000060AC, 0x00001885, 0x00006E40, 0x00003EEC, 
        0x0000175C, 0x00000D2B, 0x00004F2E, 0x00000645, 0x00006C70, 0x0000457D, 0x00005CD8, 0x00002B12, 
        0x0000011C, 0x00007AAD, 0x00002E5E, 0x000037CB, 0x00005CF8, 0x00005C48, 0x0000648F, 0x00003841, 
        0x00006344, 0x00007F63, 0x000005C2, 0x00000BE2, 0x0000717A, 0x00007317, 0x0000711A, 0x00004344, 
        0x00000319, 0x0000756E, 0x00002F5E, 0x00006EF2, 0x000023B0, 0x00001ED5, 0x00005A1B, 0x00005FFF, 
        0x00007494, 0x00005C4C, 0x00007D2C, 0x00002C51, 0x00004BE4, 0x00005197, 0x00002384, 0x000064DD, 
        0x000062E9, 0x00005019, 0x0000447E, 0x00001DA1, 0x000070B3, 0x00005B03, 0x000017BC, 0x00004ED4, 
        0x00003E1F, 0x000026F8, 0x00002AF2, 0x00007B64, 0x00004634, 0x000069D9, 0x0000075A, 0x0000344B, 
        0x000027D0, 0x00000C9C, 0x0000385E, 0x00002496, 0x00005635, 0x000057AA, 0x000044A8, 0x000062AF, 
        0x000065E7, 0x00003284, 0x00007A73, 0x00001CCF, 0x000025F4, 0x00005DCD, 0x00005CDE, 0x0000109B, 
        0x00007890, 0x000045CF, 0x00005FEF, 0x00004ABB, 0x00000026, 0x0000047D, 0x00006121, 0x00003A42, 
        0x00005519, 0x000032AF, 0x00002096, 0x000018E7, 0x00004181, 0x00001FB2, 0x00000000, 0x00000000
    };

    p = str_input;
    if (str_input)
    {
        len = strlen(str_input);
        index = 0;
        v4 = 0;
        y = 0;
        len2 = len;
        z_last = 0;
        y_last = 0;
        x_last = 0;
        v15 = 0;
        v13 = 0;
        if (len > 0)
        {
            while (1)
            {
                chr = p[v4];
                while (arr_0toz[index] != chr)
                {
                    if (arr_0toz[index + 1] == chr)
                    {
                        ++index;
                        break;
                    }
                    if (arr_0toz[index + 2] == chr)
                    {
                        index += 2;
                        break;
                    }
                    if (arr_0toz[index + 3] == chr)
                    {
                        index += 3;
                        break;
                    }
                    if (arr_0toz[index + 4] == chr)
                    {
                        index += 4;
                        break;
                    }
                    if (arr_0toz[index + 5] == chr)
                    {
                        index += 5;
                        break;
                    }
                    index += 6;
                    if (index >= 36)
                        return 0;
                }
                if (index >= 36)
                    break;
                if (index >= 12)
                    z = (index >= 24) + 1;
                else
                    z = 0;
                if ((v4 & 1) != 0)
                {
                    v10 = v15 + 1;
                    x = index % 12;
                    v15 = v10;
                    if (v10 == 1 && dword_703020[80 * z + 10 * z + 10 * y + x] != 0x2C0E)
                        return 0;
                    v9 = v13;
                    if (v13 == len2 - 1 && dword_703020[80 * z + 10 * z + 10 * y + x] != 0x1FB2)
                        return 0;
                    if (v10 > 1)
                    {
                        if (v13 < len2
                            && (!semiprime_factorize(dword_703020[80 * z + 10 * z + 10 * y + x], &v19, &v20)
                                || v19 < 2
                                || v20 < 2
                                || v19 == v20)
                            || abs(x - x_last) + abs(y - y_last) + abs(z - z_last) != 1)
                        {
                            return 0;
                        }
                        v9 = v13;
                    }
                    x_last = x;
                    y_last = y;
                    z_last = z;
                    if (v9 == len2 - 1 && dword_703020[80 * z + 10 * z + 10 * y + x] == 0x1FB2)
                        return 1;
                    len = len2;
                }
                else
                {
                    y = index % 12;
                    v9 = v13;
                }
                v12 = v9 + 1;
                v13 = v12;
                if (v12 >= len)
                    return 0;
                p = str_input;
                v4 = v12;
                index = 0;
            }
        }
    }
    return 0;
}
Found valid string: 0001111d1e1f2f3f3e3d4d5d5e5f53637372717d7c8c8o8p8q8r8s7s6s6g6h6i6j6757565545353h3i3j2j1j1k1w2w2x3x4x5x5w6w7w8w8x
Path details:
  Point 0: (x=0, y=0, z=0) index=0 value=0x2C0E (start)
  Point 1: (x=1, y=0, z=0) index=1 value=0x1312 dist=1 semi-prime: 2*2441
  Point 2: (x=1, y=1, z=0) index=11 value=0x4019 dist=1 semi-prime: 61*269
  Point 3: (x=1, y=1, z=1) index=101 value=0x0039 dist=1 semi-prime: 3*19
  Point 4: (x=2, y=1, z=1) index=102 value=0x29DD dist=1 semi-prime: 7*1531
  Point 5: (x=3, y=1, z=1) index=103 value=0x4987 dist=1 semi-prime: 7*2689
  Point 6: (x=3, y=2, z=1) index=113 value=0x5473 dist=1 semi-prime: 13*1663
  Point 7: (x=3, y=3, z=1) index=123 value=0x5AE2 dist=1 semi-prime: 2*11633
  Point 8: (x=2, y=3, z=1) index=122 value=0x2F6B dist=1 semi-prime: 61*199
  Point 9: (x=1, y=3, z=1) index=121 value=0x61E7 dist=1 semi-prime: 71*353
  Point 10: (x=1, y=4, z=1) index=131 value=0x52A9 dist=1 semi-prime: 7*3023
  Point 11: (x=1, y=5, z=1) index=141 value=0x0697 dist=1 semi-prime: 7*241
  Point 12: (x=2, y=5, z=1) index=142 value=0x080E dist=1 semi-prime: 2*1031
  Point 13: (x=3, y=5, z=1) index=143 value=0x6883 dist=1 semi-prime: 5*5351
  Point 14: (x=3, y=5, z=0) index=53 value=0x31CF dist=1 semi-prime: 41*311
  Point 15: (x=3, y=6, z=0) index=63 value=0x2A31 dist=1 semi-prime: 7*1543
  Point 16: (x=3, y=7, z=0) index=73 value=0x661B dist=1 semi-prime: 3*8713
  Point 17: (x=2, y=7, z=0) index=72 value=0x7943 dist=1 semi-prime: 37*839
  Point 18: (x=1, y=7, z=0) index=71 value=0x1E93 dist=1 semi-prime: 3*2609
  Point 19: (x=1, y=7, z=1) index=161 value=0x636B dist=1 semi-prime: 31*821
  Point 20: (x=0, y=7, z=1) index=160 value=0x78EF dist=1 semi-prime: 83*373
  Point 21: (x=0, y=8, z=1) index=170 value=0x1C69 dist=1 semi-prime: 7*1039
  Point 22: (x=0, y=8, z=2) index=260 value=0x0026 dist=1 semi-prime: 2*19
  Point 23: (x=1, y=8, z=2) index=261 value=0x047D dist=1 semi-prime: 3*383
  Point 24: (x=2, y=8, z=2) index=262 value=0x6121 dist=1 semi-prime: 5*4973
  Point 25: (x=3, y=8, z=2) index=263 value=0x3A42 dist=1 semi-prime: 2*7457
  Point 26: (x=4, y=8, z=2) index=264 value=0x5519 dist=1 semi-prime: 5*4357
  Point 27: (x=4, y=7, z=2) index=254 value=0x5CDE dist=1 semi-prime: 2*11887
  Point 28: (x=4, y=6, z=2) index=244 value=0x5635 dist=1 semi-prime: 29*761
  Point 29: (x=4, y=6, z=1) index=154 value=0x71A3 dist=1 semi-prime: 3*9697
  Point 30: (x=5, y=6, z=1) index=155 value=0x3975 dist=1 semi-prime: 3*4903
  Point 31: (x=6, y=6, z=1) index=156 value=0x0525 dist=1 semi-prime: 3*439
  Point 32: (x=7, y=6, z=1) index=157 value=0x3E15 dist=1 semi-prime: 23*691
  Point 33: (x=7, y=6, z=0) index=67 value=0x3DEE dist=1 semi-prime: 2*7927
  Point 34: (x=7, y=5, z=0) index=57 value=0x200B dist=1 semi-prime: 13*631
  Point 35: (x=6, y=5, z=0) index=56 value=0x0A2B dist=1 semi-prime: 19*137
  Point 36: (x=5, y=5, z=0) index=55 value=0x75FA dist=1 semi-prime: 2*15101
  Point 37: (x=5, y=4, z=0) index=45 value=0x6FBE dist=1 semi-prime: 2*14303
  Point 38: (x=5, y=3, z=0) index=35 value=0x170B dist=1 semi-prime: 17*347
  Point 39: (x=5, y=3, z=1) index=125 value=0x64BB dist=1 semi-prime: 107*241
  Point 40: (x=6, y=3, z=1) index=126 value=0x071B dist=1 semi-prime: 17*107
  Point 41: (x=7, y=3, z=1) index=127 value=0x6272 dist=1 semi-prime: 2*12601
  Point 42: (x=7, y=2, z=1) index=117 value=0x1B0E dist=1 semi-prime: 2*3463
  Point 43: (x=7, y=1, z=1) index=107 value=0x6497 dist=1 semi-prime: 11*2341
  Point 44: (x=8, y=1, z=1) index=108 value=0x62C2 dist=1 semi-prime: 2*12641
  Point 45: (x=8, y=1, z=2) index=198 value=0x648F dist=1 semi-prime: 3*8581
  Point 46: (x=8, y=2, z=2) index=208 value=0x0319 dist=1 semi-prime: 13*61
  Point 47: (x=9, y=2, z=2) index=209 value=0x756E dist=1 semi-prime: 2*15031
  Point 48: (x=9, y=3, z=2) index=219 value=0x2C51 dist=1 semi-prime: 5*2269
  Point 49: (x=9, y=4, z=2) index=229 value=0x5B03 dist=1 semi-prime: 23*1013
  Point 50: (x=9, y=5, z=2) index=239 value=0x344B dist=1 semi-prime: 11*1217
  Point 51: (x=8, y=5, z=2) index=238 value=0x075A dist=1 semi-prime: 2*941
  Point 52: (x=8, y=6, z=2) index=248 value=0x65E7 dist=1 semi-prime: 19*1373
  Point 53: (x=8, y=7, z=2) index=258 value=0x5FEF dist=1 semi-prime: 41*599
  Point 54: (x=8, y=8, z=2) index=268 value=0x4181 dist=1 semi-prime: 41*409
  Point 55: (x=9, y=8, z=2) index=269 value=0x1FB2 dist=1 (end)
Verification passed.
  • 起点:值为0x2C0E的任意点
  • 终点:值为0x1FB2的点
  • 路径约束:
    • 路径上所有点(除起点外)的值必须是半质数
    • 相邻点曼哈顿距离必须为1

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

最后于 2025-8-17 14:57 被mb_ytlbasky编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回