|
第四: /*-------------------------------------------------------- 内存断点被忽略,除了硬件断点,管用以外,内存断点关键时候会不管用,我还没研究清楚.以后补 第五: /*---------------------------------------------------------- 代码在解密的时候有个固定格式: //第一个参数是特征码: //第二个参数是函数地址,这样的函数被称为手工函数,同常要跳两下才能到关键地方: 0097E000 > 68 7CB6B2A7 push A7B2B67C 0097E005 - FF25 BCE19700 jmp dword ptr [<&PAL4P.#1>] ; PAL4P.#1 //第二处跳转: 00CB6000 > /E9 7D000000 jmp 00CB6082 //最后入口,函数入口都是这样固定的格式之前版本与之后版本有所不同: 00CB6082 60 pushad 00CB6083 9C pushfd 00CB6084 FC cld 00CB6085 E8 00000000 call 00CB608A 00CB608A 5B pop ebx 00CB608B 8D9B 76FFFFFF lea ebx, dword ptr [ebx-8A] 00CB6091 8B43 48 mov eax, dword ptr [ebx+48] 00CB6094 B9 00100000 mov ecx, 1000 00CB6099 3BC1 cmp eax, ecx 00CB609B 76 0B jbe short 00CB60A8 一整大的跳转之后天南地北就分不清楚了:(,比起之前的版本增加了破解难度,之前的跳转好搞现在新版的比较难了,每次都是大跳,而且地址不一样,实在晕头转向. 第六: /*------------------------------------------------------------- 函数的重定位,实际就是把入口加密了,让你不知道调用那个函数,主要分三类: 第一,API函数:比较难,对API要特别清楚,不然很难修复确定函数是那一个的.而且要对写程序的经验也要熟悉哦!凭的就是经验了.后面会举例的 第二,内部函数加密:这个简单 第三,外部函数:这个就难了,关键是不知道调用那个函数,做了什么,一边解密一边执行,等到头了,也执行完了.相对来说最难了. 第七: /*---------------------------------------------------------------- 跳转,主要是JMP JE JNE JLE JG等等加密,让你看不出来跳那去了.解决简单. 第八: /*------------------------------------------------------------------ 举例,最简单的一个API函数修复的例子很简单的,比这个难的那就靠经验分析了哦! 这个是创建窗口的一部分,反汇编如下: 004099A0 /$Content$nbsp; 83EC 30 sub esp, 30 004099A3 |. A1 F4088E00 mov eax, dword ptr [8E08F4] 004099A8 |. 53 push ebx 004099A9 |. 8B5C24 38 mov ebx, dword ptr [esp+38] 004099AD |. 55 push ebp 004099AE |. 56 push esi 004099AF |. 8BF1 mov esi, ecx 004099B1 |. 57 push edi 004099B2 |. 6A 7F push 7F 004099B4 |. 8D4E 78 lea ecx, dword ptr [esi+78] 004099B7 |. 53 push ebx 004099B8 |. 51 push ecx 004099B9 |. 8946 68 mov dword ptr [esi+68], eax 004099BC |. E8 EFB12600 call 00674BB0 ;这里简单点,忽略或者算是修复好了吧 004099C1 |. 8B5424 58 mov edx, dword ptr [esp+58] 004099C5 |. 8B46 68 mov eax, dword ptr [esi+68] 004099C8 |. 8B4C24 64 mov ecx, dword ptr [esp+64] 004099CC |. 83C4 0C add esp, 0C 004099CF |. 33ED xor ebp, ebp 004099D1 |. C74424 10 300>mov dword ptr [esp+10], 30 004099D9 |. 68 007F0000 push 7F00 ; /RsrcName = IDC_ARROW 004099DE |. 55 push ebp ; |hInst => NULL 004099DF |. C74424 1C 002>mov dword ptr [esp+1C], 2000 ; |第一个参数从0x7F00看出来是个常数也就是说它是一个固定的值, 004099E7 |. 895424 20 mov dword ptr [esp+20], edx ; |PUSH EBP第二个参数中EBP是什么呢?往上看就看到xor ebp, ebp这句说明就是: 004099EB |. 896C24 24 mov dword ptr [esp+24], ebp ; |FUN(NULL,0x7F00)的函数,这段时间会有什么函数出现了呢?熟悉写程序的朋友都知道 004099EF |. 896C24 28 mov dword ptr [esp+28], ebp ; |最常出现的是LoadCursorA和LoadIconA那么到底那一个呢?我们发现,LoadIconA通常会是 004099F3 |. 894424 2C mov dword ptr [esp+2C], eax ; |字符串出现的多或者它还有个MAKEINTRESOURCE这个出现!还有就是0x7F00= IDC_ARROW 004099F7 |. 894C24 30 mov dword ptr [esp+30], ecx ; |出现的最多,所以这里修复使用前着LoadCursorA 004099FB |. FF15 74278400 call dword ptr [842774] ; \LoadCursorA 00409A01 |. 8B5424 5C mov edx, dword ptr [esp+5C] 00409A05 |. 894424 2C mov dword ptr [esp+2C], eax 00409A09 |. 8D4424 10 lea eax, dword ptr [esp+10] 00409A0D |. 896C24 30 mov dword ptr [esp+30], ebp 00409A11 |. 50 push eax ; /pWndClassEx 00409A12 |. 896C24 38 mov dword ptr [esp+38], ebp ; |就一个参数,结构都创建了不注册窗口等着干嘛! 00409A16 |. 895C24 3C mov dword ptr [esp+3C], ebx ; |这里100%就是注册窗口了:) 00409A1A |. 895424 40 mov dword ptr [esp+40], edx ; | 00409A1E |. FF15 70278400 call dword ptr [842770] ; \RegisterClassExA /*----------------------------------------------------------- //下面是关于注册窗口的C样板代码 wndclass.style=CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc=WindowProc; wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hInstance=hInst; wndclass.hIcon=LoadIcon(hInst,(LPCTSTR)IDI_ICON1); wndclass.hCursor=LoadCursor(NULL, IDC_ARROW); wndclass.lpszMenuName=NULL; wndclass.lpszClassName=szAppName; wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
上一页 [1] [2] [3] [4] 下一页 |