C编程解禁软件安装向导
程序员文章站
2022-11-20 15:27:06
作者: Hokkien看了这么多期黑防,还没有看到关于软件向导的注册破解,今天,我就来开个先例。Screen Saver Construction Set 2.0是一款制作屏保软件,感觉还不错...
作者: Hokkien
看了这么多期黑防,还没有看到关于软件向导的注册破解,今天,我就来开个先例。Screen Saver Construction Set 2.0是一款制作屏保软件,感觉还不错。废话不多说,我们现在就来解禁它。
认识软件
查壳显示它由“Borland C++”编译,没加壳。运行安装向导,出现如图1所示的注册信息。看来没有注册码是没法安装下去了,所以只好自力更生了。用OD载入,看看有没有什么重要字符。很遗憾,没有。但不用害怕。我们选择API函数GetWindowTextA下断点。经过筛选后,可以定位到关键代码处。
图1
算法分析
成功下断后,可以定位到下面的代码处,现在开始进行分析。
00405317 |. 51 push ecx ;输入的注册码
00405318 |. E8 CF590200 call 0042ACEC ;ScreenSa.0042ACEC
0040531D |. 59 pop ecx
0040531E |. 83F8 11 cmp eax, 11 ;比较注册码长度应为17,包括3个“-”
00405321 74 07 je short 0040532A
从上面我们知道了注册码的长度应该是17位。经过多次的跟踪发现,注册码的最终形式应该是这样的:“XXXXX-XX-XXXXX-XX”。F8接着往下走,来到下面的代码处。
00405373 |> /33C0 /xor eax, eax
00405375 |. |8A8435 08E3FF>|mov al, byte ptr [ebp+esi-1CF8] ;注册名
0040537C |. |50 |push eax ;/Arg1
0040537D |. |E8 BEB30200 |call 00430740 ;转化为小写字母
00405382 |. |59 |pop ecx
00405383 |. |8BD6 |mov edx, esi
00405385 |. |83E2 07 |and edx, 7
00405388 |. |33C9 |xor ecx, ecx
0040538A |. |8A8A 88504300 |mov cl, byte ptr [edx+435088] ;某个表
00405390 |. |33C1 |xor eax, ecx
00405392 |. |0185 38FFFFFF |add dword ptr [ebp-C8], eax
00405398 |. |46 |inc esi
00405399 |> |80BC35 08E3FF> cmp byte ptr [ebp+esi-1CF8], 0 ;注册名
004053A1 |.^75 D0 jnz short 00405373
上面是对注册名进行运算。至于上面提到的表,其形式为:“0X80,0X40,0X20,0X10,0X08,0X04,0X02,0X01”。现在,我们总结一下对注册名的处理算法:注册名的相应位字符与上面表的相应位数字异或,然后相加,所得结果备用,我们假设记为CN。接着下去,来到这里:
004053A3 |. 8B85 38FFFFFF mov eax, dword ptr [ebp-C8] ;就是上面计算的CN
004053A9 |. B9 64000000 mov ecx, 64
004053AE |. 99 cdq
004053AF |. F7F9 idiv ecx
004053B1 |. 8995 40FFFFFF mov dword ptr [ebp-C0], edx ;取余数
004053B7 |. 83BD 40FFFFFF>cmp dword ptr [ebp-C0], 0
004053BE 75 06 jnz short 004053C6
004053C0 |. FF85 40FFFFFF inc dword ptr [ebp-C0]
004053C6 |> 8D85 06E2FFFF lea eax, dword ptr [ebp-1DFA]
004053CC |. 50 push eax ;注册码第2组
004053CD |. E8 5AB50200 call 0043092C ;对注册码第2组运算的函数
004053D2 |. 59 pop ecx
004053D3 |. 3B85 40FFFFFF cmp eax, dword ptr [ebp-C0]
004053D9 74 08 je short 004053E3
现在我们知道了对注册名进行运算的作用了,即CN%0X64==Fun(注册码第2组)。那么这个Fun函数是怎么对注册码第2组进行运算的呢?我们F7进入0043092C,来到这里。
0043092C /$ 55 push ebp
0043092D |. 8BEC mov ebp, esp
0043092F |. 53 push ebx
00430930 |. 56 push esi
00430931 |. 8B55 08 mov edx, dword ptr [ebp+8]
00430934 |. 33C9 xor ecx, ecx
00430936 |> 8A02 /mov al, byte ptr [edx]
00430938 |. 42 |inc edx
00430939 |. 0FBED8 |movsx ebx, al
0043093C |. F683 DD204400>|test byte ptr [ebx+4420DD], 1
00430943 |.^ 75 F1 jnz short 00430936
00430945 |. 3C 2B cmp al, 2B
00430947 |. 74 04 je short 0043094D
00430949 |. 3C 2D cmp al, 2D
0043094B |. 75 0F jnz short 0043095C
0043094D |> 3C 2D cmp al, 2D
0043094F |. 0F94C0 sete al
00430952 |. 83E0 01 and eax, 1
00430955 |. 8BF0 mov esi, eax
00430957 |. 8A02 mov al, byte ptr [edx]
00430959 |. 42 inc edx
0043095A |. EB 14 jmp short 00430970
0043095C |> 33F6 xor esi, esi
0043095E |. EB 10 jmp short 00430970 ;下面是关键计算
00430960 |> 0FBEC0 /movsx eax, al
00430963 |. 03C9 |add ecx, ecx
00430965 |. 8D0C89 |lea ecx, dword ptr [ecx+ecx*4]
00430968 |. 03C8 |add ecx, eax
0043096A |. 8A02 |mov al, byte ptr [edx]
0043096C |. 83C1 D0 |add ecx, -30
0043096F |. 42 |inc edx
00430970 |> 3C 30 cmp al, 30
00430972 |. 7C 04 |jl short 00430978
00430974 |. 3C 39 |cmp al, 39
00430976 |.^ 7E E8 jle short 00430960
00430978 |> 85F6 test esi, esi
0043097A |. 74 06 je short 00430982
0043097C |. 8BC1 mov eax, ecx
0043097E |. F7D8 neg eax
00430980 |. EB 02 jmp short 00430984
00430982 |> 8BC1 mov eax, ecx
00430984 |> 5E pop esi
00430985 |. 5B pop ebx
00430986 |. 5D pop ebp
00430987 . C3 retn
上面的代码是这样运算的,我们以“67”进行说明。首先,把“6”变成数字的6,然后6*10=60,接着,60+ASC(“7”)=60+47=107=0X47,就是最终的结果。F8下去,来到这里:
004053FC |> /8A8435 00E2FF>/mov al, byte ptr [ebp+esi-1E00] ;第1组注册码
00
看了这么多期黑防,还没有看到关于软件向导的注册破解,今天,我就来开个先例。Screen Saver Construction Set 2.0是一款制作屏保软件,感觉还不错。废话不多说,我们现在就来解禁它。
认识软件
查壳显示它由“Borland C++”编译,没加壳。运行安装向导,出现如图1所示的注册信息。看来没有注册码是没法安装下去了,所以只好自力更生了。用OD载入,看看有没有什么重要字符。很遗憾,没有。但不用害怕。我们选择API函数GetWindowTextA下断点。经过筛选后,可以定位到关键代码处。
图1
算法分析
成功下断后,可以定位到下面的代码处,现在开始进行分析。
00405317 |. 51 push ecx ;输入的注册码
00405318 |. E8 CF590200 call 0042ACEC ;ScreenSa.0042ACEC
0040531D |. 59 pop ecx
0040531E |. 83F8 11 cmp eax, 11 ;比较注册码长度应为17,包括3个“-”
00405321 74 07 je short 0040532A
从上面我们知道了注册码的长度应该是17位。经过多次的跟踪发现,注册码的最终形式应该是这样的:“XXXXX-XX-XXXXX-XX”。F8接着往下走,来到下面的代码处。
00405373 |> /33C0 /xor eax, eax
00405375 |. |8A8435 08E3FF>|mov al, byte ptr [ebp+esi-1CF8] ;注册名
0040537C |. |50 |push eax ;/Arg1
0040537D |. |E8 BEB30200 |call 00430740 ;转化为小写字母
00405382 |. |59 |pop ecx
00405383 |. |8BD6 |mov edx, esi
00405385 |. |83E2 07 |and edx, 7
00405388 |. |33C9 |xor ecx, ecx
0040538A |. |8A8A 88504300 |mov cl, byte ptr [edx+435088] ;某个表
00405390 |. |33C1 |xor eax, ecx
00405392 |. |0185 38FFFFFF |add dword ptr [ebp-C8], eax
00405398 |. |46 |inc esi
00405399 |> |80BC35 08E3FF> cmp byte ptr [ebp+esi-1CF8], 0 ;注册名
004053A1 |.^75 D0 jnz short 00405373
上面是对注册名进行运算。至于上面提到的表,其形式为:“0X80,0X40,0X20,0X10,0X08,0X04,0X02,0X01”。现在,我们总结一下对注册名的处理算法:注册名的相应位字符与上面表的相应位数字异或,然后相加,所得结果备用,我们假设记为CN。接着下去,来到这里:
004053A3 |. 8B85 38FFFFFF mov eax, dword ptr [ebp-C8] ;就是上面计算的CN
004053A9 |. B9 64000000 mov ecx, 64
004053AE |. 99 cdq
004053AF |. F7F9 idiv ecx
004053B1 |. 8995 40FFFFFF mov dword ptr [ebp-C0], edx ;取余数
004053B7 |. 83BD 40FFFFFF>cmp dword ptr [ebp-C0], 0
004053BE 75 06 jnz short 004053C6
004053C0 |. FF85 40FFFFFF inc dword ptr [ebp-C0]
004053C6 |> 8D85 06E2FFFF lea eax, dword ptr [ebp-1DFA]
004053CC |. 50 push eax ;注册码第2组
004053CD |. E8 5AB50200 call 0043092C ;对注册码第2组运算的函数
004053D2 |. 59 pop ecx
004053D3 |. 3B85 40FFFFFF cmp eax, dword ptr [ebp-C0]
004053D9 74 08 je short 004053E3
现在我们知道了对注册名进行运算的作用了,即CN%0X64==Fun(注册码第2组)。那么这个Fun函数是怎么对注册码第2组进行运算的呢?我们F7进入0043092C,来到这里。
0043092C /$ 55 push ebp
0043092D |. 8BEC mov ebp, esp
0043092F |. 53 push ebx
00430930 |. 56 push esi
00430931 |. 8B55 08 mov edx, dword ptr [ebp+8]
00430934 |. 33C9 xor ecx, ecx
00430936 |> 8A02 /mov al, byte ptr [edx]
00430938 |. 42 |inc edx
00430939 |. 0FBED8 |movsx ebx, al
0043093C |. F683 DD204400>|test byte ptr [ebx+4420DD], 1
00430943 |.^ 75 F1 jnz short 00430936
00430945 |. 3C 2B cmp al, 2B
00430947 |. 74 04 je short 0043094D
00430949 |. 3C 2D cmp al, 2D
0043094B |. 75 0F jnz short 0043095C
0043094D |> 3C 2D cmp al, 2D
0043094F |. 0F94C0 sete al
00430952 |. 83E0 01 and eax, 1
00430955 |. 8BF0 mov esi, eax
00430957 |. 8A02 mov al, byte ptr [edx]
00430959 |. 42 inc edx
0043095A |. EB 14 jmp short 00430970
0043095C |> 33F6 xor esi, esi
0043095E |. EB 10 jmp short 00430970 ;下面是关键计算
00430960 |> 0FBEC0 /movsx eax, al
00430963 |. 03C9 |add ecx, ecx
00430965 |. 8D0C89 |lea ecx, dword ptr [ecx+ecx*4]
00430968 |. 03C8 |add ecx, eax
0043096A |. 8A02 |mov al, byte ptr [edx]
0043096C |. 83C1 D0 |add ecx, -30
0043096F |. 42 |inc edx
00430970 |> 3C 30 cmp al, 30
00430972 |. 7C 04 |jl short 00430978
00430974 |. 3C 39 |cmp al, 39
00430976 |.^ 7E E8 jle short 00430960
00430978 |> 85F6 test esi, esi
0043097A |. 74 06 je short 00430982
0043097C |. 8BC1 mov eax, ecx
0043097E |. F7D8 neg eax
00430980 |. EB 02 jmp short 00430984
00430982 |> 8BC1 mov eax, ecx
00430984 |> 5E pop esi
00430985 |. 5B pop ebx
00430986 |. 5D pop ebp
00430987 . C3 retn
上面的代码是这样运算的,我们以“67”进行说明。首先,把“6”变成数字的6,然后6*10=60,接着,60+ASC(“7”)=60+47=107=0X47,就是最终的结果。F8下去,来到这里:
004053FC |> /8A8435 00E2FF>/mov al, byte ptr [ebp+esi-1E00] ;第1组注册码
00