[作者]
网名: 猪头三
Email: pliceman_110@163.com
QQ: 643439947
编程生涯: 2001~至今[12年]
职业生涯: 10年
开发语言: C/C++; x86asm; Object Pascal; C#;
开发工具: VC++; Delphi;
研发领域: Windows应用软件安全; Windows系统内核安全; Windows系统磁盘数据安全;
技能种类: 逆向 驱动 磁盘 文件
[序言]
脱离玩破解已经好几年了, 由于前段时间在休息, 闲来玩玩, 随便找了一款国外软件1-click pc tuneup软件下手. 本人玩破解的原则是: 随便玩玩, 不跟经济利益挂钩, 选择无壳软件. 破解的目的是复习和巩固逆向思维, 而不是耗费时间和生命去研究各种刁蛮的加壳, 用自动脱壳工具就Ok了.
[本文介绍]
本文章一共分为10部分, 完全图文并茂, 分享在破解过程中的思维想法, 阅读本文需要一定的汇编语言, C/C++语言, 程序运行原理, 有开发软件实际经验, 熟悉Windows操作系统理论, 有基本的算法理论基础, 技术难度中等偏上.
1> 初步了解破解环境的部署
2> 初步了解1-click pc tuneup软件的主程序基本特征
3> 利用ollydbg定位你的处理注册号的函数
4> 多次陷入困境
5> 通过Qt类库的QString类相关函数找到处理注册号的函数
6> 开始分析处理注册号的函数
7> 不要满足直接获取注册号码
8> 分析注册号的输入规则
9> 分析注册号码的生成算法
10> 为1-click pc tuneup软件写注册机
[请做好基础知识储备]
上面已经提到需要相关的基础知识, 如果您在阅读文章之前基础不扎实, 有可能你不会明白文章所要表达的含义. 破解领域太广太深, 接触和学习破解之前, 最好都需要会编程, 这是必须要具备的技能. 关于如何学习和提高编程, 我的网站http://www.x86asm.com或者QQ空间已有详细说明.
[阅读顺序]
本篇文章为: “1-click pc tuneup破解实录-[中]”, 您需要按照顺序来进行阅读:
"1-click pc tuneup破解实录-[上]"
>>>>>>>>>>>>>>> 第六部分: 开始分析处理注册号的函数 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1. 在 >>>第五部分: 通过Qt类库的QString类相关函数找到处理注册号的函数 <<< 我们已经发现了处理注册号的函数, 这些我们把之前下过的"断点"全部删除, 然后在对处理注册号的函数的第一行代码进行下"断点",
000D4720 > 55 PUSH EBP // 处理注册号的函数的第一行代码
通过对上面这行代码下"断点"之后, 我们重新返回1-click pc tuneup软件的注册对话框, 再次按下"Activate Now", 此时ollydbg就会停顿在刚才我们下"断点"的代码行上. 这时我们就需要F8(单步步过), 看看会发现什么变化?
000D4720 > 55 PUSH EBP // 处理注册号的函数的第一行代码
'
' {中间代码省略}
'
000D476B . E8 8ECAFEFF CALL PCtuneup.000C11FE // [注意]当运行到此处的时候, 现如果继续按F8(单步步过), 那么返回False, 并跳到结尾处并返回.
// 也就意味着当前PCtuneup.000C11FE这个函数针对我们输入的注册号进行了判断和验证之后,
// 返回了0, 0就是False,
因此我们有理由确定这个函数也跟注册号处理有关.
000D4770 . 84C0 TEST AL,AL
000D4772 . 0F84 59010000 JE PCtuneup.000D48D1
'
' {中间代码省略}
'
000D48D1 > 8B75 08 MOV ESI,DWORD PTR [EBP+8]
000D48D4 . 68 B4550E00 PUSH PCtuneup.000E55B4 ; 0
000D48D9 . 8BCE MOV ECX,ESI
000D48DB . FF15 F8F20E00 CALL DWORD PTR [<&QtCore4.??0QString@@QA>; QtCore4.??0QString@@QAE@PBD@Z
000D48E1 . 897D E8 MOV DWORD PTR [EBP-18],EDI
000D48E4 > 8D4D 0C LEA ECX,DWORD PTR [EBP+C]
000D48E7 . C645 FC 00 MOV BYTE PTR [EBP-4],0
000D48EB . FF15 04F30E00 CALL DWORD PTR [<&QtCore4.??1QString@@QA>; QtCore4.??1QXmlStreamStringRef@@QAE@XZ
000D48F1 . 8BC6 MOV EAX,ESI
000D48F3 . 8B4D F4 MOV ECX,DWORD PTR [EBP-C]
000D48F6 . 64:890D 00000>MOV DWORD PTR FS:[0],ECX
000D48FD . 59 POP ECX
000D48FE . 5F POP EDI
000D48FF . 5E POP ESI
000D4900 . 5B POP EBX
000D4901 . 8BE5 MOV ESP,EBP
000D4903 . 5D POP EBP
000D4904 . C2 0800 RET 8
2. 通过上面可知PCtuneup.000C11FE跟注册号处理有关,因此我们在再重新清空之前下过的"断点", 然后对
000D476B . E8 8ECAFEFF CALL PCtuneup.000C11FE
这行代码下个"断点", 重新返回1-click pc tuneup软件的注册对话框, 再次按下"Activate Now", 此时ollydbg就会停顿在刚才我们下"断点"的代码行上. 这时我们就需要F7(单步步入), 进入PCtuneup.000C11FE函数内部, 看看会有什么新发现? 结果会看到进入一个跳转到PCtuneup.000D42F0函数内部, 代码如下:
000C11FE $ /E9 ED300100 JMP PCtuneup.000D42F0 // 跳转到PCtuneup.000D42F0函数内部.
'
' {中间代码省略}
'
000D42F0 > 55 PUSH EBP // 从这里我们开始按F8(单步步过), 直到步过至
// 000D434C CALL DWORD PTR [<&QtCore4.?utf16@QString>; QtCore4.?utf16@QString@@QBEPBGXZ
// 这行代码,你就发现EAX的值显示的是我们的测试注册号.
000D42F1 . 8BEC MOV EBP,ESP
000D42F3 . 6A FF PUSH -1
000D42F5 . 68 79B40D00 PUSH PCtuneup.000DB479
000D42FA . 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
000D4300 . 50 PUSH EAX
000D4301 . 53 PUSH EBX
000D4302 . 56 PUSH ESI
000D4303 . 57 PUSH EDI
000D4304 . A1 1CC50E00 MOV EAX,DWORD PTR [EC51C]
000D4309 . 33C5 XOR EAX,EBP
000D430B . 50 PUSH EAX
000D430C . 8D45 F4 LEA EAX,DWORD PTR [EBP-C]
000D430F . 64:A3 0000000>MOV DWORD PTR FS:[0],EAX
000D4315 . 8BF1 MOV ESI,ECX
000D4317 . 837E 1C 00 CMP DWORD PTR [ESI+1C],0
000D431B . C745 FC 00000>MOV DWORD PTR [EBP-4],0
000D4322 . 75 1C JNZ SHORT PCtuneup.000D4340
000D4324 . 8D4E 0C LEA ECX,DWORD PTR [ESI+C]
000D4327 . FF15 8CF00E00 CALL DWORD PTR [<&QtCore4.?load@QLibrary>; QtCore4.?load@QLibrary@@QAE_NXZ
000D432D . 68 DC570E00 PUSH PCtuneup.000E57DC ; GetInstance
000D4332 . 8D4E 0C LEA ECX,DWORD PTR [ESI+C]
000D4335 . FF15 88F00E00 CALL DWORD PTR [<&QtCore4.?resolve@QLibr>; QtCore4.?resolve@QLibrary@@QAEPAXPBD@Z
000D433B . FFD0 CALL EAX
000D433D . 8946 1C MOV DWORD PTR [ESI+1C],EAX
000D4340 > 8B46 1C MOV EAX,DWORD PTR [ESI+1C]
000D4343 . 8D4D 08 LEA ECX,DWORD PTR [EBP+8]
000D4346 . 85C0 TEST EAX,EAX
000D4348 . 74 39 JE SHORT PCtuneup.000D4383
000D434A . 8B38 MOV EDI,DWORD PTR [EAX]
000D434C . FF15 F4F00E00 CALL DWORD PTR [<&QtCore4.?utf16@QString>; QtCore4.?utf16@QString@@QBEPBGXZ
000D4352 . 8B4E 1C MOV ECX,DWORD PTR [ESI+1C]
000D4355 . 50 PUSH EAX // 使用我们测试注册号
000D4356 . 8B47 0C MOV EAX,DWORD PTR [EDI+C] // 获取处理注册号的函数的地址
000D4359 . FFD0 CALL EAX // 调用处理注册号函数,此时按F7(单步步入)
000D435B . 8D4D 08 LEA ECX,DWORD PTR [EBP+8]
000D435E . 8AD8 MOV BL,AL
000D4360 . C745 FC FFFFF>MOV DWORD PTR [EBP-4],-1
000D4367 . FF15 04F30E00 CALL DWORD PTR [<&QtCore4.??1QString@@QA>; QtCore4.??1QXmlStreamStringRef@@QAE@XZ
000D436D . 8AC3 MOV AL,BL
000D436F . 8B4D F4 MOV ECX,DWORD PTR [EBP-C]
000D4372 . 64:890D 00000>MOV DWORD PTR FS:[0],ECX
000D4379 . 59 POP ECX
000D437A . 5F POP EDI
000D437B . 5E POP ESI
000D437C . 5B POP EBX
000D437D . 8BE5 MOV ESP,EBP
000D437F . 5D POP EBP
000D4380 . C2 0400 RET 4
000D4383 > C745 FC FFFFF>MOV DWORD PTR [EBP-4],-1
000D438A . FF15 04F30E00 CALL DWORD PTR [<&QtCore4.??1QString@@QA>; QtCore4.??1QXmlStreamStringRef@@QAE@XZ
000D4390 . 32C0 XOR AL,AL
000D4392 . 8B4D F4 MOV ECX,DWORD PTR [EBP-C]
000D4395 . 64:890D 00000>MOV DWORD PTR FS:[0],ECX
000D439C . 59 POP ECX
000D439D . 5F POP EDI
000D439E . 5E POP ESI
000D439F . 5B POP EBX
000D43A0 . 8BE5 MOV ESP,EBP
000D43A2 . 5D POP EBP
000D43A3 . C2 0400 RET 4
3. 通过上面的可知: CALL EAX 这条汇编指令, 就是处理我们测试注册码的指令, 因为这条指令的上面有PUSH EAX, 而当时的EAX是指向"123456789"这个测试注册号.
000D42F0 > 55 PUSH EBP // 从这里我们开始按F8(单步步过), 直到步过至
// 000D434C CALL DWORD PTR [<&QtCore4.?utf16@QString>; QtCore4.?utf16@QString@@QBEPBGXZ
// 这行代码,你就发现EAX的值显示的是我们的测试注册号.
'
' {中间代码省略}
'
000D4355 . 50 PUSH EAX // 使用我们测试注册号
000D4356 . 8B47 0C MOV EAX,DWORD PTR [EDI+C] // 获取处理注册号的函数的地址
000D4359 . FFD0 CALL EAX // 调用处理注册号函数,此时按F7(单步步入)
'
' {中间代码省略}
'
000D439C . 59 POP ECX
000D439D . 5F POP EDI
000D439E . 5E POP ESI
000D439F . 5B POP EBX
000D43A0 . 8BE5 MOV ESP,EBP
000D43A2 . 5D POP EBP
000D43A3 . C2 0400 RET 4
4. 按照上面的分析, 我们就在 CALL EAX 这条汇编指令, 按F7(单步步入), 看到如下代码
6E3C6AA0 55 PUSH EBP
6E3C6AA1 8BEC MOV EBP,ESP
6E3C6AA3 8B4D 08 MOV ECX,DWORD PTR [EBP+8] // 此时ECX是指向"123456789"这个测试注册号
6E3C6AA6 E8 25CD0000 CALL logiclay.6E3D37D0 // 此时按F7(单步步入)
6E3C6AAB 5D POP EBP
6E3C6AAC C2 0400 RET 4
通过观察上面的代码, 只有一个函数 logiclay.6E3D37D0, 因此毫无疑问的F7(单步步入)......
5. 按F7(单步步入)到logiclay.6E3D37D0函数内部之后, 突然眼前一片明亮, 看到了一个很像注册码的字符串"82A63CCD5F3A45AA97DB7A0C”, 看来可以锁定logiclay.6E3D37D0函数就是真正的处理注册号的函数了.
通过上面的发现, 我们可以尝试使用"82A63CCD5F3A45AA97DB7A0C”这个字符串来注册看看, 事实证明, 可以注册成功!