编程框架和MASM混合编程

前言

涉及到UI和业务逻辑的地方,用MFC, WTL, DUILIB等成型的开发框架, 舒服的开发和用户的交互, 业务逻辑.
涉及到操作寄存器的操作,用RadAsm+MASM编译成的汇编版静态库, 提供函数给编程框架调用.
这样可以极大的提高开发效率.
如果用RadAsm + MASM硬生生的写SDK工程, 还真是让人有点享受不了啊…

Demo工程下载点

srcMfcFixMasm.zip

代码片段

MASM静态库

; file MyMasmProcLib.inc

IFNDEF MY_MASM_PROC_LIB_INC_2016_0713
MY_MASM_PROC_LIB_INC_2016_0713 EQU <1>

include windows.inc

include kernel32.inc
includelib kernel32.lib

include user32.inc
includelib user32.lib

ENDIF ; IFNDEF MY_MASM_PROC_LIB_INC_2016_0713
; file MyMasmProcLib.Asm

.386
.model flat,stdcall
option casemap:none

include MyMasmProcLib.inc

fnMasm_CriticalCodeSection1 PROTO stdcall
fnMasm_CriticalCodeSection2 PROTO stdcall

.code

fnMasm_GetAddr_TEB proc stdcall
; 0:000> dt 7ffde000 _NT_TIB
; ntdll!_NT_TIB
;    +0x000 ExceptionList    : 0x0012ffe0 _EXCEPTION_REGISTRATION_RECORD
;    +0x004 StackBase        : 0x00130000 Void
;    +0x008 StackLimit       : 0x0012d000 Void
;    +0x00c SubSystemTib     : (null) 
;    +0x010 FiberData        : 0x00001e00 Void
;    +0x010 Version          : 0x1e00
;    +0x014 ArbitraryUserPointer : (null) 
;    +0x018 Self             : 0x7ffde000 _NT_TIB

    assume fs:nothing
    mov eax, fs:[18h] ; get _NT_TIB.Self, this is TEB addr

    ret
fnMasm_GetAddr_TEB endp

fnMasm_CriticalCodeSection_SehProc proc C pExcept:dword, pFrame:dword, pContext:dword, pDispatch:dword
    ; pExcept type is EXCEPTION_RECORD
    ; pContext type is CONTEXT
    mov esi, pExcept
    assume esi:ptr EXCEPTION_RECORD

    mov edi, pContext
    assume edi:ptr CONTEXT 

    mov eax, CONTEXT_ALL
    mov [edi].ContextFlags, eax

    .if ([esi].ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
        .if (([edi].regEip >= FNMASM_CRITICALCODESECTION_BEGIN) && ([edi].regEip <= FNMASM_CRITICALCODESECTION_END))
            ; 调整EIP, 跳过C05调用代码
            mov eax, [edi].regEip
            add eax, 2 ; 现在看到的引起C05的指令是2个字节
            mov [edi].regEip, eax

            ; 设置单步标志
            or [edi].regFlag, 100h

            mov eax, ExceptionContinueExecution 
        .else
            mov eax, ExceptionContinueSearch
        .endif
    .elseif ([esi].ExceptionCode == EXCEPTION_SINGLE_STEP)
        .if (([edi].regEip >= FNMASM_CRITICALCODESECTION_BEGIN) && ([edi].regEip <= FNMASM_CRITICALCODESECTION_END))
            mov ebx,[edi].regEip
            mov al, [ebx]
            .if (al == 0cch)
                ; @todo 这里退出不好,最好将程序逻辑搞乱
                invoke ExitProcess, 0
            .else
                .const
                g_szExp_EXCEPTION_SINGLE_STEP1 db 'EXCEPTION_SINGLE_STEP1', 0
                g_sz_title_ok db 'ok', 0
                .code
                invoke MessageBox, NULL, offset g_szExp_EXCEPTION_SINGLE_STEP1, offset g_sz_title_ok, MB_OK

                ; 关键代码段内,都要设置单步
                or [edi].regFlag, 100h
                mov eax, ExceptionContinueExecution
            .endif 
        .else
            mov eax, ExceptionContinueExecution
        .endif
    .else
        mov eax, ExceptionContinueSearch
    .endif

    ret
fnMasm_CriticalCodeSection_SehProc endp

fnMasm_CriticalCodeSection proc stdcall
    ;install new seh
    assume fs: nothing
    push offset fnMasm_CriticalCodeSection_SehProc
    push fs:[0]
    mov fs:[0], esp

    invoke fnMasm_CriticalCodeSection1
    mov edi, eax
@@ret:
    ;restore previous SEH
    mov eax, [esp] 
    mov fs:[0], eax
    add esp, 8

    mov eax, edi
    ret
fnMasm_CriticalCodeSection endp

fnMasm_CriticalCodeSection1_SehProc proc C pExcept:dword, pFrame:dword, pContext:dword, pDispatch:dword
    mov eax, ExceptionContinueSearch
    ret
fnMasm_CriticalCodeSection1_SehProc endp

fnMasm_CriticalCodeSection1 proc stdcall
    ;install new seh
    assume fs: nothing
    push offset fnMasm_CriticalCodeSection1_SehProc
    push fs:[0]
    mov fs:[0], esp

    invoke fnMasm_CriticalCodeSection2
    mov edi, eax

@@ret:
    ;restore previous SEH
    mov eax, [esp] 
    mov fs:[0], eax
    add esp, 8

    mov eax, edi
    ret
fnMasm_CriticalCodeSection1 endp

fnMasm_CriticalCodeSection2_SehProc proc C pExcept:dword, pFrame:dword, pContext:dword, pDispatch:dword
    mov eax, ExceptionContinueSearch
    ret
fnMasm_CriticalCodeSection2_SehProc endp

fnMasm_CriticalCodeSection2 proc stdcall
    ;install new seh
    assume fs: nothing
    push offset fnMasm_CriticalCodeSection2_SehProc
    push fs:[0]
    mov fs:[0], esp

; 关键代码段
    ; 制造异常EXCEPTION_ACCESS_VIOLATION, 在异常处理中改单步异常
    mov eax, 0ffffffffh
    mov ebx, 0ffffffffh 
FNMASM_CRITICALCODESECTION_BEGIN::
    ; 调试器单步到这,直接挂了    
    mov [ebx], eax ; make EXCEPTION_ACCESS_VIOLATION

    xor eax, eax
    nop 
    nop 
    nop 
    inc eax
    nop 
    nop 
    nop 
    inc eax
    nop 
    nop 
    nop 
    inc eax
    inc eax
    inc eax
    inc eax
FNMASM_CRITICALCODESECTION_END::
    nop

@@ret:
    mov edi, eax 

    ;restore previous SEH
    mov eax, [esp] 
    mov fs:[0], eax
    add esp, 8

    mov eax, edi

    ret
fnMasm_CriticalCodeSection2 endp

end

主程序

/// @file MyMasmProcDefine.h
/// @brief 由Masm实现的函数定义

#ifndef MY_MASM_PROC_DEFINE_H_2016_0713
#define MY_MASM_PROC_DEFINE_H_2016_0713

/// @function 得到TEB
/// @note 得到TEB后,就可以结合WinDbg, 写出操作PEB链表的实现 
extern "C" DWORD __stdcall fnMasm_GetAddr_TEB();

/// @function 执行关键代码段, 反单步调试
/// @note 3层异常, 1,2层转发异常,3层反单步调试 
extern "C" DWORD __stdcall fnMasm_CriticalCodeSection();

#endif // #ifndef MY_MASM_PROC_DEFINE_H_2016_0713
void CPrjMfcDlgDlg::OnButtonTest() 
{
    // TODO: Add your control notification handler code here
    DWORD dwAddrTeb = fnMasm_GetAddr_TEB();

    /*
    ntdll!_TEB
   +0x000 NtTib            : _NT_TIB
   +0x01c EnvironmentPointer : (null) 
   +0x020 ClientId         : _CLIENT_ID
   +0x028 ActiveRpcHandle  : (null) 
   +0x02c ThreadLocalStoragePointer : (null) 
   +0x030 ProcessEnvironmentBlock : 0x7ffdf000 _PEB
    */

    DWORD dwAddrPeb = *((DWORD*)(dwAddrTeb + 0x30));

    MessageBox(">> fnMasm_CriticalCodeSection", NULL, MB_OK);
    DWORD dwRc = fnMasm_CriticalCodeSection();
    CString str;
    str.Format("<< fnMasm_CriticalCodeSection() = 0x%X", dwRc);
    MessageBox((LPTSTR)(LPCTSTR)str, NULL, MB_OK);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值