劳动节脑洞大开!利用Debug API 获取 加壳客户端的MD5值
系统 : Windows xp
程序 : 某游戏客户端
程序下载地址 :不提供
要求 : 远程注入 & 获取MD5值
使用工具 : vc++6.0 & OD
案例说明:
该游戏客户端对自身进行散列计算,并将md5值打包加密发给服务端。由于客户端本体带有病毒和压缩壳,索性采用硬件断点,和Debug API获取该MD5的内存地址。
逆向该客户端:
客户端启动时,先初始化md5内存:
00419DE4 B9 mov ecx,
00419DE9 33C0 xor eax, eax
00419DEB 8DBD B8610200 lea edi, dword ptr [ebp+261B8]
00419DF1 F3:AB rep stos dword ptr es:[edi] ; (initial cpu selection)
然后开始计算散列值:
004EA3E2 BE B8610200 mov esi, 261B8
004EA3E7 33D2 xor edx, edx
004EA3E9 8D45 EE lea eax, dword ptr [ebp-]
004EA3EC 8A543D B4 mov dl, byte ptr [ebp+edi-4C]
004EA3F0 push edx
004EA3F1 E06D5300 push 00536DE0 ; %02x
004EA3F6 push eax
004EA3F7 E8 ABEE0100 call 005092A7
004EA3FC 8B15 943C5400 mov edx, dword ptr [543C94]
004EA402 :8B4D EE mov cx, word ptr [ebp-]
004EA406 83C4 0C add esp, 0C
004EA409 inc edi
004EA40A :890C16 mov word ptr [esi+edx], cx
004EA40E 83C6 add esi,
004EA411 81FE D8610200 cmp esi, 261D8
004EA417 ^ 7C CE jl short 004EA3E7
跳出循环后,md5值就计算完毕了。我们利用DebugAPI模拟以上操作就可以。
但是要注意一点,传参 DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS调用CreateProcess函数会将exe占用。这时,程序打开自身的CreateFile函数将失败:
0012FC98 004EA381 /CALL to CreateFileA from xxx.004EA37F
0012FC9C 0012FCC4 |FileName = "xxx.exe"
0012FCA0 80000000 |Access = GENERIC_READ
0012FCA4 00000000 |ShareMode = 0
0012FCA8 00000000 |pSecurity = NULL
0012FCAC 00000003 |Mode = OPEN_EXISTING
0012FCB0 00000000 |Attributes = 0
0012FCB4 00000000 \hTemplateFile = NULL
解决办法很简单,将ShareMode改成FILE_SHARE_READ即可。
最后整理一下我们分析的结果:
1.对程序下硬件断点,保存md5的内存地址。
2.patch掉ShareMode,改为0x01(FILE_SHARE_READ)。
3.对计算完md5之后的指令下断,并读取md5.
部分实现代码:
//用于createprocess的两个参数
STARTUPINFO si;
PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO); char ReadBuffer[] = {};
bool WhileDoFlag = true; //创建进程
if ( !CreateProcess( FileName,NULL,NULL,NULL,FALSE,
DEBUG_ONLY_THIS_PROCESS | DEBUG_PROCESS,NULL,NULL,&si,&pi ) ){
MessageBox( "打开程序失败!" ); DWORD dwRet = GetLastError();
CString strText(_T(""));
strText.Format(_T("%d"), dwRet);
AfxMessageBox("错误代码:"+strText); return ;
}
m_Pi = pi; DEBUG_EVENT DBEvent;
CONTEXT Regs;
DWORD dwSSCnt = ;
//存放md5地址
DWORD READ_ADDRESS; Regs.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS ; //设置程序在Single Step模式下执行
GetThreadContext( pi.hThread,&Regs );
Regs.EFlags |= 0x100;
SetThreadContext( pi.hThread,&Regs ); ResumeThread( pi.hThread ); while (WhileDoFlag) {
WaitForDebugEvent (&DBEvent, INFINITE);
switch (DBEvent.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT: switch (DBEvent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_SINGLE_STEP :
{
++dwSSCnt ;
if (dwSSCnt == )
{
//当收到第一个EXCEPTION_SINGLE_STEP异常信号,表示中断在程序的第一条指令,即入口点
//把Dr0设置成程序的入口地址 GetThreadContext(pi.hThread,&Regs); Regs.Dr0=Regs.Eax;
Regs.Dr7=0x101; SetThreadContext(pi.hThread,&Regs); }
else if (dwSSCnt == )
{
//第二次中断在起先设置的入口点,在BP_MOLLC处设置硬件断点 GetThreadContext(pi.hThread, &Regs) ; Regs.Dr0 = BP_MOLLC;
Regs.Dr7 = 0x101 ; SetThreadContext(pi.hThread, &Regs) ;
}
else if (dwSSCnt == )
{
//第三次中断,己到指定的地址,读取EDI寄存器的数据
GetThreadContext(pi.hThread, &Regs) ; Regs.Dr0 = BP_INITMD5;
Regs.Dr7 = 0x101 ; READ_ADDRESS = Regs.Edi; BYTE NewMode = 0x01;
int a = WriteProcessMemory( pi.hProcess,(LPVOID)SET_SHAREMODE,&NewMode,, ); SetThreadContext(pi.hThread, &Regs) ; /*
//挂起进程
SuspendThread( pi.hThread );
//通知进程异常已处理
ContinueDebugEvent(DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE) ;
//卸载调试器
int a = _DebugSetProcessKillOnExit( FALSE );
int b = _DebugActiveProcessStop(DBEvent.dwProcessId);
//最后运行线程
ResumeThread( pi.hThread ); //int b = GetLastError();
WhileDoFlag=FALSE;
*/
}
else if (dwSSCnt == )
{
//第四次中断,MD5算出,读取数据.
GetThreadContext(pi.hThread, &Regs) ; Regs.Dr0 = Regs.Dr7 = ; ReadProcessMemory( pi.hProcess,(LPVOID)READ_ADDRESS,ReadBuffer,,NULL );
SetDlgItemText( IDC_EDITMD5,ReadBuffer ); SetThreadContext(pi.hThread, &Regs) ;
}
break;
}
}
break ; case EXIT_PROCESS_DEBUG_EVENT :
WhileDoFlag=FALSE;
break ;
}
//pi.dwProcessId和pi.dwThreadId 要改成如下的代码
ContinueDebugEvent(DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE) ;
} //.end while
劳动节脑洞大开!利用Debug API 获取 加壳客户端的MD5值的更多相关文章
- 我的Java开发学习之旅------>工具类:Java获取字符串和文件进行MD5值
ps:这几天本人用百度云盘秒传了几部大片到云盘上,几个G的文件瞬秒竟然显示"上传成功"!这真让我目瞪口呆,要是这样的话,那得多快的网速,这绝对是不可能的,也许这仅是个假象.百度了一 ...
- 如何获取Azure Storage Blob的MD5值
问题表述 直接使用CloudBlockBlob对象获取的Properties是空的,无法获取到对象的MD5值,后台并未进行属性值的填充 前提:blob属性本省包含md5值,某些方式上传的blob默认并 ...
- VS2008 C++ 利用WinHttp API获取Http请求/响应头部Header
http://www.cnblogs.com/LCCRNblog/p/3833472.html 这一篇博客中,实现了获取http请求/响应后的html源码,现在需要获取http请求/响应的头部Head ...
- VS2008 C++ 利用WinHttp API获取任意Http网址的源码
最近一直在看有关Http的知识,对其基本的理论知识已经有所掌握,想通过一个C++具体的例子进行实际操作..于是上网查找了很多资料,发现在Windows系统上,可以通过WinHttp API接口开啊Ht ...
- 爬虫——python——百度地图经纬度查询——经纬度查看地点地名——利用百度API获取地名经纬度——爬取所有的中国地址
import requests address = '40.8587960,86.866991' url = 'http://api.map.baidu.com/geocoder?output=jso ...
- 利用iOS API编写简单微博客户端全过程
要编写社交网络客户端程序,可以大体上分为4个主要的步骤 下面我们按照这个流程,介绍一下: 1.引入Accounts和Social框架 工 程中需要引入Accounts和Social框架,Account ...
- iOS开发,利用文件流,算大文件的MD5值(程序不会导致内存崩溃)
CFStringRef FileMD5HashCreateWithPath(CFStringRef filePath, size_t chunkSizeForReadingData) { // Dec ...
- jni中调用java方法获取当前apk的签名文件md5值
相应的java方法: void getsign(Context context) throws Exception { PackageInfo localPackageInfo = context.g ...
- PHP获取远程http或ftp文件的md5值
PHP获取本地文件的md5值: md5_file("/path/to/file.png"); PHP获取远程http文件的md5值: md5_file("https:// ...
随机推荐
- Android自定义EditText去除边框并添加下划线
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- Oracle ASM diskgroup在主机重启后启动失败
环境:RHEL 6.4 + Oracle 11.2.0.3 + ASM单实例 1.重启主机后,+DATA diskgroup启动不成功,现象如下: [grid@JY-DB ~]$ crsctl sta ...
- 【Java基础】方法
Num1:检查参数的有效性 绝大多数的方法和构造器对于传递给它们的参数值都会有某些限制.比如:索引值必须是非负数,对象引用不能为null等等.这些都很常见,你应该在文档中清楚地指明所有这些限制,并在方 ...
- 阅读《LEARNING HARD C#学习笔记》知识点总结与摘要三
最近工作较忙,手上有几个项目等着我独立开发设计,所以平时工作日的时候没有太多时间,下班累了就不想动,也就周末有点时间,今天我花了一个下午的时间来继续总结与整理书中要点,在整理的过程中,发现了书中的一些 ...
- CSS基础-插曲
CSS学习 1:通过css来设置边框的颜色 我们可以通过border:10px solid red;来统一的设置颜色,但是我们有的时候需要每个边框的颜色不一样,我们就需要通过各自设置的方法来设置边框的 ...
- 解决MVC EF Code First错误:Model compatibility cannot be checked because the EdmMetadata type was not included in the model.
Model compatibility cannot be checked because the EdmMetadata type was not included in the model. En ...
- 解决在IE中获取数据的缓存问题,运行环境为node.js
IE下默认会开启缓存策略,不管是页面还是通过ajax请求的数据都会议一个url,url是uri(统一资源定位符)的实例,url就是资源的标识符. 写一个demo进行验证,测试环境:IE8,node.j ...
- 这几天做完简易酒店管理系统,对Sql Server执行计划的浅显了解。
我是一名大三的小学生,今天开始我的第一篇博客,最近随便做了一个简易的酒店管理系统,对sql执行计划有了初步的了解. 查看上面语句的预估执行计划,在工具栏中有这个按钮 聚集索引扫描被称为Index Sc ...
- 背水一战 Windows 10 (7) - 控件 UI: VisualState, VisualStateManager, 控件的默认 UI
[源码下载] 背水一战 Windows 10 (7) - 控件 UI: VisualState, VisualStateManager, 控件的默认 UI 作者:webabcd 介绍背水一战 Wind ...
- ListActivity的使用
Android中经常用到列表,ListActivity是实现列表的一种好方法. 使用ListActivity的方法,首先定义布局文件: <?xml version="1.0" ...