本来今天已经做完了Teksched的破解,也是相当老套的未注册版本改成注册版本,之前也有做过几个改注册版本的破解,大致思路也都差不多,本来我现在也应该在床上躺着,毕竟这几天感觉头有点凉,后来仔细想想,还是写个东西的好,我也确实有写一点东西的必要了。 话不多说,Teksched使用的是Delphi,可以说是相当的调用函数了。
这是一个时间规划表的程序,我们先来看一下程序运行:
这很明显是未注册的版本,我们今天要做的就是破解他。
首先我们按照关键词查找到registration(一般关键词的选择都是运行exe中出现的字符串)
跟入“registration key accepted”,我确实是之前考虑过直接nop掉一些代码,然后拿到注册版的key,然而我们在NOP之后,发现除了没有那个unregistered其他的都是幌子,也就是说是个表面的注册版,他的已注册功能并没有实现。并且我们想要到达584B这个位置,而并没有直接代码跳转到该位置。
所以我们继续观察,发现在成功的那行代码上面出现了ret,这是函数的返回,并且前方也有相应的push操作,我们设下断点:
004A5828 . 59 pop ecx
004A5829 . 64:8910 mov dword ptr fs:[eax], edx
**004A582C** . 68 41584A00 push 004A5841
004A5831 > 8B45 CC mov eax, dword ptr [ebp-34]
004A5834 . E8 5BE8F5FF call 00404094
004A5839 . C3 retn ; push jump
004A583A .^ E9 E9EFF5FF jmp 00404828
004A583F .^ EB F0 jmp short 004A5831
**004A5841** . C645 F3 01 mov byte ptr [ebp-D], 1
004A5845 . 807D 08 00 cmp byte ptr [ebp+8], 0
004A5849 . 75 0A jnz short 004A5855
004A584B . B8 A85A4A00 mov eax, 004A5AA8 ; ASCII "Registration Key accepted!"
004A5850 . E8 A339F9FF call 004391F8
然后我们重新载入运行到达断点,然后我们发现我们并没有断下来,emmmm那我们就接着往上看,很符合Delphi的特色了。
然后我们发现了一些有用的字符串,这大概就是在提示我们需要输入注册框的。
我们成功断下并进行调试,进入了系统dll的领空之前下断点,再次载入,将call (5461)改为nop,接着调试:
为了到达accept我们必须使得je跳转成功,将JE改为jmp:
因为jnz的跳转会使得程序结束,然后我们接着往下调试,再次发现567E的jnz会跳转到程序结束,改为NOP。
004A567E /0F85 DB010000 jnz 004A585F
004A5684 . |8D45 D8 lea eax, dword ptr [ebp-28]
004A5687 . |BA 345A4A00 mov edx, 004A5A34 ; ASCII "GJJ"
004A568C . |E8 C3FBF5FF call 00405254
004A5691 . |A1 BC5C5A00 mov eax, dword ptr [5A5CBC]
004A5696 . |66:6930 BC02 imul si, word ptr [eax], 2BC
然后再次调试(直接一路F8,会遇到很多调用),好了,终于没有GG了,我们的程序成功破解。
诉我直言,为什么选择这个东西来写,大概就是因为现阶段社会上针对逆向的方法大多了,这个程序刚开始的不能直接发现运行到成功代码的算是最垃圾的一个。 反逆向的存在加大了逆向分析的难度: