-
-
[原创]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编辑
,原因:
赞赏
他的文章
赞赏
雪币:
留言: