;frame.asm
; #########################################################################
.386 .model flat , stdcall option casemap :none ; case sensitive
; #########################################################################
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; proto directive can specifier a function type ; but must implement this function use divrective 'proc' ; and 'proc' directive will insert some instructions in your code ; and these instructions are not seen in list file !! ; these code is like below , ; lines start with ;;;; is assembler auto inserted instructions ; fun proc x:dword ;;;; push ebp ;;;; mov ebp , esp ; ; ...... ; your function body ... ; .... ; ;;;; pop ebp ; fun endp
; in api call , this is not alowed , must a direct no condition jump ; to transfer control to api function , code should like below: ; ; fun: ; jmp DWORD PTR [xxxx] ; [xxxx] store the address of the api function ;
; because these codes will be used in any different address ; can not use absolute address to addressing data ; in my code , I use IRA (instruction relative address) to every ; gloable variant and API function's address ; this behavior is defined as a macro 'ldira' (LoaD IRA) ; you can see the macro below , thus , in my api fun , ; this call like this: ; ; fun: ; ldira eax , xxxx ; jmp DWORD PTR [eax] ; ; after expand macro ldira , the code is : ; ; fun: ; call LL ; LL: ; pop eax ; add eax , xxxx - LL ; jmp DWORD PTR [eax] ; ; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc
; a void directive myaddr equ
; ------------------------------------------------------------------ ; macro for put IRA of _ira to _dst ; ------------------------------------------------------------------ ldira macro _dst , _ira local LL call LL LL: pop _dst add _dst , myaddr _ira - myaddr LL endm
; ------------------------------------------------------------------ ; macro for making STDCALL procedure and API calls. ; ------------------------------------------------------------------
Scall MACRO fun_name:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12, \ p13,p14,p15,p16,p17,p18,p19,p20,p21,p22
;; --------------------------------------- ;; loop through arguments backwards, push ;; NON blank ones and call the function. ;; ---------------------------------------
FOR arg,<p22,p21,p20,p19,p18,p17,p16,p15,p14,p13,\ p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1> IFNB <arg> ;; If not blank push arg ;; push parameter ENDIF ENDM
call fun_name ;; call the procedure
ENDM
Section_Start equ 0 ;1000h ;( 1000h - myaddr start )
MyShieldHeader struc ShieldEntry DD myaddr start - myaddr _TEXT ShieldImportAddress DD myaddr Start_Import_Table - start + Section_Start ShieldImportSize DD myaddr End_Import_Table - myaddr Start_Import_Table
ClientEntry DD myaddr NoClientProgram@@ ClientImportAddress DD ? ClientImportSize DD ?
ClientCodeBase DD ? ; need not store , but I reserve it ClientDataBase DD ?
Authentication DB 32 dup(?) ; 256 bit Authentication Number MyShieldHeader ends
_TEXT segment public 'code' org 0 start: jmp EntryPoint
org start + 10h
WangBaTitle label byte db "Íõ°Ëµ°£¡£¡ÏëÆÆ½â£¿£¿" db 0
WangBaMsg label byte db "Íõ°Ëµ°£¡£¡ÏëÆÆ½â£¿£¿" , 0DH , 0AH db "ÔÙÐÞÁ¶¼¸Äê°É£¡£¡" , 0DH , 0AH db 08h,"ºÇºÇ£¡£¡" , 0DH , 0AH db 08h,"ÒѾ´ÓÊýѧÉÏÖ¤Ã÷ÁËÕâ¸öÈí¼þ" , 0DH , 0AH db 08h,"ÔÚÓîÖæÃðÍö֮ǰÊDz»¿ÉÆÆ½âµÄ£¡£¡" , 0DH , 0AH db 0
org start + 100h
shieldHeader MyShieldHeader < > ; here stores MyshieldHeader
org start + 200h
EntryPoint:
; #################################################################################### ;;;; start of user code
ifdef _MORE_DEBUG jmp L1
szDlgTitle db 'Hello World',0 szMsg db 'Hello World',0
szDlgTitleIRA DB 'Addressing by instruction relative address',0 szMsgIRA DB 'Addressing by instruction relative address',0dh,0ah,0
L1: ldira eax , szDlgTitleIRA ldira ecx , szMsgIRA
push MB_OK ;;;invoke iraMessageBoxA , 0 , eax , ecx , MB_OK push ecx push eax push 0 call near ptr iraMessageBoxA@16
ldira eax , WangBaMsg ldira ecx , WangBaTitle Scall iraMessageBoxA@16,NULL,eax,ecx,MB_OKCANCEL endif
; ################################################################################### ; |||| ; |||| <----- Á÷³Ì˳ÐòÍùÏ£¬ÎÞÌø×ª ; \ / ; ¡Å ; ################################################################################### ; call shield function in C++ source , because shield main and user function it calls ; are in C++ source , it can be very complexcomplex ; extrn _ShieldMain@0:near call _ShieldMain@0 ; ShildMain has no parameters
; ###################################################################################
; |||| ; |||| <----- Á÷³Ì˳ÐòÍùÏ£¬ÎÞÌø×ª ; \ / ; ¡Å
; ################################################################################### ; Load Client Import Functions
Scall _LoadClientImport@0 ; ###################################################################################
; |||| ; |||| <----- Á÷³Ì˳ÐòÍùÏ£¬ÎÞÌø×ª ; \ / ; ¡Å
; ################################################################################### ; jump to the client entry point
ldira ecx , shieldHeader.ClientEntry Scall iraGetModuleHandleA@4 , NULL ; self module handle put to eax add DWORD PTR [ecx] , eax ; now [ecx] hold the current client entry point jmp DWORD PTR [ECX]
; ###################################################################################
; ################################################################################### ;;; user code compiled form C++ is int this file ;;; ¿ªÊ¼Ê±Îªµ÷ÊÔÓã¬ÏÖÔÚÕâ¸ö include ÒÑÎÞÓ㬠;;; ½«ÔÚ¡°!¿Ç!Ö÷³ÌÐò¡±Öаüº¬±¾Îļþ¡ª¡ª frame.asm , ;;; ¿ÉÓÃÓÚ¶à¸ö¡°!¿Ç!Ö÷³ÌÐò¡±£¬Éú³É¶à¸ö¿Ç
; include shield.asm
;;; End of user code ; ###################################################################################
; ################################################################################### ; only used when no client , if client is present , ; execute can not reach here
NoClientProgram@@: ldira eax , szMsgNoClient ldira ecx , szTitleNoClient Scall iraMessageBoxA@16 , NULL , eax , ecx , MB_OK
push 0 call near ptr iraExitProcess@4
szTitleNoClient db 'Have no Client Program!' db 0 szMsgNoClient db 'Have no Client Program!',0dh,0ah db 'Shield Terminate!!' db 0
; ###################################################################################
; ################################################################################### ; This is a function , it convert an address to an IRV , only used in C++ Source ; This function is efficient and perfect ! It Optimized the stack structure ; have only one parameter , this parameter is the address to be converted A2IRA@4: call A2IRA@4LL A2IRA@4LL: pop eax sub eax , A2IRA@4LL add eax , DWORD PTR [esp+4] ; the parameter ret 4
; this function return the shield header , ; can only use in shield MODULE , can not use in other MODULE , such as "merge" MODULE GetShieldHeader@0: ldira eax , shieldHeader ret 0 ; #############################################################################
_TEXT ENDS
; ############################################################################# ; Import Table Related contents are in this file
include ShieldImport.asm ; this file only contain one function named "LoadClientImport" and have no paramters ; because this function is hard coding with assembly , so i code it with C and ; compile it to assembly include LoadClientImport.asm ; #############################################################################
END start

|