亿图是一个不错的流程图软件,下面是软件帮助文档中对作者的介绍,原来跟俺是同级的邻居啊,hehe
我们是西安电子科技大学2005界硕士毕业生。我们拥有共同的爱好,那就是程序设计;我们来自同一个宿舍,那就是西安电子科技大学53#224;现在我们即将毕业,但是我们拥有共同的作品,那就是亿图,希望它可以给你们的生活和工作带来方便。
软件的确很不错,跟m$的visio(是这么写的吧?俺只用过一次,感觉奇慢无比,占用空间也很大)有的一拼。建议大家好好支持一下该软件,目前是1.5版,pj时用的是1.4版。
直接采用ollydbg 装入调试,调试过程见后面详细说明。最终仅改动了CGDI.dll 里一个字节就搞定了。
软件的保护方式为 输入序列号―>运算结果->与机器码对比(要做一个kengen是比较麻烦的);不注册版本存在使用次数限制,另存为文件格式功能受限制。程序里采用了多种加密方法,由于本人功力太浅没有做深入研究。
1.5版增加了启动时文件完整性校验功能,如果发现文件被修改则退出程序,不过加密方法还是同1.4的。因此,可以采用1.4版进行注册,保证1.5照常使用。如果仅有1.5的话,可以自己编个调用dll的程序,调用CGDI.dll里修改后的RegeditSoft函数进行注册。
很奇怪的是,注册后1.5竟然没有对序列号和机器码进行重新校验,好像是直接运算下列三个变量的函数关系(具体运算过程没有研究过),这也算是程序保护措施的一个BUG吧。由此可见如果要做注册机的话,可以从这里入手。
[HKEY_LOCAL_MACHINE\SOFTWARE\EDRAW\Shared\CrypKey]
"Name"="2128319170" (机器码)
"Serial"="2128319170" (输入的序列号,全数字)
"Password"="5555-2B09-92F0"(程序计算结果)
004CD16C . E8 F9B70600 call <jmp.&MFC42.#6282_CString::TrimLeft>
004CD171 . 8BCF mov ecx,edi
004CD173 . E8 ECB70600 call <jmp.&MFC42.#6283_CString::TrimRight>
004CD178 . 51 push ecx
004CD179 . 8BCC mov ecx,esp
004CD17B . 896424 10 mov dword ptr ss:[esp+10],esp
004CD17F . 57 push edi
004CD180 . E8 DBB50600 call <jmp.&MFC42.#535_CString::CString>
004CD185 . B9 788D5700 mov ecx,亿图.00578D78
004CD18A . C74424 6C FFFFFFFF mov dword ptr ss:[esp+6C],-1
004CD192 . E8 9058F3FF call 亿图.00402A27
004CD197 . 8BC8 mov ecx,eax
004CD199 . E8 98E40600 call <jmp.&CGdi.CCrypter::RegeditSoft> <------进行注册校验,跟入
004CD19E . 85C0 test eax,eax <--是否注册成功
004CD1A0 . 0F84 B1010000 je 亿图.004CD357 <-----返回为0 表示注册失败
004CD1A6 . 8D4C24 18 lea ecx,dword ptr ss:[esp+18]
004CD1AA . E8 726DF3FF call 亿图.00403F21
004CD1AF . 8B0D 448E5700 mov ecx,dword ptr ds:[578E44]
004CD1B5 . 8D5424 10 lea edx,dword ptr ss:[esp+10]
004CD1B9 . 52 push edx
004CD1BA . C74424 6C 03000000 mov dword ptr ss:[esp+6C],3
004CD1C2 . E8 F671F3FF call 亿图.004043BD
004CD357 > 8D4C24 10 lea ecx,dword ptr ss:[esp+10] <---注册失败 处理
004CD35B . E8 9AB30600 call <jmp.&MFC42.#540_CString::CString>
004CD360 . 68 79C90000 push 0C979
004CD365 . 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
004CD369 . C74424 6C 06000000 mov dword ptr ss:[esp+6C],6
004CD371 . E8 BAB30600 call <jmp.&MFC42.#4160_CString::LoadStringA>
004CD376 . 8B5424 10 mov edx,dword ptr ss:[esp+10]
004CD37A . 6A 00 push 0
004CD37C . 6A 00 push 0
004CD37E . 52 push edx
004CD37F . 8BCE mov ecx,esi
004CD381 . E8 0EBF0600 call <jmp.&MFC42.#4224_CWnd::MessageBoxA> <---显示注册失败的对话框
004CD386 . 68 AA850000 push 85AA
004CD38B . 8BCE mov ecx,esi
004CD38D . E8 A8B50600 call <jmp.&MFC42.#3092_CWnd::GetDlgItem>
004CD392 . 8B1D E0DB5700 mov ebx,dword ptr ds:[<&USER32.SendMessageA>] ; USER32.SendMessageA
004CD398 . 8BF8 mov edi,eax
004CD39A . 6A FF push -1 ; /lParam = FFFFFFFF
004CD39C . 6A 00 push 0 ; |wParam = 0
004CD39E . 8B47 20 mov eax,dword ptr ds:[edi+20] ; |
004CD3A1 . 68 B1000000 push 0B1 ; |Message = EM_SETSEL
004CD3A6 . 50 push eax ; |hWnd
004CD3A7 . FFD3 call ebx ; \SendMessageA
004CD3A9 . 8B4F 20 mov ecx,dword ptr ds:[edi+20]
100014AA 8B8C24 24090000 mov ecx,dword ptr ss:[esp+924]
100014B1 33F6 xor esi,esi
100014B3 897424 10 mov dword ptr ss:[esp+10],esi
100014B7 8B79 F8 mov edi,dword ptr ds:[ecx-8]
100014BA 3BFE cmp edi,esi
100014BC 7E 1C jle short CGdi.100014DA
100014BE 0FBE5434 64 movsx edx,byte ptr ss:[esp+esi+64]
100014C3 52 push edx
100014C4 FF15 9C910010 call dword ptr ds:[<&MSVCRT.isxdigit>] ; MSVCRT.isxdigit
100014CA 83C4 04 add esp,4
100014CD 85C0 test eax,eax <------ 判断输入的序列号是否为数字
100014CF 0F84 8D000000 je CGdi.10001562
100014D5 46 inc esi
100014D6 3BF7 cmp esi,edi
100014D8 ^ 7C E4 jl short CGdi.100014BE
100014DA 85FF test edi,edi
100014DC 0F84 88000000 je CGdi.1000156A <---- 如果输入的序列号包含非数字字符,判定为注册失败
100014E2 8D4424 64 lea eax,dword ptr ss:[esp+64] <---- 以下对输入的序列号进行运算, 将结果与得到的机器码进行对比
100014E6 50 push eax
100014E7 55 push ebp
100014E8 E8 43430000 call CGdi.10005830
100014ED 68 20A00010 push offset CGdi.`string' ; ASCII "7BA1817170F699EB7A8CACA70EDD8F3E35861554C632CDCC0C7BC5D516D462A5AF8F8BB80D09D87EA061DC381C23355DAB847665CA5C352FDB588C4F3E53ED8ED3BA5AD333AF63A7DE342DD562254159E2A9580C32C66E492D23991E599E8B84B0A2DE308F7618BAC69411BF8DDFA1D1757FA8EF7B948"...
100014F2 53 push ebx
100014F3 E8 38430000 call CGdi.10005830
100014F8 8B4C24 28 mov ecx,dword ptr ss:[esp+28]
100014FC 68 38A10010 push offset CGdi.`string' ; ASCII "1A663"
1000155B E8 E02A0000 call CGdi.10004040
10001560 EB 08 jmp short CGdi.1000156A
10001562 C74424 10 01000000 mov dword ptr ss:[esp+10],1
1000156A 8D9424 BC040000 lea edx,dword ptr ss:[esp+4BC]
10001571 8D4424 30 lea eax,dword ptr ss:[esp+30]
10001575 52 push edx
10001576 50 push eax
10001577 FF15 3C900010 call dword ptr ds:[<&KERNEL32.lstrcmpA>] ; KERNEL32.lstrcmpA
1000157D 85C0 test eax,eax <---- 对输入的序列号进行运算,将结果与得到的机器码进行对比,相等则注册成功
1000157F 75 29 jnz short CGdi.100015AA <---- 将此处改为 jz short CGdi.100015AA 即机器码为 74 29,对应的文件偏移为157FH
10001581 8B4424 10 mov eax,dword ptr ss:[esp+10]
10001585 BB 01000000 mov ebx,1
1000158A 3BC3 cmp eax,ebx
1000158C 74 1C je short CGdi.100015AA
1000158E 85FF test edi,edi
10001590 74 18 je short CGdi.100015AA
10001592 8B8C24 24090000 mov ecx,dword ptr ss:[esp+924]
10001599 8B7424 14 mov esi,dword ptr ss:[esp+14]
1000159D 51 push ecx
1000159E 8BCE mov ecx,esi
100015A0 E8 EB050000 call CGdi.CCrypter::WriteRegeditInfo <--- 将结果保存到注册表
100015A5 895E 04 mov dword ptr ds:[esi+4],ebx
100015A8 EB 0D jmp short CGdi.100015B7
100015AA 8B5424 14 mov edx,dword ptr ss:[esp+14]
100015FE 8D8C24 24090000 lea ecx,dword ptr ss:[esp+924]
10001605 C78424 1C090000 FFFFFFF>mov dword ptr ss:[esp+91C],-1
10001610 E8 C5160000 call <jmp.&MFC42.#800_CString::~CString>
10001615 8B8C24 14090000 mov ecx,dword ptr ss:[esp+914]
1000161C 8BC6 mov eax,esi <--- 判断结果标志,为0表示失败,最初pj时将此处改为 and AL,1,结果发现不能完全成功。
1000161E 5F pop edi
1000161F 5E pop esi
10001620 5D pop ebp
10001621 5B pop ebx
10001622 64:890D 00000000 mov dword ptr fs:[0],ecx
10001629 81C4 10090000 add esp,910
1000162F C2 0400 retn 4
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!