新手一枚,如有错误(不足)请指正,谢谢!!
<mark>个人博客:点击进入</mark>
题目的git仓库链接:点击进入
题目分析:
IDA载入,
shift+F12查找字符串
双击跟随到其所在的内存地址,摁’x’键交叉引用,找到调用此字符串的指令,来到关键代码。
F5查看伪代码
先分析sub_4014DC(v2)函数,双击进入分析
再分析sub_40156A(v2, &unk_405020)函数
查看一下内存中存储的数据
发现是每四个字节有一个数据,所以改一下数据类型更方便查看
将他声明成一个数组,之后就好看多了
也就是每次的*4是乘以的类型长度。数组的类型长度为4字节,也就是int……
看一下sub_4017D1(&unk_405020)函数,由三个函数组成
sub_40173A(a1)函数
大致功能为将内存中数据看做9*9的矩阵,遍历每行,检测每行是不是都含有1~9这9个数。
sub_4016A3(a1)函数:检测每列是不是含有1~9这九个数
sub_4015C9(a1)函数,有点难看。
将代码拷贝下来,自己添加一个长度为81的数组,写一个输出遍历元素的代码,看看遍历的规律。
可以看到他将81个元素分成了9个小方块,检测每个小方块里是不是都含有1~9
代码
#include <stdio.h>
int main()
{
int a1[81] = { 0,1,2,3,4,5,6,7,8,
9,10,11,12,13,14,15,16,17,
18,19,20,21,22,23,24,25,26,
27,28,29,30,31,32,33,34,35,
36,37,38,39,40,41,42,43,44,
45,46,47,48,49,50,51,52,53,
54,55,56,57,58,59,60,61,62,
63,64,65,66,67,68,69,70,71,
72,73,74,75,76,77,78,79,80 };
int result;
int l; // [esp+28h] [ebp-20h]
int v4; // [esp+2Ch] [ebp-1Ch]
int v5; // [esp+30h] [ebp-18h]
int k; // [esp+34h] [ebp-14h]
int j; // [esp+38h] [ebp-10h]
int i; // [esp+3Ch] [ebp-Ch]
v5 = 0;
v4 = 0;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
printf("%d\t", a1[i * 9 +j]);
printf("\n");
}
printf("\n");
for (i = 0; i <= 8; ++i)
{
for (j = v5; ; ++j)
{
result = v5 + 2;
if (j > v5 + 2)
break;
for (k = v4; k <= v4 + 2; ++k)
printf("%d ", a1[j * 9 + k]); // 变量j控制行,k控制列
}
printf("\n");
if (v4 == 6)
{
v5 += 3;
v4 = 0;
}
else
{
v4 += 3;
}
}
}
这样对函数的功能就分析透彻了
结合题目game,这正好是数独游戏的规则呀
程序流程:
将用户输入的从’a’到’j’的字符转换为1到10,
然后遍历内存中的数据,如果内存中的数据为0,则将用户输入的字符填上去一个。
填完后,满足数独游戏的规则。
开始解题:
先将内存里的数据提取出来
搜索一个解数独游戏的在线网站,填入数据
将填入的数字取出来,然后加上96转换为字符
得到最终的flag为flag{cgadcgifdfacdfibfg}