reverse第二更之问鼎杯2106-6-2

reverse第二更之问鼎杯2106-6-2

题目提供了一个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 }
文章目录
  1. 1. reverse第二更之问鼎杯2106-6-2
|