CatFly【难度:1】
题目界面
下载附件,发现是dll文件,放到linux中运行一下,运行界面如图所示:
从上图中可以看到两处字符串,上面的字符串不断滚动,下方字符串在次数上不断累加,猜测上方字符串与flag相关。
静态调试
-
打开IDA,找到main函数
方便分析,此处只粘贴关键部分代码(源代码的后半部分)
time(&timer); v13 = 1; v24 = 0LL; v23 = 0; v22 = 0; v12 = off_FA88; while ( v13 ) { if ( dword_E104 ) printf("x1B[H"); else printf("x1B[u"); for ( k = dword_E1EC; k 42 || m >= 0 ) { if ( m >= 0 && (unsigned int)k > 1) & 1) != 0 ) v18 = 1 - v18; s[128] = (__int64)",,>>&&&+++###==;;;,,"; v19 = asc_BFE3[v18 - 23 + k]; if ( !v19 ) v19 = 44; } if ( v25 ) { printf("%s", *((const char **)&unk_FCC0 + v19)); } else if ( v19 == v22 || !*((_QWORD *)&unk_FCC0 + v19) ) { printf("%s", off_FA88); } else { v22 = v19; printf("%s%s", *((const char **)&unk_FCC0 + v19), off_FA88); } } sub_65E2(1LL); } if ( dword_E100 ) { time(&time1); v11 = difftime(time1, timer); v10 = sub_6服务器托管网3FF((unsigned int)(int)v11); for ( n = (dword_E1FC - 29 - v10) / 2; n > 0; --n ) putchar(32); dword_E1E8 += printf("x1B[1;37mYou have nyaned for %d times!x1B[Jx1B[0m", (unsigned int)++dword_108E0); } v22 = 0; ++v23; if ( dword_104C4 && v23 == dword_104C4 ) sub_6471(); if ( !off_FA20[++v24] ) v24 = 0LL; usleep(1000 * v27); } return 0LL;
因为flag可能与屏幕上滚动的字符串有关,所以此处需要格外关注
printf
函数。从上述关键代码中,可以看到off_FA88最可能与flag有关,因为其他的printf函数打印的基本是一个确定的值。 -
查看目标的交叉引用路径
确定了off_FA88后,开始查找与其相关的函数。
-
第一处是469行中的对off_FA88的赋值操作
off_FA88的值是sub_6314()函数的返回值。
-
接下来进入sub_6314()函数
函数伪代码如下图所示:
其功能为:当a2!=18,a3≤4||a3>54时off_FA88不变(v12的值就是off_FA88),所以此处相当于是k=18(一次)且m∈(4,53)时会执行sub_6314函数,即循环执行50次。该函数的返回值是byte_104C8的地址,byte_104C8的值与dword_E120[a3-5],dword_E120[a3-5]的值又与sub_62B5()函数的返回值有关。这里还有个sub_62E3作为逻辑判断的条件。将此处逻辑进行还原,还原代码如下:
for (int i = 0; i
-
查看sub_62B5()函数
函数伪代码如下图所示:
可以看到该函数的返回值与dword_E1E8相关,查看dword_E1E8的交叉引用,可以看到只在main函数中有一次自增操作:
-
总结整个流程
-
-
还原关键汇编代码
此处使用大佬wp给的代码进行分析,基本都给了解析:
#include #include //在ida里面点开dword_E1E8会发现初始值为0x1106 int dword_E1E8 = 0x1106; //同理,ida里也能看到dword_E120的初始值 int dword_E120[50] = { 0x27fb, 0x27a4, 0x464e, 0x0e36, 0x7b70, 0x5e7a, 0x1a4a, 0x45c1, 0x2bdf, 0x23bd, 0x3a15, 0x5b83, 0x1e15, 0x5367, 0x50b8, 0x20ca, 0x41f5, 0x57d1, 0x7750, 0x2adf, 0x11f8, 0x09bb, 0x5724, 0x7374, 0x3ce6, 0x646e, 0x010c, 0x6e10, 0x64f4, 0x3263, 0x3137, 0x00b8, 0x229c, 0x7bcd, 0x73bd, 0x480c, 0x14db, 0x68b9, 0x5c8a, 0x1b61, 0x6c59, 0x5707, 0x09e6, 0x1fb9, 0x2ad3, 0x76d4, 0x3113, 0x7c7e, 0x11e0, 0x6c70 }; //原封不动抄下来就好了 int sub_62B5() { dword_E1E8 = 1103515245 * dword_E1E8 + 12345; return (dword_E1E8 >> 10) & 0x7FFF; } //这块是拿来算输出数字n需要多少个字符的。 //因为main函数中的dword_E1E8需要接收printf函数的返回值 //而printf函数的返回值是打印的字符长度 int llog(int n) { int a = 0; while (n /= 10)a++; return a; } //这个函数我没有特别放出来,反正这里也是照抄的 int sub_62E3(char a1) { int result; // rax if ((a1 &服务器托管网 0x7Fu) 0x20; else result = 0LL; return result; } int main() { //count代表那个不停自增的dword_108E0 int count = 0; while (1) { for (int i = 0; i
-
运行代码,得到flag
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 如何利用烛龙和谷歌插件优化CLS(累积布局偏移)
简介 CLS 衡量的是页面的整个生命周期内发生的每次意外布局偏移的最大突发性_布局偏移分数_。布局变化的发生是因为浏览器倾向于异步加载页面元素。更重要的是,您的页面上可能存在一些初始尺寸未知的媒体元素。这种组合意味着浏览器在加载完成之前无法确定单个元素将占用多…