- UID
- 2198
注册时间2005-6-29
阅读权限255
最后登录1970-1-1
副坛主
该用户从未签到
|
——
——
我们这里所说的通过Patch代码来来显示软件授权信息,是指通过在程序中Patch一些代码来实现软件无需注册也看显示授权信息这就是常说的将注册信息保存到PE文件中。实现的基本思想大约有这样几种情况:
01.在软件启动后调用注册信息时来Patch代码将我们需要的注册信息保存到PE文件,同时暴破掉软件。
02.先将软件暴破后,定位软件“关于”窗体的代码,并Patch我们需要的注册信息,这样程序就可以显示注册给我们想要的ID。
思路了解之后,操作上就涉及到一个将Patch的代码保存在PE哪里的问题。一般来说,程序代码段最下方会有很多00 00 00的空白数据,我们将Patch代码写到那里即可,如果我们需要Patch的代码很多,可以在PE中新增一个区段专用于存放我们Patch的代码。我们需要让软件显示的授权信息,可直接在空白段(00 00 00处)添加,也可修改程序中使用不到的字符串(如注册失败这样的字符串),当我们引用该数据时直接调用修改后字符串的地址即可。
下面我们就以SPX Instant Screen Capture这个程序来做Patch代码的一个演示。我们之前已经详细的分析了这个程序的验证流程及爆破方法,在学习破解中大家不要拘泥于结果,而要综合的分析该程序的加密体系,从各个角度来寻求软件的解密方法。
我们先看第一种方法,在程序启动时向PE写入注册信息。那如何来定位程序是哪些代码来调用注册信息呢?一般我们要先将程序暴破并分析出软件启动时调用注册信息的位置(对于重启验证的程序就无需暴破了),在调试程序时记录程序启动时对注册信息的调用情况,就可以清楚的看到是哪些代码在进行对注册信息的处理。
我们OD载入SPX,我们点算法CALL第一行代码时可以看到信息窗口提示该函数有两处调用,我们分别来到地址004CBBF2和004D0FB2代码处,在该代码的上方的地址下断(程序在调用算法CALL前一定会先调出注册信息,我们在算法CALL上方下段的目的就是分析程序的哪些代码调用了注册信息)。
004CBB60 > \E8 C3EEF3FF CALL spx.0040AA28 ; 我们在这里下断 程序启动时中断在这里 我们F8单步
当来到这里时:
004CBBD4 . E8 AB8CF3FF CALL spx.00404884
004CBBD9 . 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] ; 我们看记录窗口 发现该语句将注册码地址送EAX
004CBBDC . 50 PUSH EAX
004CBBDD . 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
004CBBE0 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
004CBBE3 . 83C2 40 ADD EDX,40
004CBBE6 . E8 998CF3FF CALL spx.00404884
004CBBEB . 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C] ; 我们看记录窗口 发现该语句将用户名地址送EAX
004CBBEE . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004CBBF1 . 59 POP ECX
004CBBF2 . E8 9DFCFFFF CALL spx.004CB894 ; 算法CALL
分析到这里,我们就清楚了程序启动时是哪句代码对注册信息做了赋值。然后我们决定采用哪种方法向PE中保存我们需要的注册信息:在空白区段中直接添加还是替换程序的字符串。这里我们选择后者,若我们是在程序启动时Patch代码向空白区段写入注册信息,然后赋予我们所赋值字符串地址,保存文件后,可能我们还需要将程序代码段的属性修改为可读写,有时即使修改后仍会导致程序运行时的不稳定。所以我们这里采用第二种方法来向PE保存注册信息。我们OD载入程序后,右键==>超级字串参考==>查找ASCII,来查看是否可以找到程序未注册时可能会用到的字符串,修改这些字符串来达到向程序保存注册信息的目的。我们看到ASCII中有“1 day remaining”这样的字符串。于是从这里入手修改。
我们来到004CB716看到该语句的意思是将字符串的地址放到EDX寄存器中,字符串的地址是004CB84C
004CB716 |. BA 4CB84C00 MOV EDX,spx.004CB84C ; 1 day remaining.
我们在OD的命令窗口输入:d 4cb84c 来到该地址,在“1 day remaining”上点空格,在ASCII一栏输入我们需要的注册码。同理完成004CB868处输入我们需要的用户名(如果需要单独保存这个修改后的文件,在修改的代码上点右键==>复制到可执行文件==>右键==>保存文件即可,也可在OD的反汇编窗口Ctrl+G 来到该地址进行保存)。
接着我们找Patch代码的空间,如果我们不增添区段,我们一般在OD中拉到程序的最下方,找到都是00 00 00的地方,我们尽量选择较上方的地址处来Patch代码。
我们来到程序启动时调用注册信息的代码处,做如下修改:
004CBBD4 . E8 AB8CF3FF CALL spx.00404884 ; 我们将这里修改为JMP 004EA829
004CBBD9 . 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] ; 该语句的意思是将[EBP-8](该地址保存的是注册码的地址)中的地址送到EAX
JMP到这里:
004EA829 E8 56A0F1FF CALL spx5.00404884 ; 这里要现将我们使用JMP指令时覆盖的代码补充完整 JMP指令覆盖源代码几行指令我们这里就还原几行指令
004EA82E C745 F8 4CB84C00 MOV DWORD PTR SS:[EBP-8],spx5.004CB84C ; 这里将我们保存的注册码 "Bbs.ChinaPYG.CoM"的地址先送到[EBP-8]
004EA835 ^ E9 9F13FEFF JMP spx5.004CBBD9 ; 这里要返回我们修改代码处的下一行代码
同理完成用户名地址的赋值:
004CBBE6 . E8 998CF3FF CALL spx.00404884 ; 将这里修改为JMP 004EA83A
004CBBEB . 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C] ; (Initial CPU selection)
004EA83A E8 45A0F1FF CALL spx5.00404884
004EA83F C745 F4 68B84C00 MOV DWORD PTR SS:[EBP-C],spx5.004CB868 ; 这里将我们用户名"[PYG]解密小组"的地址送到[EBP-C]中
004EA846 ^ E9 A013FEFF JMP spx5.004CBBEB ; 返回
经过以上修改我们就完成了程序启动时注册信息的赋值,接下来我们暴破掉算法CALL中的比较语句:
004CB99A |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
004CB99D 8B55 EC MOV EDX,DWORD PTR SS:[EBP-14] ; 将这里修该为[EBP-10]
004CB9A0 |. E8 7F90F3FF CALL spx.00404A24
004CB9A5 |. 0F94C0 SETE AL ; 或者将这里修改为SETNE AL
004CB9A8 |. 8843 34 MOV BYTE PTR DS:[EBX+34],AL
004CB9AB |. 807B 34 00 CMP BYTE PTR DS:[EBX+34],0
004CB9AF |. 74 34 JE SHORT spx.004CB9E5
我们保存修改后的文件:复制到可执行文件==>所有修改。这时我们运行修改后的程序,点程序的about显示我们Patch到PE中的注册信息。删除掉注册信息亦如此。
接下来我们看第二种方法:直接在about处Patch代码来显示我们需要注册信息。我们观察上方的注册后的about图片,发现有一句"This product is licensed.",在OD中找到该字符串,来到这里下断:
004CC2BC . 53 PUSH EBX
004CC2BD . 8BD8 MOV EBX,EAX
004CC2BF . 83BB 3C030000 00 CMP DWORD PTR DS:[EBX+33C],0 ; 这里比较用户名是否为空
004CC2C6 . 0F84 DC000000 JE spx.004CC3A8 ; 注册码空则跳走
004CC2CC . 83BB 40030000 00 CMP DWORD PTR DS:[EBX+340],0 ; 这里比较注册码是否为空
004CC2D3 . 0F84 CF000000 JE spx.004CC3A8 ; 空则跳走
004CC2D9 . 33D2 XOR EDX,EDX
004CC2DB . 8B83 30030000 MOV EAX,DWORD PTR DS:[EBX+330]
004CC2E1 . E8 D2F6F7FF CALL spx.0044B9B8
004CC2E6 . BA B4C34C00 MOV EDX,spx.004CC3B4 ; This product is licensed.
分析出程序显示About时对注册信息的调用后,我们就可以施行Patch代码赋值。第一步我们将软件爆破掉,该程序需要修改两处:
程序启动时要判断注册信息是否为空,我们将这两个跳转NOP掉。
004CB8F1 |. E8 0ED1F3FF CALL spx.00408A04
004CB8F6 |. 837D E8 00 CMP DWORD PTR SS:[EBP-18],0
004CB8FA |. 0F84 E5000000 JE spx.004CB9E5 ; 这里判断注册信息是否为空 NOP掉
004CB900 |. 837D F8 00 CMP DWORD PTR SS:[EBP-8],0
004CB904 |. 0F84 DB000000 JE spx.004CB9E5 ; 这里也NOP掉
将算法CALL中的比较处爆破:
004CB99A |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
004CB99D 8B55 EC MOV EDX,DWORD PTR SS:[EBP-14] ; 将这里修该为[EBP-10]
004CB9A0 |. E8 7F90F3FF CALL spx.00404A24
004CB9A5 |. 0F94C0 SETE AL ; 或者将这里修改为SETNE AL
我们在向程序中保存注册信息时仍采用上文中使用的方法,替换掉程序的字符串(该程序若采用向PE中空白段写数据后,点about时将出现一些小问题)。
004CC2BF . 83BB 3C030000 00 CMP DWORD PTR DS:[EBX+33C],0 ; 这里比较用户名是否为空
004CC2C6 . 0F84 DC000000 JE spx.004CC3A8 ; 注册码空则跳走
004CC2CC . 83BB 40030000 00 CMP DWORD PTR DS:[EBX+340],0 ; 这里比较注册码是否为空
004CC2D3 . 0F84 CF000000 JE spx.004CC3A8 ; 空则跳走
修改如下:
004CC2BF . C783 3C030000 68B8>MOV DWORD PTR DS:[EBX+33C],spx.004CB868 ; 直接向[EBX+33C]赋值我们用户名的地址(替换字符串的地址)
004CC2C9 . 90 NOP
004CC2CA . 90 NOP
004CC2CB . 90 NOP
004CC2CC . C783 40030000 4CB8>MOV DWORD PTR DS:[EBX+340],spx.004CB84C ; ASCII "Bbs.ChinaPYG.CoM"
004CC2D6 . 90 NOP
004CC2D7 . 90 NOP
004CC2D8 . 90 NOP
修改后保存文件,程序即可显示我们Patch的注册信息。到这里我们就将这两种方法给大家讲解完了。学到这儿,解密上学习上就算迈出第一步了,后面的章节我们还将继续添加这样的文章供大家学习。很多程序我们都需要Patch代码来完成,破解的学习上需要我们多多思考,多多感悟。今后的道路将会更加艰难,这需要你的执着和毅力,只有坚持下来,才会取得胜利。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入我们
x
|