题目:菜鸡学逆向学得头皮发麻,终于它拿到了一段源代码
分析:考验的是代码的分析能力
难度系数: 3.0
源码为:
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { if (argc != 4) { printf("what? "); exit(1); } unsigned int first = atoi(argv[1]); if (first != 0xcafe) { printf("you are wrong, sorry. "); exit(2); } unsigned int second = atoi(argv[2]); if (second % 5 == 3 || second % 17 != 8) { printf("ha, you won't get it! "); exit(3); } if (strcmp("h4cky0u", argv[3])) { printf("so close, dude! "); exit(4); } printf("Brr wrrr grr "); unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207; printf("Get your key: "); printf("%x ", hash); return 0; }
分部分来看
第一部分:
if (argc != 4) { printf("what? "); exit(1); }
如果argc不等于 4,就退出,那其实就是告诉我们argc = 4
第二部分:
unsigned int first = atoi(argv[1]); if (first != 0xcafe) { printf("you are wrong, sorry. "); exit(2); }
atoi (表示 ascii to integer)是把字符串转换成整型数的一个函数,也就是说first接收了一个数
同上,若first不等于0xcafe就退出,所以first = 0xcafe
第三部分:
unsigned int second = atoi(argv[2]); if (second % 5 == 3 || second % 17 != 8) { printf("ha, you won't get it! "); exit(3); }
重点在 若 second % 5 == 3 或 second % 17 != 8 任意一个成立则退出,所以second % 17 == 8 ,首先想到的就是25
第四部分:
if (strcmp("h4cky0u", argv[3])) { printf("so close, dude! "); exit(4); }
strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。
这里就是告诉我们 argv[3] = "h4cky0u"
第五部分(划重点):
unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;
这里是计算后得出flag的算式 ,可以看到这里有三个未知数,我们只要把刚才得出的数替换上就好了(替换的数字已标红)
unsigned int hash = 0xcafe * 31337 + (25 % 17) * 11 + strlen("h4cky0u") - 1615810207;
但是这里没有用到argc =4 ,看另外一个大佬的WP中的解释是:argc=4 的意思是必须满足输入4个参数(文件名本身也算一个参数)即: 文件名.exe(参数0) 参数1 参数2 参数3 ,在命令行运行a.exe 51966 25 h4cky0u 即可,算是另一种方法。
最后程序将计算结果转为16进制得到flag
这里想补充另外一个大佬的做法,他为了防止溢出最后是用Python算出的答案。觉得以后可以多想一点。