Registry Medic 4

壳是标准壳,单进程,练手的好东西。
MD5算法,个人认为MD5的东西用来做算法好像没有秘密可言。

1.脱壳:
Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks
单进程

flyODBG:忽略所有异常
005137C3 R>  55             push ebp                             ; 入口点
005137C4     8BEC           mov ebp,esp
005137C6     6A FF          push -1

bp GetModuleHandleA+7
F9第8次有延迟,程序载入dll,然后停住:
00127ADC   00BD4510  /CALL 到 GetModuleHandleA 来自 00BD450A
00127AE0   00BE7B20  \pModule = "kernel32.dll"
00127AE4   00BE8BF8  ASCII "VirtualAlloc"
再次F9:
00127ADC   00BD452D  /CALL 到 GetModuleHandleA 来自 00BD4527
00127AE0   00BE7B20  \pModule = "kernel32.dll"
00127AE4   00BE8BEC  ASCII "VirtualFree"
再次F9:
00127840  |00BC47CB  返回到 00BC47CB 来自 KERNEL32.GetModuleHandleA
00127844  |00127990  ASCII "kernel32.dll"
可以返回了:
00BC47C5     FF15 0421BE00  call dword ptr ds:[BE2104]           ; KERNEL32.GetModuleHandleA
00BC47CB     8B0D 7CF6BE00  mov ecx,dword ptr ds:[BEF67C]        ; 返回在此
00BC47D1     89040E         mov dword ptr ds:[esi+ecx],eax
00BC47D4     A1 7CF6BE00    mov eax,dword ptr ds:[BEF67C]
00BC47D9     391C06         cmp dword ptr ds:[esi+eax],ebx
00BC47DC     75 16          jnz short 00BC47F4
00BC47DE     8D85 B4FEFFFF  lea eax,dword ptr ss:[ebp-14C]
00BC47E4     50             push eax
00BC47E5     FF15 0C21BE00  call dword ptr ds:[BE210C]           ; KERNEL32.LoadLibraryA
00BC47EB     8B0D 7CF6BE00  mov ecx,dword ptr ds:[BEF67C]
00BC47F1     89040E         mov dword ptr ds:[esi+ecx],eax
00BC47F4     A1 7CF6BE00    mov eax,dword ptr ds:[BEF67C]
00BC47F9     391C06         cmp dword ptr ds:[esi+eax],ebx
00BC47FC     0F84 2F010000  je 00BC4931                          ; MAGIC JUMP

bp GetCurrentThreadId
00127400   66001E3A  /CALL 到 GetCurrentThreadId 来自 66001E34
001273E0   66003505  /CALL 到 GetCurrentThreadId 来自 660034FF
0012D794   00BC4B97  /CALL 到 GetCurrentThreadId 来自 00BC4B91
第3次又有延迟,而且00BC4B97是程序的领空,可以返回,然后F8步过若干call来到call ecx:
00BDCA3D     83FF 01        cmp edi,1
00BDCA40     75 18          jnz short 00BDCA5A
00BDCA42     FF76 04        push dword ptr ds:[esi+4]
00BDCA45     FF76 08        push dword ptr ds:[esi+8]
00BDCA48     6A 00          push 0
00BDCA4A     52             push edx
00BDCA4B     8B50 6C        mov edx,dword ptr ds:[eax+6C]
00BDCA4E     3350 50        xor edx,dword ptr ds:[eax+50]
00BDCA51     3350 18        xor edx,dword ptr ds:[eax+18]
00BDCA54     2BCA           sub ecx,edx
00BDCA56     FFD1           call ecx                           ; 准备进入OEP=Regmedic.004D08D0

004D08D0     55             push ebp                           ; OEP
004D08D1     8BEC           mov ebp,esp
004D08D3     83C4 F0        add esp,-10
...
LORDPE选择进程dump,ImportREC:OEP=000D08D0,自动搜索后,RVA=000D51A0,SIZE=00000874,删除无效的函数(一定要删除,不要用第一层或第二层修复)后修复。

修复后PEID:Borland Delphi 6.0 - 7.0,运行ok。

2.断点+关键地方:
用户名:cyto
注册码:87654321
提示:Registration failed. Please try again!

串参考:好几个,选地址最小的一个
004B3A7B      mov edx,dumped_.004B3CB4   ; ASCII "Registration failed. Please try again!"
往上找源头下断:004B3A14     55             push ebp

断下后往下发现对注册码长度的比较:
004B3A61     E8 5612F5FF    call dumped_.00404CBC                ; 注册码长度
004B3A66     83F8 21        cmp eax,21
004B3A69     74 52          je short dumped_.004B3ABD
004B3A6B     8B45 F0        mov eax,dword ptr ss:[ebp-10]
004B3A6E     E8 4912F5FF    call dumped_.00404CBC
004B3A73     83F8 27        cmp eax,27
004B3A76     74 45          je short dumped_.004B3ABD
004B3A78     8D45 EC        lea eax,dword ptr ss:[ebp-14]
004B3A7B     BA B43C4B00    mov edx,dumped_.004B3CB4             ; ASCII "Registration failed. Please try again!"

注册码需要33位或39位
练码改为:87654321-12345678-12345678-761103
又提示用户名需要6位以上,改:cyto1234567

往下又判断了几次用户名或注册码长度,然后来到:
004B3B5B     B8 E43C4B00    mov eax,dumped_.004B3CE4                 ; 用户名
004B3B60     E8 9314F5FF    call dumped_.00404FF8
  00405011     8A06           mov al,byte ptr ds:[esi]          ; 40=@
  00405013     46             inc esi
  00405014     29D1           sub ecx,edx
  00405016     7E 14          jle short dumped_.0040502C
  00405018     F2:AE          repne scas byte ptr es:[edi]
004B3B65     85C0           test eax,eax
004B3B67     75 45          jnz short dumped_.004B3BAE
004B3B69     8D45 EC        lea eax,dword ptr ss:[ebp-14]
004B3B6C     BA B43C4B00    mov edx,dumped_.004B3CB4                   ; ASCII "Registration failed. Please try again!"
这段检查用户名是否有@,没有的话不行的。
我靠,再改用户名:gao@263.com

这下来到关键地方了:
004B3BAE     8B55 F0        mov edx,dword ptr ss:[ebp-10]      ; ZCM
004B3BB1     8B45 F4        mov eax,dword ptr ss:[ebp-C]       ; YHM
004B3BB4     E8 D7D3FFFF    call dumped_.004B0F90              ; 核心call-1
004B3BB9     E8 4ED6FFFF    call dumped_.004B120C              ; 核心call-2
004B3BBE     A1 5C274D00    mov eax,dword ptr ds:[4D275C]
004B3BC3     8038 00        cmp byte ptr ds:[eax],0
004B3BC6     74 4A          je short dumped_.004B3C12
004B3BC8     A1 B0274D00    mov eax,dword ptr ds:[4D27B0]
004B3BCD     8338 00        cmp dword ptr ds:[eax],0
004B3BD0     8D45 EC        lea eax,dword ptr ss:[ebp-14]
004B3BD3     BA F03C4B00    mov edx,dumped_.004B3CF0           ; ASCII "Thank you for registering Registry Medic."

修改004B3BC6处的跳转提示谢谢注册。
跳转之前2个call,呵呵关键处非他们莫属。

3.核心call-1:004B3BB4    call dumped_.004B0F90
参数:edx=注册码; eax=用户名
它们的地址是变的。

先对用户名下硬件访问断点:HR EAX
004AAD4E     84DB           test bl,bl
004AAD50     74 28          je short dumped_.004AAD7A
...
004AAD7A     8B45 FC        mov eax,dword ptr ss:[ebp-4]
004AAD7D     8A4430 FF      mov al,byte ptr ds:[eax+esi-1]      ; 顺取用户名
004AAD81     34 08          xor al,8                            ; 停在此
004AAD83     34 04          xor al,4
004AAD85     25 FF000000    and eax,0FF                         ; 6B,6D...
004AAD8A     8D4D EC        lea ecx,dword ptr ss:[ebp-14]
004AAD8D     BA 02000000    mov edx,2
004AAD92     E8 99E7F5FF    call dumped_.00409530               ; 跟进,转换为字符
004AAD97     8B55 EC        mov edx,dword ptr ss:[ebp-14]
004AAD9A     8D45 F4        lea eax,dword ptr ss:[ebp-C]
004AAD9D     E8 229FF5FF    call dumped_.00404CC4               ; 连接字符
004AADA2     46             inc esi
004AADA3     4F             dec edi
004AADA4   ^ 75 A8          jnz short dumped_.004AAD4E

跟进004AAD92的call: call dumped_.00409530 
0040953E     894424 0C      mov dword ptr ss:[esp+C],eax        ; 保存到12FCC4

HR 12FCC4:
0040A040     8B06           mov eax,dword ptr ds:[esi]          ; 6B
0040A042     0FB656 04      movzx edx,byte ptr ds:[esi+4]       ; 停在此
0040A046     FF2495 4DA0400>jmp dword ptr ds:[edx*4+40A04D]     ; dumped_.0040A14E
...
0040A14E     80F9 44        cmp cl,44
0040A151     74 15          je short dumped_.0040A168
0040A153     80F9 55        cmp cl,55
0040A156     74 22          je short dumped_.0040A17A
0040A158     80F9 58        cmp cl,58
0040A15B   ^ 0F85 30FFFFFF  jnz dumped_.0040A091
0040A161     B9 10000000    mov ecx,10
0040A166     EB 17          jmp short dumped_.0040A17F
...
0040A17F     8D75 9F        lea esi,dword ptr ss:[ebp-61]
0040A182     31D2           xor edx,edx
0040A184     F7F1           div ecx
0040A186     80C2 30        add dl,30
0040A189     80FA 3A        cmp dl,3A
0040A18C     72 03          jb short dumped_.0040A191
0040A18E     80C2 07        add dl,7
0040A191     4E             dec esi
0040A192     8816           mov byte ptr ds:[esi],dl            ; 保存于0012EC2A,0012EC29
0040A194     09C0           or eax,eax
0040A196   ^ 75 EA          jnz short dumped_.0040A182

转换后为:0012EC29  36 42                    6B

拷贝:
断点: 0012EC29
00409FC3     F3:A4          rep movs byte ptr es:[edi],byte ptr ds:[esi]
0012ECA8  36 42                    6B
断点:0012ECA8
004029FA     F3:A4          rep movs byte ptr es:[edi],byte ptr ds:[esi]
00F56ACC  36 42                    6B

然后返回到:
004AAD92     E8 99E7F5FF    call dumped_.00409530
004AAD97     8B55 EC        mov edx,dword ptr ss:[ebp-14]

看来该call只是将计算后的值转换成字符。

004AAD9D     E8 229FF5FF    call dumped_.00404CC4  
对第一个字符6B下硬件访问断点没发现处理,对第2个字符6D下应将访问断点才发现004AAD9D     E8 229FF5FF    call dumped_.00404CC4  是用来连接字符的。
004029FA     F3:A4          rep movs byte ptr es:[edi],byte ptr ds:[esi]
其中地址EDI好像会变,最后:
00F57968  36 42 36 44 36 33 34 43 33 45 33 41 33 46 32 32  6B6D634C3E3A3F22
00F57978  36 46 36 33 36 31 00 00                          6F6361..

拷贝(HR 00F57968):
004029D3     F3:A5          rep movs dword ptr es:[edi],dword ptr ds:[esi]
004029D5     89C1           mov ecx,eax                ; 断在此
00F50838  36 42 36 44 36 33 34 43 33 45 33 00              6B6D634C3E3.

返回到:
004AADC5     E8 4AA1F5FF    call dumped_.00404F14             ; 取前半段
004AADCA     8B45 E8        mov eax,dword ptr ss:[ebp-18]     ;  (ASCII "6B6D634C3E3")
004AADCD     50             push eax
004AADCE     8D45 E4        lea eax,dword ptr ss:[ebp-1C]
004AADD1     50             push eax
004AADD2     8B45 F4        mov eax,dword ptr ss:[ebp-C]      ; 用户名计算值
004AADD5     E8 E29EF5FF    call dumped_.00404CBC             ; 长度=16
004AADDA     8BC8           mov ecx,eax
004AADDC     2BCB           sub ecx,ebx                       ; 16-B(取出的.长度.)
004AADDE     8D53 01        lea edx,dword ptr ds:[ebx+1]      ; C
004AADE1     8B45 F4        mov eax,dword ptr ss:[ebp-C]
004AADE4     E8 2BA1F5FF    call dumped_.00404F14             ; 取后半段
004AADE9     8B55 E4        mov edx,dword ptr ss:[ebp-1C]     ;  (ASCII "A3F226F6361")
004AADEC     8B45 F8        mov eax,dword ptr ss:[ebp-8]
004AADEF     59             pop ecx
004AADF0     E8 139FF5FF    call dumped_.00404D08             ; 对换位置?

6B6D634C3E3A3F226F6361>>>>A3F226F63616B6D634C3E3

然后头尾加上2个字节(随机?,每次都变)得到:
堆栈 ss:[0012FD4C]=00F579A4, (ASCII "8BA3F226F63616B6D634C3E3F8")

返回到:
004B10EF     E8 ECA4FFFF    call dumped_.004AB5E0
004B10F4     FF75 D0        push dword ptr ss:[ebp-30]        ; 8BA3F226F63616B6D634C3E3F8

这样就完成了用户名的处理:gao@263.com
顺取用户名ASCII码 XOR 8 XOR 4,得到的值转换成字符,连接起来= "6B6D634C3E3A3F226F6361"
头尾连接上2个字节=XX6B6D634C3E3A3F226F6361XX

再往下来到:
004B1107     E8 703CF5FF    call dumped_.00404D7C
此时堆栈如下:
0012FD24   00F5D700  ASCII "87654321-12345678-12345678-761103"
0012FD28   004B11F0  dumped_.004B11F0
0012FD2C   00F579A4  ASCII "8BA3F226F63616B6D634C3E3F8"
0012FD30   00F5D7A4  ASCII "30383B383B3A38383E77-C43C3F3C383E3C3C3A06-"

原来是连接得到:30383B383B3A38383E77-C43C3F3C383E3C3C3A06-8BA3F226F63616B6D634C3E3F8-87654321-12345678-12345678-761103
然后写入注册表:
HKCR\CLSID\{83CCB4F4-8A44-4E45-A640-5086C06C62A2}\AppIdK  
HKCR\CLSID\{CD942387-A2E5-4F5D-B83E-9E757FFF4BBC}\AppIdK

现在跟踪注册码的处理:HR EDX,一直到上面写入注册表都没发现对注册码的处理。
因此估计这个call只是对用户名处理然后连接一些数据写入注册表存取。
他接下来的call应该才是计算比较的关键。

4.核心call-2:004B3BB9     call dumped_.004B120C
跟进后来到:
004B121F     E8 489FFFFF      call dumped_.004AB16C
再跟进来到:
004AB1C2     E8 9501FCFF      call dumped_.0046B35C
004AB1C7     33C9             xor ecx,ecx
004AB1C9     BA B8B24A00      mov edx,dumped_.004AB2B8                  ; ASCII "SoftWare\Classes\CLSID\{83CCB4F4-8A44-4E45-A640-5086C06C62A2}"
004AB1CE     8B45 F8          mov eax,dword ptr ss:[ebp-8]
004AB1D1     E8 EE01FCFF      call dumped_.0046B3C4
004AB1D6     84C0             test al,al
004AB1D8     74 56            je short dumped_.004AB230
004AB1DA     BA 00B34A00      mov edx,dumped_.004AB300                  ; ASCII "AppIdK"
004AB1DF     8B45 F8          mov eax,dword ptr ss:[ebp-8]
004AB1E2     E8 6909FCFF      call dumped_.0046BB50
004AB1E7     84C0             test al,al
004AB1E9     74 45            je short dumped_.004AB230
004AB1EB     E8 E0040000      call dumped_.004AB6D0
004AB1F0     84C0             test al,al
004AB1F2     74 5C            je short dumped_.004AB250
004AB1F4     8D4D F4          lea ecx,dword ptr ss:[ebp-C]
004AB1F7     BA 00B34A00      mov edx,dumped_.004AB300                  ; ASCII "AppIdK"
004AB1FC     8B45 F8          mov eax,dword ptr ss:[ebp-8]
004AB1FF     E8 3C07FCFF      call dumped_.0046B940                     ; 取得注册表里的内容?
004AB204     8B45 F4          mov eax,dword ptr ss:[ebp-C]
004AB207     E8 94060000      call dumped_.004AB8A0                     ; 核心?
004AB20C     84C0             test al,al
004AB20E     74 06            je short dumped_.004AB216                 ; 关键跳转

取得注册表里的信息,堆栈 ss:[0012FF44]=00F543B8, (ASCII "30383B383B3A38383E77-C43C3F3C383E3C3C3A06-2EA3F226F63616B6D634C3E3D8-87654321-12345678-12345678-761103")
然后进行比较,目标锁定004AB207的call。

004AB207     E8 94060000      call dumped_.004AB8A0     
代码如下:
004AB8CE     BA 04000000    mov edx,4
004AB8D3     8B45 FC        mov eax,dword ptr ss:[ebp-4]
004AB8D6     E8 01050000    call dumped_.004ABDDC               ; 取得第4组
004AB8DB     8B45 F8        mov eax,dword ptr ss:[ebp-8]        ; 87654321
004AB8DE     50             push eax
004AB8DF     8D4D F4        lea ecx,dword ptr ss:[ebp-C]
004AB8E2     BA 03000000    mov edx,3
004AB8E7     8B45 FC        mov eax,dword ptr ss:[ebp-4]
004AB8EA     E8 ED040000    call dumped_.004ABDDC               ; 取得第3组
004AB8EF     8B45 F4        mov eax,dword ptr ss:[ebp-C]        ;  (ASCII "2EA3F226F63616B6D634C3E3D8")
004AB8F2     5A             pop edx
004AB8F3     E8 2C000000    call dumped_.004AB924                ; 计算

再跟进004AB8F3     call dumped_.004AB924 :  
004AB997     8D55 C8         lea edx,dword ptr ss:[ebp-38]
004AB99A     8B45 F8         mov eax,dword ptr ss:[ebp-8]
004AB99D     E8 3ED7F5FF     call dumped_.004090E0               ; 检查并拷贝第4组=87654321
004AB9A2     8D45 B0         lea eax,dword ptr ss:[ebp-50]
004AB9A5     8B0D C83F4D00   mov ecx,dword ptr ds:[4D3FC8]       ; "9af19b63a9db476829d7f04d9632fd56"
004AB9AB     8B55 F0         mov edx,dword ptr ss:[ebp-10]       ; ASCII "gao@263.com"
004AB9AE     E8 5593F5FF     call dumped_.00404D08               ; 连接
004AB9B3     8B45 B0         mov eax,dword ptr ss:[ebp-50]
004AB9B6     8D55 B4         lea edx,dword ptr ss:[ebp-4C]
004AB9B9     E8 1AF1FFFF     call dumped_.004AAAD8               ; MD5
004AB9BE     8D45 B4         lea eax,dword ptr ss:[ebp-4C]
004AB9C1     8D55 EC         lea edx,dword ptr ss:[ebp-14]
004AB9C4     E8 83F1FFFF     call dumped_.004AAB4C
004AB9C9     8D45 AC         lea eax,dword ptr ss:[ebp-54]
004AB9CC     8B0D 80404D00   mov ecx,dword ptr ds:[4D4080]       ; "2b45e1182533a1fb3c0bc66f536e64fc")
004AB9D2     8B55 EC         mov edx,dword ptr ss:[ebp-14]       ; "0bc71bcce533bff7ee6fa25cc5a6fa3b")
004AB9D5     E8 2E93F5FF     call dumped_.00404D08               ; 连接
004AB9DA     8B45 AC         mov eax,dword ptr ss:[ebp-54]
004AB9DD     8D55 B4         lea edx,dword ptr ss:[ebp-4C]
004AB9E0     E8 F3F0FFFF     call dumped_.004AAAD8               ; MD5
004AB9E5     8D45 B4         lea eax,dword ptr ss:[ebp-4C]
004AB9E8     8D55 E8         lea edx,dword ptr ss:[ebp-18]
004AB9EB     E8 5CF1FFFF     call dumped_.004AAB4C
004AB9F0     8D45 A8         lea eax,dword ptr ss:[ebp-58]
004AB9F3     8B0D 903E4D00   mov ecx,dword ptr ds:[4D3E90]       ; "685741366c409b32b56387ffcf1be72a")
004AB9F9     8B55 E8         mov edx,dword ptr ss:[ebp-18]       ; "59a1f9766f8bea7003f5669b189dc515")
004AB9FC     E8 0793F5FF     call dumped_.00404D08               ; 连接
004ABA01     8B45 A8         mov eax,dword ptr ss:[ebp-58]
004ABA04     8D55 B4         lea edx,dword ptr ss:[ebp-4C]
004ABA07     E8 CCF0FFFF     call dumped_.004AAAD8               ; MD5
004ABA0C     8D45 B4         lea eax,dword ptr ss:[ebp-4C]
004ABA0F     8D55 E4         lea edx,dword ptr ss:[ebp-1C]
004ABA12     E8 35F1FFFF     call dumped_.004AAB4C
004ABA17     8D45 A4         lea eax,dword ptr ss:[ebp-5C]
004ABA1A     8B0D 3C404D00   mov ecx,dword ptr ds:[4D403C]       ; "d83aa6e66c68a865110c2f51e8495ced")
004ABA20     8B55 E4         mov edx,dword ptr ss:[ebp-1C]       ; "54528f8555c8f0a3c3e44bad293df596")
004ABA23     E8 E092F5FF     call dumped_.00404D08
004ABA28     8B45 A4         mov eax,dword ptr ss:[ebp-5C]
004ABA2B     8D55 B4         lea edx,dword ptr ss:[ebp-4C]
004ABA2E     E8 A5F0FFFF     call dumped_.004AAAD8               ; MD5
004ABA33     8D45 B4         lea eax,dword ptr ss:[ebp-4C]
004ABA36     8D55 E0         lea edx,dword ptr ss:[ebp-20]
004ABA39     E8 0EF1FFFF     call dumped_.004AAB4C
004ABA3E     8D45 A0         lea eax,dword ptr ss:[ebp-60]
004ABA41     8B0D 7C414D00   mov ecx,dword ptr ds:[4D417C]       ; "d6cdf360ef1fbe03d6c5f5b27fc0cb59")
004ABA47     8B55 E0         mov edx,dword ptr ss:[ebp-20]       ;  "485be39a626dfb63b41cb5dd6d4962db")
004ABA4A     E8 B992F5FF     call dumped_.00404D08
004ABA4F     8B45 A0         mov eax,dword ptr ss:[ebp-60]
004ABA52     8D55 B4         lea edx,dword ptr ss:[ebp-4C]
004ABA55     E8 7EF0FFFF     call dumped_.004AAAD8               ; MD5
004ABA5A     8D45 B4         lea eax,dword ptr ss:[ebp-4C]
004ABA5D     8D55 DC         lea edx,dword ptr ss:[ebp-24]
004ABA60     E8 E7F0FFFF     call dumped_.004AAB4C
004ABA65     8D4D 9C         lea ecx,dword ptr ss:[ebp-64]
004ABA68     BA 01000000     mov edx,1
004ABA6D     8B45 EC         mov eax,dword ptr ss:[ebp-14]       ; "0bc71bcce533bff7ee6fa25cc5a6fa3b")
004ABA70     E8 BBF1FFFF     call dumped_.004AAC30
004ABA75     8B55 9C         mov edx,dword ptr ss:[ebp-64]
004ABA78     8D45 EC         lea eax,dword ptr ss:[ebp-14]
004ABA7B     E8 1C90F5FF     call dumped_.00404A9C
004ABA80     8D4D 98         lea ecx,dword ptr ss:[ebp-68]
004ABA83     BA 01000000     mov edx,1
004ABA88     8B45 E8         mov eax,dword ptr ss:[ebp-18]       ; "59a1f9766f8bea7003f5669b189dc515")
004ABA8B     E8 A0F1FFFF     call dumped_.004AAC30
004ABA90     8B55 98         mov edx,dword ptr ss:[ebp-68]
004ABA93     8D45 E8         lea eax,dword ptr ss:[ebp-18]
004ABA96     E8 0190F5FF     call dumped_.00404A9C
004ABA9B     8D4D 94         lea ecx,dword ptr ss:[ebp-6C]
004ABA9E     BA 01000000     mov edx,1
004ABAA3     8B45 E4         mov eax,dword ptr ss:[ebp-1C]       ; "54528f8555c8f0a3c3e44bad293df596")
004ABAA6     E8 85F1FFFF     call dumped_.004AAC30
004ABAAB     8B55 94         mov edx,dword ptr ss:[ebp-6C]
004ABAAE     8D45 E4         lea eax,dword ptr ss:[ebp-1C]
004ABAB1     E8 E68FF5FF     call dumped_.00404A9C
004ABAB6     8D4D 90         lea ecx,dword ptr ss:[ebp-70]
004ABAB9     BA 01000000     mov edx,1
004ABABE     8B45 E0         mov eax,dword ptr ss:[ebp-20]       ; "485be39a626dfb63b41cb5dd6d4962db")
004ABAC1     E8 6AF1FFFF     call dumped_.004AAC30
004ABAC6     8B55 90         mov edx,dword ptr ss:[ebp-70]
004ABAC9     8D45 E0         lea eax,dword ptr ss:[ebp-20]
004ABACC     E8 CB8FF5FF     call dumped_.00404A9C
004ABAD1     8D4D 8C         lea ecx,dword ptr ss:[ebp-74]
004ABAD4     BA 01000000     mov edx,1
004ABAD9     8B45 DC         mov eax,dword ptr ss:[ebp-24]       ; "07274d30ea3d54bb3435d9f68c657d4e")
004ABADC     E8 4FF1FFFF     call dumped_.004AAC30
004ABAE1     8B55 8C         mov edx,dword ptr ss:[ebp-74]
004ABAE4     8D45 DC         lea eax,dword ptr ss:[ebp-24]
004ABAE7     E8 B08FF5FF     call dumped_.00404A9C
004ABAEC     FF75 EC         push dword ptr ss:[ebp-14]
004ABAEF     FF75 E8         push dword ptr ss:[ebp-18]
004ABAF2     FF75 E4         push dword ptr ss:[ebp-1C]
004ABAF5     FF75 E0         push dword ptr ss:[ebp-20]
004ABAF8     FF75 DC         push dword ptr ss:[ebp-24]
004ABAFB     8D45 D8         lea eax,dword ptr ss:[ebp-28]
004ABAFE     BA 05000000     mov edx,5
004ABB03     E8 7492F5FF     call dumped_.00404D7C
004ABB08     8D4D CC         lea ecx,dword ptr ss:[ebp-34]
004ABB0B     BA 05000000     mov edx,5
004ABB10     8B45 C8         mov eax,dword ptr ss:[ebp-38]
004ABB13     E8 18F1FFFF     call dumped_.004AAC30               ; 取注册码前5位=87654
004ABB18     8D4D D4         lea ecx,dword ptr ss:[ebp-2C]
004ABB1B     BA 03000000     mov edx,3
004ABB20     8B45 C8         mov eax,dword ptr ss:[ebp-38]
004ABB23     E8 60F1FFFF     call dumped_.004AAC88               ; ??
004ABB28     8D4D 84         lea ecx,dword ptr ss:[ebp-7C]
004ABB2B     BA 1E000000     mov edx,1E
004ABB30     8B45 C8         mov eax,dword ptr ss:[ebp-38]
004ABB33     E8 F8F0FFFF     call dumped_.004AAC30               ; 取注册码前30位
004ABB38     8B45 84         mov eax,dword ptr ss:[ebp-7C]
004ABB3B     8D55 B4         lea edx,dword ptr ss:[ebp-4C]
004ABB3E     E8 95EFFFFF     call dumped_.004AAAD8
004ABB43     8D45 B4         lea eax,dword ptr ss:[ebp-4C]
004ABB46     8D55 88         lea edx,dword ptr ss:[ebp-78]
004ABB49     E8 FEEFFFFF     call dumped_.004AAB4C               ; MD5(注册码前30位)
004ABB4E     8B45 88         mov eax,dword ptr ss:[ebp-78]       ; "5e8667a439c68f5145dd2fcbecf02209")
004ABB51     8D4D D0         lea ecx,dword ptr ss:[ebp-30]
004ABB54     BA 03000000     mov edx,3
004ABB59     E8 D2F0FFFF     call dumped_.004AAC30               ; ??
004ABB5E     8B45 D8         mov eax,dword ptr ss:[ebp-28]       ; 05540
004ABB61     8B55 CC         mov edx,dword ptr ss:[ebp-34]       ; 87654
004ABB64     E8 9792F5FF     call dumped_.00404E00
004ABB69     75 11           jnz short dumped_.004ABB7C
004ABB6B     8B45 D4         mov eax,dword ptr ss:[ebp-2C]       ; 321
004ABB6E     8B55 D0         mov edx,dword ptr ss:[ebp-30]       ; 5e8
004ABB71     E8 8A92F5FF     call dumped_.00404E00
004ABB76     75 04           jnz short dumped_.004ABB7C
004ABB78     C645 F7 01      mov byte ptr ss:[ebp-9],1            ; 它的赋值决定返回后的跳转
004ABB7C     33C0            xor eax,eax
004ABB7E     5A              pop edx
004ABB7F     59              pop ecx
004ABB80     59              pop ecx
004ABB81     64:8910         mov dword ptr fs:[eax],edx
004ABB84     68 91BB4A00     push dumped_.004ABB91
004ABB89     C3              retn

流程很明显,都是MD5的运算,参与运算的两个参数,一个用户名gao@263.com,一个是注册码(因为注册码以“-”号形式连接,所以只取“-”号前面的,后面的不参与)。

5.算法总结:
5.1程序对输入的用户名及注册码有要求:
用户名大于6位,注册码要33位或者39位。
对用户名进行计算:
顺取用户名ASCII码 XOR 8 XOR 4,得到的值转换成字符,连接起来= "6B6D634C3E3A3F226F6361"
头尾转换A3F226F63616B6D634C3E3,随机连接上2个字节=XXA3F226F63616B6D634C3E3XX
然后连接字符串: 30383B383B3A38383E77;C43C3F3C383E3C3C3A06;和输入的注册码87654321-12345678-12345678-761103:
 "30383B383B3A38383E77-C43C3F3C383E3C3C3A06-XXA3F226F63616B6D634C3E3XX-87654321-12345678-12345678-761103")
写入注册表。

5.2从注册表里取出信息,以“-”号连接的,第一第二组为程序加上去的,第3组为用户名的计算值,第4组为注册码,如果注册码也是以“-”号连接的话只取到“-”号为止。
先取第3组,还原成用户名;再取第4组注册码(只取“-”号前的字符);

用户名与字符串9af19b63a9db476829d7f04d9632fd56连接:
gao@263.com9af19b63a9db476829d7f04d9632fd56
MD5()=0bc71bcce533bff7ee6fa25cc5a6fa3b;

连接 2b45e1182533a1fb3c0bc66f536e64fc:
0bc71bcce533bff7ee6fa25cc5a6fa3b2b45e1182533a1fb3c0bc66f536e64fc
MD5()=59a1f9766f8bea7003f5669b189dc515;

连接685741366c409b32b56387ffcf1be72a:
59a1f9766f8bea7003f5669b189dc515685741366c409b32b56387ffcf1be72a
MD5()=54528f8555c8f0a3c3e44bad293df596

连接d83aa6e66c68a865110c2f51e8495ced:
54528f8555c8f0a3c3e44bad293df596d83aa6e66c68a865110c2f51e8495ced
MD5()=485be39a626dfb63b41cb5dd6d4962db

连接"d6cdf360ef1fbe03d6c5f5b27fc0cb59":
485be39a626dfb63b41cb5dd6d4962dbd6cdf360ef1fbe03d6c5f5b27fc0cb59
MD5()=07274d30ea3d54bb3435d9f68c657d4e

其中这几个为内置的字符串,或者其他,但相对固定的:
9af19b63a9db476829d7f04d9632fd56
2b45e1182533a1fb3c0bc66f536e64fc
685741366c409b32b56387ffcf1be72a
d83aa6e66c68a865110c2f51e8495ced
d6cdf360ef1fbe03d6c5f5b27fc0cb59

然后取每个MD5值的第一位数连接起来:05540
这个与注册码的前5位比较,要相等。
然后对MD5(注册码前30位),值的前3位=注册码的后3位。
这样的话输入的注册码前33位不能有“-”号,要不逆推md5会死人。
39位的注册码类似。

这样就注册成功!

用户名:gao@263.com
注册码:055408888888888888888888888888C6D

写入注册表项目:
HKCR\CLSID\{83CCB4F4-8A44-4E45-A640-5086C06C62A2}\AppIdK  
HKCR\CLSID\{CD942387-A2E5-4F5D-B83E-9E757FFF4BBC}\AppIdK
HKLM\SOFTWARE\Microsoft\Cryptography\RNG\Seed  


6.后记
发现硬件访问断点非常好用,对入栈的参数分别进行下断跟踪,层层下断层层跟踪找到源头,然后再层层返回。
最后所有参数断点都指向某个call的时候该call就是真正核心计算的地方了。
一个缺点就是硬件访问断点碰到拷贝次数多的时候很累很繁琐,有时候还要跟飞。但我认为比一个一个call的跟进好多了。
对于md5运算的,准备好md5计算器,看到可疑的32位的就md5一下,呵呵,屡试不爽。