Techra Virtual Programmable Keyboard 1.02算法分析
【文章标题】: Techra Virtual Programmable Keyboard 1.02算法分析【文章作者】: qifeon
【软件名称】: Techra Virtual Programmable Keyboard
【下载地址】: http://www.techrasoft.com/index.asp
【保护方式】: 注册码
【编写语言】: 英文
【操作平台】: winxp sp2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
一、分析过程
首先PEID查壳,Borland Delphi 6.0 - 7.0编写,无壳。运行程序,输入“qifeon,123456”,有错误提示"invalid unlock information"。好的,我们就利用最简单而有效的查找字符串的方法。
不要小瞧它哦,不必再去麻烦DeDe先生了。OD载入,插件查找上面的错误提示。
Ultra String Reference, 条目 3004
Address=0056D6B0
Disassembly=mov eax, 0056D7D4
Text String=invalid unlock information!
双击后来到
*******************************************************************************************************************************************************
0056D6A9 .^\E9 2A69E9FF jmp 00403FD8 ;向上找到跳转
0056D6AE .^ EB F0 jmp short 0056D6A0
0056D6B0 > \B8 D4D75600 mov eax, 0056D7D4 ;invalid unlock information!
0056D6B5 .E8 C66AECFF call 00434180
0056D6BA .8B83 18030000 mov eax, dword ptr
0056D6C0 .8B10 mov edx, dword ptr
0056D6C2 .FF92 C4000000 call dword ptr
0056D6C8 >33C0 xor eax, eax
0056D6CA .5A pop edx
0056D6CB .59 pop ecx
0056D6CC .59 pop ecx
*****************************************************************************************************************************************************
由跳转向上找到注册按钮事件段首
*****************************************************************************************************************************************************
0056D536 .55 push ebp ;段首
0056D537 .68 F8D65600 push 0056D6F8
0056D53C .64:FF30 push dword ptr fs:
0056D53F .64:8920 mov dword ptr fs:, esp
0056D542 .8D55 F8 lea edx, dword ptr
0056D545 .8B83 18030000 mov eax, dword ptr
0056D54B .E8 7069EEFF call 00453EC0 ;取用户名长度
0056D550 .837D F8 00 cmp dword ptr , 0
0056D554 .74 14 je short 0056D56A ;用户名为空则跳
0056D556 .8D55 F4 lea edx, dword ptr
0056D559 .8B83 1C030000 mov eax, dword ptr
0056D55F .E8 5C69EEFF call 00453EC0 ;取试炼码长度
0056D564 .837D F4 00 cmp dword ptr , 0 试炼码是否为空?
0056D568 .75 1D jnz short 0056D587
0056D56A >B8 0CD75600 mov eax, 0056D70C ;please enter unlock information!
0056D56F .E8 0C6CECFF call 00434180
0056D574 .8B83 18030000 mov eax, dword ptr
0056D57A .8B10 mov edx, dword ptr
0056D57C .FF92 C4000000 call dword ptr
0056D582 .E9 41010000 jmp 0056D6C8
0056D587 >8D55 F0 lea edx, dword ptr
0056D58A .8B83 1C030000 mov eax, dword ptr
0056D590 .E8 2B69EEFF call 00453EC0
0056D595 .8B45 F0 mov eax, dword ptr ;试炼码放入eax
0056D598 .50 push eax
0056D599 .8D55 E8 lea edx, dword ptr
0056D59C .8B83 18030000 mov eax, dword ptr
0056D5A2 .E8 1969EEFF call 00453EC0
0056D5A7 .8B55 E8 mov edx, dword ptr ;用户名放入edx
0056D5AA .8D4D EC lea ecx, dword ptr
0056D5AD .A1 74B75800 mov eax, dword ptr
0056D5B2 .8B00 mov eax, dword ptr
0056D5B4 .E8 D3140000 call 0056EA8C ;算法call,我们马上进入
0056D5B9 .8B55 EC mov edx, dword ptr ;真正注册码
0056D5BC .58 pop eax ;试炼码
0056D5BD .E8 A274E9FF call 00404A64 ;真正注册码与假码相比较
0056D5C2 .0F85 E8000000 jnz 0056D6B0 ;关键跳转
0056D5C8 .33C0 xor eax, eax
0056D5CA .55 push ebp
0056D5CB .68 A9D65600 push 0056D6A9
0056D5D0 .64:FF30 push dword ptr fs:
0056D5D3 .64:8920 mov dword ptr fs:, esp
0056D5D6 .B2 01 mov dl, 1
0056D5D8 .A1 489E4300 mov eax, dword ptr
0056D5DD .E8 6AC9ECFF call 00439F4C
0056D5E2 .8945 FC mov dword ptr , eax
0056D5E5 .BA 02000080 mov edx, 80000002
0056D5EA .8B45 FC mov eax, dword ptr
0056D5ED .E8 FAC9ECFF call 00439FEC
0056D5F2 .B1 01 mov cl, 1
0056D5F4 .BA 38D75600 mov edx, 0056D738 ;software\vpk
0056D5F9 .8B45 FC mov eax, dword ptr
0056D5FC .E8 2FCBECFF call 0043A130
0056D601 .8D55 E4 lea edx, dword ptr
0056D604 .8B83 18030000 mov eax, dword ptr
0056D60A .E8 B168EEFF call 00453EC0
0056D60F .8B45 E4 mov eax, dword ptr
0056D612 .50 push eax
0056D613 .B9 50D75600 mov ecx, 0056D750 ;registeredto
0056D618 .33D2 xor edx, edx
0056D61A .8B45 FC mov eax, dword ptr
0056D61D .E8 9ECFECFF call 0043A5C0
0056D622 .8D55 E0 lea edx, dword ptr
0056D625 .8B83 1C030000 mov eax, dword ptr
0056D62B .E8 9068EEFF call 00453EC0
0056D630 .8B45 E0 mov eax, dword ptr
0056D633 .50 push eax
0056D634 .B9 68D75600 mov ecx, 0056D768 ;unlockcode
0056D639 .33D2 xor edx, edx
0056D63B .8B45 FC mov eax, dword ptr
0056D63E .E8 7DCFECFF call 0043A5C0
0056D643 .A1 74B75800 mov eax, dword ptr
0056D648 .8B00 mov eax, dword ptr
0056D64A .E8 FD120000 call 0056E94C
0056D64F .84C0 test al, al
0056D651 .74 2F je short 0056D682
0056D653 .B8 7CD75600 mov eax, 0056D77C ;software has been successfully unlocked!
0056D658 .E8 236BECFF call 00434180
0056D65D .A1 74B75800 mov eax, dword ptr
0056D662 .8B00 mov eax, dword ptr
0056D664 .8B80 28030000 mov eax, dword ptr
0056D66A .33D2 xor edx, edx
0056D66C .E8 078AEFFF call 00466078
0056D671 .C783 4C020000>mov dword ptr , 1
0056D67B .E8 3C6AE9FF call 004040BC
0056D680 .EB 46 jmp short 0056D6C8
0056D682 >B8 B0D75600 mov eax, 0056D7B0 ;error unlocking software!
0056D687 .E8 F46AECFF call 00434180
0056D68C .E8 2B6AE9FF call 004040BC
*******************************************************************************************************************************************************
0056D5B4处,进入算法 call 0056EA8C
*********************************************************************************************************************************************8**********
0056EA8C $55 push ebp
0056EA8D .8BEC mov ebp, esp
0056EA8F .6A 00 push 0
0056EA91 .6A 00 push 0
0056EA93 .6A 00 push 0
0056EA95 .6A 00 push 0
0056EA97 .6A 00 push 0
0056EA99 .53 push ebx
0056EA9A .56 push esi
0056EA9B .57 push edi
0056EA9C .8BF9 mov edi, ecx
0056EA9E .8955 FC mov dword ptr , edx
0056EAA1 .8B45 FC mov eax, dword ptr
0056EAA4 .E8 5F60E9FF call 00404B08
0056EAA9 .33C0 xor eax, eax
0056EAAB .55 push ebp
0056EAAC .68 E2EB5600 push 0056EBE2
0056EAB1 .64:FF30 push dword ptr fs:
0056EAB4 .64:8920 mov dword ptr fs:, esp
0056EAB7 .33C0 xor eax, eax
0056EAB9 .55 push ebp
0056EABA .68 B5EB5600 push 0056EBB5
0056EABF .64:FF30 push dword ptr fs:
0056EAC2 .64:8920 mov dword ptr fs:, esp
0056EAC5 .8D45 F4 lea eax, dword ptr
0056EAC8 .8B4D FC mov ecx, dword ptr ;用户名
0056EACB .BA F8EB5600 mov edx, 0056EBF8 ;ASCII "TEST123"
0056EAD0 .E8 8F5EE9FF call 00404964 ;连接固定字符串"TEST123"与用户名,设为link
0056EAD5 .8B45 F4 mov eax, dword ptr
0056EAD8 .8BD7 mov edx, edi
0056EADA .E8 598AECFF call 00437538 ;把连接后字符串link翻转,设为reverse
0056EADF .33C0 xor eax, eax
0056EAE1 .8945 F8 mov dword ptr , eax
0056EAE4 .8B07 mov eax, dword ptr
0056EAE6 .E8 2D5EE9FF call 00404918
0056EAEB .8BF0 mov esi, eax ;字符串reverse长度设为len放入esi
0056EAED .85F6 test esi, esi
0056EAEF .7E 15 jle short 0056EB06
0056EAF1 .BB 01000000 mov ebx, 1 ;ebx=1
0056EAF6 >8B07 mov eax, dword ptr ;字符串reverse放入eax
0056EAF8 .0FB64418 FF movzx eax, byte ptr ;字符串reverse逐位取扩展放入eax
0056EAFD .F7EB imul ebx ;eax=eax*ebx
0056EAFF .0145 F8 add dword ptr , eax ;=+eax,循环最后计算值保存于ebp-8,设为sum
0056EB02 .43 inc ebx ;ebx增1
0056EB03 .4E dec esi ;esi减1
0056EB04 .^ 75 F0 jnz short 0056EAF6 ;esi不为0则继续循环
0056EB06 >8B07 mov eax, dword ptr
0056EB08 .E8 0B5EE9FF call 00404918
0056EB0D .8BF0 mov esi, eax
0056EB0F .85F6 test esi, esi
0056EB11 .7E 3C jle short 0056EB4F
0056EB13 .BB 01000000 mov ebx, 1
0056EB18 >8B07 mov eax, dword ptr ;字符串reverse放入eax
0056EB1A .0FB64418 FF movzx eax, byte ptr ;字符串reverse逐位取扩展放入eax
0056EB1F .F7EB imul ebx ;eax=eax*ebx
0056EB21 .83C0 02 add eax, 2 ;eax=eax+2
0056EB24 .3345 F8 xor eax, dword ptr ;eax=eax xor sum
0056EB27 .B9 0A000000 mov ecx, 0A ;ecx=0Ah
0056EB2C .99 cdq ;edx清零
0056EB2D .F7F9 idiv ecx ;eax/ecx 商保存在 eax余数保存于edx
0056EB2F .8BC2 mov eax, edx
0056EB31 .8D55 F0 lea edx, dword ptr
0056EB34 .E8 17A4E9FF call 00408F50 ;把上面逐位计算的余数16进制数字转换为对应字符
0056EB39 .8B45 F0 mov eax, dword ptr
0056EB3C .8A00 mov al, byte ptr ;转换后字符放入al
0056EB3E .50 push eax
0056EB3F .8BC7 mov eax, edi
0056EB41 .E8 2A60E9FF call 00404B70
0056EB46 .5A pop edx ;dl内的值等于上面al数值
0056EB47 .885418 FF mov byte ptr , dl ;dl值替换字符串reverse内字符
0056EB4B .43 inc ebx
0056EB4C .4E dec esi ;esi不为0则继续循环
0056EB4D .^ 75 C9 jnz short 0056EB18
0056EB4F >8B07 mov eax, dword ptr ;reverse全部替换后得到字符串设为replace
0056EB51 .E8 C25DE9FF call 00404918
0056EB56 .8BF0 mov esi, eax ;字符串replace长度
0056EB58 .85F6 test esi, esi
0056EB5A .7E 3D jle short 0056EB99
0056EB5C .BB 01000000 mov ebx, 1
0056EB61 >8B07 mov eax, dword ptr ;字符串replace放入eax
0056EB63 .0FB64418 FF movzx eax, byte ptr ;字符串replace逐位取扩展放入eax
0056EB68 .F7EB imul ebx ;eax值乘以ebx
0056EB6A .8BD0 mov edx, eax ;相乘得值由eax放入edx
0056EB6C .C1E0 03 shl eax, 3 ;eax值左移3位
0056EB6F .2BC2 sub eax, edx ;eax=eax-edx
0056EB71 .B9 0A000000 mov ecx, 0A ;ecx=10
0056EB76 .99 cdq ;edx清零
0056EB77 .F7F9 idiv ecx ;eax/ecx 商保存在 eax余数保存于edx
0056EB79 .8BC2 mov eax, edx ;余数传送给eax
0056EB7B .8D55 EC lea edx, dword ptr
0056EB7E .E8 CDA3E9FF call 00408F50 ;把上面逐位计算的余数16进制数字转换为对应字符
0056EB83 .8B45 EC mov eax, dword ptr
0056EB86 .8A00 mov al, byte ptr ;转换后字符放入al
0056EB88 .50 push eax
0056EB89 .8BC7 mov eax, edi
0056EB8B .E8 E05FE9FF call 00404B70
0056EB90 .5A pop edx ;dl内的值等于上面al数值
0056EB91 .885418 FF mov byte ptr , dl ;dl值替换字符串reverse内字符
0056EB95 .43 inc ebx
0056EB96 .4E dec esi
0056EB97 .^ 75 C8 jnz short 0056EB61
0056EB99 >57 push edi
0056EB9A .8B07 mov eax, dword ptr ;replace全部替换后的字符串设为regcode
0056EB9C .B9 06000000 mov ecx, 6 ;ecx=6
0056EBA1 .BA 01000000 mov edx, 1
0056EBA6 .E8 CD5FE9FF call 00404B78 ;取字符串regcode前6位作为注册码
0056EBAB .33C0 xor eax, eax
0056EBAD .5A pop edx
0056EBAE .59 pop ecx
0056EBAF .59 pop ecx
0056EBB0 .64:8910 mov dword ptr fs:, edx
0056EBB3 .EB 0A jmp short 0056EBBF
0056EBB5 .^ E9 6A51E9FF jmp 00403D24
0056EBBA .E8 CD54E9FF call 0040408C
0056EBBF >33C0 xor eax, eax
0056EBC1 .5A pop edx
0056EBC2 .59 pop ecx
0056EBC3 .59 pop ecx
0056EBC4 .64:8910 mov dword ptr fs:, edx
0056EBC7 .68 E9EB5600 push 0056EBE9
0056EBCC >8D45 EC lea eax, dword ptr
0056EBCF .BA 03000000 mov edx, 3
0056EBD4 .E8 A35AE9FF call 0040467C
0056EBD9 .8D45 FC lea eax, dword ptr
0056EBDC .E8 775AE9FF call 00404658
0056EBE1 .C3 retn
*********************************************************************************************************************************************
二、注册算法总结
算法有些琐碎,经过多次转换。本人尝试描述清楚。
1、固定字符串"TEST123"与用户名name连接得到字符串link;
2、翻转字符串link得到字符串reverse;
3、字符reverse乘以字符串对应位置(i+1)依次相加之和为sum;
4、字符reverse乘以字符串对应位置(i+1),然后加上2,再与sum异或,异或后的值除以10,
余数转化为16进制对应的字符替换掉reverse,得到字符串replace;(如0x1转为字符"1")
5、字符replace乘以字符串对应位置(i+1),所得数值左移3位,减去replace*(i+1),再除以10,
余数转化为16进制对应的字符替换掉replace,得到字符串regcode;
6、取字符串regcode前6位组成的字符串即为注册码。
*************************************************************************************************************************************************
三、C语言注册机源码
#include "stdio.h"
#include "string.h"
void main()
{
int i,j,k,len,o,p;
static int sum=0;
char regcode;
char replace;
char reverse;
char name;
char link="TEST123";
printf("请输入用户名:");
scanf("%s",name);
strcat (link,name);
strrev(link);
strcpy(reverse,link);
len=strlen(reverse);
for (i=0;i<len;i++)
sum=sum+reverse*(i+1);
for (i=0;i<len;i++)
{k=reverse*(i+1)+2 ;
j=k ^ sum;
replace=j % 10+0x30;
}
for (i=0;i<len;i++)
{
o=replace*(i+1);
p=o<< 3;
regcode=(p-o) % 10+0x30;
}
regcode='\0';
printf("注册码是:%s",regcode);
}
页:
[1]