躲猫猫!验证机制隐藏在API中
2015-06-22 20:01
218 查看
把软件的注册机制隐藏在API里最大的好处就是不容易被破解者发现,因为他们经常会用OD的F8快捷键步过API,很少有人跟进去看把?然后…程序的注册机制调用就在XX API中。
原理比较简单,主要是利用了流行的HOOK技术,至于怎么HOOK完全取决于你,反正要能改变API函数的流程即可。
如果选的HOOK点适当,我觉得这一招还是很阴的….
比如:
MessageBoxA
IsDebuggerPresent
等特别容易被忽视的API函数。
在这篇文章中我选择使用MessageBoxA来作为目标。
考虑下面的代码段:
注意观察第一个参数,这个是我们的后门标记。
破解者一般都会跳过带”失败“特征的分支…..
假如我们HOOK MessageBoxA这个函数,并留下了进入验证机制的后门….
在 MessageBox(XXX,”注册失败!”,”err”,MB_OK); 中触发后门,触发条件是XXX=后门设置的某个值…
一旦跳过了这一个分支,那么就等于跳过了进入注册机制的路…..呵呵,你懂得…
然后显示注册失败什么的 就可以在验证完后改变MessageBox的参数现实提示。
HOOK操作代码最后放到隐秘一点的地方,比如异常处理函数..
下面是完整的验证DLL代码,写地很简单。
原理比较简单,主要是利用了流行的HOOK技术,至于怎么HOOK完全取决于你,反正要能改变API函数的流程即可。
如果选的HOOK点适当,我觉得这一招还是很阴的….
比如:
MessageBoxA
IsDebuggerPresent
等特别容易被忽视的API函数。
在这篇文章中我选择使用MessageBoxA来作为目标。
考虑下面的代码段:
if(key==2) { MessageBox(XXX,"注册失败!","err",MB_OK); }else { //这个只是假的成功吧。 MessageBox(0,"注册成功!","err",MB_OK) }
注意观察第一个参数,这个是我们的后门标记。
破解者一般都会跳过带”失败“特征的分支…..
假如我们HOOK MessageBoxA这个函数,并留下了进入验证机制的后门….
在 MessageBox(XXX,”注册失败!”,”err”,MB_OK); 中触发后门,触发条件是XXX=后门设置的某个值…
一旦跳过了这一个分支,那么就等于跳过了进入注册机制的路…..呵呵,你懂得…
然后显示注册失败什么的 就可以在验证完后改变MessageBox的参数现实提示。
HOOK操作代码最后放到隐秘一点的地方,比如异常处理函数..
下面是完整的验证DLL代码,写地很简单。
//By 无名侠 void HookMessageBox(); BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: HookMessageBox(); case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } char *err = "注册失败!"; char *regok ="注册成功!"; char * FunAddr = NULL; void HookMessageBox(); int __stdcall REG(int key) { if (key==0xcccccccc) { return 1; }else { return 0; } } __declspec(naked) void MyMessagebox() { _asm { push ebp mov ebp,esp cmp [ebp+20],0xAA jne next push [ebp+8] call REG push ebx mov ebx,0 mov [ebp+8],ebx mov [ebp+20],ebx pop ebx cmp eax,1 jne iferr mov eax,regok mov [ebp+12],eax jmp next iferr: mov eax,err mov [ebp+12],eax next: mov eax,FunAddr add eax,5 jmp eax } } void HookMessageBox() { unsigned char JmpCode[5]; int addr2; DWORD oldProtect; FunAddr=(char *)GetProcAddress(GetModuleHandleA("User32.dll"),"MessageBoxA"); if (!FunAddr) { MessageBoxA(0,"error!","",MB_OK); ExitProcess(-1); } JmpCode[0]=0xE9; addr2 = (int)MyMessagebox-(int)FunAddr-5; *((int*)&JmpCode[1])=addr2; VirtualProtect(FunAddr,5,PAGE_EXECUTE_READWRITE,&oldProtect); memcpy(FunAddr,JmpCode,5); VirtualProtect(FunAddr,5,oldProtect,NULL); }
By 无名侠 转载请保留出处。
相关文章推荐
- alpha阶段总结
- Android Studio开发第四篇版本管理Git(下)
- RedHat下构建LAMP平台+Discuz!论坛 推荐
- Skype for Business Server 2015-10-ADFS-2-配置
- 背包问题
- UVA - 11809 Floating-Point Numbers
- 《你的灯亮着吗》 阅读笔记三
- [转载]二叉树的非递归遍历方法
- 用户调研
- bzoj2002:[Hnoi2010]Bounce 弹飞绵羊
- 类方法和对象方法
- Redis实现分布式锁全局锁—Redis客户端Redisson中分布式锁RLock实现
- 如何用unity3D编辑英雄技能冷切框
- 《你的灯亮着吗》 阅读笔记二
- js document
- 剑指offer-第二章-基础篇
- 比较java comparable和Comparator 区别
- Jenkins安装入门
- xml文件的生成
- Skype for Business Server 2015-10-ADFS-1-部署