1:
很简单的MFC程序, 中途有点CC和checksum的自校验,让判断自校验的地方nop掉就可以下断点了。
2:
程序流程需要输入12位的用户名和53位的注册码
3:
用户名必须在a~y之间, 并且不重复
4:
注册码必须位0~3之前给值
5:
经过选择排序,记录下用户名的在"排序后的数组中(假象数组,并不存在)"的位置表,
记做表1, 显然是0到11之间的12个数字。
6:
表1跟序列号表经过运算函数FN后, 返回一个24字节的表,
拆分成12个字节的2个表tbl_a, tbl_b, 然后对他们跟用户名一样求位置表
tbl_pos_a, tbl_pos_b,
要求 memcmp(表1, tbl_pos_a, 12)==0 并且 memcmp(表1, tbl_pos_b, 12)==0
===========
观看FN, 他只能输出 'a','b'....'l' 刚好12个字节。
显然, 要顺序对上, 那么则必须有下列的2元对应关系
(0,a), (1,b)......(11, l)
这是因程序每次从表1取出一个symbol来, 重复两论。
但第一次给symbol是>, 第二次则为<
显然, 需要找到1,1对应关系。
分析流程图后 (见源代码的doc.txt描述), 可知道某些位的取值。
问题是 11--28, 这里的do_line_change需要满足N多条件。
数量不大, 可穷举之~
另外还有一个估计是程序的故意设计
if (a<b)
r[oc++] = 'g';
if (a<b)
r[oc++] = 'h'; // bug???
因为对于第一轮来说, 第7大的数会接着连续的写入'g','h', 同时
第8大的数字一个都不output.
显然, 要求我们构造用户名的时候, 第7大和第8大的字符必须连续。
可参考源代码。
用户名和序列号无任何关系, 所以分别用2个函数生成。
附件中包含源码, 以及流程和原理描述的doc.txt
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)