阅读了“MFC程序逆向 – 消息篇(上)+(下)”一文后,收获颇丰。作者提到对于对话框程序,在这个函数函数入口处设置断点最好(请记住这个函数:CCmdTarget::OnCmdMsg())。在学习的过程中,对OD的一些使用方法进一步加深了理解。
mfc程序 按钮 call调用 都是通过在全局函数_AfxDispatchCmdMsg里
网上看到一些是用特征代码,搜索的,不准确, mfc60.dll mfc70.dll mfc90.dll debug realse版特征代码都是不一样的
但是都是通过调用AFX_STATIC BOOL AFXAPI _AfxDispatchCmdMsg(CCmdTarget* pTarget, UINT nID, int nCode,
AFX_PMSG pfn, void* pExtra, UINT_PTR nSig, AFX_CMDHANDLERINFO* pHandlerInfo)函数
这个函数用7个参数,所以这个函数调用应该是如下特征
012D6151 push dword ptr [ebp+14h]
012D6154 push dword ptr [eax+10h]
012D6157 push dword ptr [ebp+10h]
012D615A push dword ptr [eax+14h]
012D615D push dword ptr [ebp+0Ch]
012D6160 push dword ptr [ebp+8]
012D6163 push ebx
012D6164 call _AfxDispatchCmdMsg (12D5F15h)
这个debug realse 不一样, 7个push 1个call。 注意观察 就能找到
OllyDbg所支持的用于指定断点的关键字(以正则表达式形式给出)
关键字 描述
R8 任意8位寄存器(AL,BL,CL,DL,AH,BH,CH,DH)
R16 任意16位寄存器(AX,BX,CX,DX,SP,BP,SI,DI)
R32 任意32位寄存器(EAX,EBX,ECX,EDX,ESP,EBP,ESI,EDI)
FPU 任意数学协处理器寄存器(ST0:ST7)
MMX 任何MMX寄存器(MM0:MM7)
CRX 任何控制寄存器(CR0:CR7)
DRX 任何调试寄存器(DR0:DR7)
CONST 任何常量
OFFSET 任何偏移量(类似于常量)
JCC 任意条件跳转(JE,JC,JNGE…… )
SETCC 任何设置字节的条件指令(SETE,SETC,SETNGE……)
CMOVCC 任何条件移动(CMOVE,CMOVC,CMOVNGE……)
以下是特征码 通配符查找,在vs2005 2008 vc6上都可以,CTRL+S 输入指令序列
指令序列下的CALL 就是 _AfxDispatchCmdMsg函数,跟入 就是按钮调用
Release版本:
静态库中使用:
push dword ptr [R32+CONST]
push dword ptr [R32+CONST]
push dword ptr [R32+CONST]
push dword ptr [R32+CONST]
push dword ptr [R32+CONST]
push dword ptr [R32+CONST]
push R32
call CONST
共享dll中使用
push dword ptr [R32+CONST]
mov edi,dword ptr [R32+CONST]
push dword ptr [R32+CONST]
mov R32,R32
push R32
push R32
call CONST
*-----------------------------------------------------------------------------*/
Debug 版本:
静态库中使用
mov R32, dword ptr [R32+OFFSET]
push R32
mov R32, dword ptr [R32+OFFSET]
push R32
mov R32, dword ptr [R32+OFFSET]
push R32
mov R32, dword ptr [R32-OFFSET]
push R32
共享dll中使用
mov R32,dword ptr [R32-OFFSET]
mov R32,dword ptr [R32+OFFSET]
push R32
mov R32,dword ptr [R32+OFFSET]
push R32
mov R32,dword ptr [R32+8]
push R32
mov R32,dword ptr [R32-3C]
以上是本人的一些学习心得,不妥之处,敬请指正。