一、程序流程:
对话框创建,处理WM_INITDIALOG时:
1.程序通过获取磁盘信息等,再由得到的信息经过一些计算后查询密码表:
SAFURENURBKESOLTAGPXFNOKMHYBANkdudqonxcuamxfuajncyjabguf943200jnufadf9980745987235
并最终得到机器码和注册码并存放到变量中
2.获取注册表中的字符串(键值chounan),字符串需要是12个字符才是合法的注册码
3.取信息的后八位(输入信息需要是12个字符)并存放到%system%下的Option.ini中,然后启动一个timer id=1
4.取注册表中输入信息的前8个字符和正确的注册码前8个字符经一轮运算后进行比较,正确的话设置窗口title为“已注册”,并且“已注册”几个字符串是通过编码存放的!
Q3JhY2tNZSBb0tHXorLhXQ==
5.设置timer id=2
对话框创建完毕后:
1.程序来到timer id=1 的消息处理流程:
读取%system%下的Option.ini中的8个字符
和之前计算出的正确的注册码的后八个字符经过一些计算后比较,正确的话显示注册成功,并显示美女图片,错误的话设置title为“未注册”
2.程序来到timer id=2 的消息处理流程:
通过ReadProcessMemory检查此处代码
0040182E |. 0BC0 or eax, eax
00401830 |. 74 2F je short 00401861
是否被篡改,以防止暴力jmp(这个好像太弱了一点,至少检查范围应该再大一些),如果被改掉则向lstrlen函数传递一个无用的指针,使程序崩溃
004018D9 |. 6A 00 push 0
004018DB |. A0 48674000 mov al, byte ptr [406748]
004018E0 |. 66:0FB6C0 movzx ax, al
004018E4 |. 66:50 push ax ; /String
004018E6 |. E8 E7030000 call <jmp.&kernel32.lstrlenA> ; \lstrlenA
当然,作者还不忘加了一个push 0 在前面,以防止这段代码被nop掉后,可以破坏外层的栈平衡
二、下面来说说程序的bug,当然我也不知道此bug究竟是作者留来反调试的还是什么
1.程序在获取波形文件资源后,分配了一块大小为获取的资源大小+4的内存块,然后将资源拷贝到在此处
004013B1 |. 50 push eax ; /MemSize
004013B2 |. 6A 40 push 40 ; |Flags = GPTR
004013B4 |. E8 CB080000 call <jmp.&kernel32.GlobalAlloc> ; \GlobalAlloc
004013B9 |. A3 7C664000 mov dword ptr [40667C], eax
004013BE |. 8B0D 78664000 mov ecx, dword ptr [406678]
004013C4 |. 8908 mov dword ptr [eax], ecx
004013C6 |. 83C0 04 add eax, 4
004013C9 |. 8BF8 mov edi, eax
004013CB |. F3:A4 rep movs byte ptr es:[edi], byte ptr>; 将资源拷贝到分配的内存中,大小刚好是分配的内存大小!内存块头四字节存放资源大小!
代码执行到此处时的edi正好指向分配的内存块末尾后的内容!指向 001618c3!
2.程序继续运行到如下代码
00401604 |. 68 C8684000 |push 004068C8 ; /StringToAdd = "0"
00401609 |. 57 |push edi ; |ConcatString
0040160A |. E8 AB060000 |call <jmp.&kernel32.lstrcatA> ; \lstrcatA,此处代码为向edi指向的内存后附加数据,当然是要附加到以00结尾的地方!
这个时候edi并没变,在我的机器上还是指向 001618c3,如下
001618C3 AB AB AB AB AB AB AB AB FE EE FE EE FE 30 00 00 ?..
001618D3 00 00 00 00 00 2D 00 40 0A 46 07 1C 00 90 7A E5 .....-.@.F.恴
明显楼主没考虑到这个时候的edi已经指向了分配的内存块的末尾,后面可能有无法预料的数据,在我机器上OD加载此程序运行就会有上图的乱码刚好在内存块后面,接下来的代码正是向001618C3处拷贝计算出来的机器码,由于001618C3处已有数据(AB AB ...),所以函数只好往后lstrcat(找到数据为00的地方才附加),导致后面的注册码比较模块还是从001618c3处拷贝数据!这样拷贝的当然就不是正确的数据了!
但是奇怪的是如果不用OD加载此程序,001618C3处刚好是00 00 ...,没有数据存在,而计算出来的机器码当然就不会往后拷贝!可能是OD加载此程序会导致此处有一些数据的写入??还是楼主正好以此反调试??望楼主或高人解答!
大家可以试试,使用正确的注册码,如果使用OD加载程序后运行和单独运行程序的效果是不一样的,一个不能显示注册成功,一个能注册成功,原因就是我上面说的楼主没考虑内存分配问题,但是这刚好又做到了反调试??至少我机器上是这样