⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jacket.inc

📁 此为本书的配套光盘.本书结合实例
💻 INC
字号:


Protectcode MACRO
vstart:											;加入到程序里面的代码开始 
			call nstart
nstart:
			pop ebp 
			sub ebp,offset nstart
			mov    dword ptr [ebp+appBase],ebp
			mov	dword ptr [ebp+PROC_s_ebp],ebp
			
			mov    eax,[esp]                      		;返回k32地址 
			mov [ebp+p_version],eax						;后面可以用p_version来判断操作系统
			xor    edx,edx 
getK32Base: 
			dec    eax                            ;逐字节比较验证 
			mov    dx,word  ptr [eax+IMAGE_DOS_HEADER.e_lfanew]  ;就是ecx+3ch 
			test    dx,0f000h                      ;Dos Header+stub不可能太大,超过4096byte 
			jnz    getK32Base                      ;加速检验 
			cmp    eax,dword ptr [eax+edx+IMAGE_NT_HEADERS.OptionalHeader.ImageBase] 
			jnz    getK32Base                      ;看Image_Base值是否等于ecx即模块起始值, 
			mov    [ebp+k32Base],eax              ;如果是,就认为找到kernel32的Base值 
			lea    edi,[ebp+aGetModuleHandle] 
			lea    esi,[ebp+lpApiAddrs] 
lop_get: 
			lodsd 
			cmp    eax,0 							;比较是否到达lpApiAddrs的结尾了
			jz      End_Get 
			add    eax,ebp 						;得到的函数名的地址必须加上一个ebp的偏移
			push    eax 							;参数1-->函数名地址
			push    dword ptr [ebp+k32Base] 		;参数2-->kernel32的Base值
			call    GetApiA                   	;把找到的api地址存放到指定aGetModuleHandle的空间中      
			stosd 
			jmp    lop_get
      
End_Get:
			mov eax,[ebp+p_version]
			test eax,eax
			js _9x	;判断操作系统
		
ExitProc:
			cmp dwShellExecute[ebp],0
			jnz NoSdk
			mov dwShellExecute[ebp],1
			mov eax,EnFunctionRva[ebp]
			cmp eax,0
			jz NoSdk
			mov eax,DeFunctionRva[ebp]
			cmp eax,0
			jz NoSdk
			
			push offset Crypt_Sdk_Data_End-offset Crypt_Sdk_Data
			push GMEM_FIXED+GMEM_ZEROINIT
			call [ebp+aGlobalAlloc]			;临时分配一片内存用于存放加密代码
			cmp eax,0
			jz NoSdk
			
			push eax
			xchg eax,edi					; eax -> mem base
			mov  esi,offset Crypt_Sdk_Data
			add  esi,ebp
			mov ecx,offset Crypt_Sdk_Data_End-offset Crypt_Sdk_Data
			rep    movsb					;拷贝到分配的内存
			pop eax							;我们的加密函数的指针
						

			push eax						;传递我们的函数指针给程序,
			mov eax,des_base[ebp]			;得到基址
			add eax,EnFunctionRva[ebp]		;基址+rva就是程序输出函数的执行点
			CALL eax						;调用程序的输出函数,把我们加密函数的指针传递过去

			push offset DeCrypt_Sdk_Data_End-offset DeCrypt_Sdk_Data
			push GMEM_FIXED+GMEM_ZEROINIT
			call [ebp+aGlobalAlloc]			;临时分配一片内存用于存放解密代码
			cmp eax,0
			jz NoSdk

			push eax
			xchg eax,edi					; ebx -> mem base
			mov  esi,offset DeCrypt_Sdk_Data
			add  esi,ebp
			mov ecx,offset DeCrypt_Sdk_Data_End-offset DeCrypt_Sdk_Data
			rep    movsb					;拷贝到分配的内存
			pop eax							;我们的解密函数指针
						

			push eax						;传递我们的函数指针给程序
			mov eax,des_base[ebp]			;得到基址
			add eax,DeFunctionRva[ebp]		;基址+rva就是程序输出函数的执行点
			CALL eax						;调用程序的输出函数,把我们解密函数的指针传递过去

NoSdk:
			mov eax,des_base[ebp]			;查找结束
			add eax,des_in[ebp]
			
			
PSkipDecryptSec:
			push eax
			ret								;返回原程序入口

_9x:
	
			jmp     ExitProc

K32_api_retrieve        proc    Base:DWORD ,sApi:DWORD 

			push    edx                    ;保存edx     
			xor    eax,eax                ;此时esi=sApi 
Next_Api:                              ;edi=AddressOfNames 
			mov    esi,sApi 
			xor    edx,edx 
			dec    edx 
Match_Api_name: 
			movzx  ebx,byte  ptr [esi] 
			inc    esi 
			cmp    ebx,0 
			je      foundit 

			inc    edx 
			
			push    eax 
			mov    eax,[edi+eax*4]        ;AddressOfNames的指针,递增 
			add    eax,Base                ;注意是RVA,一定要加Base值 
			cmp    bl,byte  ptr [eax+edx]  ;逐字符比较   
			pop    eax 
			je      Match_Api_name          ;继续搜寻 
			inc    eax                    ;不匹配,下一个api 
			loop    Next_Api 
no_exist: 
			pop    edx                    ;若全部搜完,即未存在 
			xor    eax,eax 
			ret 
                               
foundit: 
			pop    edx                    ;edx=AddressOfNameOrdinals 
			                        ;*2得到AddressOfNameOrdinals的指针 
			movzx  eax,word  ptr [edx+eax*2] ;eax返回指向AddressOfFunctions的指针 
			ret 
K32_api_retrieve        endp 

;---------------------------------------------
;这个函数用于查找相关的api的地址
;---------------------------------------------
GetApiA        proc    Base:DWORD,sApi:DWORD 
      local    ADDRofFun:DWORD 
			pushad 
			mov    esi,Base 
			mov    eax,esi 
			mov    ebx,eax 
			mov    ecx,eax 
			mov    edx,eax 
			mov    edi,eax                            ;all is Base! 
			
			add    ecx,[ecx+3ch]                      ;现在esi=off PE_HEADER                                                                           
			
			add    esi,[ecx+78h]                      ;得到esi=IMAGE_EXPORT_DIRECTORY入口                               
			                                           
			
			add    eax,[esi+1ch]                  ;eax=AddressOfFunctions的地址 
			mov    ADDRofFun,eax 
			                                       
			mov    ecx,[esi+18h]                  ;ecx=NumberOfNames 
			
			add    edx,[esi+24h]                  ;edx=AddressOfNameOrdinals 
			
			add    edi,[esi+20h]                  ;esi=AddressOfNames 
			
			invoke    K32_api_retrieve,Base,sApi 
			
			mov    ebx,ADDRofFun 
			mov    eax,[ebx+eax*4]                ;要*4才得到偏移 
			
			add    eax,Base                        ;加上Base! 
			mov    [esp+7*4],eax                  ;eax返回api地址 
			popad 
			ret 
GetApiA        endp 

des_in dd 0 ;这里是原程序的入口地址
des_base dd 0 ;
p_version dd 0 ;用来判断操作系统的
u32                    db "User32.dll",0 
k32                    db "Kernel32.dll",0 
pSMem                    dd 0

	

appBase        dd ? ;这里是全局的偏移量
k32Base        dd ? 
;-----------------------------------------apis needed 

lpApiAddrs      label  near 
              dd      offset sGetModuleHandle 
              dd      offset sGetProcAddress 
              dd      offset sLoadLibrary 
              dd      offset sGlobalAlloc
              dd      offset sVirtualAlloc 
              dd      offset sMapViewOfFile 
              dd      offset sUnmapViewOfFile 
              dd      offset sCloseHandle 
              dd      offset sGetFileSize 
              dd      offset sSetEndOfFile 
              dd      offset sSetFilePointer 

              dd      offset sExitProcess 
               
              dd      0,0 
               

sGetModuleHandle        db "GetModuleHandleA",0 
sGetProcAddress         db "GetProcAddress",0 
sLoadLibrary            db "LoadLibraryA",0 
sGlobalAlloc			db "GlobalAlloc",0 
sVirtualAlloc      		db "VirtualAlloc",0 
sMapViewOfFile          db "MapViewOfFile",0 
sUnmapViewOfFile        db "UnmapViewOfFile",0 
sCloseHandle            db "CloseHandle",0 
sGetFileSize            db "GetFileSize",0 
sSetFilePointer         db "SetFilePointer",0 
sSetEndOfFile           db "SetEndOfFile",0 
sExitProcess            db "ExitProcess",0 


 
aGetModuleHandle                dd 0 
aGetProcAddress					dd 0 
aLoadLibrary                    dd 0 
aGlobalAlloc               		dd 0  
aVirtualAlloc             		dd 0 
aMapViewOfFile                  dd 0 
aUnmapViewOfFile                dd 0 
aCloseHandle                    dd 0 
aGetFileSize                    dd 0 
aSetFilePointer                	dd 0 
aSetEndOfFile                  	dd 0 
aExitProcess                    dd 0 



	dwShellExecute            dd 0
	PROC_s_ebp				  dd 0	;原来得ebp偏移
	EnFunctionRva				dd 0
	DeFunctionRva				dd 0


;函数名: DeCrypt_Sdk_Data
;功能:解密数据
;入口参数:无
;出口参数:无
DeCrypt_Sdk_Data:
	pushad			;保存寄存器
	mov eax,[esp+20h]	;得到加密开始标记的地址
	push eax				;保存这个地址
	add eax,2
	mov ecx,DWORD ptr [eax]  ;ecx为原来保存的加密的字节数
	pop esi				;得到解密标记地址
	add esi,0ah					 ;得到解密数据开始的地址
	DeCrypt_Next_My_Data:
	not BYTE ptr [esi]		;解密
	inc esi
	loop DeCrypt_Next_My_Data
	popad				;恢复寄存器
	ret				;返回
DeCrypt_Sdk_Data_End:

;函数名: Crypt_Sdk_Data
;功能:加密数据
;入口参数:无
;出口参数:无
Crypt_Sdk_Data:
	pushad			;保存寄存器
	mov eax,[esp+20h]	;得到加密结束标记的地址
	push eax				;保存这个地址
	add eax,2
	mov ecx,DWORD ptr [eax]  ;ecx为原来保存的加密的字节数
	pop esi				;得到加密标记地址
	sub esi,ecx					 ;得到加密数据开始的地址
	Crypt_Next_My_Data:
	not BYTE ptr [esi]		;加密
	inc esi
	loop Crypt_Next_My_Data
	popad				;恢复寄存器
	ret				;返回
Crypt_Sdk_Data_End:


vend:
ENDM

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -