飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 2504|回复: 0

FoEyes申请加入PYG----作业3

[复制链接]

该用户从未签到

发表于 2008-1-20 15:55:18 | 显示全部楼层 |阅读模式
【破文标题】实创个人理财系统1.58(最新版)脱壳+去自效验+算法分析
【破文作者】FoEyes
【作者邮箱】
【作者主页】
破解工具】PEID,OD,DEDE
【破解平台】WinXP
【软件名称】实创个人理财系统
【更新时间】2008-1-13
【原版下载】http://www.chinascsoft.com/
【保护方式】壳+自效验+注册码
【软件简介】实创个人理财系统是一款界面美观大方、操作方便,数据安全、系统保密性好的个人理财系统,系统主要有以下功能:
(1)个人帐户管理,管理个人的银行存折帐户信息;
(2)个人收支管理,记录个人每天的收支情况,并可进行统计汇总及收支分析功能;
(3)个人借贷管理功能,实现个人借贷信息的管理
(4)收支分类维护,可自定义收支要类;
(5)物品管理功能,可管理家里的固定财产,并可自定义物品分类;(6)证券管理,记录证券交易明细,及时了解投资情况;
(7)资料管理,记录一些备忘录或理财之类的文章;
(8)个人所得税计算;
(9)存款计算器;
(10)在线升级功能。同时系统还具有手工或自动数据备份恢复功能
【破解声明】本文仅供研究学习,本人对因这篇文章而导致的一切后果,不承担任何法律责任
------------------------------------------------------------------------
【破解过程】PEid检查 ASPack 2.12 -> Alexey Solodovnikov,这里练习一下手动利用ESP定律脱壳。

再次PEid之,Borland Delphi 6.0 - 7.0,扫描算法,blowfish,DES,SHA,base64.....汗,怀疑用了加密控件,经后来分析证实。

运行脱壳程序,直接退出,看来有自效验。

OD载入,来到这里
007E4650  |.  E8 7B82E2FF   call    0060C8D0                          得到脱壳后文件大小
007E4655  |.  8B45 EC       mov     eax, dword ptr [ebp-14]
007E4658  |.  E8 0B59C2FF   call    00409F68                         ;  
007E465D  |.  8B15 CC707F00 mov     edx, dword ptr [7F70CC]          ;  
007E4663  |.  3B02          cmp     eax, dword ptr [edx]              此处比较文件大小自效验
007E4665  |.  74 52         je      short 007E46B9                    此处jnz改为je即可
007E4667  |.  E8 60E4FFFF   call    007E2ACC
007E466C  |.  8B0D 6C6A7F00 mov     ecx, dword ptr [7F6A6C]          ;  
007E4672  |.  A1 606D7F00   mov     eax, dword ptr [7F6D60]
007E4677  |.  8B00          mov     eax, dword ptr [eax]
007E4679  |.  8B15 A0967C00 mov     edx, dword ptr [7C96A0]          ;  
007E467F  |.  E8 7012CBFF   call    004958F4
007E4684  |.  E8 77E4FFFF   call    007E2B00

改跳转 dump之。

程序有硬件码,下断GetVolumeInformationA没有反应,于是bp CreateFileA来到这里
005FCD4B   . /75 21         jnz     short 005FCD6E
005FCD4D   . |6A 00         push    0                                ; /hTemplateFile = NULL
005FCD4F   . |6A 00         push    0                                ; |Attributes = 0
005FCD51   . |6A 03         push    3                                ; |Mode = OPEN_EXISTING
005FCD53   . |6A 00         push    0                                ; |pSecurity = NULL
005FCD55   . |6A 03         push    3                                ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
005FCD57   . |68 000000C0   push    C0000000                         ; |Access = GENERIC_READ|GENERIC_WRITE
005FCD5C   . |68 80CE5F00   push    005FCE80                         ; |FileName = "\\.\PhysicalDrive0"
005FCD61   . |E8 6AA7E0FF   call    <jmp.&kernel32.CreateFileA>      ; \CreateFileA
005FCD66   . |8985 ECFDFFFF mov     dword ptr [ebp-214], eax
005FCD6C   . |EB 1C         jmp     short 005FCD8A
005FCD6E   > \6A 00         push    0                                ; /hTemplateFile = NULL
005FCD70   .  6A 00         push    0                                ; |Attributes = 0
005FCD72   .  6A 01         push    1                                ; |Mode = CREATE_NEW
005FCD74   .  6A 00         push    0                                ; |pSecurity = NULL
005FCD76   .  6A 00         push    0                                ; |ShareMode = 0
005FCD78   .  6A 00         push    0                                ; |Access = 0
005FCD7A   .  68 94CE5F00   push    005FCE94                         ; |FileName = "\\.\SMARTVSD"
005FCD7F   .  E8 4CA7E0FF   call    <jmp.&kernel32.CreateFileA>      ; \CreateFileA

005FCDF0   .  C685 D1FDFFFF>mov     byte ptr [ebp-22F], 0EC
005FCDF7   .  6A 00         push    0                                ; /pOverlapped = NULL
005FCDF9   .  8D85 E8FDFFFF lea     eax, dword ptr [ebp-218]         ; |
005FCDFF   .  50            push    eax                              ; |pBytesReturned
005FCE00   .  68 10020000   push    210                              ; |OutBufferSize = 210 (528.)
005FCE05   .  8D85 F0FDFFFF lea     eax, dword ptr [ebp-210]         ; |
005FCE0B   .  50            push    eax                              ; |OutBuffer
005FCE0C   .  6A 20         push    20                               ; |InBufferSize = 20 (32.)
005FCE0E   .  8D85 C7FDFFFF lea     eax, dword ptr [ebp-239]         ; |
005FCE14   .  50            push    eax                              ; |InBuffer
005FCE15   .  68 88C00700   push    7C088                            ; |IoControlCode = SMART_RCV_DRIVE_DATA
005FCE1A   .  8B85 ECFDFFFF mov     eax, dword ptr [ebp-214]         ; |
005FCE20   .  50            push    eax                              ; |hDevice
005FCE21   .  E8 FAA6E0FF   call    <jmp.&kernel32.DeviceIoControl>  ; \DeviceIoControl
005FCE26   .  85C0          test    eax, eax
005FCE28   .  75 07         jnz     short 005FCE31

可以得到是DeviceIoControl函数得到硬盘序列号A

继续往下走发现又获得了本机的CPUID值B

分别取B,A得后四位,连接得到了八位注册硬件码。

用dede静态分析,得到注册按钮的地址,直接下断
007819A7  |.  8D55 F8       lea     edx, dword ptr [ebp-8]
007819AA  |.  8B86 04030000 mov     eax, dword ptr [esi+304]
007819B0  |.  E8 03AFD1FF   call    0049C8B8                         ;  得到试练码
007819B5  |.  8B45 F8       mov     eax, dword ptr [ebp-8]
007819B8  |.  8D55 FC       lea     edx, dword ptr [ebp-4]
007819BB  |.  E8 9C80C8FF   call    00409A5C
007819C0  |.  8B55 FC       mov     edx, dword ptr [ebp-4]
007819C3  |.  B8 BC1A7800   mov     eax, 00781ABC                    ;  ASCII "SoftLicense"
007819C8  |.  E8 5B5DE8FF   call    00607728                         ;  注册码写入注册表
007819CD  |.  8BC6          mov     eax, esi
007819CF  |.  E8 E8FCFFFF   call    007816BC
007819D4  |.  8BC6          mov     eax, esi
007819D6  |.  E8 F9FCFFFF   call    007816D4                         ;  开始计算
007819DB  |.  8BD8          mov     ebx, eax
007819DD  |.  8BC6          mov     eax, esi
007819DF  |.  E8 C8FEFFFF   call    007818AC
007819E4  |.  84C3          test    bl, al
007819E6  |.  74 21         je      short 00781A09                   ;  这里是一个爆破点

跟进开始计算来这里
0078175C  |.  E8 FB82C8FF   call    00409A5C
00781761  |.  8B45 E8       mov     eax, dword ptr [ebp-18]          ;  0123456789foeyes
00781764  |.  8D4D EC       lea     ecx, dword ptr [ebp-14]
00781767  |.  8B55 F8       mov     edx, dword ptr [ebp-8]           ;  RUM1N0Y3OURCQ0E0OUEwNzM0MDM1MjlCMTMxQTQ2ODIxQw==
0078176A  |.  E8 4D55E8FF   call    00606CBC                         ;  关键call由以上两个得到A
0078176F  |.  8B45 EC       mov     eax, dword ptr [ebp-14]
00781772  |.  50            push    eax
00781773  |.  8D55 DC       lea     edx, dword ptr [ebp-24]
00781776  |.  8B83 00030000 mov     eax, dword ptr [ebx+300]
0078177C  |.  E8 37B1D1FF   call    0049C8B8
00781781  |.  8B45 DC       mov     eax, dword ptr [ebp-24]          ;  压入机器码FBFF6PKN
00781784  |.  8D55 E0       lea     edx, dword ptr [ebp-20]
00781787  |.  E8 D082C8FF   call    00409A5C
0078178C  |.  8B55 E0       mov     edx, dword ptr [ebp-20]
0078178F  |.  58            pop     eax
00781790  |.  E8 7B36C8FF   call    00404E10                         ;  比较A和注册码
00781795  |.  0F84 8C000000 je      00781827                         ;  关键跳转,爆破点

分析得到流程是,注册码和一个被base64的常数进行运算得到的值与硬件码比较,相等则注册成功。


继续跟进关键call

发现注册码不能小与13位,否则报错,多于16位的,只取前16位,因为要将注册码分成4组,最后一组要保证1-4位
00606D4E  |.  E8 D1E1DFFF   call    00404F24
00606D53  |.  FF75 E4       push    dword ptr [ebp-1C]               ;  5678
00606D56  |.  8D45 E0       lea     eax, dword ptr [ebp-20]
00606D59  |.  50            push    eax
00606D5A  |.  B9 04000000   mov     ecx, 4
00606D5F  |.  BA 0D000000   mov     edx, 0D
00606D64  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
00606D67  |.  E8 B8E1DFFF   call    00404F24
00606D6C  |.  FF75 E0       push    dword ptr [ebp-20]               ;  yes
00606D6F  |.  8D45 DC       lea     eax, dword ptr [ebp-24]
00606D72  |.  50            push    eax
00606D73  |.  B9 04000000   mov     ecx, 4
00606D78  |.  BA 01000000   mov     edx, 1
00606D7D  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
00606D80  |.  E8 9FE1DFFF   call    00404F24
00606D85  |.  FF75 DC       push    dword ptr [ebp-24]               ;  1234
00606D88  |.  8D45 D8       lea     eax, dword ptr [ebp-28]
00606D8B  |.  50            push    eax
00606D8C  |.  B9 04000000   mov     ecx, 4
00606D91  |.  BA 09000000   mov     edx, 9
00606D96  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
00606D99  |.  E8 86E1DFFF   call    00404F24
00606D9E  |.  FF75 D8       push    dword ptr [ebp-28]               ;  9foe
00606DA1  |.  8D45 FC       lea     eax, dword ptr [ebp-4]
00606DA4  |.  BA 04000000   mov     edx, 4
00606DA9  |.  E8 D6DFDFFF   call    00404D84                         ;  得到新串5678yes12349foe

把注册码AAAABBBBCCCCDDDD 变为 BBBBDDDDAAAACCCC形式
然后将变形后的新串从左到右分为四组,每一组和另外2个数运算得到2个字节的数据

00606DF2  |.  8B45 D0       mov     eax, dword ptr [ebp-30]          ;  5678
00606DF5  |.  8D4D F4       lea     ecx, dword ptr [ebp-C]           ;  500501
00606DF8  |.  8B55 F8       mov     edx, dword ptr [ebp-8]           ;  base64得一个值
00606DFB  |.  E8 7CFAFFFF   call    0060687C                         ;  关键函数

跟进后里面比较复杂,每组数又进行了新的变换,和两个常数又进行了一系列乱七八糟的计算,加密算法不是很熟,耽误了很长时间,最后却发现变换后的数和一组固定的数xor即

得到了结果,由此绕过了加密算法的分析

每一组又分为两组再次变形计算如下:
005F2DD2  |> /8A06          /mov     al, byte ptr [esi]              ;  第一位
005F2DD4  |. |E8 E7FFE0FF   |call    00402DC0                        ;  是字母就变大写
005F2DD9  |. |46            |inc     esi
005F2DDA  |. |3C 39         |cmp     al, 39                          ;  是数字
005F2DDC  |. |76 08         |jbe     short 005F2DE6                  ;  处理字母
005F2DDE  |. |2C 41         |sub     al, 41
005F2DE0  |. |04 0A         |add     al, 0A                          ;  -37
005F2DE2  |. |8803          |mov     byte ptr [ebx], al
005F2DE4  |. |EB 04         |jmp     short 005F2DEA
005F2DE6  |> |2C 30         |sub     al, 30                          ;  是数字-30
005F2DE8  |. |8803          |mov     byte ptr [ebx], al
005F2DEA  |> |8A06          |mov     al, byte ptr [esi]              ;  第二位
005F2DEC  |. |E8 CFFFE0FF   |call    00402DC0
005F2DF1  |. |46            |inc     esi
005F2DF2  |. |C023 04       |shl     byte ptr [ebx], 4               ;  对第一位左移处理移到高位
005F2DF5  |. |3C 39         |cmp     al, 39
005F2DF7  |. |76 08         |jbe     short 005F2E01
005F2DF9  |. |2C 41         |sub     al, 41
005F2DFB  |. |04 0A         |add     al, 0A
005F2DFD  |. |0803          |or      byte ptr [ebx], al              ;  or运算
005F2DFF  |. |EB 04         |jmp     short 005F2E05
005F2E01  |> |2C 30         |sub     al, 30
005F2E03  |. |0803          |or      byte ptr [ebx], al
005F2E05  |> |83EF 02       |sub     edi, 2
005F2E08  |. |43            |inc     ebx
005F2E09  |. |85FF          |test    edi, edi
005F2E0B  |.^\7F C5         \jg      short 005F2DD2


每一位是数字就hex-30,是字母变大写然后hex-37,将变换后的第一位左移四位,即将低位移至高位,与变换后的第二位做or运算,最终每一组四个字符得到了2个字节的数据

005F869D  |> /8B53 1C       /mov     edx, dword ptr [ebx+1C]
005F86A0  |. |8B43 24       |mov     eax, dword ptr [ebx+24]
005F86A3  |. |8B4B 14       |mov     ecx, dword ptr [ebx+14]
005F86A6  |. |E8 1DA5E0FF   |call    00402BC8
005F86AB  |. |8B53 1C       |mov     edx, dword ptr [ebx+1C]
005F86AE  |. |8BC3          |mov     eax, ebx
005F86B0  |. |8B08          |mov     ecx, dword ptr [eax]
005F86B2  |. |FF51 18       |call    dword ptr [ecx+18]              ;  
005F86B5  |. |8B45 F8       |mov     eax, dword ptr [ebp-8]
005F86B8  |. |8A00          |mov     al, byte ptr [eax]              ;  这是最后变换后的2个字节的数据
005F86BA  |. |8B53 1C       |mov     edx, dword ptr [ebx+1C]            edx里面既是一个固定的数
005F86BD  |. |3202          |xor     al, byte ptr [edx]              ;  异或得到最终结果!
005F86BF  |. |8806          |mov     byte ptr [esi], al              ;  
005F86C1  |. |8B4B 14       |mov     ecx, dword ptr [ebx+14]         ;  
005F86C4  |. |49            |dec     ecx                             ;  
005F86C5  |. |8B43 24       |mov     eax, dword ptr [ebx+24]
005F86C8  |. |50            |push    eax                             ;  
005F86C9  |. |40            |inc     eax
005F86CA  |. |5A            |pop     edx
005F86CB  |. |E8 F8A4E0FF   |call    00402BC8
005F86D0  |. |8B43 24       |mov     eax, dword ptr [ebx+24]
005F86D3  |. |8B53 14       |mov     edx, dword ptr [ebx+14]
005F86D6  |. |8B4B 1C       |mov     ecx, dword ptr [ebx+1C]
005F86D9  |. |8A09          |mov     cl, byte ptr [ecx]



------------------------------------------------------------------------
【破解总结】

注册硬件码是由DeviceIoControl函数得到硬盘序列号A,本机的CPUID值B,分别取B,A得后四位,连接得到了八位注册硬件码

验证算法流程如下
1。注册码不能少于13位,大于16位只取前16位,将AAAABBBBCCCCDDDD--->BBBBDDDDAAAACCCC(x)
2。将x从左到右分成四组,前三组每组四位,最后一组1-4位。
3。每一组再分为两组,每组两位,每一位是数字就hex-30,是字母变大写然后hex-37,将变换后的第一位左移四位,即   将低位移至高位,低位置0,与变换后的第二位做or运算,
最终每一组四个字符得到了2个字节的数据,比如7777,运算后得到0x7777。
4。假设得到四组数位0x6666,0x8888,0x5555,0x7777,分别与0x512c,0x17f3,0xe176,0xa2e5(是不变得)做异或运算     得到0x374A9F7BB423D592
5。交叉替换0x374A9F7BB423D592--->0x379F4A7BB4D52392得到最终结果与硬件码比较,相等则注册成功。

先附上爆破补丁,直接覆盖主程序即可。

------------------------------------------------------------------------
【版权声明】
加密算法了解不够,还须努力

[ 本帖最后由 foeyes 于 2008-1-20 15:56 编辑 ]
PYG19周年生日快乐!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表