题目提供了一个exe程序和一个文本readme.txt,txt内容如下:
问题描述:
name:
serial:78767-77666-76786-87788-77778-66867-66777-86767-66877-77778-88887
根据序列号求name。name就是正确的flag
Hint:
name一共12位,
name[0]='{',name[1]='h',name[2]='d',name[3]='u'
name[5]='b',name[9]='0',name[10]='_',name[11]='}'
其他位的范围为26个小写字母和下划线
暴力循环6min多点(64位i5六代cpu,python)
很明显就是个通过name计算serial的算法,name应该是{hdu?b???0_},我们可以通过已知的serial逆推name。用OD调试程序:
我们输入name=’{hdu4b3210_}’h和已知的serial,name保存到了[local16],serial保存到[local10]。
IDA和OD结合分析找到关键的函数应该是002D2080
在002D2080函数里找到上述语句,为函数002D1F30传递参数,再次跟进002D1F30
将前两位进行运算然后加起来的值7存入[local3],之后的每一位都是一样的道理,最后把五位serial码赋值到eax+0x4
name一共12位,serial一共11个部分,每两位求出一部分,过程如下:
2void decode(int forward, int back, int re[]){
3 int i;
4 int local1, local2, local3, local4, local5 = 0;//, eax, ecx, ebx;
5 int result[5] = {0};
6 printf("%c %c ", (char)forward, (char)back);
7 //temp = (forward & 1) + 6; // forward % 2 + 6;
8 //temp1 = (back >> 2 ) & 1; // back / 4 % 2
9 //local3为第一位
10 // forward % 2+6+back / 4 % 2
11 local3 = (forward & 1) + 6 + ((back >> 2 ) & 1);
12 result[0] = local3;
13 //local4为第二位
14 //ecx = ((forward >> 3)& 1)+6;// >> 3 == / 8; & 1 == % 2
15 //eax = (back >> 3) & 1;
16 //forward / 8 % 2 + 6 + back / 8 % 2;
17 local4 = ((forward >> 3)& 1)+6+((back >> 3) & 1);
18 result[1] = local4;
19 //local1为第三位
20 // forward / 2 % 2 + 6 + back / 8 % 2;
21 local1 = ((forward >> 1) & 1)+6 + ((back >> 4) & 1);
22 result[2] = local1;
23 //第4位在ecx即local2中
24 local2 = (back & 1 )+6+((forward>>2)&1);
25 result[3] = local2;
26 //第5位在ebx中
27 local5 = ((back >> 1) & 1)+6+((forward >> 4) & 1);
28 result[4] = local5;
29 printf("%d%d%d%d%d ", result[0], result[1], result[2], result[3], result[4]);
30 for(i = 0; i < 5; i++){
31 re[i] = result[i];
32 }
33 //return result;
34 }