.386
.MODEL FLAT
INCLUDE WINDOWS.INC
INCLUDELIB IMPORT32.LIB
EXTRN ExitProcess:PROC
EXTRN MessageBoxA:PROC
EXTRN VirtualProtect:PROC
CONTEXT STRUC
C_ContextFlags DD ?
C_Dr0 DD ?
C_Dr1 DD ?
C_Dr2 DD ?
C_Dr3 DD ?
C_Dr6 DD ?
C_Dr7 DD ?
C_Float DB 70H DUP(?)
C_SegGs DD ?
C_SegFs DD ?
C_SegEs DD ?
C_SegDs DD ?
C_Edi DD ?
C_Esi DD ?
C_Ebx DD ?
C_Edx DD ?
C_Ecx DD ?
C_Eax DD ?
C_Ebp DD ?
C_Eip DD ?
C_SegCs DD ?
C_EFlags DD ?
C_Esp DD ?
C_SegSs DD ?
CONTEXT ENDS
EXCEPTION_POINTERS STRUC
ExceptionRecord DD ?
ContextRecord DD ?
EXCEPTION_POINTERS ENDS
EXCEPTION_RECORD STRUC
ExceptionCode DD ?
ExceptionFlags DD ?
LPExceptionRecord DD ?
ExceptionAddress DD ?
NumberParameters DD ?
ExceptionInformation DD 0FH DUP(?)
EXCEPTION_RECORD ENDS
PAGE_EXECUTE_READWRITE = 40H
.DATA
szMessage DB 'Hello,World!',0
szCaption DB 'Win32 Asm',0
ddBuffer DD 0
.CODE
_Start:
;代码段不可写,先更改页面保护属性
PUSH OFFSET ddBuffer
PUSH PAGE_EXECUTE_READWRITE
PUSH 01000H
PUSH OFFSET _Start
CALL VirtualProtect
;将单步执行的代码加密
;简单加密,即每一个字节与 055H 进行异或运算
MOV AL,055H
LEA EDI,_SM@1
PUSH len0
POP ECX
@Loop:
XOR BYTE PTR [EDI],AL
INC EDI
LOOP @Loop
;挂接结构化异常处理函数,拦截单步异常
ASSUME FS:NOTHING
PUSH OFFSET _SEH_Entry
PUSH DWORD PTR FS:[0]
MOV FS:[0],ESP
;将单步标志置1,使程序进入单步执行
PUSHFD
OR DWORD PTR [ESP],0100H
POPFD
_StepBegin:
NOP
_SM@1: PUSH EBP
_SM@2: MOV EBP,ESP
_SM@3: PUSHFD
_SM@4: PUSH MB_OK
_SM@5: PUSH OFFSET szCaption
_SM@6: PUSH OFFSET szMessage
_SM@7: PUSH NULL
_SM@8: CALL MessageBoxA
POPFD
NOP
_SM@9: MOV ESP,EBP
_SM@10: POP EBP
_SM@11: NOP
;恢复结构化异常处理链,退出程序
POP DWORD PTR FS:[0]
ADD ESP,4
PUSH 0
CALL ExitProcess
;DWORD __cdecl ExceptionFilter(EXCEPTION_RECORD * lpRecord,EXCEPTION_REGISTRATION * lpRegist,CONTEXT * lpContext,DWORD * dwParam)
;进入函数后,栈状态如下
; [ESP+20] DWORD * dwParam
; [ESP+16] CONTEXT *
; [ESP+12] EXCEPTION_REGISTRATION *
; [ESP+8] EXCEPTION_RECORD *
; [ESP+4] return address
; [EBP] original EBP
_SEH_Entry PROC
PUSH EBP
MOV EBP,ESP
PUSH ECX
PUSH ESI
;取异常代码
MOV ESI,DWORD PTR [EBP + 8]
MOV EAX,[ESI].ExceptionCode
;只处理单步异常
CMP EAX,080000004H
JE _Step
;非单步异常则交给系统处理
XOR EAX,EAX
INC EAX
JMP _Exit
_Step:
;取单步异常发生的地址,即即将执行的下一条指令的地址
MOV ESI,DWORD PTR [EBP + 16]
MOV ESI,[ESI].C_Eip
;只处理加密代码
;EIP < SM@1 或 EIP > SM@11
LEA EAX,_SM@1
CMP ESI,EAX
JL _Exit_1
LEA EAX,_SM@11
CMP ESI,EAX
JG _Exit_0
;MessageBoxA显示一下EIP的值
PUSH 0
PUSH ESI
CALL _ShowDWORD
;获取下一条指令长
;一次只解密一条指令
LEA ESI,codeLen
ADD ESI,codeCount
XOR ECX,ECX
MOV CL,BYTE PTR [ESI]
;总共加密了10条指令,超过10则退出了
INC codeCount
CMP codeCount,10
JG _Exit_0
;循环解密指令
MOV ESI,DWORD PTR [EBP + 16]
MOV ESI,[ESI].C_Eip
_Loop1:
XOR BYTE PTR [ESI],055H
INC ESI
LOOP _Loop1
;继续将单步标志置1,下下条指令将继续触发单步异常
_Exit_1:
MOV ESI,DWORD PTR [EBP + 16]
OR [ESI].C_EFlags,0100H
_Exit_0:
;告诉系统,异常已修复,可以继续执行
XOR EAX,EAX
;INC EAX
_Exit:
POP ESI
POP ECX
MOV ESP,EBP
POP EBP
RET
_SEH_Entry ENDP
_ShowDWORD PROC
PUSH EBP
MOV EBP,ESP
SUB ESP,12
PUSH EAX
PUSH ECX
PUSH EDI
PUSHF
STD
MOV EDI,EBP
DEC EDI
MOV AL,0
STOSB
MOV AL,'H'
STOSB
MOV EAX,DWORD PTR [EBP+8]
MOV ECX,8
_Hex2Ascii:
PUSH EAX
AND AL,0FH
ADD AL,030H
CMP AL,039H
JLE _IsNumber
ADD AL,7
_IsNumber:
STOSB
POP EAX
SHR EAX,4
LOOP _Hex2Ascii
MOV AL,'X'
STOSB
MOV AL,'0'
STOSB
INC EDI
CLD
PUSH 0
PUSH 0
PUSH EDI
PUSH 0
CALL MessageBoxA
POPF
POP EDI
POP ECX
POP EAX
ADD ESP,12
MOV ESP,EBP
POP EBP
RET 8
_ShowDWORD ENDP
len0 = OFFSET _SM@11 - OFFSET _SM@1
len1 = OFFSET _SM@2 - OFFSET _SM@1
len2 = OFFSET _SM@3 - OFFSET _SM@2
len3 = OFFSET _SM@4 - OFFSET _SM@3
len4 = OFFSET _SM@5 - OFFSET _SM@4
len5 = OFFSET _SM@6 - OFFSET _SM@5
len6 = OFFSET _SM@7 - OFFSET _SM@6
len7 = OFFSET _SM@8 - OFFSET _SM@7
len8 = OFFSET _SM@9 - OFFSET _SM@8
len9 = OFFSET _SM@10 - OFFSET _SM@9
len10 = OFFSET _SM@11 - OFFSET _SM@10
DB 'xieglt',0
codeCount DD 0
codeLen DB len1,len2,len3,len4,len5,len6,len7,len8,len9,len10
END _Start