1 拿到题目,用exeinfo查看文件信息
可以看到这个程序是64位的程序,并且是个ELF文件
2 先直接把程序丢到IDA中分析,选中main函数,按F5反编译查看伪C代码
main代码如下:int __cdecl main(int argc, const char **argv, const char **envp)
{
``char v3; // al
``__int64 v5; // [rsp+0h] [rbp-40h]
int i; // [rsp+4h] [rbp-3Ch]
``FILE *stream; // [rsp+8h] [rbp-38h]
char filename[8]; // [rsp+10h] [rbp-30h]
unsigned __int64 v9; // [rsp+28h] [rbp-18h]
v9 = __readfsqword(0x28u);
LODWORD(v5) = 0;
while ( (signed int)v5 < strlen(s) )
{
if ( v5 & 1 )
gv3 = 1;
else
v3 = -1;
*(&t + (signed int)v5 + 10) = s[(signed int)v5] + v3;
LODWORD(v5) = v5 + 1;
}
strcpy(filename, "/tmp/flag.txt");
stream = fopen(filename, "w");
fprintf(stream, "%s\n", u, v5);
for ( i = 0; i < strlen(&t); ++i )
{
fseek(stream, p[i], 0);
fputc(*(&t + p[i]), stream);
fseek(stream, 0LL, 0);
fprintf(stream, "%s\n", u);
}
fclose(stream);
remove(filename);
return 0;
}
3 先用Shift+F12查看字符串
点进去跟踪,用Ctrl+X查看调用或者对应的值,发现无效,(这个时候可以查看这个值附近是否出现了变量或者函数调用)
4 很显然,这题并不是一个脑残题,并没用将flag放在String中,这个时候就要对main函数进行分析了,搞清楚main函数中在做是什么
s 对应的值
t 对应的值
通过前面的判断知道,harifCTF{????????????????????????????????}一定是与flag有关的,那么这段循环,很有可能实在生成flag,并且flag的值与变量t有关,那么我可以有两种方法去做这题,
一,既然已经知道了,flag的生成原理,以及所需的值,那么我可以自己写按照这段代码,写脚本生成flag
二,既然知道了flag的值一定与t有关,那么我可以用动态调式的方法直接跟踪t变量,来查看t中存储的值
5 这里先讲第二种方法
之后把程序丢到ubuntu中用linux中动态调试
PS:上面的分析出了点问题,我们应该分析strlen(&t)中的变量t,因为后面的t可能被改变,不过,最好还是都验证一下
!!!不懂就查
fseek
函数名: fseek
功 能: 重定位流上的文件指针
用 法: int fseek(FILE *stream, long offset, int fromwhere);
描 述: 函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere为基准,偏移offset个字 节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
返回值: 成功,返回0,否则返回其他值。
fseek position the file position pointer for the file referenced by stream to the byte location calculated by offset.