深入浅出,知无不答,言无不尽,力求详尽
下载附件, 是后缀.c的c语言源码文件
vscode打开
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc != 4) {
printf("what?\n");
exit(1);
}
unsigned int first = atoi(argv[1]);
if (first != 0xcafe) {
printf("you are wrong, sorry.\n");
exit(2);
}
unsigned int second = atoi(argv[2]);
if (second % 5 == 3 || second % 17 != 8) {
printf("ha, you won't get it!\n");
exit(3);
}
if (strcmp("h4cky0u", argv[3])) {
printf("so close, dude!\n");
exit(4);
}
printf("Brr wrrr grr\n");
unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;
printf("Get your key: ");
printf("%x\n", hash);
return 0;
}
拖到clion里直接运行一下看看结果(如果你要用编程方法, 应该导入iostream标准库, 在clion里还要用cstdio和cstring, 要不然无法运行
就输出一个what?
———————————————————————————————————————————
本来想写代码注释的方式写文章, 有点太难看了, 还是分解代码块吧。
int main(int argc, char *argv[]) {
这个main有两个参, 一个整数型argc, 一个字符型指针数组argv, 其实不单单是看起来的那样, 这个变量名是有特殊含义的, argc是外部输入参数的个数, argv是存放参数的字符串数组, 举个例子说明这两玩意, 我们去执行代码这算一个外部参, 因为程序本身内部不会自己启动吧, 然后我们执行这个程序, 假设它叫test.exe
./test.exe
一个参
./test.exe 参数1 参数2
三个参
这个时候访问argv[1]会输出 参数1, argv[2]输出 参数2
这样就懂了吧, 不懂我也没办法, 哥们只能和你说, 有的时候得靠baidu多一点, 自己可能靠不住, 不行你就来问我, 学会用问题拷打别人也是一种进步。
———————————————————————————————————————————
第一个判断代码块
if (argc != 4) {
printf("what?\n");
exit(1);
}
判断这个函数是不是刚好有四个外部参数, 没有就输出 what?, 也就是说我们要自己构造三个参数传入。(当然不是啦, 看完整个代码再说)
———————————————————————————————————————————
第二个判断代码块
unsigned int first = atoi(argv[1]);
if (first != 0xcafe) {
printf("you are wrong, sorry.\n");
exit(2);
}
检测第一个参数(以下简称1参, 并以此类推), atoi函数把1参转换成数字, 传递给无符号整数型first变量, 如果first不等于十六进制00CAFE(十进制的51966), 输出you are wrong, sorry, 程序直接结束, 没有下一步。
也就是说第二个外部参数是 51966 (加上执行命令本身)
———————————————————————————————————————————
第三个判断代码块
unsigned int second = atoi(argv[2]);
if (second % 5 == 3 || second % 17 != 8) {
printf("ha, you won't get it!\n");
exit(3);
}
2参也转换成数字了, second变量存储数据。
左边的条件: 2参除以5取余数, 余数刚好为3则是真。
右边的条件: 2参除以17取余数, 余数不等于8则是真。
"||" 这是一个逻辑或运算符, 左右两边有一个满足条件就行了, 满足一个输出True。
———————————————————————————————————————————
第四个判断代码块
if (strcmp("h4cky0u", argv[3])) {
printf("so close, dude!\n");
exit(4);
}
3参这次没有处理, 直接用strcmp比较两个字符串的ASCII码值, strcmp函数的详细用法点这里,
只要这个值不等于h4cky0u就行, if后的数据自动变成布尔类型, 布尔类型只要不是等于0都是1值。
输出一串字符串so close, dude
———————————————————————————————————————————
接下来就是flag了
unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;
到这步还用多说吗...
用python的idle都能写出来
要和判断条件反着来, 有的if能执行就是错的, 要让一部分语句不能执行。(flag唯一性去推理)
flag:
c0ffee