【标题】RAM Saver Pro V5.5 注册算法分析
【作者】forever[RCT]
【语言】LCC WIN
【保护】aspack ,注册码
【难度】简单
【工具】ollydbg,peid
【简介】RAM Saver 是款易用的内存优化软件,让您的系统运行的更流畅
【下载】http://www6.skycn.com/soft/13995.html
【正文】
很长时间没碰共享软件了。5.1是个比较郁闷的日子。抓个软柿子捏一下,出出闷气。
peid说这个软件是LCC的,ida里又没这个sig,静态库函数都识别不出来。看来只能靠od了。
没注册的软件有个nag窗口,要求输入注册码。胡乱输入注册码,点下一步,直接进主窗口了。
一点提示都没有。作者真是小气:) 看来要找到验证的地方还要想点办法。
办法还是有的,不管怎么样,程序终究还是要回到code段里执行的。打开memory窗口,在主程
序的code断下一个F2断点。马上断在了下面(见图)
希望你不要对断下来的这段代码视而不见,这其实就是注册窗口对应的窗口过程。看到
cmp eax,111 这条代码了吗?这个是对WM_COMMAND消息处理的地方,我们到对应的地址00405437看
看。往下边一点,你会看到下面这段代码:
00405493 E8 74730000 CALL 0040C80C ; JMP to USER32.GetDlgItem
00405498 68 04010000 PUSH 104
0040549D 8DBD F8FEFFFF LEA EDI,DWORD PTR SS:[EBP-108]
004054A3 57 PUSH EDI
004054A4 50 PUSH EAX
004054A5 E8 1A730000 CALL 0040C7C4 ; JMP to USER32.GetWindowTextA
004054AA 80BD F8FEFFFF 0>CMP BYTE PTR SS:[EBP-108],0
004054B1 74 40 JE SHORT 004054F3
004054B3 68 60F34000 PUSH 0040F360
004054B8 8D85 F8FEFFFF LEA EAX,DWORD PTR SS:[EBP-108]
004054BE 50 PUSH EAX
004054BF E8 4C780000 CALL 0040CD10 ; JMP to crtdll.strstr
004054C4 83C4 08 ADD ESP,8
004054C7 09C0 OR EAX,EAX
004054C9 74 28 JE SHORT 004054F3
004054CB 8D85 F8FEFFFF LEA EAX,DWORD PTR SS:[EBP-108]
004054D1 50 PUSH EAX
004054D2 E8 1FFBFFFF CALL 00404FF6
004054D7 59 POP ECX
004054D8 68 BCD94000 PUSH 0040D9BC ; ASCII "C:\Program Files\WinTools\RAM Saver Pro\ramsaverpro.ini"
004054DD 8D85 F8FEFFFF LEA EAX,DWORD PTR SS:[EBP-108]
004054E3 50 PUSH EAX
004054E4 68 01F44000 PUSH 0040F401 ; ASCII "Temp"
004054E9 68 0CF44000 PUSH 0040F40C ; ASCII "SYSFILES"
004054EE E8 89720000 CALL 0040C77C ; JMP to kernel32.WritePrivateProfileStringA
不用想了。赶紧对USER32.GetWindowTextA下一个断点吧。点 下一步 按钮,可以看到程序执行
到了这里。仔细看看,这段就是判断注册码里是否有"-"号,有的话就把注册码简单加密一下写入到
ramsaverpro.ini里。
程序并没有在这里验证注册码。想想我们还能干什么?我知道你会猜到程序在其他地方验证了注
册码,典型的是在程序启动时。好了。重新载入程序,在GetPrivateProfileStringA上下一个断点。
为什么要在这个函数上下断点?这个函数是和WritePrivateProfileStringA对应的啊,一个读,一个
写啊。^-^! 废话多了些。
仔细看断下来的地方,直到来到下面:
0040559A /$ 55 PUSH EBP
0040559B |. 89E5 MOV EBP,ESP
0040559D |. 81EC E0020000 SUB ESP,2E0
004055A3 |. 53 PUSH EBX
004055A4 |. 56 PUSH ESI
004055A5 |. 57 PUSH EDI
004055A6 |. 8D7D B3 LEA EDI,DWORD PTR SS:[EBP-4D]
004055A9 |. 8D35 A1EB4000 LEA ESI,DWORD PTR DS:[40EBA1]
004055AF |. B9 4D000000 MOV ECX,4D
004055B4 |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
004055B6 |. 68 BCD94000 PUSH 0040D9BC ; /IniFileName = "C:\Program Files\WinTools\RAM Saver Pro\ramsaverpro.ini"
004055BB |. 6A 4D PUSH 4D ; |BufSize = 4D (77.)
004055BD |. 8D45 B3 LEA EAX,DWORD PTR SS:[EBP-4D] ; |
004055C0 |. 50 PUSH EAX ; |ReturnBuffer
004055C1 |. 68 D2F74000 PUSH 0040F7D2 ; |Default = ""
004055C6 |. 68 01F44000 PUSH 0040F401 ; |Key = "Temp"
004055CB |. 68 0CF44000 PUSH 0040F40C ; |Section = "SYSFILES"
004055D0 |. E8 B7700000 CALL <JMP.&kernel32.GetPrivateProfileStr>; \GetPrivateProfileStringA
004055D5 |. 09C0 OR EAX,EAX
004055D7 |. 0F84 50010000 JE 0040572D
004055DD |. 8D45 B3 LEA EAX,DWORD PTR SS:[EBP-4D] ; 取出加密过的注册码
004055E0 |. 50 PUSH EAX
004055E1 |. E8 10FAFFFF CALL 00404FF6 ; 还原注册码
004055E6 |. 59 POP ECX
004055E7 |. 8365 AC 00 AND DWORD PTR SS:[EBP-54],0
004055EB |. 31DB XOR EBX,EBX
004055ED |. EB 0B JMP SHORT 004055FA
004055EF |> 807C1D B3 2D /CMP BYTE PTR SS:[EBP+EBX-4D],2D
004055F4 |. 75 03 |JNZ SHORT 004055F9
004055F6 |. FF45 AC |INC DWORD PTR SS:[EBP-54]
004055F9 |> 43 |INC EBX
004055FA |> 8D4D B3 LEA ECX,DWORD PTR SS:[EBP-4D]
004055FD |. 83C8 FF |OR EAX,FFFFFFFF
00405600 |> 40 |/INC EAX
00405601 |. 803C01 00 ||CMP BYTE PTR DS:[ECX+EAX],0
00405605 |.^ 75 F9 |\JNZ SHORT 00405600
00405607 |. 39C3 |CMP EBX,EAX
00405609 |.^ 72 E4 \JB SHORT 004055EF
0040560B |. 837D AC 03 CMP DWORD PTR SS:[EBP-54],3 ; 检查注册码格式是否合法
0040560F |. 74 0A JE SHORT 0040561B ; 即注册码中要有3个"-"号
00405611 |. B8 00000000 MOV EAX,0 ; 也就是用"-"号把注册码分成4个部分
00405616 |. E9 12010000 JMP 0040572D
0040561B |> 6A 2D PUSH 2D ; /c = 2D ('-')
0040561D |. 8D45 B3 LEA EAX,DWORD PTR SS:[EBP-4D] ; |
00405620 |. 50 PUSH EAX ; |s
00405621 |. E8 AE760000 CALL <JMP.&crtdll.strchr> ; \strchr
00405626 |. 6A 2D PUSH 2D ; /c = 2D ('-')
00405628 |. 8D45 B3 LEA EAX,DWORD PTR SS:[EBP-4D] ; |
0040562B |. 50 PUSH EAX ; |s
0040562C |. E8 A3760000 CALL <JMP.&crtdll.strchr> ; \strchr
00405631 |. 8D7D B3 LEA EDI,DWORD PTR SS:[EBP-4D]
00405634 |. 89C3 MOV EBX,EAX
00405636 |. 29FB SUB EBX,EDI ; 取得第一部分的长度
00405638 |. C6441D B3 00 MOV BYTE PTR SS:[EBP+EBX-4D],0
0040563D |. 8D45 B3 LEA EAX,DWORD PTR SS:[EBP-4D]
00405640 |. 50 PUSH EAX
00405641 |. 8D85 07FFFFFF LEA EAX,DWORD PTR SS:[EBP-F9] ; 拷贝第一部分到[ebp-f9]
00405647 |. 50 PUSH EAX
00405648 |. E8 3B3E0000 CALL 00409488
0040564D |. 6A 2D PUSH 2D ; /c = 2D ('-')
0040564F |. 8D441D B4 LEA EAX,DWORD PTR SS:[EBP+EBX-4C] ; |
00405653 |. 50 PUSH EAX ; |s
00405654 |. E8 7B760000 CALL <JMP.&crtdll.strchr> ; \strchr
00405659 |. 8D7C1D B4 LEA EDI,DWORD PTR SS:[EBP+EBX-4C]
0040565D |. 89C6 MOV ESI,EAX
0040565F |. 29FE SUB ESI,EDI
00405661 |. 8D7C1E 01 LEA EDI,DWORD PTR DS:[ESI+EBX+1]
00405665 |. 897D A8 MOV DWORD PTR SS:[EBP-58],EDI
00405668 |. 89F8 MOV EAX,EDI
0040566A |. C64405 B3 00 MOV BYTE PTR SS:[EBP+EAX-4D],0
0040566F |. 6A 2D PUSH 2D ; /c = 2D ('-')
00405671 |. 89F8 MOV EAX,EDI ; |
00405673 |. 8D4405 B4 LEA EAX,DWORD PTR SS:[EBP+EAX-4C] ; |
00405677 |. 50 PUSH EAX ; |s
00405678 |. E8 57760000 CALL <JMP.&crtdll.strchr> ; \strchr
0040567D |. 8D743D B4 LEA ESI,DWORD PTR SS:[EBP+EDI-4C]
00405681 |. 89C2 MOV EDX,EAX
00405683 |. 29F2 SUB EDX,ESI
00405685 |. 8D7C3A 01 LEA EDI,DWORD PTR DS:[EDX+EDI+1]
00405689 |. 89BD 54FFFFFF MOV DWORD PTR SS:[EBP-AC],EDI
0040568F |. 89F8 MOV EAX,EDI
00405691 |. C64405 B3 00 MOV BYTE PTR SS:[EBP+EAX-4D],0
00405696 |. 8D441D B4 LEA EAX,DWORD PTR SS:[EBP+EBX-4C]
0040569A |. 50 PUSH EAX
0040569B |. 8D85 5BFFFFFF LEA EAX,DWORD PTR SS:[EBP-A5] ; 拷贝第二部分
004056A1 |. 50 PUSH EAX
004056A2 |. E8 E13D0000 CALL 00409488
004056A7 |. 8B45 A8 MOV EAX,DWORD PTR SS:[EBP-58]
004056AA |. 8D4405 B4 LEA EAX,DWORD PTR SS:[EBP+EAX-4C]
004056AE |. 50 PUSH EAX ; /src
004056AF |. 8D85 5BFFFFFF LEA EAX,DWORD PTR SS:[EBP-A5] ; |
004056B5 |. 50 PUSH EAX ; |dest
004056B6 |. E8 0D760000 CALL <JMP.&crtdll.strcat> ; \strcat
004056BB |. 8B85 54FFFFFF MOV EAX,DWORD PTR SS:[EBP-AC]
004056C1 |. 8D4405 B4 LEA EAX,DWORD PTR SS:[EBP+EAX-4C]
004056C5 |. 50 PUSH EAX ; /src
004056C6 |. 8D85 5BFFFFFF LEA EAX,DWORD PTR SS:[EBP-A5] ; |
004056CC |. 50 PUSH EAX ; |dest
004056CD |. E8 F6750000 CALL <JMP.&crtdll.strcat> ; \strcat 2,3,4部分连接在一起
004056D2 |. 8D85 07FFFFFF LEA EAX,DWORD PTR SS:[EBP-F9]
004056D8 |. 50 PUSH EAX ; /s
004056D9 |. E8 42750000 CALL <JMP.&crtdll.atol> ; \atol
004056DE |. 8985 20FDFFFF MOV DWORD PTR SS:[EBP-2E0],EAX ; 第一部分转成整数
004056E4 |. 8DBD 26FDFFFF LEA EDI,DWORD PTR SS:[EBP-2DA]
004056EA |. 8D35 EEEB4000 LEA ESI,DWORD PTR DS:[40EBEE]
004056F0 |. B9 E1010000 MOV ECX,1E1
004056F5 |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>; 拷贝那张巨大的表
004056F7 |. 8D85 5BFFFFFF LEA EAX,DWORD PTR SS:[EBP-A5]
004056FD |. 50 PUSH EAX ; 2,3,4部分连接后的字符串
004056FE |. 8D85 26FDFFFF LEA EAX,DWORD PTR SS:[EBP-2DA]
00405704 |. 50 PUSH EAX
00405705 |. E8 CE3D0000 CALL 004094D8 ; 检查连接后的字符串是不是表
0040570A |. 83C4 3C ADD ESP,3C ; 的子串
0040570D |. 09C0 OR EAX,EAX
0040570F |. 74 1C JE SHORT 0040572D
00405711 |. 8D85 5BFFFFFF LEA EAX,DWORD PTR SS:[EBP-A5] ; 2,3,4部分连接后的字符串
00405717 |. 50 PUSH EAX
00405718 |. E8 15000000 CALL 00405732 ; CRC32
0040571D |. 59 POP ECX
0040571E |. 3985 20FDFFFF CMP DWORD PTR SS:[EBP-2E0],EAX ; 和第一部分转成的整数比较
00405724 |. 75 05 JNZ SHORT 0040572B
00405726 |. 31C0 XOR EAX,EAX
00405728 |. 40 INC EAX ; 相等则注册成功
00405729 |. EB 02 JMP SHORT 0040572D
0040572B |> 31C0 XOR EAX,EAX
0040572D |> 5F POP EDI
0040572E |. 5E POP ESI
0040572F |. 5B POP EBX
00405730 |. C9 LEAVE
00405731 \. C3 RETN
40EBEE处的表:
0040EBEE 34 38 37 41 43 35 48 38 39 34 4F 37 41 4A 38 36 487AC5H894O7AJ86
0040EBFE 37 35 34 4B 39 43 41 38 37 36 54 4C 4F 41 38 59 754K9CA876TLOA8Y
0040EC0E 49 54 59 47 48 53 55 4B 46 52 59 4E 54 56 4C 53 ITYGHSUKFRYNTVLS
0040EC1E 59 54 38 53 59 35 55 38 4D 59 54 43 35 38 39 37 YT8SY5U8MYTC5897
0040EC2E 57 54 39 30 35 37 36 54 30 4A 39 38 57 37 35 4F WT90576T0J98W75O
0040EC3E 38 39 37 54 47 38 39 35 57 37 36 38 39 37 57 35 897TG895W76897W5
0040EC4E 38 39 54 37 36 57 39 38 4F 35 37 4A 46 39 38 37 89T76W98O57JF987
0040EC5E 39 4B 53 46 36 39 53 4A 37 36 46 38 39 4A 37 53 9KSF69SJ76F89J7S
0040EC6E 35 38 39 37 46 36 39 38 35 37 47 36 53 35 4A 36 5897F69857G6S5J6
0040EC7E 47 38 37 53 4F 39 38 35 4A 36 47 38 39 53 37 35 G87SO985J6G89S75
0040EC8E 48 39 36 53 4F 39 46 4F 38 35 36 38 39 37 35 57 H96SO9FO8568975W
0040EC9E 53 47 39 34 49 34 33 32 46 35 46 37 32 43 4C 58 SG94I432F5F72CLX
0040ECAE 51 58 50 33 32 36 46 41 52 45 46 4D 34 33 4E 39 QXP326FAREFM43N9
0040ECBE 37 4C 30 39 51 33 4E 56 46 49 53 41 48 38 34 37 7L09Q3NVFISAH847
0040ECCE 54 46 50 38 37 4E 33 57 50 38 37 4E 42 41 39 4E TFP87N3WP87NBA9N
0040ECDE 45 53 5A 32 51 38 4B 58 38 45 34 4C 53 39 51 43 ESZ2Q8KX8E4LS9QC
0040ECEE 45 52 50 46 54 50 44 53 55 39 33 57 5A 39 49 42 ERPFTPDSU93WZ9IB
0040ECFE 4E 59 50 39 55 4F 49 4E 48 41 37 33 59 4A 48 4E NYP9UOINHA73YJHN
0040ED0E 56 38 33 50 42 4E 49 48 44 53 4F 54 53 38 53 4D V83PBNIHDSOTS8SM
0040ED1E 53 39 32 4E 44 55 57 56 44 4A 46 4A 38 39 37 4A S92NDUWVDJFJ897J
0040ED2E 38 57 57 37 4A 38 39 34 37 35 38 39 37 53 34 47 8WW7J89475897S4G
0040ED3E 38 53 37 47 52 37 54 4A 53 38 37 52 47 54 4A 37 8S7GR7TJS87RGTJ7
0040ED4E 35 53 4B 37 59 35 47 54 37 53 35 38 37 49 53 35 5SK7Y5GT7S587IS5
0040ED5E 48 37 53 35 4A 37 36 53 4C 38 35 4B 37 36 44 4C H7S5J76SL85K76DL
0040ED6E 53 38 37 35 34 4B 38 36 4A 37 53 35 47 38 39 37 S8754K86J7S5G897
0040ED7E 53 35 4A 38 34 35 47 34 38 59 4F 39 38 46 37 53 S5J845G48YO98F7S
0040ED8E 57 35 34 36 38 39 46 37 53 35 38 39 36 37 47 53 W54689F7S58967GS
0040ED9E 49 52 59 47 54 55 53 59 47 54 38 39 44 48 54 38 IRYGTUSYGT89DHT8
0040EDAE 39 37 37 44 47 35 38 36 35 34 37 36 39 33 34 37 977DG58654769347
0040EDBE 36 39 37 35 38 39 36 37 35 33 38 34 36 37 38 39 6975896753846789
看看这个算法是不是很简单^_^
1. 注册码分4部分,中间用"-"分开
2. 注册码第1部分转换成一个整数
2. 注册码第2,3,4部分连接在一起
3. 第2,3,4部分必须是那个表的子串
4. 对2,3,4部分连接成的字符串做CRC32,然后和第一部分转成的整数比较
【声明】感谢所有RCT成员及所有RCT的朋友们:)
【全文完】
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)