注册码要求
1、保证有-,且-前面的要是数字的组合,中间会调用Str2Int,下面这个是找-的位置

后来发现,这个是Delphi的Pos函数
2、前后的空格会干掉,其实是Delphi的Trim函数
3、除了0-9、A-F a-f 外,都会作为不符合标准的,不作数

4、-后面的长度超过0x10的话,只取0x10个
5、-后面的,每两个一组,前面他加了一个$拼接了一下,用来作为后面运算的区分,可以忽略,每两个一组,字符0-9和字母A-F就对应十六进制的0-F

对ABCDEF0123456789而言,最后组成的是 0x01EFCDAB,0x89674523,这两个数会替换掉原有的栈中的数据,参加下面的运算
6、这两个又去做了一个HASH运算,倒数第二次的结果 & 0xFFFF,和0x9C5B比较,要相等;

算法如下:

7、上面算法里,还有一个外层的源,简称外源,可以通过如下方法找:

5EE3C58是在多次调试的时候,观察数据得到,重复调式时,有几次会有相同的位置,自己调试的时候断下两次,第二次才是

不过,看到eax的来源,是0x9749EC,刚好位于.data段(见下图),数据已经初始化过;可以得到这个值;
后面的 mov eax, dword ptr ds:[eax],说明刚才的这个值也是个地址,看了一下,发现这个地址是

而0x97EAB0,落在.bss段,可见是需要进行初始化的,我们就需要在这个地址处下断;

会断在这里,

看下eax附近的值,关注eax+4开始的4个dword


已经被赋值了,那现在就要看下eax的来源了,发现来自于上面的call,可以进去看看,不建议先进去
在进入call前,先看下上下的环境,尤其是对栈的操作以及对寄存器的操作,进行大致的观察

分别看下578150、974BB8的数据
这个是代码的二级指针,先不管他了

这个值有什么含义,969CF0,也是一个地址,再跟进下看看

若有所获,根据内存布局,969CF0位于.data段,用010打开这个PE看一下初始值

的确是从这个位置拿到的,这样,那个call我们先不用进去了;
8、先写一下注册机,把刚才的地方过掉,看下是否还有别的要求,目前看,用户名好像还没有什么用呢(的确没啥用),而且,-前面的部分貌似还没有用到,另外,倒数第一次的运算的结果还没有用呢
0019F9D8 1245A178 外层[0]
0019F9DC F44AACD0 外层[1]
0019F9E0 007AC989 外层[2]
0019F9E4 2AF937D9 外层[3]
0019F9E8 00000000
0019F9EC 01EFCDAB HASH[0]
0019F9F0 89674523 HASH[1]


0000000071990300
00000000, 00039971
倒数第一次的结果:0x73F9 20E8
倒数第二次的结果:0xD7C6 9C5B
9、往下走,-前面的部分,倒数第一次的运算的结果就用到了


-前面的字符串,和常量字符串"L-User",分别做HASH运算,两个HASH之和,和最后一次运算的结果相等即可;
这个字符串HASH的算法如下

10、编写注册码,跑出几个结果,试着修改了下用户名,发现没有关系
799144-17B9D32321AD4120
470878-E2288FB57FF06B24

但是,有个问题,这里依然显示未注册,

接着跟,发现,-前面的字符串,是有一定含义的,而且只能是5位
88:企业
66:网站
5:商业
4:并行授权 ?
2:单一商业 ?
3:非商业

16867-AC6BC962858F445F
72224-62B322D7D6DA0723
跑出来一个不大容易,就不贴代码了,上面的注册码不是最终的哦,有兴趣的可以自己根据上面的分析的逻辑,写注册机,欢迎NB的注册机,仅供学习交流;
[培训]科锐逆向工程师培训第53期2025年7月8日开班!