一、首先是了解flashget 1.65的注册原理
flashget(以下简称fg)是先填写注册码,
填写好了以后fg会把注册码保存在注册表里面,
例如:
[HKEY_CURRENT_USER\Software\JetCar\JetCar\General]
"RegPass"="aabbccdd"
然后在下次启动的时候检查注册码是否正确来确定是否显示广告条。
二、破解原理
在调试工具中(我用的是ollydbg v1.10 http://home.t-online.de/home/Ollydbg/)
找到有关注册的那部分,然后进行跟踪,分析fg是如何判断是否注册的
三、ollydbg(以下简称odbg)使用简单介绍
打开odbg,open一个程序,odbg会自动会程序进行反汇编,
反汇编结束以后,你会看到整个窗口被分成了四个部分
左上角的用于显示反编译的代码
右上角的用于显示寄存器数据
左下角显示当前所载入的软件数据在内存中的位置
右下角显示被各种函数所使用的内存
四、破解
1、先用ollydbg打开flashget.exe,odbg自动对fg反汇编,
然后就能看到flashget.exe的汇编代码
下面要找到注册相关的部分,我们就来查找RegPass这个字段
在反汇编出来的代码窗口中点右键,选择“Search for->All referencd text strings”
弹出一个窗口,都是referencd text strings,点右键,选择“search for text”。
这里注意他只会往下找,所以要把光标移动到最上面再查找
填入RegPass,注意大小写。
一共找到两个,现在要排除一个。
都设置成断点(f2)
然后run(f9),发现到0041dce6的那个断点停下了,说明是fg启动时候调用的
取消这个断点,restart,run,发现fg界面出来了,说明另外一个断点应该是存入用的
而前面一个断点应该就是关键了
我们可以把这个地方加入bookmark,以后就可以方便的使用alt+数字转到这里
2、分析附近代码
观察附近的代码(空指令nop),以及左边的大括号(一个子程序)
发现以下代码,先不要仔细看:
0041DC80 /$ 6A FF PUSH -1
0041DC82 |. 68 20334F00 PUSH flashget.004F3320 ; SE handler installation
0041DC87 |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0041DC8D |. 50 PUSH EAX
0041DC8E |. 64:8925 000000>MOV DWORD PTR FS:[0],ESP
0041DC95 |. 83EC 20 SUB ESP,20
0041DC98 |. 53 PUSH EBX
0041DC99 |. 55 PUSH EBP
0041DC9A |. 56 PUSH ESI
0041DC9B |. 57 PUSH EDI
0041DC9C |. 68 E8B85300 PUSH flashget.0053B8E8
0041DCA1 |. 68 A0E55200 PUSH flashget.0052E5A0 ; ASCII "RegName"
0041DCA6 |. 8D4424 18 LEA EAX,DWORD PTR SS:[ESP+18]
0041DCAA |. 8BE9 MOV EBP,ECX
0041DCAC |. 68 A0C15200 PUSH flashget.0052C1A0 ; ASCII "General"
0041DCB1 |. 50 PUSH EAX
0041DCB2 |. 896C24 28 MOV DWORD PTR SS:[ESP+28],EBP
0041DCB6 |. E8 95C70C00 CALL flashget.004EA450
0041DCBB |. 8DB5 60030000 LEA ESI,DWORD PTR SS:[EBP+360]
0041DCC1 |. 50 PUSH EAX
0041DCC2 |. 8BCE MOV ECX,ESI
0041DCC4 |. C74424 3C 0000>MOV DWORD PTR SS:[ESP+3C],0
0041DCCC |. E8 83660B00 CALL flashget.004D4354
0041DCD1 |. 83CF FF OR EDI,FFFFFFFF
0041DCD4 |. 8D4C24 10 LEA ECX,DWORD PTR SS:[ESP+10]
0041DCD8 |. 897C24 38 MOV DWORD PTR SS:[ESP+38],EDI
0041DCDC |. E8 3A650B00 CALL flashget.004D421B
0041DCE1 |. 68 E8B85300 PUSH flashget.0053B8E8
0041DCE6 |. 68 98E55200 PUSH flashget.0052E598 ; ASCII "RegPass"
0041DCEB |. 8D4C24 1C LEA ECX,DWORD PTR SS:[ESP+1C]
0041DCEF |. 68 A0C15200 PUSH flashget.0052C1A0 ; ASCII "General"
0041DCF4 |. 51 PUSH ECX
0041DCF5 |. 8BCD MOV ECX,EBP
0041DCF7 |. E8 54C70C00 CALL flashget.004EA450
0041DCFC |. 81C5 64030000 ADD EBP,364
0041DD02 |. BB 01000000 MOV EBX,1
0041DD07 |. 50 PUSH EAX
0041DD08 |. 8BCD MOV ECX,EBP
0041DD0A |. 895C24 3C MOV DWORD PTR SS:[ESP+3C],EBX
0041DD0E |. E8 41660B00 CALL flashget.004D4354
0041DD13 |. 8D4C24 14 LEA ECX,DWORD PTR SS:[ESP+14]
0041DD17 |. 897C24 38 MOV DWORD PTR SS:[ESP+38],EDI
0041DD1B |. E8 FB640B00 CALL flashget.004D421B
0041DD20 |. 8B16 MOV EDX,DWORD PTR DS:[ESI]
0041DD22 |. 8B42 F8 MOV EAX,DWORD PTR DS:[EDX-8]
0041DD25 |. 85C0 TEST EAX,EAX
0041DD27 |. 0F84 4E010000 JE flashget.0041DE7B
0041DD2D |. 8B45 00 MOV EAX,DWORD PTR SS:[EBP]
0041DD30 |. 8B48 F8 MOV ECX,DWORD PTR DS:[EAX-8]
0041DD33 |. 85C9 TEST ECX,ECX
0041DD35 |. 0F84 40010000 JE flashget.0041DE7B
0041DD3B |. 8BCE MOV ECX,ESI
0041DD3D |. E8 89210B00 CALL flashget.004CFECB
0041DD42 |. 8BCE MOV ECX,ESI
0041DD44 |. E8 36210B00 CALL flashget.004CFE7F
0041DD49 |. 8B0E MOV ECX,DWORD PTR DS:[ESI]
0041DD4B |. 8379 F8 05 CMP DWORD PTR DS:[ECX-8],5
0041DD4F |. 0F8E 26010000 JLE flashget.0041DE7B
0041DD55 |. 68 BCE55200 PUSH flashget.0052E5BC
0041DD5A |. 8BCE MOV ECX,ESI
0041DD5C |. E8 851D0B00 CALL flashget.004CFAE6
0041DD61 |. 85C0 TEST EAX,EAX
0041DD63 |. 0F8C 12010000 JL flashget.0041DE7B
0041DD69 |. 68 B8E55200 PUSH flashget.0052E5B8
0041DD6E |. 8BCE MOV ECX,ESI
0041DD70 |. E8 711D0B00 CALL flashget.004CFAE6
0041DD75 |. 85C0 TEST EAX,EAX
0041DD77 |. 0F8C FE000000 JL flashget.0041DE7B
0041DD7D |. 8BCD MOV ECX,EBP
0041DD7F |. E8 47210B00 CALL flashget.004CFECB
0041DD84 |. 8BCD MOV ECX,EBP
0041DD86 |. E8 F4200B00 CALL flashget.004CFE7F
0041DD8B |. 8B55 00 MOV EDX,DWORD PTR SS:[EBP]
0041DD8E |. 8B42 F8 MOV EAX,DWORD PTR DS:[EDX-8]
0041DD91 |. 83F8 2C CMP EAX,2C
0041DD94 |. 0F85 E1000000 JNZ flashget.0041DE7B
0041DD9A |. 68 B0E55200 PUSH flashget.0052E5B0 ; ASCII "fgc-"
0041DD9F |. 8BCD MOV ECX,EBP
0041DDA1 |. E8 401D0B00 CALL flashget.004CFAE6
0041DDA6 |. 85C0 TEST EAX,EAX
0041DDA8 |. 75 06 JNZ SHORT flashget.0041DDB0
0041DDAA |. 895C24 10 MOV DWORD PTR SS:[ESP+10],EBX
0041DDAE |. EB 18 JMP SHORT flashget.0041DDC8
0041DDB0 |> 68 A8E55200 PUSH flashget.0052E5A8 ; ASCII "fgf-"
0041DDB5 |. 8BCD MOV ECX,EBP
0041DDB7 |. E8 2A1D0B00 CALL flashget.004CFAE6
0041DDBC |. 85C0 TEST EAX,EAX
0041DDBE |. 0F85 B7000000 JNZ flashget.0041DE7B
0041DDC4 |. 894424 10 MOV DWORD PTR SS:[ESP+10],EAX
0041DDC8 |> 6A 2C PUSH 2C
0041DDCA |. 8BCD MOV ECX,EBP
0041DDCC |. E8 7A680B00 CALL flashget.004D464B
0041DDD1 |. 8BF8 MOV EDI,EAX
0041DDD3 |. 33C9 XOR ECX,ECX
0041DDD5 |. 83C7 04 ADD EDI,4
0041DDD8 |. 33F6 XOR ESI,ESI
0041DDDA |> 8B07 /MOV EAX,DWORD PTR DS:[EDI]
0041DDDC |. 8BD6 |MOV EDX,ESI
0041DDDE |. 83C7 04 |ADD EDI,4
0041DDE1 |. 83EA 00 |SUB EDX,0 ; Switch (cases 0..2)
0041DDE4 |. 894424 1C |MOV DWORD PTR SS:[ESP+1C],EAX
0041DDE8 |. 74 26 |JE SHORT flashget.0041DE10
0041DDEA |. 4A |DEC EDX
0041DDEB |. 74 17 |JE SHORT flashget.0041DE04
0041DDED |. 4A |DEC EDX
0041DDEE |. 75 38 |JNZ SHORT flashget.0041DE28
0041DDF0 |. 0FBE4C24 1E |MOVSX ECX,BYTE PTR SS:[ESP+1E] ; Case 2 of switch 0041DDE1
0041DDF5 |. 0FBED4 |MOVSX EDX,AH
0041DDF8 |. 0FAFCA |IMUL ECX,EDX
0041DDFB |. 0FBE5424 1F |MOVSX EDX,BYTE PTR SS:[ESP+1F]
0041DE00 |. 03CA |ADD ECX,EDX
0041DE02 |. EB 1F |JMP SHORT flashget.0041DE23
0041DE04 |> 0FBE4C24 1E |MOVSX ECX,BYTE PTR SS:[ESP+1E] ; Case 1 of switch 0041DDE1
0041DE09 |. 0FBED4 |MOVSX EDX,AH
0041DE0C |. 23CA |AND ECX,EDX
0041DE0E |. EB 0B |JMP SHORT flashget.0041DE1B
0041DE10 |> 8A4C24 1E |MOV CL,BYTE PTR SS:[ESP+1E] ; Case 0 of switch 0041DDE1
0041DE14 |. 8AD4 |MOV DL,AH
0041DE16 |. 33CA |XOR ECX,EDX
0041DE18 |. 83E1 7F |AND ECX,7F
0041DE1B |> 0FBE5424 1F |MOVSX EDX,BYTE PTR SS:[ESP+1F]
0041DE20 |. 0FAFCA |IMUL ECX,EDX
0041DE23 |> 0FBEC0 |MOVSX EAX,AL
0041DE26 |. 03C8 |ADD ECX,EAX
0041DE28 |> 8B4424 10 |MOV EAX,DWORD PTR SS:[ESP+10] ; Default case of switch 0041DDE1
0041DE2C |. 85C0 |TEST EAX,EAX
0041DE2E |. 74 0C |JE SHORT flashget.0041DE3C
0041DE30 |. 0FBE1D 2BC7520>|MOVSX EBX,BYTE PTR DS:[52C72B]
0041DE37 |. 83FE 02 |CMP ESI,2
0041DE3A |. 74 07 |JE SHORT flashget.0041DE43
0041DE3C |> 0FBE9E 28C7520>|MOVSX EBX,BYTE PTR DS:[ESI+52C728]
0041DE43 |> 8BC1 |MOV EAX,ECX
0041DE45 |. 33D2 |XOR EDX,EDX
0041DE47 |. F7F3 |DIV EBX
0041DE49 |. 8BC6 |MOV EAX,ESI
0041DE4B |. 83E8 00 |SUB EAX,0 ; Switch (cases 0..2)
0041DE4E |. 74 13 |JE SHORT flashget.0041DE63
0041DE50 |. 48 |DEC EAX
0041DE51 |. 74 09 |JE SHORT flashget.0041DE5C
0041DE53 |. 48 |DEC EAX
0041DE54 |. 75 11 |JNZ SHORT flashget.0041DE67
0041DE56 |. 85D2 |TEST EDX,EDX ; Case 2 of switch 0041DE4B
0041DE58 |. 75 18 |JNZ SHORT flashget.0041DE72
0041DE5A |. EB 0B |JMP SHORT flashget.0041DE67
0041DE5C |> 83FA 08 |CMP EDX,8 ; Case 1 of switch 0041DE4B
0041DE5F |. 75 11 |JNZ SHORT flashget.0041DE72
0041DE61 |. EB 04 |JMP SHORT flashget.0041DE67
0041DE63 |> 85D2 |TEST EDX,EDX ; Case 0 of switch 0041DE4B
0041DE65 |. 75 0B |JNZ SHORT flashget.0041DE72
0041DE67 |> 46 |INC ESI ; Default case of switch 0041DE4B
0041DE68 |. 83FE 03 |CMP ESI,3
0041DE6B |. 7D 23 |JGE SHORT flashget.0041DE90
0041DE6D |.^E9 68FFFFFF \JMP flashget.0041DDDA
0041DE72 |> 6A FF PUSH -1
0041DE74 |. 8BCD MOV ECX,EBP
0041DE76 |. E8 1F680B00 CALL flashget.004D469A
0041DE7B |> 5F POP EDI
0041DE7C |. 5E POP ESI
0041DE7D |. 5D POP EBP
0041DE7E |. 33C0 XOR EAX,EAX
0041DE80 |. 5B POP EBX
0041DE81 |. 8B4C24 20 MOV ECX,DWORD PTR SS:[ESP+20]
0041DE85 |. 64:890D 000000>MOV DWORD PTR FS:[0],ECX
0041DE8C |. 83C4 2C ADD ESP,2C
0041DE8F |. C3 RETN
0041DE90 |> 6A FF PUSH -1
0041DE92 |. 8BCD MOV ECX,EBP
0041DE94 |. E8 01680B00 CALL flashget.004D469A
0041DE99 |. 8B45 00 MOV EAX,DWORD PTR SS:[EBP]
0041DE9C |. 8B4C24 18 MOV ECX,DWORD PTR SS:[ESP+18]
0041DEA0 |. 6A 01 PUSH 1
0041DEA2 |. 50 PUSH EAX
0041DEA3 |. 68 A0C15200 PUSH flashget.0052C1A0 ; ASCII "General"
0041DEA8 |. E8 37C50C00 CALL flashget.004EA3E4
0041DEAD |. 8B4C24 30 MOV ECX,DWORD PTR SS:[ESP+30]
0041DEB1 |. 5F POP EDI
0041DEB2 |. F7D8 NEG EAX
0041DEB4 |. 1BC0 SBB EAX,EAX
0041DEB6 |. 5E POP ESI
0041DEB7 |. 5D POP EBP
0041DEB8 |. 5B POP EBX
0041DEB9 |. F7D8 NEG EAX
0041DEBB |. 64:890D 000000>MOV DWORD PTR FS:[0],ECX
0041DEC2 |. 83C4 2C ADD ESP,2C
0041DEC5 \. C3 RETN
以上的代码就是判断RegPass是否正确的子程序了
我们再精简一下,只留下跳转语句、返回语句和跳转到的语句:
0041DC80 /$ 6A FF PUSH -1
0041DD27 |. 0F84 4E010000 JE flashget.0041DE7B ;没有regpass的话在这里就跳了
0041DD35 |. 0F84 40010000 JE flashget.0041DE7B
0041DD4F |. 0F8E 26010000 JLE flashget.0041DE7B
0041DD63 |. 0F8C 12010000 JL flashget.0041DE7B
0041DD77 |. 0F8C FE000000 JL flashget.0041DE7B
0041DD94 |. 0F85 E1000000 JNZ flashget.0041DE7B ;如果有个随便写的注册码的话在这里跳
0041DDA8 |. 75 06 JNZ SHORT flashget.0041DDB0
0041DDAE |. EB 18 JMP SHORT flashget.0041DDC8
0041DDB0 |> 68 A8E55200 PUSH flashget.0052E5A8 ; ASCII "fgf-"
0041DDBE |. 0F85 B7000000 JNZ flashget.0041DE7B
0041DDC8 |> 6A 2C PUSH 2C
0041DDDA |> 8B07 /MOV EAX,DWORD PTR DS:[EDI]
0041DDE8 |. 74 26 |JE SHORT flashget.0041DE10
0041DDEB |. 74 17 |JE SHORT flashget.0041DE04
0041DDEE |. 75 38 |JNZ SHORT flashget.0041DE28
0041DE02 |. EB 1F |JMP SHORT flashget.0041DE23
0041DE04 |> 0FBE4C24 1E |MOVSX ECX,BYTE PTR SS:[ESP+1E] ; Case 1 of switch 0041DDE1
0041DE0E |. EB 0B |JMP SHORT flashget.0041DE1B
0041DE10 |> 8A4C24 1E |MOV CL,BYTE PTR SS:[ESP+1E] ; Case 0 of switch 0041DDE1
0041DE1B |> 0FBE5424 1F |MOVSX EDX,BYTE PTR SS:[ESP+1F]
0041DE23 |> 0FBEC0 |MOVSX EAX,AL
0041DE28 |> 8B4424 10 |MOV EAX,DWORD PTR SS:[ESP+10] ; Default case of switch 0041DDE1
0041DE2E |. 74 0C |JE SHORT flashget.0041DE3C
0041DE3A |. 74 07 |JE SHORT flashget.0041DE43
0041DE3C |> 0FBE9E 28C7520>|MOVSX EBX,BYTE PTR DS:[ESI+52C728]
0041DE43 |> 8BC1 |MOV EAX,ECX
0041DE4E |. 74 13 |JE SHORT flashget.0041DE63
0041DE51 |. 74 09 |JE SHORT flashget.0041DE5C
0041DE54 |. 75 11 |JNZ SHORT flashget.0041DE67
0041DE58 |. 75 18 |JNZ SHORT flashget.0041DE72
0041DE5A |. EB 0B |JMP SHORT flashget.0041DE67
0041DE5C |> 83FA 08 |CMP EDX,8 ; Case 1 of switch 0041DE4B
0041DE5F |. 75 11 |JNZ SHORT flashget.0041DE72
0041DE61 |. EB 04 |JMP SHORT flashget.0041DE67
0041DE63 |> 85D2 |TEST EDX,EDX ; Case 0 of switch 0041DE4B
0041DE65 |. 75 0B |JNZ SHORT flashget.0041DE72
0041DE67 |> 46 |INC ESI ; Default case of switch 0041DE4B
0041DE6B |. 7D 23 |JGE SHORT flashget.0041DE90
0041DE6D |.^E9 68FFFFFF \JMP flashget.0041DDDA
0041DE72 |> 6A FF PUSH -1
0041DE7B |> 5F POP EDI ;这里已经判断是没注册的了
0041DE8F |. C3 RETN ;这里返回,跳出了检查注册码的子函数,返回到了004128EB
0041DE90 |> 6A FF PUSH -1
0041DEC5 \. C3 RETN
分析一下,可以发现:
a、很多跳转是到的0041DE7B。跳到0041DE7B以后,就是一个retn,返回了。
而这里返回就是被发现是未注册的了。
b、其他跳转都是在内部跳的,都是循环,不会跳出去,除了一个:
0041DE6B JGE SHORT flashget.0041DE90
他跳到了0041DE90,然后就是一个返回,所以说只可能这个是注册的返回。
现在,我们可以对上面的这个子程序做一个总体分析,
0041DC80-0041DDD8是初始判断
而0041DDDA-0041DE6D是进阶判断
0041DE7B-0041DE8F是注册码错误时的返回
0041DE90-0041DEC5是注册码正确时的返回
所以我们只要在一开始就跳到0041DE90就可以了
我的方法是在0041DD27把JE 0041DE7B修改成jmp 0041DE90
在odbg里面修改以后,记录二进制代码为E96401000090
五、修改文件
用WinHex或者UltraEdit修改
找到0001DD27(0041DD27)
把0F844E010000修改成E96401000090
OK,成功!
说明:
fg1.65和网上说的前面几个版本不同,不能直接从寄存器里面得到注册码的
而是通过对你提供的注册码的一步步循环的计算来判断是否正确
所以这里只是修改文件,并没有找出注册码的计算方法。
以前使用算号器,过了一段时候以后又会出现广告
据lucian说,是fg会上网验证的
所以还是直接修改文件保险、简单。
后记:
后来看了一下调用这个子程序的代码004128EB附近的代码
发现这个子程序的作用就是当注册码错误时,使EAX为0;
当注册码正确时(经上述5步破解),使EAX为1,然后
004128f2 MOV DWORD PTR SS:[EBP+284],EAX
只要令DWORD PTR SS:[EBP+284](0053bb74)不为0就去了广告
修改MOV DWORD PTR SS:[EBP+284],EAX为MOV DWORD PTR SS:[EBP+284],ECX
更或者004128EB CALL 0041DC80改成nop或者CALL 00425790(mov eax,1)
这样也少执行一段代码。
一开始我用的是w32dasm反编译的,
因为发现它比较容易上手,但是调试不太方便,太占cpu,反汇编太慢;
而odbg界面比较复杂,调试比较方便,所以开始我是两种工具结合使用的,
而后来随着对odbg的熟悉,全部使用odbg完成。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!