好友
阅读权限40
听众
最后登录1970-1-1
|
网络断魂
发表于 2008-11-10 19:28
【文章作者】: 网络断魂
【软件名称】: 某物流软件
【下载地址】: 国产的,不说了,不然有人找麻烦,
【加壳方式】: 无壳
【保护方式】: 机器码序列号
【编写语言】: Borland Delphi 6.0 - 7.0
【使用工具】: PEID,OD,
【操作平台】: XP SP3,
【作者声明】: 菜鸟学习算法,失误之处敬请诸位大侠赐教!
软件无壳,找关键点比较简单,可以通过中文提示找到,直奔主题部份1、机器码逆推硬盘号:
006D1940 /$ 55 push ebp
006D1941 |. 8BEC mov ebp, esp
006D1943 |. 83C4 E8 add esp, -18
006D1946 |. 53 push ebx
006D1947 |. 56 push esi
006D1948 |. 57 push edi
006D1949 |. 33C9 xor ecx, ecx
006D194B |. 894D E8 mov dword ptr [ebp-18], ecx
006D194E |. 894D EC mov dword ptr [ebp-14], ecx
006D1951 |. 894D F0 mov dword ptr [ebp-10], ecx
006D1954 |. 8955 F8 mov dword ptr [ebp-8], edx
006D1957 |. 8945 FC mov dword ptr [ebp-4], eax
006D195A |. 8B45 FC mov eax, dword ptr [ebp-4] ; //注册码(或机器码)送给EAX
006D195D |. E8 563AD3FF call 004053B8
006D1962 |. 33C0 xor eax, eax
006D1964 |. 55 push ebp
006D1965 |. 68 2C1A6D00 push 006D1A2C
006D196A |. 64:FF30 push dword ptr fs:[eax]
006D196D |. 64:8920 mov dword ptr fs:[eax], esp
006D1970 |. 8B45 F8 mov eax, dword ptr [ebp-8] ; //堆栈地址送给EAX
006D1973 |. E8 A035D3FF call 00404F18
006D1978 |. 8B45 FC mov eax, dword ptr [ebp-4]
006D197B |. E8 5038D3FF call 004051D0 ; //记算注册码(或机器码)长度
006D1980 B9 03000000 mov ecx, 3 ; //ECX=3,作除数
006D1985 |. 99 cdq
006D1986 |. F7F9 idiv ecx ; //注册码(或机器码)长度除以3
006D1988 |. 8BF8 mov edi, eax ; //商送给EDI
006D198A |. 85FF test edi, edi
006D198C |. 7E 7B jle short 006D1A09 ; //商小于零则跳
006D198E |. BE 01000000 mov esi, 1 ; //ESI=1,循环记算标志位
006D1993 |> 8BC6 /mov eax, esi
006D1995 |. B9 03000000 |mov ecx, 3 ; //ECX=3,作除数
006D199A |. 99 |cdq
006D199B |. F7F9 |idiv ecx ; //记算标志除以3,得出的余数用于指向 hjy 的位置
006D199D |. 8BCA |mov ecx, edx ; //余数送给ECX
006D199F |. 85C9 |test ecx, ecx ; //余数是否为零
006D19A1 |. 75 09 |jnz short 006D19AC ; //不为零则跳,
006D19A3 |. C745 F4 03000>|mov dword ptr [ebp-C], 3 ; //余数若为零(即3的倍数位),直接赋值3
006D19AA |. EB 03 |jmp short 006D19AF
006D19AC |> 894D F4 |mov dword ptr [ebp-C], ecx ; //余数存入堆栈
006D19AF |> 8D45 F0 |lea eax, dword ptr [ebp-10] ; //堆栈地址送给EAX
006D19B2 |. 50 |push eax
006D19B3 |. 8BC6 |mov eax, esi ; //标志位送给EAX
006D19B5 |. 48 |dec eax ; //EAX-1
006D19B6 |. 8D1440 |lea edx, dword ptr [eax+eax*2] ; //EDX=3*EAX
006D19B9 |. 42 |inc edx ; //EDX+1,从第 3*EAX+1 位开始取
006D19BA |. B9 03000000 |mov ecx, 3 ; //ECX=3,取3位,
006D19BF |. 8B45 FC |mov eax, dword ptr [ebp-4] ; //注册码(或机器码)送给EAX
006D19C2 |. E8 613AD3FF |call 00405428 ; //取3位,从第 3*EAX+1 位开始取,
006D19C7 |. 8D45 EC |lea eax, dword ptr [ebp-14] ; //堆栈地址送给EAX
006D19CA |. 8B4D F0 |mov ecx, dword ptr [ebp-10] ; //上面取到的三位字符串送给ECX
006D19CD |. BA 441A6D00 |mov edx, 006D1A44 ; // $ 字符送给EDX,
006D19D2 |. E8 4538D3FF |call 0040521C ; //连接字符串, $ 字符放前面
006D19D7 |. 8B45 EC |mov eax, dword ptr [ebp-14] ; //连接后的字符串送给EAX
006D19DA |. E8 B18ED3FF |call 0040A890 ; //转换为数值
006D19DF |. 8BD8 |mov ebx, eax ; //数值送给EBX
006D19E1 |. B8 501A6D00 |mov eax, 006D1A50 ; //固定字符串 hjy 送给EAX
006D19E6 |. 8B55 F4 |mov edx, dword ptr [ebp-C] ; //余数送给EDX,取 hjy 中的第几位,
006D19E9 |. 325C10 FF |xor bl, byte ptr [eax+edx-1] ; //转换后数值的低位跟 hjy 中第N位的ASCII值异或
006D19ED |. 8D45 E8 |lea eax, dword ptr [ebp-18] ; //堆栈地址送给EAX,
006D19F0 |. 8BD3 |mov edx, ebx ; //异或后的值送给EDX
006D19F2 |. E8 0137D3FF |call 004050F8 ; //异或值的低位转换成字符
006D19F7 |. 8B55 E8 |mov edx, dword ptr [ebp-18] ; //转换后字符的地址送给EDX
006D19FA |. 8B45 F8 |mov eax, dword ptr [ebp-8] ; //堆栈地址送给EAX
006D19FD |. E8 D637D3FF |call 004051D8 ; //转存
006D1A02 |. 8B45 F8 |mov eax, dword ptr [ebp-8] ; //地址送给EAX
006D1A05 |. 46 |inc esi ; //标志位+1,计算下一位,
006D1A06 |. 4F |dec edi ; //长度除以3的值循环减1,是否计算完,
006D1A07 |.^ 75 8A \jnz short 006D1993 ; //未完继续
006D1A09 |> 33C0 xor eax, eax ; //EAX清零
006D1A0B |. 5A pop edx
006D1A0C |. 59 pop ecx
006D1A0D |. 59 pop ecx
006D1A0E |. 64:8910 mov dword ptr fs:[eax], edx
006D1A11 |. 68 331A6D00 push 006D1A33
006D1A16 |> 8D45 E8 lea eax, dword ptr [ebp-18] ; //堆栈地址送给EAX
006D1A19 |. BA 03000000 mov edx, 3 ; //EDX=3
006D1A1E |. E8 1935D3FF call 00404F3C
006D1A23 |. 8D45 FC lea eax, dword ptr [ebp-4]
006D1A26 |. E8 ED34D3FF call 00404F18
006D1A2B \. C3 retn
006D1A2C .^ E9 0F2ED3FF jmp 00404840
006D1A31 .^ EB E3 jmp short 006D1A16
006D1A33 . 5F pop edi
006D1A34 . 5E pop esi
006D1A35 . 5B pop ebx
006D1A36 . 8BE5 mov esp, ebp
006D1A38 . 5D pop ebp
006D1A39 . C3 retn
2、硬盘号变换出一串八位字符串:(日期变换采用相同算法)
007252B8 |. 8B85 BCFDFFFF mov eax, dword ptr [ebp-244] ; //硬盘号送给EAX,
007252BE |. E8 0DFFCDFF call 004051D0 ; //计算长度
007252C3 |. 83F8 08 cmp eax, 8 ; //与此8比较
007252C6 |. 7D 2F jge short 007252F7 ; //大于等于8则跳
007252C8 |. 8D85 B4FDFFFF lea eax, dword ptr [ebp-24C]
007252CE |. E8 E5C4FAFF call 006D17B8
007252D3 |. 8B85 B4FDFFFF mov eax, dword ptr [ebp-24C]
007252D9 |. 8D95 B8FDFFFF lea edx, dword ptr [ebp-248]
007252DF |. E8 0450CEFF call 0040A2E8
007252E4 |. 8B85 B8FDFFFF mov eax, dword ptr [ebp-248]
007252EA |. 8D4D B0 lea ecx, dword ptr [ebp-50]
007252ED |. BA 08000000 mov edx, 8
007252F2 |. E8 3183D2FF call 0044D628
007252F7 |> 8D85 70FFFFFF lea eax, dword ptr [ebp-90]
007252FD |. E8 16FCCDFF call 00404F18
00725302 |. 8D85 68FFFFFF lea eax, dword ptr [ebp-98]
00725308 |. E8 0BFCCDFF call 00404F18
0072530D |. 8D55 90 lea edx, dword ptr [ebp-70]
00725310 |. 8B45 B0 mov eax, dword ptr [ebp-50]
00725313 |. E8 D04FCEFF call 0040A2E8
00725318 |. 8B45 90 mov eax, dword ptr [ebp-70]
0072531B |. E8 B0FECDFF call 004051D0 ; //计算长度
00725320 |. 8945 88 mov dword ptr [ebp-78], eax ; //存入,
00725323 |. B8 08000000 mov eax, 8 ; //EAX=8
00725328 |. 85C0 test eax, eax
0072532A |. 0F8E 1B010000 jle 0072544B ; //小于等于0则跳
00725330 |. 8985 3CFFFFFF mov dword ptr [ebp-C4], eax
00725336 |. BF 01000000 mov edi, 1 ; //循环开始标志位 EDI=1
0072533B |> 8D85 B0FDFFFF /lea eax, dword ptr [ebp-250]
00725341 |. 50 |push eax
00725342 |. B9 01000000 |mov ecx, 1 ; //ECX=1,取一位
00725347 |. 8BD7 |mov edx, edi ; //EDX=EDI,标志位(从第N位开始取)
00725349 |. 8B45 90 |mov eax, dword ptr [ebp-70] ; //硬盘号送给EAX
0072534C |. E8 D700CEFF |call 00405428 ; //取字符串,
00725351 |. 8B95 B0FDFFFF |mov edx, dword ptr [ebp-250] ; //取到的字符串的地址送给EDX
00725357 |. 8D45 98 |lea eax, dword ptr [ebp-68] ; //也是存储地址,
0072535A |. E8 7904CEFF |call 004057D8 ; //取地址,
0072535F |. 8B45 98 |mov eax, dword ptr [ebp-68] ; //字符串地址送给EAX
00725362 |. 66:8B00 |mov ax, word ptr [eax] ; //取到的硬盘号字符ASCII值送给AX
00725365 |. 0FB7D8 |movzx ebx, ax ; //AX送给EBX
00725368 |. 83FB 30 |cmp ebx, 30 ; //与30(0)比较,
0072536B |. 7C 13 |jl short 00725380 ; //小于则跳
0072536D |. 83FB 39 |cmp ebx, 39 ; //与39(9)比较,
00725370 |. 7F 0E |jg short 00725380 ; //大于则跳,(这两个比较用来较验字符是否为数字)
00725372 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
00725378 |. 8D53 31 |lea edx, dword ptr [ebx+31] ; //EDX=EBX+31,若为数字则ASCII值+31
0072537B |. E8 78FDCDFF |call 004050F8 ; //相加后的值存储,
00725380 |> 83FB 41 |cmp ebx, 41 ; //与41(A)比较,
00725383 |. 7C 15 |jl short 0072539A ; //小于则跳
00725385 |. 83FB 4A |cmp ebx, 4A ; //与4A(J)比较,
00725388 |. 7F 10 |jg short 0072539A ; //大于则跳,这两个比较用于较验字符是否在A-J之间
0072538A |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
00725390 |. 8BD3 |mov edx, ebx
00725392 |. 83EA 11 |sub edx, 11 ; //若在A-J之间,则ASCII值-11后再存储(即转换为数字)
00725395 |. E8 5EFDCDFF |call 004050F8 ; //存储
0072539A |> 83FB 4B |cmp ebx, 4B ; //与4B(K 大写)比较,
0072539D |. 7C 13 |jl short 007253B2 ; //小于则跳
0072539F |. 83FB 52 |cmp ebx, 52 ; //与52(R)比较,
007253A2 |. 7F 0E |jg short 007253B2 ; //大于则跳这两个比较用于较验字符是否在K-R之间
007253A4 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
007253AA |. 8D53 28 |lea edx, dword ptr [ebx+28] ; //EDX=EBX+28,若字符在K-R之间,则ASCII值+28后再存储
007253AD |. E8 46FDCDFF |call 004050F8
007253B2 |> 83FB 53 |cmp ebx, 53 ; //与53(S 大写)比较,
007253B5 |. 7C 13 |jl short 007253CA ; //小于则跳
007253B7 |. 83FB 5A |cmp ebx, 5A ; //与5A(Z大写)比较,
007253BA |. 7F 0E |jg short 007253CA ; //大于则跳这两个比较用于较验字符是否在S-Z(大写)之间
007253BC |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
007253C2 |. 8D53 18 |lea edx, dword ptr [ebx+18] ; //EDX=EBX+18,若字符在S-Z之间,则ASCII值+18后再存储
007253C5 |. E8 2EFDCDFF |call 004050F8
007253CA |> 83FB 61 |cmp ebx, 61 ; //与61(a)比较,
007253CD |. 7C 15 |jl short 007253E4 ; //小于则跳,
007253CF |. 83FB 68 |cmp ebx, 68 ; //与68(h)比较
007253D2 |. 7F 10 |jg short 007253E4 ; //大于则跳
007253D4 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
007253DA |. 8BD3 |mov edx, ebx
007253DC |. 83EA 16 |sub edx, 16 ; //EDX-16,若字符在a-h之间,则ASCII值-16再存储
007253DF |. E8 14FDCDFF |call 004050F8
007253E4 |> 83FB 69 |cmp ebx, 69 ; //与69(i)比较
007253E7 |. 7C 15 |jl short 007253FE ; //小于则跳
007253E9 |. 83FB 70 |cmp ebx, 70 ; //与70(p)比较
007253EC |. 7F 10 |jg short 007253FE ; //大于则跳
007253EE |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
007253F4 |. 8BD3 |mov edx, ebx
007253F6 |. 83EA 16 |sub edx, 16 ; //EDX-16,若字符在i-p之间,则ASCII值-16再存储
007253F9 |. E8 FAFCCDFF |call 004050F8
007253FE |> 83FB 71 |cmp ebx, 71 ; //与71(q)比较
00725401 |. 7C 15 |jl short 00725418 ; //小于则跳
00725403 |. 83FB 7A |cmp ebx, 7A ; //与7A(z)比较,
00725406 |. 7F 10 |jg short 00725418 ; //大于则跳,
00725408 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
0072540E |. 8BD3 |mov edx, ebx
00725410 |. 83EA 30 |sub edx, 30 ; //EDX-30,若字符在q-z之间,则ASCII值-30再存储
00725413 |. E8 E0FCCDFF |call 004050F8
00725418 |> 83FB 2D |cmp ebx, 2D ; //与2D(-)比较,
0072541B |. 75 10 |jnz short 0072542D ; //不等则跳,
0072541D |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
00725423 |. BA 0C637200 |mov edx, 0072630C ; //若字符为 - ,则用 x 代替后存储,
00725428 |. E8 83FBCDFF |call 00404FB0
0072542D |> 8D85 68FFFFFF |lea eax, dword ptr [ebp-98]
00725433 |. 8B95 70FFFFFF |mov edx, dword ptr [ebp-90]
00725439 |. E8 9AFDCDFF |call 004051D8 ; //转存
0072543E |. 47 |inc edi ; //标志位+1,计算下一位,
0072543F |. FF8D 3CFFFFFF |dec dword ptr [ebp-C4] ; //长度-1,较验是否计算完
00725445 |.^ 0F85 F0FEFFFF \jnz 0072533B ; //未完继续
0072544B |> 68 18637200 push 00726318 ; select * from khzc where xlh='
00725450 |. 8D95 ACFDFFFF lea edx, dword ptr [ebp-254]
00725456 |. 8B45 90 mov eax, dword ptr [ebp-70] ; //硬盘号送给EAX
00725459 |. E8 1AC4FAFF call 006D1878 ; //生成机器码,跟进,这是注册码逆推的反运算
0072545E |. FFB5 ACFDFFFF push dword ptr [ebp-254] ; //生成的机器码入栈
3、变换出的字符串作为偶数位,奇数位上填充日期变换出来的字符:
007255EC |> \8D85 68FFFFFF lea eax, dword ptr [ebp-98] ; //硬盘号变换出来字符串的地址送给EAX
007255F2 |. E8 21F9CDFF call 00404F18
007255F7 |. 8D85 64FFFFFF lea eax, dword ptr [ebp-9C]
007255FD |. E8 16F9CDFF call 00404F18
00725602 |. BF 01000000 mov edi, 1
00725607 |> 8BC7 /mov eax, edi ; //循环标志位送给EAX
00725609 |. 25 01000080 |and eax, 80000001 ; //奇偶较验
0072560E |. 79 05 |jns short 00725615
00725610 |. 48 |dec eax
00725611 |. 83C8 FE |or eax, FFFFFFFE
00725614 |. 40 |inc eax
00725615 |> 85C0 |test eax, eax
00725617 |. 0F85 09010000 |jnz 00725726 ; //奇数位则跳,偶数位不跳
0072561D |. 8D85 88FDFFFF |lea eax, dword ptr [ebp-278]
00725623 |. 50 |push eax
00725624 |. B9 01000000 |mov ecx, 1 ; //ECX=1,取1位,
00725629 |. 8BD7 |mov edx, edi ; //EDX=EDI,取第N位,N为循环标志位
0072562B |. 8B85 60FFFFFF |mov eax, dword ptr [ebp-A0] ; //注册码逆推字符串送给EAX
00725631 |. E8 F2FDCDFF |call 00405428 ; //取字符串
00725636 |. 8B95 88FDFFFF |mov edx, dword ptr [ebp-278] ; //地址送给EDX
0072563C |. 8D45 98 |lea eax, dword ptr [ebp-68]
0072563F |. E8 9401CEFF |call 004057D8
00725644 |. 8B45 98 |mov eax, dword ptr [ebp-68]
00725647 |. 66:8B00 |mov ax, word ptr [eax] ; //字符ASCII值送给AX,
0072564A |. 0FB7D8 |movzx ebx, ax ; //AX送给EBX
0072564D |. 83FB 61 |cmp ebx, 61 ; //与61(a)比较,
00725650 |. 7C 15 |jl short 00725667 ; //小于则跳
00725652 |. 83FB 6A |cmp ebx, 6A ; //与6A(j)比较,
00725655 |. 7F 10 |jg short 00725667 ; //大于则跳
00725657 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
0072565D |. 8BD3 |mov edx, ebx
0072565F |. 83EA 31 |sub edx, 31 ; //EDX-31,若字符在a-j之间,则ASCII值-31后存储
00725662 |. E8 91FACDFF |call 004050F8
00725667 |> 83FB 30 |cmp ebx, 30 ; //与30(0)比较,
0072566A |. 7C 13 |jl short 0072567F ; //小于则跳
0072566C |. 83FB 39 |cmp ebx, 39 ; //与39(9)比较,
0072566F |. 7F 0E |jg short 0072567F ; //大于则跳
00725671 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
00725677 |. 8D53 11 |lea edx, dword ptr [ebx+11] ; //EDX=EBX+11,若字符在0-9之间,则ASCII值+11后存储
0072567A |. E8 79FACDFF |call 004050F8
0072567F |> 83FB 6B |cmp ebx, 6B ; //与6B(k)比较,
00725682 |. 7C 15 |jl short 00725699 ; //小于则跳,
00725684 |. 83FB 72 |cmp ebx, 72 ; //与72(r)比较,
00725687 |. 7F 10 |jg short 00725699 ; //大于则跳,
00725689 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
0072568F |. 8BD3 |mov edx, ebx
00725691 |. 83EA 18 |sub edx, 18 ; //EDX-18,若字符在k-r之间,则ASCII值-18后存储
00725694 |. E8 5FFACDFF |call 004050F8
00725699 |> 83FB 73 |cmp ebx, 73 ; //与73(s)比较,
0072569C |. 7C 15 |jl short 007256B3 ; //小与则跳
0072569E |. 83FB 7A |cmp ebx, 7A ; //与7A(z)比较,
007256A1 |. 7F 10 |jg short 007256B3 ; //大于则跳
007256A3 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
007256A9 |. 8BD3 |mov edx, ebx
007256AB |. 83EA 28 |sub edx, 28 ; //EDX-28,若字符在s-z之间,则ASCII值-28后存储
007256AE |. E8 45FACDFF |call 004050F8
007256B3 |> 83FB 44 |cmp ebx, 44 ; //与44(D)比较,
007256B6 |. 7C 13 |jl short 007256CB ; //小于则跳
007256B8 |. 83FB 54 |cmp ebx, 54 ; //与54(T)比较,
007256BB |. 7F 0E |jg short 007256CB ; //大于则跳
007256BD |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
007256C3 |. 8D53 16 |lea edx, dword ptr [ebx+16]
007256C6 |. E8 2DFACDFF |call 004050F8
007256CB |> 83FB 53 |cmp ebx, 53 ; //S(大写)
007256CE |. 7C 13 |jl short 007256E3
007256D0 |. 83FB 5A |cmp ebx, 5A ; //Z(大写)
007256D3 |. 7F 0E |jg short 007256E3
007256D5 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
007256DB |. 8D53 16 |lea edx, dword ptr [ebx+16] ; //EDX=EBX+16,若字符在S-Z之间,则ASCII值+16后存储
007256DE |. E8 15FACDFF |call 004050F8
007256E3 |> 83FB 41 |cmp ebx, 41 ; //A
007256E6 |. 7C 13 |jl short 007256FB
007256E8 |. 83FB 4A |cmp ebx, 4A ; //J
007256EB |. 7F 0E |jg short 007256FB
007256ED |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
007256F3 |. 8D53 30 |lea edx, dword ptr [ebx+30] ; //EDX=EBX+30,若字符在A-J之间,则ASCII值+30后存储
007256F6 |. E8 FDF9CDFF |call 004050F8
007256FB |> 83FB 58 |cmp ebx, 58 ; //X(大写)
007256FE |. 75 10 |jnz short 00725710 ; //不等则跳
00725700 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
00725706 |. BA A4637200 |mov edx, 007263A4 ; //若字符为 - ,则用X代替,
0072570B |. E8 A0F8CDFF |call 00404FB0
00725710 |> 8D85 68FFFFFF |lea eax, dword ptr [ebp-98]
00725716 |. 8B95 70FFFFFF |mov edx, dword ptr [ebp-90]
0072571C |. E8 B7FACDFF |call 004051D8
00725721 |. E9 9F000000 |jmp 007257C5
00725726 |> 8D85 84FDFFFF |lea eax, dword ptr [ebp-27C]
0072572C |. 50 |push eax
0072572D |. B9 01000000 |mov ecx, 1 ; //ECX=1,取1位,
00725732 |. 8BD7 |mov edx, edi ; //EDX=EDI,EDI为标志位,
00725734 |. 8B85 60FFFFFF |mov eax, dword ptr [ebp-A0] ; //注册码逆推后的值送给EAX
0072573A |. E8 E9FCCDFF |call 00405428 ; //取字符串,
0072573F |. 8B95 84FDFFFF |mov edx, dword ptr [ebp-27C] ; (initial cpu selection)
00725745 |. 8D45 94 |lea eax, dword ptr [ebp-6C]
00725748 |. E8 8B00CEFF |call 004057D8 ; //取ASCII值
0072574D |. 8B45 94 |mov eax, dword ptr [ebp-6C]
00725750 |. 66:8B00 |mov ax, word ptr [eax] ; //ASCII值送给AX
00725753 |. 0FB7D8 |movzx ebx, ax ; //AX送给EBX
00725756 |. 83FB 58 |cmp ebx, 58 ; //与X(58)比较,
00725759 |. 75 10 |jnz short 0072576B ; //不等则跳
0072575B |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90]
00725761 |. BA A4637200 |mov edx, 007263A4 ; //第一位若是 - 号,刚用x替换
00725766 |. E8 45F8CDFF |call 00404FB0
0072576B |> 83FB 58 |cmp ebx, 58 ; //与X(58)比较,
0072576E |. 74 44 |je short 007257B4 ; //是则跳
00725770 |. 8BC3 |mov eax, ebx
00725772 |. 83E8 31 |sub eax, 31 ; //ASCII值减31(1)
00725775 |. 83F8 30 |cmp eax, 30 ; //与30(0)比较
00725778 |. 7C 1C |jl short 00725796 ; //小于则跳,跳往注册码不正确
0072577A |. 8BC3 |mov eax, ebx
0072577C |. 83E8 31 |sub eax, 31
0072577F |. 83F8 39 |cmp eax, 39 ; //与39(9)比较,
00725782 7F 12 jg short 00725796 ; //大于则跳,跳往注册码不正确
00725784 |. 8D85 70FFFFFF |lea eax, dword ptr [ebp-90] ;
//这两个比较,说明注册码逆推后字符串的奇数位必须为a-j之间(这里是日期)
0072578A |. 8BD3 |mov edx, ebx
0072578C |. 83EA 31 |sub edx, 31
0072578F |. E8 64F9CDFF |call 004050F8 ; //转存
00725794 |. EB 1E |jmp short 007257B4
00725796 |> B8 B0637200 |mov eax, 007263B0 ; 注册码不正确!!
0072579B |. E8 686FD2FF |call 0044C708
007257A0 |. A1 2CA07600 |mov eax, dword ptr [76A02C]
007257A5 |. 8B00 |mov eax, dword ptr [eax]
007257A7 |. 8B10 |mov edx, dword ptr [eax]
007257A9 |. FF92 E8000000 |call dword ptr [edx+E8]
007257AF |. E9 F9000000 |jmp 007258AD
007257B4 |> 8D85 64FFFFFF |lea eax, dword ptr [ebp-9C]
007257BA |. 8B95 70FFFFFF |mov edx, dword ptr [ebp-90]
007257C0 |. E8 13FACDFF |call 004051D8
007257C5 |> 47 |inc edi ; //标志位+1
007257C6 |. 83FF 11 |cmp edi, 11 ; //与17比较,较验是否计算完成
007257C9 |.^ 0F85 38FEFFFF \jnz 00725607
007257CF |. 8D85 64FFFFFF lea eax, dword ptr [ebp-9C]
007257D5 |. 8B8D 64FFFFFF mov ecx, dword ptr [ebp-9C]
007257DB |. BA CC637200 mov edx, 007263CC ; //20
007257E0 |. E8 37FACDFF call 0040521C //连接字符串
007257E5 |. 8B85 68FFFFFF mov eax, dword ptr [ebp-98]
007257EB |. 8B55 B0 mov edx, dword ptr [ebp-50]
007257EE |. E8 21FBCDFF call 00405314 //转换为日期,若连接后的字符串不是有效的日期则报错!
007257F3 |. 74 0F je short 00725804
007257F5 |. B8 D8637200 mov eax, 007263D8 ; 注册码不正确,无法使用!
007257FA |. E8 096FD2FF call 0044C708
007257FF |. E9 A9000000 jmp 007258AD
00725804 |> 8B85 64FFFFFF mov eax, dword ptr [ebp-9C]
0072580A |. E8 5997CEFF call 0040EF68
0072580F |. DD9D 7CFDFFFF fstp qword ptr [ebp-284]
00725815 |. 9B wait
00725816 |. E8 2181CEFF call 0040D93C
0072581B |. DC9D 7CFDFFFF fcomp qword ptr [ebp-284]
00725821 |. DFE0 fstsw ax
00725823 |. 9E sahf
00725824 |. 76 78 jbe short 0072589E
00725826 |. B8 68637200 mov eax, 00726368 ; 试用期限已过,软件无法正常使用,请申请正版注册码!
4、填充奇数位后的字符串计算出注册码:
006D1878 /$ 55 push ebp ; //硬盘号生成机器码的关键算法
006D1879 |. 8BEC mov ebp, esp
006D187B |. 83C4 F4 add esp, -0C
006D187E |. 53 push ebx
006D187F |. 56 push esi
006D1880 |. 57 push edi
006D1881 |. 33C9 xor ecx, ecx ; //ECX清零
006D1883 |. 894D F4 mov dword ptr [ebp-C], ecx
006D1886 |. 8BFA mov edi, edx
006D1888 |. 8945 FC mov dword ptr [ebp-4], eax ; //硬盘号送入堆栈中
006D188B |. 8B45 FC mov eax, dword ptr [ebp-4] ; //反送给EAX
006D188E |. E8 253BD3FF call 004053B8
006D1893 |. 33C0 xor eax, eax ; //EAX清零
006D1895 |. 55 push ebp
006D1896 |. 68 25196D00 push 006D1925
006D189B |. 64:FF30 push dword ptr fs:[eax]
006D189E |. 64:8920 mov dword ptr fs:[eax], esp
006D18A1 |. 8BC7 mov eax, edi
006D18A3 |. E8 7036D3FF call 00404F18
006D18A8 |. 8B45 FC mov eax, dword ptr [ebp-4] ; //硬盘号送给EAX
006D18AB |. E8 2039D3FF call 004051D0 ; //取长度
006D18B0 |. 8BF0 mov esi, eax ; //送给ESI
006D18B2 |. 85F6 test esi, esi ; //长度是否为零
006D18B4 |. 7E 51 jle short 006D1907 ; //小于零则跳
006D18B6 |. BB 01000000 mov ebx, 1 ; //EBX=1,循环计算开始的标志位
006D18BB |> 8BC3 /mov eax, ebx ; //EAX=EBX,(第N位)
006D18BD |. B9 03000000 |mov ecx, 3 ; //ECX=3,作除数
006D18C2 |. 99 |cdq
006D18C3 |. F7F9 |idiv ecx ; //除以3
006D18C5 |. 8BCA |mov ecx, edx ; //余数送给ECX
006D18C7 |. 85C9 |test ecx, ecx ; //余数是否为零,
006D18C9 |. 75 07 |jnz short 006D18D2 ; //不为零则跳
006D18CB |. B8 03000000 |mov eax, 3 ; //为零(3的倍数位),则直接赋值3
006D18D0 |. EB 02 |jmp short 006D18D4
006D18D2 |> 8BC1 |mov eax, ecx ; //余数送给EAX
006D18D4 |> BA 3C196D00 |mov edx, 006D193C ; //固定字符串 hjy 送给EDX
006D18D9 |. 8A4402 FF |mov al, byte ptr [edx+eax-1];//hjy字符串中第余数位(若余数为零则指向第3位)的ASCII值送给AL
006D18DD |. 8B55 FC |mov edx, dword ptr [ebp-4] ; //硬盘号送给EDX
006D18E0 |. 32441A FF |xor al, byte ptr [edx+ebx-1] ; //硬盘号的第N位与hjy中的第余数位ASCII值异或
006D18E4 |. 8845 FB |mov byte ptr [ebp-5], al ; //异或值存入堆栈
006D18E7 |. 8D4D F4 |lea ecx, dword ptr [ebp-C]
006D18EA |. 33C0 |xor eax, eax ; //EAX清零
006D18EC |. 8A45 FB |mov al, byte ptr [ebp-5] ; //异或值送给AL
006D18EF |. BA 03000000 |mov edx, 3 ; //EDX=3
006D18F4 |. E8 5B8FD3FF |call 0040A854 ; //数值转换为字符串,不足3位则前而添0,
006D18F9 |. 8B55 F4 |mov edx, dword ptr [ebp-C] ; //转换后的字符串送给EDX
006D18FC |. 8BC7 |mov eax, edi ; //送堆栈地址
006D18FE |. E8 D538D3FF |call 004051D8 ; //转存
006D1903 |. 43 |inc ebx ; //计算下一位
006D1904 |. 4E |dec esi ; //长度-1,用于较验是否计算完成
006D1905 |.^ 75 B4 \jnz short 006D18BB ; //未完继续
006D1907 |> 33C0 xor eax, eax
006D1909 |. 5A pop edx
006D190A |. 59 pop ecx
006D190B |. 59 pop ecx
006D190C |. 64:8910 mov dword ptr fs:[eax], edx
006D190F |. 68 2C196D00 push 006D192C
006D1914 |> 8D45 F4 lea eax, dword ptr [ebp-C]
006D1917 |. E8 FC35D3FF call 00404F18
006D191C |. 8D45 FC lea eax, dword ptr [ebp-4]
006D191F |. E8 F435D3FF call 00404F18
006D1924 \. C3 retn
006D1925 .^ E9 162FD3FF jmp 00404840
006D192A .^ EB E8 jmp short 006D1914
006D192C . 5F pop edi
006D192D . 5E pop esi
006D192E . 5B pop ebx
006D192F . 8BE5 mov esp, ebp
006D1931 . 5D pop ebp
006D1932 . C3 retn
6、以本机为例手工推算:
机器码05D03A03205805D02D025022 逆推出硬盘号 5PK07TMH,硬盘号转换后得到字符串fxsahlu7,日期10-09-09转换后得到字符串baXajXaj
填充奇偶字符后 bfaxXsaajhXlauj7,跟hjy异或者运算后计算出注册码:00A00C01801003200A00900B01300003201500901F01305F
1 5 0 P - K 0 0 9 7 - T 0 M 9 H (20)10-09-09 5PK07TMH
31 35 30 50 2D 4B 30 30 39 37 2D 54 30 4D 39 48
+31 +31 +31 +28 =58 +28 +31 +31 +31 +31 =58 +18 +31 +28 +31 -11
62 66 61 78 58 73 61 61 6A 68 58 6C 61 75 6A 37
b f a x X s a a j h X l a u j 7
(20)10-09-09 == (20)baXajXaj 5PK07TMH ==fxsahlu7
b f a x X s a a j h X l a u j 7
62 66 61 78 58 73 61 61 6A 68 58 6c 61 75 6A 37
XOR
h j y h j y h j y h j y h j y h
68 6A 79 68 6A 79 68 6A 79 68 6A 79 68 6A 79 68
00A 00C 018 010 032 00A 009 00B 013 000 032 015 009 01F 013 05F
00A00C01801003200A00900B01300003201500901F01305F
7、注册机源码(写代码确实很菜,不要见笑):
//机器码转换成硬盘号
CString JqmToYph(CString jqm)
{
CString yph;
CString str_tmp;
CString str_hjy = "hjy";
int jqmlen;
int str_num;
jqmlen = jqm.GetLength();
for (int i = 0;i < jqmlen/3;i++)
{
str_tmp = jqm.Mid(3*i,3);
str_num = strtol(str_tmp,NULL,16);
str_num = str_num ^ (int)str_hjy[i%3];
yph += (char)str_num;
}
return yph;
}
//硬盘号或日期字符串生成注册码
CString YphRqToZcm(CString YphRq)
{
int str_len = 0;
CString hjy = "hjy";
CString zcm,zcm_tmp;
str_len = YphRq.GetLength();
for (int i = 0;i<str_len;i++)
{
int str_int = (int)YphRq;
if ( 0x30 <= str_int && str_int <= 0x39 )
{
str_int = str_int + 0x31;
}
else if ( 0x41 <= str_int && str_int <= 0x4A )
{
str_int = str_int - 0x11;
}
else if ( 0x4B <= str_int && str_int <= 0x52 )
{
str_int = str_int + 0x28;
}
else if ( 0x53 <= str_int && str_int <= 0x5A )
{
str_int = str_int + 0x18;
}
else if ( 0x61 <= str_int && str_int <= 0x70 )
{
str_int = str_int - 0x16;
}
else if ( 0x71 <= str_int && str_int <= 0x7A )
{
str_int = str_int - 0x30;
}
else if ( str_int == 0x2D )
{
str_int = 0x58;
}
zcm_tmp += (char)str_int;
str_int = str_int ^ (int)hjy[i%3];
zcm_tmp.Format("%2x",str_int);
zcm_tmp.Remove(' ');
if (zcm_tmp.GetLength() == 1)
{
zcm_tmp = "00" + zcm_tmp;
}
else if (zcm_tmp.GetLength() == 2)
{
zcm_tmp = "0" + zcm_tmp;
}
zcm += zcm_tmp;
zcm.MakeUpper();
}
return zcm;
}
void C物流通注册机Dlg::OnBnClickedOk()
{
CString jqm,rq,rqy,rqm,rqd,zcm;//机器码,日期,年,月,日,注册码
CString yph;//硬盘号
CString YphRq;//硬盘号日期混合字符串
int jqm_len = 0,rq_len = 0,rqy_len = 0,rqm_len = 0,rqd_len = 0;//机器码、日期、年、月、日的长度
GetDlgItemText(IDC_EDIT1,jqm);//取机器码
GetDlgItemText(IDC_EDIT2,rqy);//取年份
GetDlgItemText(IDC_EDIT3,rqm);//取月份
GetDlgItemText(IDC_EDIT4,rqd);//取日
jqm_len = jqm.GetLength();//取机器码长度
rqy_len = rqy.GetLength();//取年份长度
rqm_len = rqm.GetLength();//取月份长度
rqd_len = rqd.GetLength();//取日期长度
if (jqm_len <= 0)
{
MessageBox("请输入机器码!");
return;
}
for (int i = 0;i < jqm_len;i++)
{
if ( !(('0'<= jqm && jqm <= '9') || ('A' <= jqm && jqm <= 'F') || ('a' <= jqm && jqm <= 'f')) )
{
MessageBox("机器码应该为十六进制字符,‘0-9’,‘a-f’,‘A-F’!");
return;
}
}
if (rqy_len > 2 || rqy_len <= 0)
{
MessageBox("请输入00-99之间的两位数年份!");
return;
}
if (rqy_len == 1)
{
rqy = "0" + rqy;
}
if (rqm_len > 2 || rqm_len <= 0)
{
MessageBox("请输入00-12之间的两位数月份!");
return;
}
if (rqm_len == 1)
{
rqm = "0"+rqm;
}
int rqm_int = atoi(rqm);
if (rqm_int > 12)
{
MessageBox("月份数没有大于12的!");
return;
}
if (rqd_len > 2 || rqd_len<= 0)
{
MessageBox("请输入00-31之间的两位数日期!");
return;
}
if (rqd_len == 1)
{
rqd = "0"+rqd;
}
int rqd_int = atoi(rqd);
if (rqm_int == 2 && rqd_int > 28)
{
MessageBox("本月份最大日期为28!");
return;
}
if (((rqm_int == 4) || (rqm_int == 6) || (rqm_int == 9) || (rqm_int == 11)) && rqd_int > 30)
{
MessageBox("本月份最大日期为30!");
return;
}
rq = rqy + "-" + rqm + "-" + rqd;
yph = JqmToYph(jqm);
for (int i = 0;i < 8;i++)
{
YphRq += rq;
YphRq += yph;
}
zcm = YphRqToZcm(YphRq);
SetDlgItemText(IDC_EDIT5,zcm);
}
[ 本帖最后由 lqiulu 于 2008-11-10 20:52 编辑 ] |
|