重起验证——外贸专家注册算法分析
【破解作者】 jsliyangsj
【作者邮箱】 sjcrack@yahoo.com.cn
【使用工具】 peid OllyDbg1.10
【破解平台】 Winxp
【软件名称】 外贸专家
【软件地址】 http://www.eimpex.net/business1.htm
用PEID查ASPack 2.11 -> Alexey Solodovnikov脱壳后,没有对话框、提示,用万能断点:
我的机器在 77D29303     F3:A>rep movs dword ptr es:[edi],dword ptr >
来到关键点:
……………………………………………………………………………………………………………………
0092D0FD   |.  64>mov dword ptr fs:[eax],esp
0092D100   |.  8D>lea edx,dword ptr ss:[ebp-1D8]
0092D106   |.  8B>mov eax,dword ptr ds:[ebx+30C]
0092D10C   |.  E8>call unpacked.0045819C
0092D111   |.  83>cmp dword ptr ss:[ebp-1D8],0           ;  检查是否输入
0092D118   |.  0F>je unpacked.0092D21B
0092D11E   |.  A1>mov eax,dword ptr ds:[95BFF0]
0092D123   |.  80>cmp byte ptr ds:[eax],1                ;  标志位检查是否已经注册过的
0092D126   |.  75>jnz short unpacked.0092D13E            ;  如果等于1 出现已经注册
0092D128   |.  B8>mov eax,unpacked.0092D26C              ;  您已注册
0092D12D   |.  E8>call unpacked.0045052C
0092D132   |.  8B>mov eax,ebx
0092D134   |.  E8>call unpacked.00476784
0092D139   |.  E9>jmp unpacked.0092D21B
0092D13E   |>  8D>lea eax,dword ptr ss:[ebp-8]
0092D141   |.  BA>mov edx,90
0092D146   |.  E8>call unpacked.004055F4
0092D14B   |.  68>push 90
0092D150   |.  8B>mov eax,dword ptr ss:[ebp-8]
0092D153   |.  E8>call unpacked.00405468
0092D158   |.  50 push eax                               ; |Buffer
0092D159   |.  E8>call <jmp.&kernel32.GetSystemDirectory>; \得到系统目录,C:\windows\system32
0092D15E   |.  8B>mov eax,dword ptr ss:[ebp-8]
0092D161   |.  E8>call unpacked.00405468
0092D166   |.  E8>call unpacked.0040AFC4
0092D16B   |.  8B>mov edx,eax
0092D16D   |.  8D>lea eax,dword ptr ss:[ebp-8]
0092D170   |.  E8>call unpacked.004055F4
0092D175   |.  8D>lea eax,dword ptr ss:[ebp-4]
0092D178   |.  B9>mov ecx,unpacked.0092D280              ;  得到文件名 _ft50.sys
0092D17D   |.  8B>mov edx,dword ptr ss:[ebp-8]
0092D180   |.  E8>call unpacked.004052BC                 ;  将他们组合C:\windows\system32\_ft50.sys
0092D185   |.  8B>mov eax,dword ptr ss:[ebp-4]
0092D188   |.  E8>call unpacked.0040AA5C
0092D18D   |.  84>test al,al
0092D18F   |.  74>je short unpacked.0092D199
0092D191   |.  8B>mov eax,dword ptr ss:[ebp-4]           ;  得到文件
0092D194   |.  E8>call unpacked.0040AB84
0092D199   |>  8B>mov edx,dword ptr ss:[ebp-4]
0092D19C   |.  8D>lea eax,dword ptr ss:[ebp-1D4]
0092D1A2   |.  E8>call unpacked.004030F8
0092D1A7   |.  8D>lea eax,dword ptr ss:[ebp-1D4]
0092D1AD   |.  E8>call unpacked.00402E94
0092D1B2   |.  E8>call unpacked.004029AC
0092D1B7   |.  68>push 7BA
0092D1BC   |.  8D>lea eax,dword ptr ss:[ebp-1DC]
0092D1C2   |.  50 push eax
0092D1C3   |.  8D>lea edx,dword ptr ss:[ebp-1E0]
0092D1C9   |.  8B>mov eax,dword ptr ds:[ebx+30C]
0092D1CF   |.  E8>call unpacked.0045819C
0092D1D4   |.  8B>mov eax,dword ptr ss:[ebp-1E0]         ;  得到输入码
0092D1DA   |.  B9>mov ecx,7B9
0092D1DF   |.  BA>mov edx,7B8
0092D1E4   |.  E8>call unpacked.0066DBB4
0092D1E9   |.  8B>mov edx,dword ptr ss:[ebp-1DC]
0092D1EF   |.  8D>lea eax,dword ptr ss:[ebp-1D4]
0092D1F5   |.  E8>call unpacked.00405684
0092D1FA   |.  E8>call unpacked.004031B4
0092D1FF   |.  E8>call unpacked.004029AC
0092D204   |.  8D>lea eax,dword ptr ss:[ebp-1D4]
0092D20A   |.  E8>call unpacked.004031C0
0092D20F   |.  E8>call unpacked.004029AC
0092D214   |.  8B>mov eax,ebx
0092D216   |.  E8>call unpacked.00476784
0092D21B   |>  33>xor eax,eax
0092D21D   |.  5A pop edx
0092D21E   |.  59 pop ecx
0092D21F   |.  59 pop ecx
0092D220   |.  64>mov dword ptr fs:[eax],edx
0092D223   |.  68>push unpacked.0092D25E
0092D228   |>  8D>lea eax,dword ptr ss:[ebp-1E0]
0092D22E   |.  E8>call unpacked.00404FA8
0092D233   |.  8D>lea eax,dword ptr ss:[ebp-1DC]
0092D239   |.  E8>call unpacked.00404FA8
0092D23E   |.  8D>lea eax,dword ptr ss:[ebp-1D8]
0092D244   |.  E8>call unpacked.00404FA8
0092D249   |.  8D>lea eax,dword ptr ss:[ebp-8]
0092D24C   |.  BA>mov edx,2
0092D251   |.  E8>call unpacked.00404FCC
0092D256   \.  C3 retn                                   ;  
………………………………………………………………………………………………………………………………
整个这段,是将输入码转化并存入文件C:\windows\system32\_ft50.sys中怎么转化这里不细说了,
因为重新启动后又将它还原为输入码,同时在C:\windows\system32中
还有另外一个文件_ft50num它是存放机器码的转化后的。这里可以从查找字符串“_ft50.sys”入手
下面一段,是点击“注册”后的标志位检查。
……………………………………………………………………………………………………………………………
0092CD56    .  8B>mov edx,dword ptr ss:[ebp-8]
0092CD59    .  E8>call unpacked.004581CC
0092CD5E    .  A1>mov eax,dword ptr ds:[95BFF0]          ;  取标志位地址
0092CD63    .  80>cmp byte ptr ds:[eax],0                ;  比较标志位 全局变量?
0092CD66    .  75>jnz short unpacked.0092CD90            ;  只要不等于0就是注册版
0092CD68    .  A1>mov eax,dword ptr ds:[95C8A4]
0092CD6D    .  80>cmp byte ptr ds:[eax],1
0092CD70    .  75>jnz short unpacked.0092CD81
0092CD72    .  BA>mov edx,unpacked.0092CE10              ;  外贸专家已注册
0092CD77    .  8B>mov eax,dword ptr ss:[ebp-4]
0092CD7A    .  E8>call unpacked.004581CC
0092CD7F    .  EB>jmp short unpacked.0092CD9D
0092CD81    >  BA>mov edx,unpacked.0092CE30              ;  外贸专家未注册,可用50次
0092CD86    .  8B>mov eax,dword ptr ss:[ebp-4]
0092CD89    .  E8>call unpacked.004581CC
0092CD8E    .  EB>jmp short unpacked.0092CD9D
0092CD90    >  BA>mov edx,unpacked.0092CE10              ;  外贸专家已注册
0092CD95    .  8B>mov eax,dword ptr ss:[ebp-4]
0092CD98    .  E8>call unpacked.004581CC
0092CD9D    >  A1>mov eax,dword ptr ds:[95C754]
0092CDA2    .  83>cmp dword ptr ds:[eax],1
0092CDA5    .  75>jnz short unpacked.0092CDB9
0092CDA7    .  8B>mov eax,dword ptr ss:[ebp-4]
0092CDAA    .  8B>mov eax,dword ptr ds:[eax+31C]
0092CDB0    .  B2>mov dl,1
0092CDB2    .  E8>call unpacked.004580BC
0092CDB7    .  EB>jmp short unpacked.0092CDC9
0092CDB9    >  8B>mov eax,dword ptr ss:[ebp-4]
0092CDBC    .  8B>mov eax,dword ptr ds:[eax+31C]
0092CDC2    .  33>xor edx,edx
0092CDC4    .  E8>call unpacked.004580BC
0092CDC9    >  33>xor eax,eax
0092CDCB    .  5A pop edx
………………………………………………………………………………………………………………………………
这里可以从查找字符串“_ft50.sys”重新启动,断在这里:
………………………………………………………………………………………………………………………………
0095301B    .  E8>call unpacked.004055F4
00953020    .  8D>lea eax,dword ptr ss:[ebp-4]
00953023    .  B9>mov ecx,unpacked.00953538              ;  ASCII "\_ft50num.sys"
00953028    .  8B>mov edx,dword ptr ss:[ebp-C]
0095302B    .  E8>call unpacked.004052BC
00953030    .  8D>lea eax,dword ptr ss:[ebp-8]
00953033    .  B9>mov ecx,unpacked.00953550              ;  ASCII "\_ft50.sys"
00953038    .  8B>mov edx,dword ptr ss:[ebp-C]
0095303B    .  E8>call unpacked.004052BC                 ;  组合文件名
00953040    .  8B>mov eax,dword ptr ss:[ebp-4]
00953043    .  E8>call unpacked.0040AA5C
00953048    .  84>test al,al
0095304A    .  75>jnz short unpacked.009530A6            ;  判断是否有输入码
0095304C    .  8B>mov edx,dword ptr ss:[ebp-4]
0095304F    .  8D>lea eax,dword ptr ss:[ebp-1E8]
00953055    .  E8>call unpacked.004030F8
0095305A    .  8D>lea eax,dword ptr ss:[ebp-1E8]
00953060    .  E8>call unpacked.00402E94
00953065    .  E8>call unpacked.004029AC
0095306A    .  BA>mov edx,unpacked.00953564              ;  ASCII "01AbEfiK"
0095306F    .  8D>lea eax,dword ptr ss:[ebp-1E8]
……………………省略………………………………
009530A6    >  8B>mov edx,dword ptr ss:[ebp-4]           ;  得到储存机器码的文件
009530A9    .  8D>lea eax,dword ptr ss:[ebp-1E8]
009530AF    .  E8>call unpacked.004030F8
009530B4    .  8D>lea eax,dword ptr ss:[ebp-1E8]
009530BA    .  E8>call unpacked.00402E88
009530BF    .  E8>call unpacked.004029AC
009530C4    .  8D>lea edx,dword ptr ss:[ebp-10]
009530C7    .  8D>lea eax,dword ptr ss:[ebp-1E8]
009530CD    .  E8>call unpacked.004034F0
009530D2    .  E8>call unpacked.004029AC
009530D7    .  8D>lea eax,dword ptr ss:[ebp-1E8]
009530DD    .  E8>call unpacked.004031C0
009530E2    .  E8>call unpacked.004029AC
009530E7    .  8D>lea eax,dword ptr ss:[ebp-1C]
009530EA    .  50 push eax
009530EB    .  B9>mov ecx,1
009530F0    .  BA>mov edx,1
009530F5    .  8B>mov eax,dword ptr ss:[ebp-10]          ;  得到机器码文件中的内容
009530F8    .  E8>call unpacked.004054C8
009530FD    .  8B>mov eax,dword ptr ss:[ebp-1C]
00953100    .  BA>mov edx,unpacked.00953584
00953105    .  E8>call unpacked.004053B4
0095310A    .  75>jnz short unpacked.00953124
0095310C    .  8D>lea eax,dword ptr ss:[ebp-10]
0095310F    .  50 push eax
00953110    .  B9>mov ecx,1
00953115    .  BA>mov edx,2
0095311A    .  8B>mov eax,dword ptr ss:[ebp-10]
0095311D    .  E8>call unpacked.004054C8
00953122    .  EB>jmp short unpacked.0095313A
00953124    >  8D>lea eax,dword ptr ss:[ebp-10]
00953127    .  50 push eax
00953128    .  B9>mov ecx,2
0095312D    .  BA>mov edx,1
00953132    .  8B>mov eax,dword ptr ss:[ebp-10]
00953135    .  E8>call unpacked.004054C8
0095313A    >  8B>mov eax,dword ptr ss:[ebp-8]
0095313D    .  E8>call unpacked.0040AA5C
00953142    .  84>test al,al
00953144    .  0F>jnz unpacked.009532AC                  ;  判断是否输入
0095314A    .  A1>mov eax,dword ptr ds:[95BFF0]
0095314F    .  C6>mov byte ptr ds:[eax],0
……………………省略………………………………
009532E2    .  8D>lea eax,dword ptr ss:[ebp-3BC]
009532E8    .  50 push eax
009532E9    .  B9>mov ecx,7B9
009532EE    .  BA>mov edx,7B8
009532F3    .  8B>mov eax,dword ptr ss:[ebp-18]          ;  又得到另一文件内容
009532F6    .  E8>call unpacked.0066DC58
009532FB    .  8B>mov edx,dword ptr ss:[ebp-3BC]         ;  将转化后储存的输入码又转化过来了
00953301    .  8D>lea eax,dword ptr ss:[ebp-18]
00953304    .  E8>call unpacked.00405040
00953309    .  8D>lea eax,dword ptr ss:[ebp-3B4]
0095330F    .  E8>call unpacked.004031C0
00953314    .  E8>call unpacked.004029AC
00953319    .  33>xor eax,eax
0095331B    .  55 push ebp
0095331C    .  68>push unpacked.00953339
00953321    .  64>push dword ptr fs:[eax]
00953324    .  64>mov dword ptr fs:[eax],esp
00953327    .  8D>lea eax,dword ptr ss:[ebp-14]
0095332A    .  E8>call unpacked.0092C714                 ;  将转化后储存的机器码又转化过来了
0095332F    .  33>xor eax,eax
00953331    .  5A pop edx
00953332    .  59 pop ecx
00953333    .  59 pop ecx
00953334    .  64>mov dword ptr fs:[eax],edx
00953337    .  EB>jmp short unpacked.00953350
00953339    .^ E9>jmp unpacked.00404598
0095333E    .  8D>lea eax,dword ptr ss:[ebp-14]
00953341    .  BA>mov edx,unpacked.009535D0              ;  ASCII "L8U9X575Y503Z31"
00953346    .  E8>call unpacked.00405040
0095334B    .  E8>call unpacked.004049C4
00953350    >  83>cmp dword ptr ss:[ebp-14],0            ;  判断机器码是否等于0
00953354    .  75>jnz short unpacked.00953363
00953356    .  8D>lea eax,dword ptr ss:[ebp-14]
00953359    .  BA>mov edx,unpacked.009535D0              ;  ASCII "L8U9X575Y503Z31"
0095335E    .  E8>call unpacked.00405040
00953363    >  8D>lea ecx,dword ptr ss:[ebp-3C0]
00953369    .  8B>mov edx,dword ptr ds:[95C6D4]          ;  用到一个固定值815E
0095336F    .  66>mov dx,word ptr ds:[edx]               ;  将这个固定值取出来
00953372    .  8B>mov eax,dword ptr ss:[ebp-18]          ;  得到输入码
00953375    .  E8>call unpacked.0092C69C                 ;  真正关键的地方  对输入码进行处理的地方
0095337A    .  8B>mov edx,dword ptr ss:[ebp-3C0]
00953380    .  8B>mov eax,dword ptr ss:[ebp-14]          ;  机器码
00953383    .  E8>call unpacked.004053B4                 ;  上面计算出来的值与机器码比较了!
00953388    .  75>jnz short unpacked.00953397
0095338A    .  A1>mov eax,dword ptr ds:[95BFF0]          ;  标志位置1 已注册啊
0095338F    .  C6>mov byte ptr ds:[eax],1
00953392    .  E9>jmp unpacked.009534F4
00953397    >  A1>mov eax,dword ptr ds:[95BFF0]
0095339C    .  C6>mov byte ptr ds:[eax],0                ;  标志位置0 未注册啊
0095339F    .  33>xor edx,edx
009533A1    .  55 push ebp
…………………………………………………………………………………………………………………………
进入00953375    .  E8>call unpacked.0092C69C                 ;  真正关键的地方
…………………………………………………………………………………………………………………………
0092C6A8   |.  8B>mov ebx,eax
0092C6AA   |.  33>xor eax,eax
0092C6AC   |.  55 push ebp
0092C6AD   |.  68>push unpacked.0092C6E4
0092C6B2   |.  64>push dword ptr fs:[eax]
0092C6B5   |.  64>mov dword ptr fs:[eax],esp
0092C6B8   |.  8D>lea edx,dword ptr ss:[ebp-4]
0092C6BB   |.  8B>mov eax,ebx                            ;  得到输入码
0092C6BD   |.  E8>call unpacked.0092C58C                 ;  关键处理1
0092C6C2   |.  8B>mov eax,dword ptr ss:[ebp-4]           ;  结果地址
0092C6C5   |.  8B>mov ecx,edi
0092C6C7   |.  8B>mov edx,esi                            ;  固定值 815E
0092C6C9   |.  E8>call unpacked.0092C628                 ;  再次处理
0092C6CE   |.  33>xor eax,eax
0092C6D0   |.  5A pop edx
0092C6D1   |.  59 pop ecx
0092C6D2   |.  59 pop ecx
0092C6D3   |.  64>mov dword ptr fs:[eax],edx
0092C6D6   |.  68>push unpacked.0092C6EB
0092C6DB   |>  8D>lea eax,dword ptr ss:[ebp-4]
…………………………………………………………………………………………………………………………
里面有两次对输入码的处理,处理的结果必须要与机器码相等,即为注册成功
进入处理1:
0092C6BD   |.  E8>call unpacked.0092C58C 
…………………………………………………………………………………………………………………………
0092C5A9   |.  8D>lea eax,dword ptr ss:[ebp-4]
0092C5AC   |.  8B>mov edx,esi                            ;  得到输入码
0092C5AE   |.  E8>call unpacked.00405040
0092C5B3   |.  8B>mov eax,ebx
0092C5B5   |.  E8>call unpacked.00404FA8
0092C5BA   |.  EB>jmp short unpacked.0092C5F9
0092C5BC   |>  8D>/lea eax,dword ptr ss:[ebp-C]
0092C5BF   |.  50 |push eax
0092C5C0   |.  B9>|mov ecx,4
0092C5C5   |.  BA>|mov edx,1
0092C5CA   |.  8B>|mov eax,dword ptr ss:[ebp-4]          ;  得到输入码
0092C5CD   |.  E8>|call unpacked.004054C8                ;  每次取4位进行计算
0092C5D2   |.  8B>|mov eax,dword ptr ss:[ebp-C]          ;  取4位的结果
0092C5D5   |.  8D>|lea edx,dword ptr ss:[ebp-8]
0092C5D8   |.  E8>|call unpacked.0092C458                ;  关键  每4位一组进行计算   计算的结果在EDX中
0092C5DD   |.  8B>|mov edx,dword ptr ss:[ebp-8]          ;  得到计算好的地址
0092C5E0   |.  8B>|mov eax,ebx
0092C5E2   |.  E8>|call unpacked.00405278                ;  把每次计算好的组合了
0092C5E7   |.  8D>|lea eax,dword ptr ss:[ebp-4]
0092C5EA   |.  B9>|mov ecx,4
0092C5EF   |.  BA>|mov edx,1
0092C5F4   |.  E8>|call unpacked.00405508                ;  去掉已经计算过的4位
0092C5F9   |>  83> cmp dword ptr ss:[ebp-4],0            ;  是否取完
0092C5FD   |.^ 75>\jnz short unpacked.0092C5BC
0092C5FF   |.  33>xor eax,eax
0092C601   |.  5A pop edx
0092C602   |.  59 pop ecx
0092C603   |.  59 pop ecx
0092C604   |.  64>mov dword ptr fs:[eax],edx
0092C607   |.  68>push unpacked.0092C621
………………………………………………………………………………………………………………………………
每次4位输入码进行计算,计算为3组结果,若最后一次如果没有4位:
若只有3位了,计算出2位结果,
如果只有2位了,计算出1位结果,输入码的位数不可能除以4后余1的。
下面进入:0092C5D8   |.  E8>|call unpacked.0092C458                ;  关键  每4位一组进行计算
……………………………………………………………………………………………………………………
0092C45B   |.  8B>mov esi,edx
0092C45D   |.  8B>mov ebx,eax
0092C45F   |.  8B>mov eax,ebx
0092C461   |.  E8>call unpacked.00405270                 ;  得到位数!!
0092C466   |.  83>sub eax,2                              ;  Switch (cases 2..4)
0092C469   |.  74>je short unpacked.0092C47A             ;  这里跳到是最后只有2位的情况
0092C46B   |.  48 dec eax
0092C46C   |.  74>je short unpacked.0092C4C5             ;  这里跳到是最后只有3位的情况
0092C46E   |.  48 dec eax
0092C46F   |.  0F>je unpacked.0092C51E                   ;  这里跳到是有4位的正常情况
0092C475   |.  E9>jmp unpacked.0092C586
0092C47A   |>  33>xor eax,eax                            ;  这里处理还有2位的情况; Case 2 of switch 0092C466
0092C47C   |.  8A>mov al,byte ptr ds:[ebx]
0092C47E   |.  0F>movzx eax,byte ptr ds:[eax+95BB5C]     ;  第1位在密码表中取值
0092C485   |.  33>xor edx,edx
0092C487   |.  8A>mov dl,byte ptr ds:[ebx+1]
0092C48A   |.  0F>movzx edx,byte ptr ds:[edx+95BB5C]     ;  第2位在密码表中取值
0092C491   |.  C1>shl edx,6
0092C494   |.  03>add eax,edx                            ;  第2次取值的结果,左移6,加上第1位取值的结果
0092C496   |.  89>mov dword ptr ss:[esp],eax
0092C499   |.  8B>mov eax,esi
0092C49B   |.  BA>mov edx,1
0092C4A0   |.  E8>call unpacked.004055F4
0092C4A5   |.  8B>mov eax,dword ptr ds:[esi]
0092C4A7   |.  E8>call unpacked.00405270
0092C4AC   |.  50 push eax
0092C4AD   |.  8B>mov eax,esi
0092C4AF   |.  E8>call unpacked.004054C0
0092C4B4   |.  8B>mov edx,eax
0092C4B6   |.  8D>lea eax,dword ptr ss:[esp+4]
0092C4BA   |.  59 pop ecx
0092C4BB   |.  E8>call unpacked.00402AF0
0092C4C0   |.  E9>jmp unpacked.0092C586
0092C4C5   |>  33>xor eax,eax                            ;  这里处理还剩下3位的情况; Case 3 of switch 0092C466
0092C4C7   |.  8A>mov al,byte ptr ds:[ebx]
0092C4C9   |.  0F>movzx eax,byte ptr ds:[eax+95BB5C]     ;  第1位在密码表中取值
0092C4D0   |.  33>xor edx,edx
0092C4D2   |.  8A>mov dl,byte ptr ds:[ebx+1]
0092C4D5   |.  0F>movzx edx,byte ptr ds:[edx+95BB5C]     ;  第2位在密码表中取值
0092C4DC   |.  C1>shl edx,6
0092C4DF   |.  03>add eax,edx                            ;  第2次取值的结果,左移6,加上第1位取值的结果
0092C4E1   |.  33>xor edx,edx
0092C4E3   |.  8A>mov dl,byte ptr ds:[ebx+2]
0092C4E6   |.  0F>movzx edx,byte ptr ds:[edx+95BB5C]     ;  第3位在密码表中取值
0092C4ED   |.  C1>shl edx,0C
0092C4F0   |.  03>add eax,edx                            ;  把第3位取的值左移0C位加上上面的值
0092C4F2   |.  89>mov dword ptr ss:[esp],eax
0092C4F5   |.  8B>mov eax,esi
0092C4F7   |.  BA>mov edx,2
0092C4FC   |.  E8>call unpacked.004055F4
0092C501   |.  8B>mov eax,dword ptr ds:[esi]
0092C503   |.  E8>call unpacked.00405270
0092C508   |.  50 push eax
0092C509   |.  8B>mov eax,esi
0092C50B   |.  E8>call unpacked.004054C0
0092C510   |.  8B>mov edx,eax
0092C512   |.  8D>lea eax,dword ptr ss:[esp+4]
0092C516   |.  59 pop ecx
0092C517   |.  E8>call unpacked.00402AF0
0092C51C   |.  EB>jmp short unpacked.0092C586
0092C51E   |>  33>xor eax,eax                            ;  这里处理4位输入码的情况; Case 4 of switch 0092C466
0092C520   |.  8A>mov al,byte ptr ds:[ebx]               ;  得到第1位的ASCII
0092C522   |.  0F>movzx eax,byte ptr ds:[eax+95BB5C]     ;  第1位在密码表中取值
0092C529   |.  33>xor edx,edx
0092C52B   |.  8A>mov dl,byte ptr ds:[ebx+1]             ;  得到第2位的ASCII
0092C52E   |.  0F>movzx edx,byte ptr ds:[edx+95BB5C]     ;  第2位在密码表中取值
0092C535   |.  C1>shl edx,6                              ;  第2个左移6
0092C538   |.  03>add eax,edx                            ;  加上第1次计算出来的值
0092C53A   |.  33>xor edx,edx
0092C53C   |.  8A>mov dl,byte ptr ds:[ebx+2]             ;  得到第3位的ASCII
0092C53F   |.  0F>movzx edx,byte ptr ds:[edx+95BB5C]     ;  第3位在密码表中取值
0092C546   |.  C1>shl edx,0C                             ;  第3个左移0C
0092C549   |.  03>add eax,edx                            ;  把第3位取的值左移0C位加上上面的值
0092C54B   |.  33>xor edx,edx
0092C54D   |.  8A>mov dl,byte ptr ds:[ebx+3]             ;  得到第4位的ASCII
0092C550   |.  0F>movzx edx,byte ptr ds:[edx+95BB5C]     ;  第4位在密码表中取值
0092C557   |.  C1>shl edx,12                             ;  第4位取的值左移12,加上上面的值
0092C55A   |.  03>add eax,edx
0092C55C   |.  89>mov dword ptr ss:[esp],eax
0092C55F   |.  8B>mov eax,esi
0092C561   |.  BA>mov edx,3
0092C566   |.  E8>call unpacked.004055F4
0092C56B   |.  8B>mov eax,dword ptr ds:[esi]
0092C56D   |.  E8>call unpacked.00405270
0092C572   |.  50 push eax
0092C573   |.  8B>mov eax,esi
0092C575   |.  E8>call unpacked.004054C0
0092C57A   |.  8B>mov edx,eax
0092C57C   |.  8D>lea eax,dword ptr ss:[esp+4]           ;  得到计算结果地址
0092C580   |.  59 pop ecx
0092C581   |.  E8>call unpacked.00402AF0                 ;  储存了
0092C586   |>  5A pop edx                                ;  Default case of switch 0092C466
0092C587   |.  5E pop esi
………………………………………………………………………………………………………………………………
上面的SHL 6 其实就是乘以64,逆向时,可以除以64,一个取商,一个取余数,各自在密码表中查找数据
对应的位数,这个位数就是我要输入的ASCII值。
密码表:
0095BB5C  00 00 00 00 00 00 00 00  ........
0095BB64  00 00 00 00 00 00 00 00  ........
0095BB6C  00 00 00 00 00 00 00 00  ........
0095BB74  00 00 00 00 00 00 00 00  ........
0095BB7C  00 00 00 00 00 00 00 00  ........
0095BB84  00 00 00 3E 00 00 00 3F  ...>...?
0095BB8C  34 35 36 37 38 39 3A 3B  456789:;
0095BB94  3C 3D 00 00 00 00 00 00  <=......
0095BB9C  00 00 01 02 03 04 05 06  ..
0095BBA4  07 08 09 0A 0B 0C 0D 0E  .. ..
0095BBAC  0F 10 11 12 13 14 15 16  
0095BBB4  17 18 19 00 00 00 00 00  .....
0095BBBC  00 1A 1B 1C 1D 1E 1F 20  .
0095BBC4  21 22 23 24 25 26 27 28  !"#$%&'(
0095BBCC  29 2A 2B 2C 2D 2E 2F 30  )*+,-./0
0095BBD4  31 32 33 00 00 00 00 00  123.....

进入:0092C6C9   |.  E8>call unpacked.0092C628                 ;  再次处理
………………………………………………………………………………………………………………………
0092C63B   |.  E8>call unpacked.00404FFC
0092C640   |.  8B>mov esi,ebx
0092C642   |.  8B>mov eax,dword ptr ss:[ebp]
0092C645   |.  E8>call unpacked.00405270                 ;  上面结果的位数
0092C64A   |.  66>test ax,ax
0092C64D   |.  76>jbe short unpacked.0092C693
0092C64F   |.  66>mov word ptr ss:[esp+4],ax             ;  位数储存
0092C654   |.  66>mov bx,1
0092C658   |>  8B>/mov eax,ebp
0092C65A   |.  E8>|call unpacked.004054C0                ;  复制一个计算的结果
0092C65F   |.  0F>|movzx edi,bx
0092C662   |.  8B>|mov edx,dword ptr ss:[ebp]
0092C665   |.  8A>|mov dl,byte ptr ds:[edx+edi-1]        ;  依次在内存中一个字节一个字节的取数据
0092C669   |.  0F>|movzx ecx,si                          ;  第一次是固定值815E,后面会改变
0092C66C   |.  C1>|shr ecx,8                             ;  固定值右移8位,就是取前面两位
0092C66F   |.  32>|xor dl,cl                             ;  固定值的前面两位与计算出来内存中的依次每个字节XOR
0092C671   |.  88>|mov byte ptr ds:[eax+edi-1],dl        ;  存储了
0092C675   |.  8B>|mov eax,dword ptr ss:[esp]
0092C678   |.  0F>|movzx eax,byte ptr ds:[eax+edi-1]     ;  还是取出内存中的结果,用前一位计算出下一位参与运算的固定值
0092C67D   |.  66>|add si,ax
0092C680   |.  66>|imul ax,si,0CE1B
0092C685   |.  66>|add ax,5BA2                           ;  下一个的固定值:本次的固定值加上本次内存结果乘以CE1B加上5BA2这个可以在整形数组中完成
0092C689   |.  8B>|mov esi,eax
0092C68B   |.  43 |inc ebx
0092C68C   |.  66>|dec word ptr ss:[esp+4]
0092C691   |.^ 75>\jnz short unpacked.0092C658
0092C693   |>  59 pop ecx
0092C694   |.  5A pop edx
0092C695   |.  5D pop ebp
0092C696   |.  5F pop edi
0092C697   |.  5E pop esi
0092C698   |.  5B pop ebx
0092C699   \.  C3 retn
………………………………………………………………………………………………………………………………
两次处理后结果,要等于机器码即可成功
……………………………………………………………………………………………………………………
算法总结:
确定输入码的位数:机器码除以3的商再乘以4,因为的每3位将转化为4位输入码,
如果余数为2,则上面的位数加上3位,
如果余数为1,则上面的位数加上2位;
首先:输入码每4位进入计算,2位2位一组,分别是第2位在密码表中取的值乘以64,
加上第1位输入码取的值
上面处理后得到一串与机器码位数相同的ASCII,再进行第2次处理:
每一组ASCII都与固定值XOR(呵呵XOR是可逆的),
这个固定值是变化的,由本次参与计算的ASCII,计算下一个固定值,其中第一次的固定值为815E
……………………………………………………………………………………………………………………
附注册机程序:
int chazhao(shu)
int shu;
{
int jieguo,i;
static int mimabiao[128]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x3F,
0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
0x3C,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
0x17,0x18,0x19,0x00,0x00,0x00,0x00,0x00,
0x00,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,
0x31,0x32,0x33,0x00,0x00,0x00,0x00,0x00};


if(shu==0)
{
jieguo=0x41;
}
else
{
for(i=0;i<128;i++)
{
if(shu==mimabiao[i])
{
jieguo=i;
}
}
}

return(jieguo);
}



main ()
{
static char jianpan[30],zuizong[30];
int i, len,shang,yushu,a,b,wei=0;
unsigned int guding=0x815e,shu12,shu34,chuli[30];
scanf("%s",jianpan);
len=strlen(jianpan);
for(i=0;i<len;i++)
{
chuli[i]=jianpan[i]^(guding>>8);
guding=guding+chuli[i];
guding=guding*0xce1b;
guding=guding+0x5ba2;
}
for(i=0;i<len;i++)
{printf("%x" ,chuli[i]);}

printf("\n");

a=len/3;
b=len%3;
for(i=0;i<a;i++)
{
shu12=((chuli[3*i+1]<<12)>>4)+chuli[3*i];

shu34=(chuli[3*i+2]<<4)+(chuli[3*i+1]>>4);

shang=shu12/64;
yushu=shu12%64;
zuizong[wei]=chazhao(yushu);wei++;
zuizong[wei]=chazhao(shang);wei++;
shang=shu34/64;
yushu=shu34%64;
zuizong[wei]=chazhao(yushu);wei++;
zuizong[wei]=chazhao(shang);wei++;
}


if(b==1)
{
shu12=0x300+chuli[len-1];
shang=shu12/64;
yushu=shu12%64;
zuizong[wei]=chazhao(yushu);wei++;
zuizong[wei]=chazhao(shang);wei++;
}
else if(b==2)
{
shu12=((chuli[len-1]<<12)>>4)+chuli[len-2];
shu34=chuli[len-1]>>4;
shang=shu12/64;
yushu=shu12%64;
zuizong[wei]=chazhao(yushu);wei++;
zuizong[wei]=chazhao(shang);wei++;
yushu=shu34%64;
zuizong[wei]=chazhao(yushu);wei++;
}

printf("%s",zuizong);
}