您的位置:首页 > 编程语言

编程框架和MASM混合编程

2016-07-14 01:03 375 查看

前言

涉及到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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: