GIF Movie Gear逆向实战+注册代码+补丁
-
准备
我是在windows 8.1 x64上进行的操作。有不足之处,还望大虾指出。
-
获取资源
网站下载:http://www.gamani.com/gmgdown.htm,国内站点是汉化破解好的。
GIF Movie Gear4.2.3是一款GIF动画制作软件,几乎有需要 制作GIF动画的编辑功能它都有,无须再用其它的图型软件辅助。GIF Movie Gear可以处理背景透明化而且做法容易,做好的图片可以做最佳化处理使图片减肥,另外它除了可 以把做好的图片存成GIF的动画图外,还可支援PSD,JPEG,AVI,BMP,GIF,与AVI格式输出。
-
受限预先查看
-
运行
确实受限了,其实在推出时也恼人,弹窗不然直接退出要等下出现个按钮,点ok关闭。
-
查看pe信息
貌似没有欺骗我们,没加壳
-
找看看有无注册窗口Version 4.2.3
-
定位
-
程序要判断注册的对不对,首先获取输入值。
-
回到od,查找一些符号,这里找GetDlgItemText或者GetWindowText,这里直接找GetWindowText(因为GetDlgItemText=GetDlgItem+GetWindowText,没有找到也没关系(如LoadLibary),直接到User2.dll模块找)并且是ASCII版的。方便点的有cmdBar插件直接入下图方式下断。
-
回到界面点ok按钮,断点起作用了,和预想的一样。
看看堆栈,或者直接Alt+F9执行到程序模块。
可以看到两次调用GetWindowTextA,后面一个call,入参是EDX和ECX,来自于获取到编辑框里的值的缓冲区[LOCAL.49]和[LOCAL.24]。控件1103是Name,1104是Code。
后面还有一个根据返回值来jz的,并且有创建注册表项的字符串。这也太明显了,太快了,怎么这个就不设防。。。
注册信息保存在注册表HKEY_LOCAL_MACHINE \Software\gamani\GIFMovieGear\2.0下的两个键SubKey = "RegName3"和SubKey = "RegCode3" ,过期时间来自HKLM\SOFTWARE\Wow6432Node\Loani\MG4\stamp,保存的是秒数。
new Date(0x540b1713 * 1000) = Sat Jan 17 1970 15:40:12 GMT+0800 (China Standard Time)
需要注意x64位,这里的调用,注册表会被重定向:
3:29:05.3795926 PM movgear.exe 5756 RegQueryValue HKCU\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Wow6432Node\gamani\GIFMovieGear\2.0\RegName3 SUCCESS Type: REG_SZ, Length: 10, Data: 苏北小麦 3:29:06.8898693 AM movgear.exe 4380 RegQueryValue HKCU\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Wow6432Node\gamani\GIFMovieGear\2.0\RegCode3 SUCCESS Type: REG_SZ, Length: 26, Data: mg37sfhh4045 3:29:53.9921742 AM movgear.exe 4380 RegQueryValue HKLM\SOFTWARE\Wow6432Node\Loani\MG4\stamp SUCCESS Type: REG_BINARY, Length: 4, Data: 13 17 0B 54
-
注册获取窗口信息
CPU Disasm 地址十六进制数据指令注释 004344F9 |> \8BBC24 2C0100 MOV EDI,DWORD PTR SS:[ARG.1] ; 事例 1 of switch movgear.4344D1 00434500 |. 8B35 D0F44700 MOV ESI,DWORD PTR DS:[<&USER32.GetDlgIte 00434506 |. 6A 64 PUSH 64 ; /MaxCount = 100. 00434508 |. 8D5424 64 LEA EDX,[LOCAL.49] ; | 0043450C |. 52 PUSH EDX ; |String => OFFSET LOCAL.49 0043450D |. 68 4F040000 PUSH 44F ; |/ItemID = 1103. 00434512 |. 57 PUSH EDI ; ||hDialog => [ARG.1] 00434513 |. FFD6 CALL ESI ; |\USER32.GetDlgItem 00434515 |. 8B1D 4CF34700 MOV EBX,DWORD PTR DS:[<&USER32.GetWindow ; | 0043451B |. 50 PUSH EAX ; |hWnd 0043451C |. FFD3 CALL EBX ; \USER32.GetWindowTextA 0043451E |. 6A 64 PUSH 64 ; /MaxCount = 100. 00434520 |. 8D8424 C80000 LEA EAX,[LOCAL.24] ; | 00434527 |. 50 PUSH EAX ; |String => OFFSET LOCAL.24 00434528 |. 68 50040000 PUSH 450 ; |/ItemID = 1104. 0043452D |. 57 PUSH EDI ; ||hDialog => [ARG.1] 0043452E |. FFD6 CALL ESI ; |\USER32.GetDlgItem 00434530 |. 50 PUSH EAX ; |hWnd 00434531 |. FFD3 CALL EBX ; \USER32.GetWindowTextA 00434533 |. 8D8C24 C40000 LEA ECX,[LOCAL.24] 0043453A |. 51 PUSH ECX ; /Arg2 => OFFSET LOCAL.24 0043453B |. 8D5424 64 LEA EDX,[LOCAL.49] ; | 0043453F |. 52 PUSH EDX ; |Arg1 => OFFSET LOCAL.49 00434540 |. E8 EBFBFFFF CALL 00434130 ; \movgear.00434130 00434545 |. 83C4 08 ADD ESP,8 00434548 |. 85C0 TEST EAX,EAX 0043454A |. 0F84 B6000000 JZ 00434606 00434550 |. 8D4424 10 LEA EAX,[LOCAL.69] 00434554 |. 50 PUSH EAX ; /pDisposition => OFFSET LOCAL.69 00434555 |. 8D4C24 10 LEA ECX,[LOCAL.70] ; | 00434559 |. 51 PUSH ECX ; |pResult => OFFSET LOCAL.70 0043455A |. 6A 00 PUSH 0 ; |pSecurity = NULL 0043455C |. 68 3F000F00 PUSH 0F003F ; |DesiredAccess = KEY_ALL_ACCESS 00434561 |. 6A 00 PUSH 0 ; |Options = REG_OPTION_NON_VOLATILE 00434563 |. 68 85F64700 PUSH OFFSET 0047F685 ; |Class 00434568 |. 6A 00 PUSH 0 ; |Reserved = 0 0043456A |. 68 84E44800 PUSH OFFSET 0048E484 ; |Subkey = "Software\gamani\GIFMovieGear\2.0" 0043456F |. 68 02000080 PUSH 80000002 ; |hKey = HKEY_LOCAL_MACHINE 00434574 |. FF15 0CF04700 CALL DWORD PTR DS:[<&ADVAPI32.RegCreateK ; \ADVAPI32.RegCreateKeyExA 0043457A |. 8D4424 60 LEA EAX,[LOCAL.49] 0043457E |. 8D50 01 LEA EDX,[EAX+1] 00434581 |> 8A08 /MOV CL,BYTE PTR DS:[EAX] 00434583 |. 40 |INC EAX 00434584 |. 84C9 |TEST CL,CL 00434586 |.^ 75 F9 \JNZ SHORT 00434581 00434588 |. 8B35 00F04700 MOV ESI,DWORD PTR DS:[<&ADVAPI32.RegSetV 0043458E |. 2BC2 SUB EAX,EDX 00434590 |. 40 INC EAX 00434591 |. 50 PUSH EAX ; /DataSize 00434592 |. 8B4424 10 MOV EAX,DWORD PTR SS:[LOCAL.70] ; | 00434596 |. 8D5424 64 LEA EDX,[LOCAL.49] ; | 0043459A |. 52 PUSH EDX ; |Data => OFFSET LOCAL.49 0043459B |. 6A 01 PUSH 1 ; |Type = REG_SZ 0043459D |. 6A 00 PUSH 0 ; |Reserved = 0 0043459F |. 68 C8F34800 PUSH OFFSET 0048F3C8 ; |SubKey = "RegName3" 004345A4 |. 50 PUSH EAX ; |hKey => [LOCAL.70] 004345A5 |. FFD6 CALL ESI ; \ADVAPI32.RegSetValueExA 004345A7 |. 8D8424 C40000 LEA EAX,[LOCAL.24] 004345AE |. 8D48 01 LEA ECX,[EAX+1] 004345B1 |> 8A10 /MOV DL,BYTE PTR DS:[EAX] 004345B3 |. 40 |INC EAX 004345B4 |. 84D2 |TEST DL,DL 004345B6 |.^ 75 F9 \JNZ SHORT 004345B1 004345B8 |. 8B5424 0C MOV EDX,DWORD PTR SS:[LOCAL.70] 004345BC |. 2BC1 SUB EAX,ECX 004345BE |. 40 INC EAX 004345BF |. 50 PUSH EAX ; /DataSize 004345C0 |. 8D8C24 C80000 LEA ECX,[LOCAL.24] ; | 004345C7 |. 51 PUSH ECX ; |Data => OFFSET LOCAL.24 004345C8 |. 6A 01 PUSH 1 ; |Type = REG_SZ 004345CA |. 6A 00 PUSH 0 ; |Reserved = 0 004345CC |. 68 D4F34800 PUSH OFFSET 0048F3D4 ; |SubKey = "RegCode3" 004345D1 |. 52 PUSH EDX ; |hKey => [LOCAL.70] 004345D2 |. FFD6 CALL ESI ; \ADVAPI32.RegSetValueExA 004345D4 |. 8B4424 0C MOV EAX,DWORD PTR SS:[LOCAL.70] 004345D8 |. 50 PUSH EAX ; /hKey => [LOCAL.70] 004345D9 |. FF15 18F04700 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe ; \ADVAPI32.RegCloseKey 004345DF |. 68 E0F34800 PUSH OFFSET 0048F3E0 ; /Subkey = "Software\Loani\MG4" 004345E4 |. 68 02000080 PUSH 80000002 ; |hKey = HKEY_LOCAL_MACHINE 004345E9 |. FF15 14F04700 CALL DWORD PTR DS:[<&ADVAPI32.RegDeleteK ; \ADVAPI32.RegDeleteKeyA 004345EF |. 6A 01 PUSH 1 ; /Result = 1 004345F1 |. 57 PUSH EDI ; |hDialog => [ARG.1] 004345F2 |. FF15 A4F34700 CALL DWORD PTR DS:[<&USER32.EndDialog>] ; \USER32.EndDialog 004345F8 |. 5F POP EDI 004345F9 |. 5E POP ESI 004345FA |. 33C0 XOR EAX,EAX 004345FC |. 5B POP EBX 004345FD |. 81C4 1C010000 ADD ESP,11C 00434603 |. C2 1000 RETN 10 00434606 |> 6A 30 PUSH 30 ; /Arg4 = 30 00434608 |. 68 159D0000 PUSH 9D15 ; |Arg3 = 9D15 0043460D |. 68 149D0000 PUSH 9D14 ; |Arg2 = 9D14 00434612 |. 57 PUSH EDI ; |Arg1 => [ARG.1] 00434613 |. E8 F8D8FDFF CALL 00411F10 ; \movgear.00411F10 00434618 |. 83C4 10 ADD ESP,10 0043461B |. 68 4F040000 PUSH 44F ; /ItemID = 1103. 00434620 |. 57 PUSH EDI ; |hDialog => [ARG.1] 00434621 |. FFD6 CALL ESI ; \USER32.GetDlgItem 00434623 |. 50 PUSH EAX ; /hWnd 00434624 |. FF15 A8F44700 CALL DWORD PTR DS:[<&USER32.SetFocus>] ; \USER32.SetFocus 0043462A |. 5F POP EDI 0043462B |. 5E POP ESI 0043462C |. 33C0 XOR EAX,EAX 0043462E |. 5B POP EBX 0043462F |. 81C4 1C010000 ADD ESP,11C 00434635 |. C2 1000 RETN 10
-
失败弹窗走
CPU Disasm 地址 十六进制数据 指令 注释 00411EE0 /$ 8B4424 04 MOV EAX,DWORD PTR SS:[ARG.1] ; movgear.00411EE0(推测 Arg1) 00411EE4 |. 8B0D C4C24A00 MOV ECX,DWORD PTR DS:[4AC2C4] 00411EEA |. 68 00020000 PUSH 200 ; /Count = 512. 00411EEF |. 68 80BF4A00 PUSH OFFSET 004ABF80 ; |Buffer = "The information you have provided is invalid. Please be sure that you typed it exactly as it was given to you." 00411EF4 |. 50 PUSH EAX ; |StringID => [ARG.1] 00411EF5 |. 51 PUSH ECX ; |hInst => [4AC2C4] = 00400000 ('movgear') 00411EF6 |. FF15 C0F44700 CALL DWORD PTR DS:[<&USER32.LoadStringA> ; \USER32.LoadStringA 00411EFC |. 85C0 TEST EAX,EAX 00411EFE |. 74 0D JZ SHORT 00411F0D 00411F00 |. 3D 00020000 CMP EAX,200 00411F05 |. 7D 06 JGE SHORT 00411F0D 00411F07 |. B8 80BF4A00 MOV EAX,OFFSET 004ABF80 ; ASCII "The information you have provided is invalid. Please be sure that you typed it exactly as it was given to you." 00411F0C |. C3 RETN 00411F0D |> 33C0 XOR EAX,EAX 00411F0F \. C3 RETN 00411F10 /$ 8B4C24 0C MOV ECX,DWORD PTR SS:[ARG.3] ; movgear.00411F10(推测 Arg1,Arg2,Arg3,Arg4) 00411F14 |. 8B15 C4C24A00 MOV EDX,DWORD PTR DS:[4AC2C4] 00411F1A |. 81EC 00010000 SUB ESP,100 00411F20 |. 68 FF000000 PUSH 0FF ; /Count = 255. 00411F25 |. 8D4424 04 LEA EAX,[LOCAL.63] ; | 00411F29 |. 50 PUSH EAX ; |Buffer => OFFSET LOCAL.63 00411F2A |. 51 PUSH ECX ; |StringID = 40213. => 'Invalid Registration Info' 00411F2B |. 52 PUSH EDX ; |hInst => [4AC2C4] = 00400000 ('movgear') 00411F2C |. FF15 C0F44700 CALL DWORD PTR DS:[<&USER32.LoadStringA> ; \USER32.LoadStringA 00411F32 |. 8B8424 100100 MOV EAX,DWORD PTR SS:[ARG.4] 00411F39 |. 8B9424 080100 MOV EDX,DWORD PTR SS:[ARG.2] 00411F40 |. 0D 00200000 OR EAX,00002000 00411F45 |. 50 PUSH EAX ; /Type 00411F46 |. 8D4C24 04 LEA ECX,[LOCAL.63] ; | 00411F4A |. 51 PUSH ECX ; |Caption => OFFSET LOCAL.63 00411F4B |. 52 PUSH EDX ; |/Arg1 => [ARG.2] 00411F4C |. E8 8FFFFFFF CALL 00411EE0 ; |\movgear.00411EE0 00411F51 |. 83C4 04 ADD ESP,4 ; | 00411F54 |. 50 PUSH EAX ; |Text 00411F55 |. 8B8424 100100 MOV EAX,DWORD PTR SS:[ARG.1] ; | 00411F5C |. 50 PUSH EAX ; |hOwner => [ARG.1] 00411F5D |. FF15 C4F44700 CALL DWORD PTR DS:[<&USER32.MessageBoxA> ; \USER32.MessageBoxA 00411F63 |. 81C4 00010000 ADD ESP,100 00411F69 \. C3 RETN
-
关键
-
看注册过程
-
我们来看看0048F3F8偏移处的值,32个黑名单
-
第一种注册码验证过程,Code是mg37开头就是走这种的。
CPU Disasm 地址 十六进制数据 指令 注释 00434130 /$ 53 PUSH EBX ; movgear.00434130(推测 Arg1,Arg2) 00434131 |. 55 PUSH EBP 00434132 |. 8B6C24 10 MOV EBP,DWORD PTR SS:[ARG.2] ; EBP指向Code,ASCII "12345678" 00434136 |. 807D 00 6D CMP BYTE PTR SS:[EBP],6D ; Code的第一字节,和'm'比较 0043413A |. 56 PUSH ESI 0043413B |. 57 PUSH EDI 0043413C |. 0F85 AD000000 JNE 004341EF 00434142 |. 807D 01 67 CMP BYTE PTR SS:[EBP+1],67 ; Code的第2字节,和'g'比较 00434146 |. 0F85 A3000000 JNE 004341EF 0043414C |. 807D 02 33 CMP BYTE PTR SS:[EBP+2],33 ; Code的第3字节,和'3'比较 00434150 |. 0F85 99000000 JNE 004341EF 00434156 |. 807D 03 37 CMP BYTE PTR SS:[EBP+3],37 ; Code的第4字节,和'7'比较 0043415A |. 0F85 8F000000 JNE 004341EF 00434160 |. 33DB XOR EBX,EBX ; 和黑名单库里的比较 00434162 |> 8BBB F8F34800 /MOV EDI,DWORD PTR DS:[EBX+48F3F8] ; 到 PTR ASCII "mvg21951736" 00434168 |. 8BC7 |MOV EAX,EDI ; strlen开始 0043416A |. 8D50 01 |LEA EDX,[EAX+1] 0043416D |. 8D49 00 |LEA ECX,[ECX] 00434170 |> 8A08 |/MOV CL,BYTE PTR DS:[EAX] 00434172 |. 40 ||INC EAX 00434173 |. 84C9 ||TEST CL,CL 00434175 |.^ 75 F9 |\JNZ SHORT 00434170 00434177 |. 2BC2 |SUB EAX,EDX ; EAX = strlen() 00434179 |. 8BC8 |MOV ECX,EAX ; blackLengthECX = blackLengthEAX,比较次数 0043417B |. 8BF5 |MOV ESI,EBP ; pszchESI = pszchEBP 0043417D |. 33C0 |XOR EAX,EAX 0043417F |. F3:A6 |REPE CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI] 00434181 |. 74 65 |JE SHORT 004341E8 ; 黑名单直接返回FALSE 00434183 |. 83C3 04 |ADD EBX,4 00434186 |. 81FB 80000000 |CMP EBX,80 0043418C |.^ 72 D4 \JB SHORT 00434162 0043418E |. 807D 04 73 CMP BYTE PTR SS:[EBP+4],73 ; Code的第5字节,和's'比较 00434192 |. 75 01 JNE SHORT 00434195 00434194 |. 45 INC EBP 00434195 |> 8D4D 07 LEA ECX,[EBP+7] ; pszchECX = pszchCode + 7或8 00434198 |. 51 PUSH ECX 00434199 |. E8 56BE0300 CALL 0046FFF4 0043419E |. 8B5C24 18 MOV EBX,DWORD PTR SS:[ARG.1] ; pszchNameEBX指向Name 004341A2 |. 8A13 MOV DL,BYTE PTR DS:[EBX] ; EDX_DL = *pszchNameEBX 004341A4 |. 83C4 04 ADD ESP,4 004341A7 |. 33C9 XOR ECX,ECX 004341A9 |. 84D2 TEST DL,DL ; 判断是否空串 004341AB |. 8BFB MOV EDI,EBX ; pszchCodeEDI = pszchCodeEBX 004341AD |. BE DF0B0000 MOV ESI,0BDF ; ESI = 0BDF=3039 004341B2 |. 74 26 JZ SHORT 004341DA ; 004341B4 |> 0FBED2 /MOVSX EDX,DL 004341B7 |. 41 |INC ECX 004341B8 |. 0FAFD1 |IMUL EDX,ECX 004341BB |. 03F2 |ADD ESI,EDX ; ESI += *pszchEDI * ECX 004341BD |. 81FE BE170000 |CMP ESI,17BE 004341C3 |. 7E 06 |JLE SHORT 004341CB 004341C5 |. 81EE BE170000 |SUB ESI,17BE ; ESI += *pszchEDI * ECX - 6078. 004341CB |> 83F9 0A |CMP ECX,0A 004341CE |. 7E 02 |JLE SHORT 004341D2 004341D0 |. 33C9 |XOR ECX,ECX 004341D2 |> 8A57 01 |MOV DL,BYTE PTR DS:[EDI+1] 004341D5 |. 47 |INC EDI 004341D6 |. 84D2 |TEST DL,DL 004341D8 |.^ 75 DA \JNZ SHORT 004341B4 004341DA |> 3BF0 CMP ESI,EAX 004341DC |. 75 15 JNE SHORT 004341F3 004341DE |. 5F POP EDI 004341DF |. 5E POP ESI 004341E0 |. 5D POP EBP 004341E1 |. B8 01000000 MOV EAX,1 004341E6 |. 5B POP EBX 004341E7 |. C3 RETN 004341E8 |> 5F POP EDI 004341E9 |. 5E POP ESI 004341EA |. 5D POP EBP 004341EB |. 33C0 XOR EAX,EAX 004341ED |. 5B POP EBX 004341EE |. C3 RETN 004341EF |> 8B5C24 14 MOV EBX,DWORD PTR SS:[ARG.1] ; EBX指向Name,ASCII "Fang" 004341F3 |> 55 PUSH EBP 004341F4 |. 53 PUSH EBX 004341F5 |. E8 16FCFFFF CALL 00433E10 004341FA |. 83C4 08 ADD ESP,8 004341FD |. 5F POP EDI 004341FE |. 5E POP ESI 004341FF |. 5D POP EBP 00434200 |. 5B POP EBX 00434201 \. C3 RETN
-
第二种注册码生成过程,直接比较Code == Func(Name)形式,这是最初级方式,容易点。
EBP = EDX
= ((EAX + (1 - pszHKRWQ) -1) * (EAX + (1 - pszHKRWQ)) + EBP) % strlen(pszHKRWQ)
= ((EAX - pszHKRWQ) * (EAX - pszHKRWQ + 1) +EBP) % 28
= (indexOf(pszHKRWQ, pszOkName[i]) * (indexOf(pszHKRWQ, pszOkName[i]) + 1) +EBP) % 28
CPU Disasm 地址十六进制数据指令注释 00433E10 /$ 8B4424 04 MOV EAX,DWORD PTR SS:[ARG.1] 00433E14 |. 8D9424 38FFFF LEA EDX,[LOCAL.49] 00433E1B |. 81EC D8000000 SUB ESP,0D8 ; 0D8=216.分配空间 00433E21 |. 2BD0 SUB EDX,EAX 00433E23 |> 8A08 /MOV CL,BYTE PTR DS:[EAX] ; 拷贝Name倒Local.49缓冲区 00433E25 |. 880C02 |MOV BYTE PTR DS:[EAX+EDX],CL 00433E28 |. 40 |INC EAX 00433E29 |. 84C9 |TEST CL,CL 00433E2B |.^ 75 F6 \JNZ SHORT 00433E23 00433E2D |. 53 PUSH EBX 00433E2E |. 55 PUSH EBP 00433E2F |. 56 PUSH ESI 00433E30 |. 57 PUSH EDI 00433E31 |. 8D4424 20 LEA EAX,[LOCAL.49] 00433E35 |. 50 PUSH EAX ; /String => OFFSET LOCAL.49 00433E36 |. FF15 1CF34700 CALL DWORD PTR DS:[<&USER32.CharUpperA>] ; \USER32.CharUpperA 00433E3C |. 8A4424 20 MOV AL,BYTE PTR SS:[LOCAL.49] ; Local.49里全是大写了 00433E40 |. 84C0 TEST AL,AL ; 判断Local.49是否为空串 00433E42 |. 8D7424 20 LEA ESI,[LOCAL.49] 00433E46 |. 8D7C24 20 LEA EDI,[LOCAL.49] 00433E4A |. 74 26 JZ SHORT 00433E72 00433E4C |. 8D6424 00 LEA ESP,[LOCAL.57] ; Name里在"HKRWQV2958DWNTQRGNSCFSXAZPYK"的字符拷贝到pszEDIBuffer里,既写回LOCAL.49缓冲区 00433E50 |> 0FBE0E /MOVSX ECX,BYTE PTR DS:[ESI] ; char chECX = *pszESI 00433E53 |. 51 |PUSH ECX 00433E54 |. 68 78F44800 |PUSH OFFSET 0048F478 ; ASCII "HKRWQV2958DWNTQRGNSCFSXAZPYK" 00433E59 |. E8 E2C10300 |CALL 00470040 ; 查找字符 00433E5E |. 83C4 08 |ADD ESP,8 00433E61 |. 85C0 |TEST EAX,EAX ; 判断是否找到,返回值非空为找到 00433E63 |. 74 05 |JZ SHORT 00433E6A 00433E65 |. 8A16 |MOV DL,BYTE PTR DS:[ESI] ; char chDL = *pszESI 00433E67 |. 8817 |MOV BYTE PTR DS:[EDI],DL ; *pszEDI = chDL 00433E69 |. 47 |INC EDI ; pszEDI++ 00433E6A |> 8A46 01 |MOV AL,BYTE PTR DS:[ESI+1] ; char chAL = *(pszESI+1) 00433E6D |. 46 |INC ESI ; pszESI++ 00433E6E |. 84C0 |TEST AL,AL 00433E70 |.^ 75 DE \JNZ SHORT 00433E50 ; while(0! = chAL) 00433E72 |> 8D4424 20 LEA EAX,[LOCAL.49] 00433E76 |. C607 00 MOV BYTE PTR DS:[EDI],0 ; LOCAL.49弄成0结尾字符串 00433E79 |. 8D50 01 LEA EDX,[EAX+1] ; 获取LOCAL.49长度,开始 00433E7C |. 8D6424 00 LEA ESP,[LOCAL.57] 00433E80 |> 8A08 /MOV CL,BYTE PTR DS:[EAX] 00433E82 |. 40 |INC EAX 00433E83 |. 84C9 |TEST CL,CL 00433E85 |.^ 75 F9 \JNZ SHORT 00433E80 00433E87 |. 2BC2 SUB EAX,EDX ; 获取LOCAL.49长度,结束,EAX=EAX-EDX 00433E89 |. 83F8 18 CMP EAX,18 ; 名字长度和18=24.比较 00433E8C |. 7D 1E JGE SHORT 00433EAC ; 大于0x18=24.就跳转 00433E8E |. B9 18000000 MOV ECX,18 00433E93 |. 2BC8 SUB ECX,EAX ; ECX=ECX-EAX=24.-NameLength_EAX 00433E95 |. 8D7C04 20 LEA EDI,[EAX+ESP+20] 00433E99 |. 8BC1 MOV EAX,ECX 00433E9B |. C1E9 02 SHR ECX,2 00433E9E |. BE 78F44800 MOV ESI,OFFSET 0048F478 ; ASCII "HKRWQV2958DWNTQRGNSCFSXAZPYK" 00433EA3 |. F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] ; strcat(LOCAL.49, strchr("HKRW...", LOCAL.49[0])) 00433EA5 |. 8BC8 MOV ECX,EAX 00433EA7 |. 83E1 03 AND ECX,00000003 00433EAA |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 00433EAC |> B8 78F44800 MOV EAX,OFFSET 0048F478 ; ASCII "HKRWQV2958DWNTQRGNSCFSXAZPYK" 00433EB1 |. C64424 39 00 MOV BYTE PTR SS:[LOCAL.43+1],0 00433EB6 |. C68424 840000 MOV BYTE PTR SS:[LOCAL.24],0 00433EBE |. 33ED XOR EBP,EBP ; EBP = 0 00433EC0 |. 8D48 01 LEA ECX,[EAX+1] ; 计算"HKRWQV2958DWNTQRGNSCFSXAZPYK"长度 00433EC3 |> 8A10 /MOV DL,BYTE PTR DS:[EAX] 00433EC5 |. 40 |INC EAX 00433EC6 |. 84D2 |TEST DL,DL 00433EC8 |.^ 75 F9 \JNZ SHORT 00433EC3 00433ECA |. 2BC1 SUB EAX,ECX ; 计算"HKRWQV2958DWNTQRGNSCFSXAZPYK"结束 00433ECC |. 894424 10 MOV DWORD PTR SS:[LOCAL.53],EAX ; LOCAL53 = 长度24 00433ED0 |. B8 01000000 MOV EAX,1 00433ED5 |. 2D 78F44800 SUB EAX,OFFSET 0048F478 ; ASCII "HKRWQV2958DWNTQRGNSCFSXAZPYK" 00433EDA |. 894424 18 MOV DWORD PTR SS:[LOCAL.51],EAX ; LOCAL51 = 1 - 0048F478 = FFB70B89 00433EDE |. 33DB XOR EBX,EBX ; EBX = 0 00433EE0 |. B8 78F44800 MOV EAX,OFFSET 0048F478 ; ASCII "HKRWQV2958DWNTQRGNSCFSXAZPYK" 00433EE5 |. 48 DEC EAX ; EAX = 0048F478-1=0048F477 00433EE6 |. 894424 14 MOV DWORD PTR SS:[LOCAL.52],EAX ; LOCAL52 = 0048F477 00433EEA |. 8D4424 20 LEA EAX,[LOCAL.49] ; pszchEAX = pszchOkName 00433EEE |. 48 DEC EAX ; pszchEAX-- 00433EEF |. 8DBC24 840000 LEA EDI,[LOCAL.24] 00433EF6 |. 894424 1C MOV DWORD PTR SS:[LOCAL.50],EAX ; pszchLOCAL50 = pszchEAX = pszchOkName - 1 00433EFA |. EB 04 JMP SHORT 00433F00 00433EFC |> 8B4424 1C /MOV EAX,DWORD PTR SS:[LOCAL.50] 00433F00 |> 0FBE4C18 01 |MOVSX ECX,BYTE PTR DS:[EBX+EAX+1] ; pszchECX = pszchOkName[EBX + 1] 00433F05 |. 8D73 01 |LEA ESI,[EBX+1] ; ESI = EBX + 1 00433F08 |. 51 |PUSH ECX 00433F09 |. 68 78F44800 |PUSH OFFSET 0048F478 ; ASCII "HKRWQV2958DWNTQRGNSCFSXAZPYK" 00433F0E |. E8 2DC10300 |CALL 00470040 00433F13 |. 8B5424 20 |MOV EDX,DWORD PTR SS:[LOCAL.51] ; EDX = FFB70B89 00433F17 |. 8BC8 |MOV ECX,EAX 00433F19 |. 03CA |ADD ECX,EDX ; ECX = EAX + FFB70B89 00433F1B |. 8D41 FF |LEA EAX,[ECX-1] ; EAX = EAX + FFB70B89 - 1 00433F1E |. 0FAFC1 |IMUL EAX,ECX ; EAX = (ECX - 1) * ECX = FFB70B88 * ECX 00433F21 |. 03C5 |ADD EAX,EBP ; EAX = EAX + EBP 00433F23 |. 99 |CDQ ; 双字数据扩展为四字类型 EDX = EAX < 80000000 ? 00000000 : FFFFFFFF 00433F24 |. F77C24 18 |IDIV DWORD PTR SS:[LOCAL.53] ; 商=(EAX)=(EDX,EAX)/(LOCAL53)(长度),余数=(EDX)=(EDX,EAX)%(LOCAL53)(长度) 00433F28 |. 83C4 08 |ADD ESP,8 00433F2B |. B9 06000000 |MOV ECX,6 00433F30 |. 42 |INC EDX 00433F31 |. 8BEA |MOV EBP,EDX ; EBP = EDX = ((EAX + (1 - pszHKRWQ) -1) * (EAX + (1 - pszHKRWQ)) + EBP) % strlen(pszHKRWQ) 00433F33 |. 8B5424 14 |MOV EDX,DWORD PTR SS:[LOCAL.52] 00433F37 |. 8A042A |MOV AL,BYTE PTR DS:[EBP+EDX] ; AL = pszHKRWQ[EBP] 00433F3A |. 8807 |MOV BYTE PTR DS:[EDI],AL ; *pszchEDI = AL = pszHKRWQ[EBP] 00433F3C |. 8BC6 |MOV EAX,ESI 00433F3E |. 99 |CDQ 00433F3F |. F7F9 |IDIV ECX 00433F41 |. 47 |INC EDI 00433F42 |. 85D2 |TEST EDX,EDX 00433F44 |. 75 09 |JNZ SHORT 00433F4F 00433F46 |. 83FB 17 |CMP EBX,17 ; EBC 和 17=23.比较 00433F49 |. 7D 04 |JGE SHORT 00433F4F 00433F4B |. C607 2D |MOV BYTE PTR DS:[EDI],2D ; *pszchEDI = '-' 00433F4E |. 47 |INC EDI 00433F4F |> 8BDE |MOV EBX,ESI 00433F51 |. 83FB 18 |CMP EBX,18 ; 和长度18=24.比较 00433F54 |.^ 7C A6 \JL SHORT 00433EFC ; 小于继续循环,否则结束循环 00433F56 |. 8B8424 F00000 MOV EAX,DWORD PTR SS:[ARG.2] ; pszEAX = pszCode 00433F5D |. C607 00 MOV BYTE PTR DS:[EDI],0 00433F60 |. 8DB424 840000 LEA ESI,[LOCAL.24] ; pszESI=pszRealCode; 一段序列,如HSDWQ9-QKFADW-H92C5A-GAGVNK 00433F67 |> 8A10 /MOV DL,BYTE PTR DS:[EAX] 00433F69 |. 8A1E |MOV BL,BYTE PTR DS:[ESI] 00433F6B |. 8ACA |MOV CL,DL 00433F6D |. 3AD3 |CMP DL,BL 00433F6F |. 75 1E |JNE SHORT 00433F8F 00433F71 |. 84C9 |TEST CL,CL 00433F73 |. 74 16 |JZ SHORT 00433F8B 00433F75 |. 8A50 01 |MOV DL,BYTE PTR DS:[EAX+1] 00433F78 |. 8A5E 01 |MOV BL,BYTE PTR DS:[ESI+1] 00433F7B |. 8ACA |MOV CL,DL 00433F7D |. 3AD3 |CMP DL,BL 00433F7F |. 75 0E |JNE SHORT 00433F8F 00433F81 |. 83C0 02 |ADD EAX,2 00433F84 |. 83C6 02 |ADD ESI,2 00433F87 |. 84C9 |TEST CL,CL 00433F89 |.^ 75 DC \JNZ SHORT 00433F67 00433F8B |> 33C0 XOR EAX,EAX 00433F8D |. EB 05 JMP SHORT 00433F94 00433F8F |> 1BC0 SBB EAX,EAX ; Calculates sign(EAX) 00433F91 |. 83D8 FF SBB EAX,-1 00433F94 |> 85C0 TEST EAX,EAX 00433F96 |. 5F POP EDI 00433F97 |. 5E POP ESI 00433F98 |. 5D POP EBP 00433F99 |. 5B POP EBX 00433F9A |. 75 0C JNZ SHORT 00433FA8 ; Code和Func(Name)的值不等,就跳,返回假 00433F9C |. B8 01000000 MOV EAX,1 00433FA1 |. 81C4 D8000000 ADD ESP,0D8 00433FA7 |. C3 RETN 00433FA8 |> 33C0 XOR EAX,EAX 00433FAA |. 81C4 D8000000 ADD ESP,0D8 00433FB0 \. C3 RETN
-
顺便
-
程序打开时验证模块代码
-
刚打开也会断到验证里,看了下堆栈,写在这。
读取注册表注册信息,位置HKEY_LOCAL_MACHINE \Software\gamani\GIFMovieGear\2.0下的两个键SubKey = "RegName3"和SubKey = "RegCode3",,过期时间来自HKLM\SOFTWARE\Wow6432Node\Loani\MG4\stamp,保存的是秒数。
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\gamani\GIFMovieGear\2.0] "RegName3"="Fang" "RegCode3"="HSDWQ9-QKFADW-H92C5A-GAGVNK"
CPU Disasm 地址 十六进制数据 指令 注释 00434210 /$ 81EC D0000000 SUB ESP,0D0 ; movgear.00434210(推测 Arg1,Arg2) 00434216 |. 53 PUSH EBX 00434217 |. 56 PUSH ESI 00434218 |. 8B35 04F04700 MOV ESI,DWORD PTR DS:[<&ADVAPI32.RegOpenKeyExA>] 0043421E |. 8D4424 08 LEA EAX,[LOCAL.51] 00434222 |. 50 PUSH EAX ; /pResult => OFFSET LOCAL.51 00434223 |. 68 19000200 PUSH 20019 ; |DesiredAccess = KEY_READ 00434228 |. 6A 00 PUSH 0 ; |Reserved = 0 0043422A |. 68 84E44800 PUSH OFFSET 0048E484 ; |SubKey = "Software\gamani\GIFMovieGear\2.0" 0043422F |. 68 02000080 PUSH 80000002 ; |hKey = HKEY_LOCAL_MACHINE 00434234 |. 83CB FF OR EBX,FFFFFFFF ; | 00434237 |. FFD6 CALL ESI ; \ADVAPI32.RegOpenKeyExA 00434239 |. 85C0 TEST EAX,EAX 0043423B |. 74 20 JZ SHORT 0043425D 0043423D |. 8D4C24 08 LEA ECX,[LOCAL.51] 00434241 |. 51 PUSH ECX ; /pResult => OFFSET LOCAL.51 00434242 |. 68 19000200 PUSH 20019 ; |DesiredAccess = KEY_READ 00434247 |. 6A 00 PUSH 0 ; |Reserved = 0 00434249 |. 68 84E44800 PUSH OFFSET 0048E484 ; |SubKey = "Software\gamani\GIFMovieGear\2.0" 0043424E |. 68 01000080 PUSH 80000001 ; |hKey = HKEY_CURRENT_USER 00434253 |. FFD6 CALL ESI ; \ADVAPI32.RegOpenKeyExA 00434255 |. 85C0 TEST EAX,EAX 00434257 |. 0F85 AF000000 JNZ 0043430C 0043425D |> 8B4C24 08 MOV ECX,DWORD PTR SS:[LOCAL.51] 00434261 |. 8B35 08F04700 MOV ESI,DWORD PTR DS:[<&ADVAPI32.RegQueryValueEx 00434267 |. 8D5424 0C LEA EDX,[LOCAL.50] 0043426B |. 52 PUSH EDX ; /pDataLen => OFFSET LOCAL.50 0043426C |. 8D4424 14 LEA EAX,[LOCAL.49] ; | 00434270 |. 50 PUSH EAX ; |pData => OFFSET LOCAL.49 00434271 |. 6A 00 PUSH 0 ; |pType = NULL 00434273 |. 6A 00 PUSH 0 ; |Reserved = 0 00434275 |. 68 C8F34800 PUSH OFFSET 0048F3C8 ; |Name = "RegName3" 0043427A |. 51 PUSH ECX ; |hKey => [LOCAL.51] 0043427B |. C74424 24 640 MOV DWORD PTR SS:[LOCAL.50],64 ; | 00434283 |. FFD6 CALL ESI ; \ADVAPI32.RegQueryValueExA 00434285 |. 85C0 TEST EAX,EAX 00434287 |. 0F85 7F000000 JNZ 0043430C ;没有找到注册名字信息 0043428D |. 8B4C24 08 MOV ECX,DWORD PTR SS:[LOCAL.51] 00434291 |. 8D5424 0C LEA EDX,[LOCAL.50] 00434295 |. 52 PUSH EDX ; /pDataLen => OFFSET LOCAL.50 00434296 |. 8D4424 78 LEA EAX,[LOCAL.24] ; | 0043429A |. 50 PUSH EAX ; |pData => OFFSET LOCAL.24 0043429B |. 6A 00 PUSH 0 ; |pType = NULL 0043429D |. 6A 00 PUSH 0 ; |Reserved = 0 0043429F |. 68 D4F34800 PUSH OFFSET 0048F3D4 ; |Name = "RegCode3" 004342A4 |. 51 PUSH ECX ; |hKey => [LOCAL.51] 004342A5 |. C74424 24 640 MOV DWORD PTR SS:[LOCAL.50],64 ; | 004342AD |. FFD6 CALL ESI ; \ADVAPI32.RegQueryValueExA 004342AF |. 85C0 TEST EAX,EAX 004342B1 |. 75 59 JNZ SHORT 0043430C ;没有找到注册码信息 004342B3 |. 8D5424 74 LEA EDX,[LOCAL.24] 004342B7 |. 52 PUSH EDX ; /Arg2 => OFFSET LOCAL.24 004342B8 |. 8D4424 14 LEA EAX,[LOCAL.49] ; | 004342BC |. 50 PUSH EAX ; |Arg1 => OFFSET LOCAL.49 004342BD |. E8 6EFEFFFF CALL 00434130 ; \movgear.00434130 ;注册验证 004342C2 |. 83C4 08 ADD ESP,8 004342C5 |. 85C0 TEST EAX,EAX 004342C7 |. 74 43 JZ SHORT 0043430C ;验证失败 004342C9 |. 8B9424 DC0000 MOV EDX,DWORD PTR SS:[ARG.1] 004342D0 |. 85D2 TEST EDX,EDX 004342D2 |. BB 01000000 MOV EBX,1 004342D7 |. 74 14 JZ SHORT 004342ED 004342D9 |. 8D4C24 10 LEA ECX,[LOCAL.49] 004342DD |. 8D4424 10 LEA EAX,[LOCAL.49] 004342E1 |. 2BD1 SUB EDX,ECX 004342E3 |> 8A08 /MOV CL,BYTE PTR DS:[EAX] 004342E5 |. 880C02 |MOV BYTE PTR DS:[EAX+EDX],CL 004342E8 |. 40 |INC EAX 004342E9 |. 84C9 |TEST CL,CL 004342EB |.^ 75 F6 \JNZ SHORT 004342E3 004342ED |> 8B9424 E00000 MOV EDX,DWORD PTR SS:[ARG.2] 004342F4 |. 85D2 TEST EDX,EDX 004342F6 |. 74 14 JZ SHORT 0043430C 004342F8 |. 8D4C24 74 LEA ECX,[LOCAL.24] 004342FC |. 8D4424 74 LEA EAX,[LOCAL.24] 00434300 |. 2BD1 SUB EDX,ECX 00434302 |> 8A08 /MOV CL,BYTE PTR DS:[EAX] 00434304 |. 880C02 |MOV BYTE PTR DS:[EAX+EDX],CL 00434307 |. 40 |INC EAX 00434308 |. 84C9 |TEST CL,CL 0043430A |.^ 75 F6 \JNZ SHORT 00434302 0043430C |> 8B5424 08 MOV EDX,DWORD PTR SS:[LOCAL.51] 00434310 |. 52 PUSH EDX ; /hKey => [LOCAL.51] 00434311 |. FF15 18F04700 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKey>] ; \ADVAPI32.RegCloseKey 00434317 |. 5E POP ESI 00434318 |. 8BC3 MOV EAX,EBX 0043431A |. 5B POP EBX 0043431B |. 81C4 D0000000 ADD ESP,0D0 00434321 \. C3 RETN
-
REPE CMPS
OD Shift+F1帮助命令,放在一起说明了
Command: REPE CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI]
Hex dump: F3:A6
Searches strings for the first non-matching byte.
On each iteration, processor compares byte at address [ESI] with the byte at address [EDI] and sets flags C, O, S, Z, A and P
according to the difference [ESI]-[EDI]. The operands themselves are not modified. After the comparison, registers ESI and
EDI are incremented by 1 (if flag D is cleared) or decremented by 1 (if flag D is set). Register ECX is always decremented
by 1. If ECX after decrement is zero, or if compared operands were different (flag Z was cleared), search stops; otherwise,
processor repeats the whole cycle again and again, until count exhausts or non-matching pair will be found.
Note that if ECX initially contains zero, this instruction does nothing.
REPE :repeat equal,意思是相等的时候重复,
REPNE repeat not equal,不等的时候重复;
他们每循环一次ECX自动减一。
/**正常使用等价于*/ //准备int rECX = 循环次数; //指令开始 bool bZF = true;//比较标志位,由指令REPE决定 while (bZF && !rECX)//循环条件,由指令REPE决定bZF,REPNE决定!bZF { bZF = *pbyteESI++ == *pbyteEDI++;// DF位决定++还是--,根据结果设置标志位bZF rECX--;//总是-- }
字符串比较指令(Compare String Instruction) 该指令是把指针DS:SI和ES:DI所指向字节、字或双字的值相减,并用所得到的差来设置有关的标志位。与此同时,变址寄存器SI和DI也将根据标志位DF的值作相应增减。 指令的格式:CMPS 地址表达式1, 地址表达式2 受影响的标志位:AF、CF、OF、PF、SF和ZF |
-
注册代码
特别写了个js的代码,涉及中文名字时的gbk 在内存中的摆放。
-
Javascript(在线查看 http://runjs.cn/code/npiizz88)
DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>GIFMovieGear KeyGentitle>
<style type="text/css">
p {
font-family: 'Lucida Console', Monaco, monospace;
}
button {
width: 150px;
}
.bg {
font-style: italic;
color: gray;
}
style>
<script language="javascript" type="text/javascript">
//Fang = HSDWQ9-QKFADW-H92C5A-GAGVNK CB D5 B1 B1|D0 A1 C2 F3| = 苏北小麦
function Generate() {
var inputs = document.getElementsByTagName("input");
//var addrHKRW = 0x48F478, local51 = 1 - 0x48F478, local52 = 0x48F478 - 1;
//local51 = 0xFFB70B89;//0xFFFFFFFF - 0x48F478 + 2
var idx, i, ch;
var name = inputs[0].value, rName = [], resTab = "HKRWQV2958DWNTQRGNSCFSXAZPYK";
var letterTable = "0123456789abcdefghijklmnopqrstuvwxyz"
var ediRCode = [], ebp = 0;//, eax, ecx;
var codeTypes = document.getElementsByName("codetype");
//两种注册码,mg37开头的和不是这开头的短横线分割的
if (!codeTypes[2].checked) {
do {
ediRCode = "mg37";
idx = name.length;
if (codeTypes[0].checked)
ediRCode += 's';
ediRCode += randomLetter(letterTable) + randomLetter(letterTable) + randomLetter(letterTable);
var esi = 3039, ecx = 0, edx;
//每一项0x00 - 0xFF
var codes = GB2312CodeArray(name);
for (i = 0; i < codes.length; i++) {
++ecx;
edx = codes[i];
if (edx > 0x7F)
edx = -(~(edx - 1) & 0xff);
esi += ecx * edx;
if (esi > 6078)
esi -= 6078;
if (ecx > 10)
ecx = 0;
}
ediRCode += esi;
} while (isBlackCode(ediRCode));
} else {
name = name.toUpperCase()
for (i = 0; i < name.length; i++) {
ch = name.charAt(i);
idx = resTab.indexOf(ch);
if (-1 != idx)//有才压入
rName.push(ch);
}
//rName每一个字符都存在于resTab中
rName = rName.join("");
//不足24位补齐
if (rName.length < 24)
rName = rName + resTab.substring(0, 24 - rName.length);
i = 0;
//Code长度为24
while (i < 24) {
idx = resTab.indexOf(rName.charAt(i));
//eax = addrHKRW + idx;
//ecx = (eax + local51) & 0xFFFFFFFF;//rAdd(eax, local51);
//ebp = rAdd(ebp, (ecx - 1)* ecx) % resTab.length;
ebp = (idx * (idx + 1) + ebp) % resTab.length;
ediRCode.push(resTab.charAt(ebp++));
if (!(++i % 6) && i < 24)
ediRCode.push('-');
}
ediRCode = ediRCode.join("");
}
inputs[1].value = ediRCode;
};
//模拟32位寄存器值相加
/*function rAdd(v1, v2){
var v = v1 + v2;
if(v > 0xFFFFFFFF)
v &= 0xFFFFFFFF;
return v;
}*/
var blackCodes = ["mvg21951736", "mg374604342", "mg370534035", "mg373465241", "mg37NTi", "mg372503958", "mg379843149", "mg370151347", "mg370353008", "mg372021424", "mg375953248", "mg379223953", "mg373473759", "mg378542544", "mg370473710", "mg37064348", "mg378822469", "mg374394987", "mg371073478", "mg379773651", "mg371895266", "mg373223554", "mg377583454", "mg37644957", "mg370342692", "mg376484039", "mg376871434", "mg370704788", "mg377643863", "mg377753931", "mg379342689", "mg374344777"];
function isBlackCode(code) {
for (i = blackCodes.length; i > 0; i--) {
if (code == blackCodes[--i]) {
return true;
}
}
return false;
}
function randomLetter(letterTable) {
return letterTable.charAt(Math.floor(Math.random() * letterTable.length));
}
function codeChange() {
var testCode = document.getElementsByName("testCode");
var raw = testCode[0].value;
var charCodes = [];
for (var i = 0; i < raw.length; i++) {
charCodes.push(raw.charCodeAt(i).toString(16));
}
testCode[1].value = charCodes.join();
//
charCodes.length = 0;
var encodeArray = encodeURI(raw).split("%");
for (var i = 1; i < encodeArray.length; i += 3) {
charCodes.push(encodeArray[i] + encodeArray[i + 1] + encodeArray[i + 2]);
}
testCode[2].value = charCodes.join();
charCodes.length = 0;
//
var gb2312Codes = GB2312CodeArray(raw);
for (var i = 0; i < gb2312Codes.length; i += 2) {
charCodes.push(gb2312Codes[i].toString(16) + gb2312Codes[i + 1].toString(16));
}
testCode[3].value = charCodes.join();
}
function init() {
Generate();
codeChange();
var c = document.getElementById("c");
var ctx = c.getContext("2d");
c.height = 100;
c.width = 300;
var txts = "CRACK".split("");
var font_size = 12;
var columns = c.width / font_size;
var drops = [];
for (var x = 0; x < columns; x++)
drops[x] = 1;
function draw() {
ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
ctx.fillRect(0, 0, c.width, c.height);
ctx.fillStyle = "#0F0";
ctx.font = font_size + "px arial";
for (var i = 0; i < drops.length; i++) {
var text = txts[Math.floor(Math.random() * txts.length)];
ctx.fillText(text, i * font_size, drops[i] * font_size);
if (drops[i] * font_size > c.height || Math.random() > 0.8)
drops[i] = 0;
drops[i]++;
}
}
setInterval(draw, 66);
}
/** 返回[] http://blog.csdn.net/yimengqiannian/article/details/7016720 */
function GB2312CodeArray(str) {
/*********改自qiushuiwuhen(2002-9-16)********/
var ch, pos, cod, gbkCode = [];
for (var i = 0; i < str.length; i++) {
ch = str.charAt(i);
cod = str.charCodeAt(i);
//汉字字符
if (cod >= 0x4e00 && cod < 0x9FA5) {
if (-1 != (pos = GBhz.indexOf(ch))) {
gbkCode.push(0xB0 + parseInt(pos / 94));
gbkCode.push(0xA1 + pos % 94);
}
} else if ((pos = GBfh.indexOf(ch)) != -1) {
gbkCode.push(0xA1 + parseInt(pos / 94));
gbkCode.push(0xA1 + pos % 94);
}
else gbkCode.push(parseInt(cod));
}
return gbkCode;
}
//采录的只是GB2312编码
var GBfh = " 、。•ˉˇ¨〃々—~‖…''""〔〕〈〉《》「」『』〖〗【】±×÷∶∧∨∑∏∪∩∈∷√⊥∥∠⌒⊙∫∮≡≌≈∽∝≠≮≯≤≥∞∵∴♂♀°′″℃$¤¢£‰§№☆★○●◎◇◆□■△▲※→←↑↓〓ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹ⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇①②③④⑤⑥⑦⑧⑨⑩㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ!"#¥%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} ̄ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψω︵︶︹︺︿﹀︽︾﹁﹂﹃﹄︻︼︷︸︱︳︴АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюяāáǎàēéěèīíǐìōóǒòūúǔùǖǘǚǜüêɑńňɡㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ─━│┃┄┅┆┇┈┉┊┋┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋";
var GBhz = "啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑班搬扳般颁板版扮拌伴瓣半办绊邦帮梆榜膀绑棒磅蚌镑傍谤苞胞包褒剥薄雹保堡饱宝抱报暴豹鲍爆杯碑悲卑北辈背贝钡倍狈备惫焙被奔苯本笨崩绷甭泵蹦迸逼鼻比鄙笔彼碧蓖蔽毕毙毖币庇痹闭敝弊必辟壁臂避陛鞭边编贬扁便变卞辨辩辫遍标彪膘表鳖憋别瘪彬斌濒滨宾摈兵冰柄丙秉饼炳病并玻菠播拨钵波博勃搏铂箔伯帛舶脖膊渤泊驳捕卜哺补埠不布步簿部怖擦猜裁材才财睬踩采彩菜蔡餐参蚕残惭惨灿苍舱仓沧藏操糙槽曹草厕策侧册测层蹭插叉茬茶查碴搽察岔差诧拆柴豺搀掺蝉馋谗缠铲产阐颤昌猖场尝常长偿肠厂敞畅唱倡超抄钞朝嘲潮巢吵炒车扯撤掣彻澈郴臣辰尘晨忱沉陈趁衬撑称城橙成呈乘程惩澄诚承逞骋秤吃痴持匙池迟弛驰耻齿侈尺赤翅斥炽充冲虫崇宠抽酬畴踌稠愁筹仇绸瞅丑臭初出橱厨躇锄雏滁除楚础储矗搐触处揣川穿椽传船喘串疮窗幢床闯创吹炊捶锤垂春椿醇唇淳纯蠢戳绰疵茨磁雌辞慈瓷词此刺赐次聪葱囱匆从丛凑粗醋簇促蹿篡窜摧崔催脆瘁粹淬翠村存寸磋撮搓措挫错搭达答瘩打大呆歹傣戴带殆代贷袋待逮怠耽担丹单郸掸胆旦氮但惮淡诞弹蛋当挡党荡档刀捣蹈倒岛祷导到稻悼道盗德得的蹬灯登等瞪凳邓堤低滴迪敌笛狄涤翟嫡抵底地蒂第帝弟递缔颠掂滇碘点典靛垫电佃甸店惦奠淀殿碉叼雕凋刁掉吊钓调跌爹碟蝶迭谍叠丁盯叮钉顶鼎锭定订丢东冬董懂动栋侗恫冻洞兜抖斗陡豆逗痘都督毒犊独读堵睹赌杜镀肚度渡妒端短锻段断缎堆兑队对墩吨蹲敦顿囤钝盾遁掇哆多夺垛躲朵跺舵剁惰堕蛾峨鹅俄额讹娥恶厄扼遏鄂饿恩而儿耳尔饵洱二贰发罚筏伐乏阀法珐藩帆番翻樊矾钒繁凡烦反返范贩犯饭泛坊芳方肪房防妨仿访纺放菲非啡飞肥匪诽吠肺废沸费芬酚吩氛分纷坟焚汾粉奋份忿愤粪丰封枫蜂峰锋风疯烽逢冯缝讽奉凤佛否夫敷肤孵扶拂辐幅氟符伏俘服浮涪福袱弗甫抚辅俯釜斧脯腑府腐赴副覆赋复傅付阜父腹负富讣附妇缚咐噶嘎该改概钙盖溉干甘杆柑竿肝赶感秆敢赣冈刚钢缸肛纲岗港杠篙皋高膏羔糕搞镐稿告哥歌搁戈鸽胳疙割革葛格蛤阁隔铬个各给根跟耕更庚羹埂耿梗工攻功恭龚供躬公宫弓巩汞拱贡共钩勾沟苟狗垢构购够辜菇咕箍估沽孤姑鼓古蛊骨谷股故顾固雇刮瓜剐寡挂褂乖拐怪棺关官冠观管馆罐惯灌贯光广逛瑰规圭硅归龟闺轨鬼诡癸桂柜跪贵刽辊滚棍锅郭国果裹过哈骸孩海氦亥害骇酣憨邯韩含涵寒函喊罕翰撼捍旱憾悍焊汗汉夯杭航壕嚎豪毫郝好耗号浩呵喝荷菏核禾和何合盒貉阂河涸赫褐鹤贺嘿黑痕很狠恨哼亨横衡恒轰哄烘虹鸿洪宏弘红喉侯猴吼厚候后呼乎忽瑚壶葫胡蝴狐糊湖弧虎唬护互沪户花哗华猾滑画划化话槐徊怀淮坏欢环桓还缓换患唤痪豢焕涣宦幻荒慌黄磺蝗簧皇凰惶煌晃幌恍谎灰挥辉徽恢蛔回毁悔慧卉惠晦贿秽会烩汇讳诲绘荤昏婚魂浑混豁活伙火获或惑霍货祸击圾基机畸稽积箕肌饥迹激讥鸡姬绩缉吉极棘辑籍集及急疾汲即嫉级挤几脊己蓟技冀季伎祭剂悸济寄寂计记既忌际妓继纪嘉枷夹佳家加荚颊贾甲钾假稼价架驾嫁歼监坚尖笺间煎兼肩艰奸缄茧检柬碱硷拣捡简俭剪减荐槛鉴践贱见键箭件健舰剑饯渐溅涧建僵姜将浆江疆蒋桨奖讲匠酱降蕉椒礁焦胶交郊浇骄娇嚼搅铰矫侥脚狡角饺缴绞剿教酵轿较叫窖揭接皆秸街阶截劫节桔杰捷睫竭洁结解姐戒藉芥界借介疥诫届巾筋斤金今津襟紧锦仅谨进靳晋禁近烬浸尽劲荆兢茎睛晶鲸京惊精粳经井警景颈静境敬镜径痉靖竟竞净炯窘揪究纠玖韭久灸九酒厩救旧臼舅咎就疚鞠拘狙疽居驹菊局咀矩举沮聚拒据巨具距踞锯俱句惧炬剧捐鹃娟倦眷卷绢撅攫抉掘倔爵觉决诀绝均菌钧军君峻俊竣浚郡骏喀咖卡咯开揩楷凯慨刊堪勘坎砍看康慷糠扛抗亢炕考拷烤靠坷苛柯棵磕颗科壳咳可渴克刻客课肯啃垦恳坑吭空恐孔控抠口扣寇枯哭窟苦酷库裤夸垮挎跨胯块筷侩快宽款匡筐狂框矿眶旷况亏盔岿窥葵奎魁傀馈愧溃坤昆捆困括扩廓阔垃拉喇蜡腊辣啦莱来赖蓝婪栏拦篮阑兰澜谰揽览懒缆烂滥琅榔狼廊郎朗浪捞劳牢老佬姥酪烙涝勒乐雷镭蕾磊累儡垒擂肋类泪棱楞冷厘梨犁黎篱狸离漓理李里鲤礼莉荔吏栗丽厉励砾历利傈例俐痢立粒沥隶力璃哩俩联莲连镰廉怜涟帘敛脸链恋炼练粮凉梁粱良两辆量晾亮谅撩聊僚疗燎寥辽潦了撂镣廖料列裂烈劣猎琳林磷霖临邻鳞淋凛赁吝拎玲菱零龄铃伶羚凌灵陵岭领另令溜琉榴硫馏留刘瘤流柳六龙聋咙笼窿隆垄拢陇楼娄搂篓漏陋芦卢颅庐炉掳卤虏鲁麓碌露路赂鹿潞禄录陆戮驴吕铝侣旅履屡缕虑氯律率滤绿峦挛孪滦卵乱掠略抡轮伦仑沦纶论萝螺罗逻锣箩骡裸落洛骆络妈麻玛码蚂马骂嘛吗埋买麦卖迈脉瞒馒蛮满蔓曼慢漫谩芒茫盲氓忙莽猫茅锚毛矛铆卯茂冒帽貌贸么玫枚梅酶霉煤没眉媒镁每美昧寐妹媚门闷们萌蒙檬盟锰猛梦孟眯醚靡糜迷谜弥米秘觅泌蜜密幂棉眠绵冕免勉娩缅面苗描瞄藐秒渺庙妙蔑灭民抿皿敏悯闽明螟鸣铭名命谬摸摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌谋牟某拇牡亩姆母墓暮幕募慕木目睦牧穆拿哪呐钠那娜纳氖乃奶耐奈南男难囊挠脑恼闹淖呢馁内嫩能妮霓倪泥尼拟你匿腻逆溺蔫拈年碾撵捻念娘酿鸟尿捏聂孽啮镊镍涅您柠狞凝宁拧泞牛扭钮纽脓浓农弄奴努怒女暖虐疟挪懦糯诺哦欧鸥殴藕呕偶沤啪趴爬帕怕琶拍排牌徘湃派攀潘盘磐盼畔判叛乓庞旁耪胖抛咆刨炮袍跑泡呸胚培裴赔陪配佩沛喷盆砰抨烹澎彭蓬棚硼篷膨朋鹏捧碰坯砒霹批披劈琵毗啤脾疲皮匹痞僻屁譬篇偏片骗飘漂瓢票撇瞥拼频贫品聘乒坪苹萍平凭瓶评屏坡泼颇婆破魄迫粕剖扑铺仆莆葡菩蒲埔朴圃普浦谱曝瀑期欺栖戚妻七凄漆柒沏其棋奇歧畦崎脐齐旗祈祁骑起岂乞企启契砌器气迄弃汽泣讫掐恰洽牵扦钎铅千迁签仟谦乾黔钱钳前潜遣浅谴堑嵌欠歉枪呛腔羌墙蔷强抢橇锹敲悄桥瞧乔侨巧鞘撬翘峭俏窍切茄且怯窃钦侵亲秦琴勤芹擒禽寝沁青轻氢倾卿清擎晴氰情顷请庆琼穷秋丘邱球求囚酋泅趋区蛆曲躯屈驱渠取娶龋趣去圈颧权醛泉全痊拳犬券劝缺炔瘸却鹊榷确雀裙群然燃冉染瓤壤攘嚷让饶扰绕惹热壬仁人忍韧任认刃妊纫扔仍日戎茸蓉荣融熔溶容绒冗揉柔肉茹蠕儒孺如辱乳汝入褥软阮蕊瑞锐闰润若弱撒洒萨腮鳃塞赛三叁伞散桑嗓丧搔骚扫嫂瑟色涩森僧莎砂杀刹沙纱傻啥煞筛晒珊苫杉山删煽衫闪陕擅赡膳善汕扇缮墒伤商赏晌上尚裳梢捎稍烧芍勺韶少哨邵绍奢赊蛇舌舍赦摄射慑涉社设砷申呻伸身深娠绅神沈审婶甚肾慎渗声生甥牲升绳省盛剩胜圣师失狮施湿诗尸虱十石拾时什食蚀实识史矢使屎驶始式示士世柿事拭誓逝势是嗜噬适仕侍释饰氏市恃室视试收手首守寿授售受瘦兽蔬枢梳殊抒输叔舒淑疏书赎孰熟薯暑曙署蜀黍鼠属术述树束戍竖墅庶数漱恕刷耍摔衰甩帅栓拴霜双爽谁水睡税吮瞬顺舜说硕朔烁斯撕嘶思私司丝死肆寺嗣四伺似饲巳松耸怂颂送宋讼诵搜艘擞嗽苏酥俗素速粟僳塑溯宿诉肃酸蒜算虽隋随绥髓碎岁穗遂隧祟孙损笋蓑梭唆缩琐索锁所塌他它她塔獭挞蹋踏胎苔抬台泰酞太态汰坍摊贪瘫滩坛檀痰潭谭谈坦毯袒碳探叹炭汤塘搪堂棠膛唐糖倘躺淌趟烫掏涛滔绦萄桃逃淘陶讨套特藤腾疼誊梯剔踢锑提题蹄啼体替嚏惕涕剃屉天添填田甜恬舔腆挑条迢眺跳贴铁帖厅听烃汀廷停亭庭挺艇通桐酮瞳同铜彤童桶捅筒统痛偷投头透凸秃突图徒途涂屠土吐兔湍团推颓腿蜕褪退吞屯臀拖托脱鸵陀驮驼椭妥拓唾挖哇蛙洼娃瓦袜歪外豌弯湾玩顽丸烷完碗挽晚皖惋宛婉万腕汪王亡枉网往旺望忘妄威巍微危韦违桅围唯惟为潍维苇萎委伟伪尾纬未蔚味畏胃喂魏位渭谓尉慰卫瘟温蚊文闻纹吻稳紊问嗡翁瓮挝蜗涡窝我斡卧握沃巫呜钨乌污诬屋无芜梧吾吴毋武五捂午舞伍侮坞戊雾晤物勿务悟误昔熙析西硒矽晰嘻吸锡牺稀息希悉膝夕惜熄烯溪汐犀檄袭席习媳喜铣洗系隙戏细瞎虾匣霞辖暇峡侠狭下厦夏吓掀锨先仙鲜纤咸贤衔舷闲涎弦嫌显险现献县腺馅羡宪陷限线相厢镶香箱襄湘乡翔祥详想响享项巷橡像向象萧硝霄削哮嚣销消宵淆晓小孝校肖啸笑效楔些歇蝎鞋协挟携邪斜胁谐写械卸蟹懈泄泻谢屑薪芯锌欣辛新忻心信衅星腥猩惺兴刑型形邢行醒幸杏性姓兄凶胸匈汹雄熊休修羞朽嗅锈秀袖绣墟戌需虚嘘须徐许蓄酗叙旭序畜恤絮婿绪续轩喧宣悬旋玄选癣眩绚靴薛学穴雪血勋熏循旬询寻驯巡殉汛训讯逊迅压押鸦鸭呀丫芽牙蚜崖衙涯雅哑亚讶焉咽阉烟淹盐严研蜒岩延言颜阎炎沿奄掩眼衍演艳堰燕厌砚雁唁彦焰宴谚验殃央鸯秧杨扬佯疡羊洋阳氧仰痒养样漾邀腰妖瑶摇尧遥窑谣姚咬舀药要耀椰噎耶爷野冶也页掖业叶曳腋夜液一壹医揖铱依伊衣颐夷遗移仪胰疑沂宜姨彝椅蚁倚已乙矣以艺抑易邑屹亿役臆逸肄疫亦裔意毅忆义益溢诣议谊译异翼翌绎茵荫因殷音阴姻吟银淫寅饮尹引隐印英樱婴鹰应缨莹萤营荧蝇迎赢盈影颖硬映哟拥佣臃痈庸雍踊蛹咏泳涌永恿勇用幽优悠忧尤由邮铀犹油游酉有友右佑釉诱又幼迂淤于盂榆虞愚舆余俞逾鱼愉渝渔隅予娱雨与屿禹宇语羽玉域芋郁吁遇喻峪御愈欲狱育誉浴寓裕预豫驭鸳渊冤元垣袁原援辕园员圆猿源缘远苑愿怨院曰约越跃钥岳粤月悦阅耘云郧匀陨允运蕴酝晕韵孕匝砸杂栽哉灾宰载再在咱攒暂赞赃脏葬遭糟凿藻枣早澡蚤躁噪造皂灶燥责择则泽贼怎增憎曾赠扎喳渣札轧铡闸眨栅榨咋乍炸诈摘斋宅窄债寨瞻毡詹粘沾盏斩辗崭展蘸栈占战站湛绽樟章彰漳张掌涨杖丈帐账仗胀瘴障招昭找沼赵照罩兆肇召遮折哲蛰辙者锗蔗这浙珍斟真甄砧臻贞针侦枕疹诊震振镇阵蒸挣睁征狰争怔整拯正政帧症郑证芝枝支吱蜘知肢脂汁之织职直植殖执值侄址指止趾只旨纸志挚掷至致置帜峙制智秩稚质炙痔滞治窒中盅忠钟衷终种肿重仲众舟周州洲诌粥轴肘帚咒皱宙昼骤珠株蛛朱猪诸诛逐竹烛煮拄瞩嘱主著柱助蛀贮铸筑住注祝驻抓爪拽专砖转撰赚篆桩庄装妆撞壮状椎锥追赘坠缀谆准捉拙卓桌琢茁酌啄着灼浊兹咨资姿滋淄孜紫仔籽滓子自渍字鬃棕踪宗综总纵邹走奏揍租足卒族祖诅阻组钻纂嘴醉最罪尊遵昨左佐柞做作坐座亍丌兀丐廿卅丕亘丞鬲孬噩丨禺丿匕乇夭爻卮氐囟胤馗毓睾鼗丶亟鼐乜乩亓芈孛啬嘏仄厍厝厣厥厮靥赝匚叵匦匮匾赜卦卣刂刈刎刭刳刿剀剌剞剡剜蒯剽劂劁劐劓冂罔亻仃仉仂仨仡仫仞伛仳伢佤仵伥伧伉伫佞佧攸佚佝佟佗伲伽佶佴侑侉侃侏佾佻侪佼侬侔俦俨俪俅俚俣俜俑俟俸倩偌俳倬倏倮倭俾倜倌倥倨偾偃偕偈偎偬偻傥傧傩傺僖儆僭僬僦僮儇儋仝氽佘佥俎龠汆籴兮巽黉馘冁夔勹匍訇匐凫夙兕亠兖亳衮袤亵脔裒禀嬴蠃羸冫冱冽冼凇冖冢冥讠讦讧讪讴讵讷诂诃诋诏诎诒诓诔诖诘诙诜诟诠诤诨诩诮诰诳诶诹诼诿谀谂谄谇谌谏谑谒谔谕谖谙谛谘谝谟谠谡谥谧谪谫谮谯谲谳谵谶卩卺阝阢阡阱阪阽阼陂陉陔陟陧陬陲陴隈隍隗隰邗邛邝邙邬邡邴邳邶邺邸邰郏郅邾郐郄郇郓郦郢郜郗郛郫郯郾鄄鄢鄞鄣鄱鄯鄹酃酆刍奂劢劬劭劾哿勐勖勰叟燮矍廴凵凼鬯厶弁畚巯坌垩垡塾墼壅壑圩圬圪圳圹圮圯坜圻坂坩垅坫垆坼坻坨坭坶坳垭垤垌垲埏垧垴垓垠埕埘埚埙埒垸埴埯埸埤埝堋堍埽埭堀堞堙塄堠塥塬墁墉墚墀馨鼙懿艹艽艿芏芊芨芄芎芑芗芙芫芸芾芰苈苊苣芘芷芮苋苌苁芩芴芡芪芟苄苎芤苡茉苷苤茏茇苜苴苒苘茌苻苓茑茚茆茔茕苠苕茜荑荛荜茈莒茼茴茱莛荞茯荏荇荃荟荀茗荠茭茺茳荦荥荨茛荩荬荪荭荮莰荸莳莴莠莪莓莜莅荼莶莩荽莸荻莘莞莨莺莼菁萁菥菘堇萘萋菝菽菖萜萸萑萆菔菟萏萃菸菹菪菅菀萦菰菡葜葑葚葙葳蒇蒈葺蒉葸萼葆葩葶蒌蒎萱葭蓁蓍蓐蓦蒽蓓蓊蒿蒺蓠蒡蒹蒴蒗蓥蓣蔌甍蔸蓰蔹蔟蔺蕖蔻蓿蓼蕙蕈蕨蕤蕞蕺瞢蕃蕲蕻薤薨薇薏蕹薮薜薅薹薷薰藓藁藜藿蘧蘅蘩蘖蘼廾弈夼奁耷奕奚奘匏尢尥尬尴扌扪抟抻拊拚拗拮挢拶挹捋捃掭揶捱捺掎掴捭掬掊捩掮掼揲揸揠揿揄揞揎摒揆掾摅摁搋搛搠搌搦搡摞撄摭撖摺撷撸撙撺擀擐擗擤擢攉攥攮弋忒甙弑卟叱叽叩叨叻吒吖吆呋呒呓呔呖呃吡呗呙吣吲咂咔呷呱呤咚咛咄呶呦咝哐咭哂咴哒咧咦哓哔呲咣哕咻咿哌哙哚哜咩咪咤哝哏哞唛哧唠哽唔哳唢唣唏唑唧唪啧喏喵啉啭啁啕唿啐唼唷啖啵啶啷唳唰啜喋嗒喃喱喹喈喁喟啾嗖喑啻嗟喽喾喔喙嗪嗷嗉嘟嗑嗫嗬嗔嗦嗝嗄嗯嗥嗲嗳嗌嗍嗨嗵嗤辔嘞嘈嘌嘁嘤嘣嗾嘀嘧嘭噘嘹噗嘬噍噢噙噜噌噔嚆噤噱噫噻噼嚅嚓嚯囔囗囝囡囵囫囹囿圄圊圉圜帏帙帔帑帱帻帼帷幄幔幛幞幡岌屺岍岐岖岈岘岙岑岚岜岵岢岽岬岫岱岣峁岷峄峒峤峋峥崂崃崧崦崮崤崞崆崛嵘崾崴崽嵬嵛嵯嵝嵫嵋嵊嵩嵴嶂嶙嶝豳嶷巅彳彷徂徇徉後徕徙徜徨徭徵徼衢彡犭犰犴犷犸狃狁狎狍狒狨狯狩狲狴狷猁狳猃狺狻猗猓猡猊猞猝猕猢猹猥猬猸猱獐獍獗獠獬獯獾舛夥飧夤夂饣饧饨饩饪饫饬饴饷饽馀馄馇馊馍馐馑馓馔馕庀庑庋庖庥庠庹庵庾庳赓廒廑廛廨廪膺忄忉忖忏怃忮怄忡忤忾怅怆忪忭忸怙怵怦怛怏怍怩怫怊怿怡恸恹恻恺恂恪恽悖悚悭悝悃悒悌悛惬悻悱惝惘惆惚悴愠愦愕愣惴愀愎愫慊慵憬憔憧憷懔懵忝隳闩闫闱闳闵闶闼闾阃阄阆阈阊阋阌阍阏阒阕阖阗阙阚丬爿戕氵汔汜汊沣沅沐沔沌汨汩汴汶沆沩泐泔沭泷泸泱泗沲泠泖泺泫泮沱泓泯泾洹洧洌浃浈洇洄洙洎洫浍洮洵洚浏浒浔洳涑浯涞涠浞涓涔浜浠浼浣渚淇淅淞渎涿淠渑淦淝淙渖涫渌涮渫湮湎湫溲湟溆湓湔渲渥湄滟溱溘滠漭滢溥溧溽溻溷滗溴滏溏滂溟潢潆潇漤漕滹漯漶潋潴漪漉漩澉澍澌潸潲潼潺濑濉澧澹澶濂濡濮濞濠濯瀚瀣瀛瀹瀵灏灞宀宄宕宓宥宸甯骞搴寤寮褰寰蹇謇辶迓迕迥迮迤迩迦迳迨逅逄逋逦逑逍逖逡逵逶逭逯遄遑遒遐遨遘遢遛暹遴遽邂邈邃邋彐彗彖彘尻咫屐屙孱屣屦羼弪弩弭艴弼鬻屮妁妃妍妩妪妣妗姊妫妞妤姒妲妯姗妾娅娆姝娈姣姘姹娌娉娲娴娑娣娓婀婧婊婕娼婢婵胬媪媛婷婺媾嫫媲嫒嫔媸嫠嫣嫱嫖嫦嫘嫜嬉嬗嬖嬲嬷孀尕尜孚孥孳孑孓孢驵驷驸驺驿驽骀骁骅骈骊骐骒骓骖骘骛骜骝骟骠骢骣骥骧纟纡纣纥纨纩纭纰纾绀绁绂绉绋绌绐绔绗绛绠绡绨绫绮绯绱绲缍绶绺绻绾缁缂缃缇缈缋缌缏缑缒缗缙缜缛缟缡缢缣缤缥缦缧缪缫缬缭缯缰缱缲缳缵幺畿巛甾邕玎玑玮玢玟珏珂珑玷玳珀珉珈珥珙顼琊珩珧珞玺珲琏琪瑛琦琥琨琰琮琬琛琚瑁瑜瑗瑕瑙瑷瑭瑾璜璎璀璁璇璋璞璨璩璐璧瓒璺韪韫韬杌杓杞杈杩枥枇杪杳枘枧杵枨枞枭枋杷杼柰栉柘栊柩枰栌柙枵柚枳柝栀柃枸柢栎柁柽栲栳桠桡桎桢桄桤梃栝桕桦桁桧桀栾桊桉栩梵梏桴桷梓桫棂楮棼椟椠棹椤棰椋椁楗棣椐楱椹楠楂楝榄楫榀榘楸椴槌榇榈槎榉楦楣楹榛榧榻榫榭槔榱槁槊槟榕槠榍槿樯槭樗樘橥槲橄樾檠橐橛樵檎橹樽樨橘橼檑檐檩檗檫猷獒殁殂殇殄殒殓殍殚殛殡殪轫轭轱轲轳轵轶轸轷轹轺轼轾辁辂辄辇辋辍辎辏辘辚軎戋戗戛戟戢戡戥戤戬臧瓯瓴瓿甏甑甓攴旮旯旰昊昙杲昃昕昀炅曷昝昴昱昶昵耆晟晔晁晏晖晡晗晷暄暌暧暝暾曛曜曦曩贲贳贶贻贽赀赅赆赈赉赇赍赕赙觇觊觋觌觎觏觐觑牮犟牝牦牯牾牿犄犋犍犏犒挈挲掰搿擘耄毪毳毽毵毹氅氇氆氍氕氘氙氚氡氩氤氪氲攵敕敫牍牒牖爰虢刖肟肜肓肼朊肽肱肫肭肴肷胧胨胩胪胛胂胄胙胍胗朐胝胫胱胴胭脍脎胲胼朕脒豚脶脞脬脘脲腈腌腓腴腙腚腱腠腩腼腽腭腧塍媵膈膂膑滕膣膪臌朦臊膻臁膦欤欷欹歃歆歙飑飒飓飕飙飚殳彀毂觳斐齑斓於旆旄旃旌旎旒旖炀炜炖炝炻烀炷炫炱烨烊焐焓焖焯焱煳煜煨煅煲煊煸煺熘熳熵熨熠燠燔燧燹爝爨灬焘煦熹戾戽扃扈扉礻祀祆祉祛祜祓祚祢祗祠祯祧祺禅禊禚禧禳忑忐怼恝恚恧恁恙恣悫愆愍慝憩憝懋懑戆肀聿沓泶淼矶矸砀砉砗砘砑斫砭砜砝砹砺砻砟砼砥砬砣砩硎硭硖硗砦硐硇硌硪碛碓碚碇碜碡碣碲碹碥磔磙磉磬磲礅磴礓礤礞礴龛黹黻黼盱眄眍盹眇眈眚眢眙眭眦眵眸睐睑睇睃睚睨睢睥睿瞍睽瞀瞌瞑瞟瞠瞰瞵瞽町畀畎畋畈畛畲畹疃罘罡罟詈罨罴罱罹羁罾盍盥蠲钅钆钇钋钊钌钍钏钐钔钗钕钚钛钜钣钤钫钪钭钬钯钰钲钴钶钷钸钹钺钼钽钿铄铈铉铊铋铌铍铎铐铑铒铕铖铗铙铘铛铞铟铠铢铤铥铧铨铪铩铫铮铯铳铴铵铷铹铼铽铿锃锂锆锇锉锊锍锎锏锒锓锔锕锖锘锛锝锞锟锢锪锫锩锬锱锲锴锶锷锸锼锾锿镂锵镄镅镆镉镌镎镏镒镓镔镖镗镘镙镛镞镟镝镡镢镤镥镦镧镨镩镪镫镬镯镱镲镳锺矧矬雉秕秭秣秫稆嵇稃稂稞稔稹稷穑黏馥穰皈皎皓皙皤瓞瓠甬鸠鸢鸨鸩鸪鸫鸬鸲鸱鸶鸸鸷鸹鸺鸾鹁鹂鹄鹆鹇鹈鹉鹋鹌鹎鹑鹕鹗鹚鹛鹜鹞鹣鹦鹧鹨鹩鹪鹫鹬鹱鹭鹳疒疔疖疠疝疬疣疳疴疸痄疱疰痃痂痖痍痣痨痦痤痫痧瘃痱痼痿瘐瘀瘅瘌瘗瘊瘥瘘瘕瘙瘛瘼瘢瘠癀瘭瘰瘿瘵癃瘾瘳癍癞癔癜癖癫癯翊竦穸穹窀窆窈窕窦窠窬窨窭窳衤衩衲衽衿袂袢裆袷袼裉裢裎裣裥裱褚裼裨裾裰褡褙褓褛褊褴褫褶襁襦襻疋胥皲皴矜耒耔耖耜耠耢耥耦耧耩耨耱耋耵聃聆聍聒聩聱覃顸颀颃颉颌颍颏颔颚颛颞颟颡颢颥颦虍虔虬虮虿虺虼虻蚨蚍蚋蚬蚝蚧蚣蚪蚓蚩蚶蛄蚵蛎蚰蚺蚱蚯蛉蛏蚴蛩蛱蛲蛭蛳蛐蜓蛞蛴蛟蛘蛑蜃蜇蛸蜈蜊蜍蜉蜣蜻蜞蜥蜮蜚蜾蝈蜴蜱蜩蜷蜿螂蜢蝽蝾蝻蝠蝰蝌蝮螋蝓蝣蝼蝤蝙蝥螓螯螨蟒蟆螈螅螭螗螃螫蟥螬螵螳蟋蟓螽蟑蟀蟊蟛蟪蟠蟮蠖蠓蟾蠊蠛蠡蠹蠼缶罂罄罅舐竺竽笈笃笄笕笊笫笏筇笸笪笙笮笱笠笥笤笳笾笞筘筚筅筵筌筝筠筮筻筢筲筱箐箦箧箸箬箝箨箅箪箜箢箫箴篑篁篌篝篚篥篦篪簌篾篼簏簖簋簟簪簦簸籁籀臾舁舂舄臬衄舡舢舣舭舯舨舫舸舻舳舴舾艄艉艋艏艚艟艨衾袅袈裘裟襞羝羟羧羯羰羲籼敉粑粝粜粞粢粲粼粽糁糇糌糍糈糅糗糨艮暨羿翎翕翥翡翦翩翮翳糸絷綦綮繇纛麸麴赳趄趔趑趱赧赭豇豉酊酐酎酏酤酢酡酰酩酯酽酾酲酴酹醌醅醐醍醑醢醣醪醭醮醯醵醴醺豕鹾趸跫踅蹙蹩趵趿趼趺跄跖跗跚跞跎跏跛跆跬跷跸跣跹跻跤踉跽踔踝踟踬踮踣踯踺蹀踹踵踽踱蹉蹁蹂蹑蹒蹊蹰蹶蹼蹯蹴躅躏躔躐躜躞豸貂貊貅貘貔斛觖觞觚觜觥觫觯訾謦靓雩雳雯霆霁霈霏霎霪霭霰霾龀龃龅龆龇龈龉龊龌黾鼋鼍隹隼隽雎雒瞿雠銎銮鋈錾鍪鏊鎏鐾鑫鱿鲂鲅鲆鲇鲈稣鲋鲎鲐鲑鲒鲔鲕鲚鲛鲞鲟鲠鲡鲢鲣鲥鲦鲧鲨鲩鲫鲭鲮鲰鲱鲲鲳鲴鲵鲶鲷鲺鲻鲼鲽鳄鳅鳆鳇鳊鳋鳌鳍鳎鳏鳐鳓鳔鳕鳗鳘鳙鳜鳝鳟鳢靼鞅鞑鞒鞔鞯鞫鞣鞲鞴骱骰骷鹘骶骺骼髁髀髅髂髋髌髑魅魃魇魉魈魍魑飨餍餮饕饔髟髡髦髯髫髻髭髹鬈鬏鬓鬟鬣麽麾縻麂麇麈麋麒鏖麝麟黛黜黝黠黟黢黩黧黥黪黯鼢鼬鼯鼹鼷鼽鼾齄";
script>
head>
<body onload="init()">
<canvas id="c">canvas><br>
<p>Name:<input value="Fang" size="36" />p>
<p>Code:<input size="36" readonly="true" />p>
<p>
<input type="radio" name="codetype" checked="checked" />Site License<br>
<input type="radio" name="codetype" />Register Code N<br>
<input type="radio" name="codetype" />Register Code A
p>
<p><button onclick="Generate()">Generatebutton><button onclick="window.close();">Closebutton>p>
<p>
<span class="bg">"HKRWQV2958DWNTQRGNSCFSXAZPYK"span><br>
<span class="bg">[Provided by Fang3s]span>
p>
<table>
<tr><td>Input Here:td><td><input name="testCode" onchange="codeChange()" value="苏北小麦" size="36" />td>tr>
<tr><td>charCodeAt:td><td><input name="testCode" value="" size="36" />td>tr>
<tr><td>encodeURI:td><td><input name="testCode" value="" size="36" />td>tr>
<tr><td>GB2312:td><td><input name="testCode" value="" size="36" />td>tr>
table>
body>
html>
-
C++
const char *psBlackCodes[] = { "mvg21951736", "mg374604342", "mg370534035", "mg373465241", "mg37NTi", "mg372503958", "mg379843149", "mg370151347", "mg370353008", "mg372021424", "mg375953248", "mg379223953", "mg373473759", "mg378542544", "mg370473710", "mg37064348", "mg378822469", "mg374394987", "mg371073478", "mg379773651", "mg371895266", "mg373223554", "mg377583454", "mg37644957", "mg370342692", "mg376484039", "mg376871434", "mg370704788", "mg377643863", "mg377753931", "mg379342689", "mg374344777" }; const char* pszRandomCharTable = "0123456789abcdefghijklmnopqrstuvwxyz"; const int lengthOfCharTable = lstrlenA(pszRandomCharTable); const char *pResourceTable = "HKRWQV2958DWNTQRGNSCFSXAZPYK"; inline char randomChar(void){ return pszRandomCharTable[rand() % (lengthOfCharTable + 1 - 0) + 0]; } bool keygen(const char *pszchName, int keygenType, char *pchCodeBuffer, size_t sizeOfBuffer) { if (NULL == pszchName || !*pszchName) { return false; } if (0 == keygenType) { if (sizeOfBuffer >= 28) { char buffer[1024], *pNameCursor, *pOkNameCursor, *pchCodeCursor; int length, indexOfTable, ebp, idx; const int lengthOfTable = lstrlenA(pResourceTable); pNameCursor = buffer; pOkNameCursor = buffer; lstrcpynA(buffer, pszchName, _countof(buffer)); CharUpperA(buffer); //在资源表pResourceTable中的名字才合法 while (*pNameCursor) { if (strchr(pResourceTable, *pNameCursor)) { *pOkNameCursor++ = *pNameCursor; } pNameCursor++; } *pOkNameCursor = '\0'; length = lstrlenA(buffer); //名字不足24位补齐 if (length < 24){ lstrcpynA(buffer, pResourceTable, 25 - length);//'\0'算在第三个参数长度 } //buffer全是pResourceTable里的字符, 长度为24 ebp = 0; idx = 0; pchCodeCursor = pchCodeBuffer; while (idx < 24) { indexOfTable = strchr(pResourceTable, buffer[idx]) - pResourceTable; ebp = (indexOfTable * (indexOfTable + 1) + ebp) % lengthOfTable; *pchCodeCursor++ = pResourceTable[ebp++]; if (!(++idx % 6) && idx < 24) *pchCodeCursor++ = '-'; } *pchCodeCursor = '\0'; } else return false; } else{ // if (sizeOfBuffer >= 4 + 1 + 3 + 10){ char *pchCodeAppend, *pNameCursor, buffer[1024]; int esi = 3039, ecx = 0; srand((unsigned int)time(0)); pchCodeBuffer[0] = 'm'; pchCodeBuffer[1] = 'g'; pchCodeBuffer[2] = '3'; pchCodeBuffer[3] = '7'; pchCodeBuffer[5] = randomChar(); pchCodeBuffer[6] = randomChar(); if (keygenType == 1){ pchCodeBuffer[4] = 's'; pchCodeBuffer[7] = randomChar(); pchCodeAppend = pchCodeBuffer+8; } else{ pchCodeBuffer[4] = randomChar(); pchCodeAppend = pchCodeBuffer + 7; } pNameCursor = const_cast<char *>(pszchName); while (*pNameCursor) { ++ecx; esi += ecx * *pNameCursor++; if (esi > 6078) esi -= 6078; if (ecx > 10) ecx = 0; } _itoa_s(esi, buffer, 10); lstrcpynA(pchCodeAppend, buffer, sizeOfBuffer - (pchCodeBuffer - pchCodeAppend)); } else{ return false; } } return true; } int _tmain(int argc, _TCHAR* argv[]) { char name[1024], code[1024] = {0}; while (true){ printf("Input Name :\t"); lstrcpynA(name, "苏北小麦", _countof(name)); scanf_s("%s", name); printf("%s\n", name); keygen(name, 0, code, _countof(code)); printf("Site License :\t\t%s\n", code); keygen(name, 1, code, _countof(code)); printf("Register Code N :\t%s\n", code); keygen(name, 2, code, _countof(code)); printf("Register Code A :\t%s\n", code); } //getchar(); return 0; }
如果dump代码,怎么搞都没搞成,不用ebp的。。
//see http://msdn.microsoft.com/zh-cn/library/chh3fb0k(v=vs.80).aspx http://msdn.microsoft.com/zh-cn/library/2kxx5t2c(VS.80).aspx //#pragma optimize( "y", off ) // 对下面的代码使用 /Oy 优化 Generate frame pointers on the program stack. int keygen_dump(const char *arg_0, const char *arg_4){ //框架指针寄存器"ebp"被内联程序集代码修改 _asm{ mov ebp, arg_4 //就乱了。。。。 cmp byte ptr[ebp + 0], 6Dh jnz loc_4341EF cmp byte ptr[ebp + 1], 67h jnz loc_4341EF cmp byte ptr[ebp + 2], 33h jnz loc_4341EF cmp byte ptr[ebp + 3], 37h jnz loc_4341EF xor ebx, ebx loc_434162 : mov edi, psBlackCodes mov eax, edi lea edx, [eax + 1] lea ecx, [ecx + 0] loc_434170 : mov cl, [eax] inc eax test cl, cl jnz short loc_434170 sub eax, edx mov ecx, eax mov esi, ebp xor eax, eax repe cmpsb jz short loc_4341E8 add ebx, 4 cmp ebx, 80h jb short loc_434162 cmp byte ptr[ebp + 4], 73h jnz short loc_434195 inc ebp loc_434195 : lea ecx, [ebp + 7] push ecx push ecx call codekeygen //---------------------------------- pop ecx pop ecx push ecx call atol mov ebx, arg_0 mov dl, [ebx] add esp, 4 xor ecx, ecx test dl, dl mov edi, ebx mov esi, 0BDFh jz short loc_4341DA loc_4341B4 : movsx edx, dl inc ecx imul edx, ecx add esi, edx cmp esi, 17BEh jle short loc_4341CB sub esi, 17BEh loc_4341CB: cmp ecx, 0Ah jle short loc_4341D2 xor ecx, ecx loc_4341D2 : mov dl, [edi + 1] inc edi test dl, dl jnz short loc_4341B4 loc_4341DA : push esi cmp esi, eax jnz short loc_4341F3 pop ebp mov eax, 1 pop ebx retn//移除pop esi和pop ebp loc_4341E8 : pop edi xor eax, eax pop ebx retn //移除pop esi和pop ebp loc_4341EF : mov ebx, arg_0 loc_4341F3 : push ebp push ebx call codekeygen //移除两参数 pop ebp pop ebx retn//移除pop esi和pop ebp } } //#pragma optimize("", on) // 恢复到编译器 /O 选项指定的优化
-
汇编(跃然纸上)
注册时让注册码跃然纸上,这招貌似叫内嵌补丁。
个人觉得算是个费时的活儿,又写汇编,又要了解PE等,知识点散。而且只适用于程序把注册码计算出来和输入的Code直接比较,即Code == Func(Name)???型。避免了写注册机算法等等,如果很复杂这很适合,当然也可以远程调用。
为了便于好看,有大量截图,也是用心写的证明,就想发点有价值的东西,不然不好。
-
第一处改写。
主要获取Code窗口句柄HWND和保存,如果是局部变量就好了,但是我没看看它是不是,直接保存到代码区的。
修改前两处
修改前后
-
目标代码。
来到我们预定的空隙处,这里也是准备些代码的地方,这里call api暂时是拷贝的,后面修改。
设置访问方式
修改访问后,再执行此条指令,如下图我们看到地址0x0047EA94值变了,共4字节。注意这里是临时修改,要实际修改,还要保存。君子善假于物也。使用论坛工具LordPE。
继续执行到原来PUSH EAX后的指令CALL EBX时,即此处的寄存器状态和之前未修改的图是一致的。这里要说下,原来未修改的截图还未执行PUSH EAX,所以原ESP比这里的大4,截得不好。
-
第二处改写
来到注册码已经出来的地方,然后我们想在界面Code编辑框里打印显示出来。
说明下,由于ESP寻找局部变量,所以只要找到ESP+84(十六进制)处看看就可,右下角堆栈窗口就可以看;或者直接点击代码行右键-数据窗口中跟随-内存地址,即可左小角查看。
这条指令大于5字节,直接线程替换为我们的跳转JMP 0047EA9E,剩余的90填充然后F7或F8跟随进去。
当我们获取原来LEA ESI, [LOCAL.24]里的[LOCAL.24]=[ESP + 84]时,堆栈和原来不一样的差了8.*4 = 32. = 20h,从右下角的图也可以看出,当时记录的ESP和此时ESP相差$-20。所以取值时多加了这个差值。
我们走一步,通过赋值给ESI看下这时的值,OllyDbg会提示的。
再看看第一个入参,[Alt+W]打开当前可预见的窗口。
-
这里call API有一定讲究。
导入API
首先看它导入了没有,OK。
OllyDbg的查找所有模块中的名称(Ctrl+N)
call地址计算
目标进程右键-载入PE编辑器-目录-输入表一行左边省略号按钮上面ListView点选USER32.dll-下面输入SetWindowTextA搜索自动定位。
注意未勾选总是查看FisrtThunk时值时,ThunkRVA按照函数列表计算的值是不一样的。
未勾选时,第一个函数SystemParametersInfoA的ThunkRVA是0008BCC8和USER32.dll的OrigianlFirstThunk一样的,以后相差+4。
勾选后,地址为0007F30C,记下它,后面会眼熟的。
我们来拿个现成例子看看地址间关系。
回到OllyDbg,在程序模块movgear.exe,右键查找-所有模块间调用
搜索System看到
点击进入
我们看看SystemParametersInfoA的调用方式不是CALL xx,而是CALL DWORD PTR DS:[xx],即call机器码不一样。
再看看地址关系,可以看出CALL DWORD PTR DS:[xx]的xx是0047F30C,后4位是不是很眼熟。是的,和前面看到的ThunkRVA = 0047F30C,是一致的,只是多了个400000,其实40万(十六进制)就是我们在前面一起看到的,基本PE头信息里的镜像基址(BaseImage)400000。
接下来看我们的SetWindowTextA,以此类推,调用写法,400000 + 0007F448 = 0047F448 ,48F44700,CALL DWORD PTR DS:[ 0047F448],OllyDbg自动解析为对应符号。
-
修改的代码
CPU Disasm 地址 十六进制数据 指令 注释 00434531 /E9 68A50400 JMP 0047EA9E CPU Disasm 地址 十六进制数据 指令 注释 00433F60 /E9 39AB0400 JMP 0047EA9E CPU Disasm 地址 十六进制数据 指令 注释 0047EA97 00 DB 00 ; 原来.text区是不可写,这也证明了足够 0047EA98 00 DB 00 ; 安全性,而且原是0映射后还是0, 0047EA99 00 DB 00 ; 不用搞检测看这段是否可能被修改。 0047EA9A 00 DB 00 ; 一般程序也不会调用API来改吧,又没壳。 0047EA9B 00 DB 00 0047EA9C 00 DB 00 0047EA9D 00 DB 00 0047EA9E /> 60 PUSHAD ; /Arg1_4, >>保存8大寄存器状态,也可仅push使用的 0047EA9F |. E8 00000000 CALL 0047EAA4 ; \movgear.0047EAA4, 随意搞吧,不管你怎么使用寄存器,只要栈操作平衡。 0047EAA4 |$ 59 POP ECX ; 获取EIP,即ECX = EIP = 0047EAA4 0047EAA5 |. 8B51 F0 MOV EDX,DWORD PTR DS:[ECX-10] ; 这里把.text区地址0047EA94上DWORD大小给了EDX 0047EAA8 |. 85D2 TEST EDX,EDX 0047EAAA |. 75 12 JNZ SHORT 0047EABE 0047EAAC |. 8941 F0 MOV DWORD PTR DS:[ECX-10],EAX 0047EAAF |. 61 POPAD ; <<恢复8大寄存器状态 0047EAB0 |. FFD3 CALL EBX ; >>恢复原指令的调用流程 0047EAB2 |. 8D8CE4 C40000 LEA ECX,[LOCAL.24] ; <<恢复原指令的调用流程 0047EAB9 |.^ E9 7C5AFBFF JMP 0043453A ; 回去并执行接下来的指令 0047EABE |> C741 F0 00000 MOV DWORD PTR DS:[ECX-10],0 0047EAC5 |. 8DB4E4 A40000 LEA ESI,[LOCAL.24] ; 这里使用ESP的局部变量要注意。 0047EACC |. 56 PUSH ESI ; /Text 0047EACD |. 52 PUSH EDX ; |hWnd 0047EACE |. FF15 48F44700 CALL DWORD PTR DS:[<&USER32.SetWindowTex ; \USER32.SetWindowTextA, call xx 需要计算xx = ImageBase + ThunkRVAOfAPI 0047EAD4 |. 61 POPAD ; <<恢复8大寄存器状态 0047EAD5 |. 8DB4E4 840000 LEA ESI,[LOCAL.24] ; >><<恢复原指令的调用流程 0047EADC \.^ E9 8654FBFF JMP 00433F67 ; 回去并执行接下来的指令 0047EAE1 E8 6B25EB74 CALL SetWindowTextA ;直接修改为CALL SetWindowTextA,错,仅临时偏移对
-
最后看下效果图:
在弹窗前注册码已经写入了Code编辑框内了。。。
-
总结
LoadPE使用,熟练OllyDbg,Call API
-
附件
CPU Disasm
地址 十六进制数据 指令 注释
00434531 /E9 68A50400 JMP0047EA9E
CPU Disasm
地址 十六进制数据 指令 注释
00433F60 /E9 39AB0400 JMP0047EA9E
CPU Disasm
地址 十六进制数据 指令 注释
0047EA97 00 DB 00 ; 原来.text区是不可写,这也证明了足够
0047EA98 00 DB 00 ; 安全性,而且原是0映射后还是0,
0047EA99 00 DB 00 ; 不用搞检测看这段是否可能被修改。
0047EA9A 00 DB 00 ; 一般程序也不会调用API来改吧,又没壳。
0047EA9B 00 DB 00
0047EA9C 00 DB 00
0047EA9D 00 DB 00
0047EA9E /> 60 PUSHAD ; /Arg1_4, >>保存8大寄存器状态,也可仅push使用的
0047EA9F |. E8 00000000 CALL0047EAA4 ; \movgear.0047EAA4, 随意搞吧,不管你怎么使用寄存器,只要栈操作平衡。
0047EAA4 |$ 59 POP ECX ; 获取EIP,即ECX = EIP = 0047EAA4
0047EAA5 |. 8B51 F0 MOV EDX,DWORD PTR DS:[ECX-10] ; 这里把.text区地址0047EA94上DWORD大小给了EDX
0047EAA8 |. 85D2 TEST EDX,EDX
0047EAAA |. 7512 JNZ SHORT 0047EABE
0047EAAC |. 8941 F0 MOV DWORD PTR DS:[ECX-10],EAX
0047EAAF |. 61 POPAD ; <<恢复8大寄存器状态
0047EAB0 |. FFD3 CALL EBX ; >>恢复原指令的调用流程
0047EAB2 |. 8D8CE4 C40000 LEA ECX,[LOCAL.24] ; <<恢复原指令的调用流程
0047EAB9 |.^ E9 7C5AFBFF JMP0043453A ; 回去并执行接下来的指令
0047EABE |> C741 F0 00000MOV DWORD PTR DS:[ECX-10],0
0047EAC5 |. 8DB4E4 A40000 LEA ESI,[LOCAL.24] ; 这里使用ESP的局部变量要注意。
0047EACC |. 56 PUSH ESI ; /Text
0047EACD |. 52 PUSH EDX ; |hWnd
0047EACE |. FF15 48F44700 CALL DWORD PTR DS:[<&USER32.SetWindowTex ; \USER32.SetWindowTextA, call xx 需要计算xx = ImageBase + ThunkRVAOfAPI
0047EAD4 |. 61 POPAD ; <<恢复8大寄存器状态
0047EAD5 |. 8DB4E4 840000LEA ESI,[LOCAL.24] ; >><<恢复原指令的调用流程
0047EADC \.^ E9 8654FBFF JMP00433F67 ; 回去并执行接下来的指令
0047EAE1 E8 6B25EB74 CALL SetWindowTextA ;直接修改为CALL SetWindowTextA,错,仅临时偏移对
-
教训特别修改(已测)
没有测试打开验证,由于只走验证,代码区本来想保存HWND一直为0,走了保存窗口句柄的,导致CALL失败。需要拆分为两个独立的过程比较好,如下,修改第二个验证跳转和内嵌代码。丑大了,没有思考过只走验证和没有再次打开测试。。。
地址 十六进制数据 指令 注释 00433F60 E9 59AB0400 JMP 0047EABE
CPU Disasm 地址 十六进制数据 指令 注释 0047EA9E \60 PUSHAD 0047EA9F E8 00000000 CALL 0047EAA4 0047EAA4 59 POP ECX ; movgear_crack.0047EAA4(推测 Arg1,Arg2,Arg3,Arg4) 0047EAA5 8B51 F0 MOV EDX,DWORD PTR DS:[ECX-10] 0047EAA8 85D2 TEST EDX,EDX 0047EAAA 75 03 JNZ SHORT 0047EAAF 0047EAAC 8941 F0 MOV DWORD PTR DS:[ECX-10],EAX 0047EAAF 61 POPAD 0047EAB0 FFD3 CALL EBX 0047EAB2 8D8CE4 C40000 LEA ECX,[ESP+0C4] 0047EAB9 ^ E9 7C5AFBFF JMP 0043453A 0047EABE \60 PUSHAD 0047EABF E8 00000000 CALL 0047EAC4 0047EAC4 59 POP ECX 0047EAC5 8B51 F0 MOV EDX,DWORD PTR DS:[ECX-10] 0047EAC8 85D2 TEST EDX,EDX 0047EACA 74 16 JE SHORT 0047EAE2 0047EACC C741 C8 00000 MOV DWORD PTR DS:[ECX-38],0 0047EAD3 8DB4E4 A40000 LEA ESI,[ESP+0A4] 0047EADA 56 PUSH ESI 0047EADB 52 PUSH EDX 0047EADC FF15 48F44700 CALL DWORD PTR DS:[<&USER32.SetWindowTex 0047EAE2 61 POPAD 0047EAE3 8DB4E4 840000 LEA ESI,[ESP+84] 0047EAEA ^ E9 7854FBFF JMP 00433F67 0047EAEF E8 5D25EB74 CALL SetWindowTextA
插件编写比较方便
<0047EA9E> @L00000001: PUSHAD CALL @L00000002 @L00000002: POP ECX MOV EDX,DWORD PTR DS:[ECX-10] TEST EDX,EDX JNE SHORT @L00000003 MOV DWORD PTR DS:[ECX-10],EAX @L00000003: POPAD CALL EBX LEA ECX,[ESP+0C4] JMP 0043453A PUSHAD CALL @L00000004 @L00000004: POP ECX MOV EDX,DWORD PTR DS:[ECX-10] TEST EDX,EDX JE SHORT @L00000005 MOV DWORD PTR DS:[ECX-38],0 LEA ESI,[ESP+0A4] PUSH ESI PUSH EDX CALL DWORD PTR DS:[47F448] @L00000005: POPAD LEA ESI,[ESP+84] JMP 00433F67 CALL 75331051