📄 jacket.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 + -