📄 prot.asm
字号:
mov ReadBuffer,0
invoke SetFilePointer, hFile, eax, NULL, FILE_BEGIN
invoke ReadFile, hFile, ADDR ReadBuffer, 2, ADDR NumberOfBytesRW, NULL
mov eax,ReadBuffer
test ax,2000h
jnz FileMaybeDll
invoke AddLine,ADDR M_FileIsPeExe
invoke CloseHandle,hFile
pop esi
xor eax,eax
inc eax
ret
OpenFileErr:
invoke AddLine,ADDR M_FileOpenErr
pop esi
xor eax,eax
ret
FileIsNotExe:
invoke AddLine,ADDR M_FileIsNotExe
pop esi
xor eax,eax
ret
FileIsNotPe:
invoke AddLine,ADDR M_FileIsNotPe
pop esi
xor eax,eax
ret
FileMaybeDll:
invoke AddLine,ADDR M_FileMaybeDll
pop esi
xor eax,eax
ret
FileIsExe ENDP
;*************************压缩保护文件****************************
ProtTheFile PROC
LOCAL ReadBuffer :DWORD
LOCAL NumberOfBytesRW :DWORD
pushad
.if IsCreateBak==1h
invoke CreateBakFile,ADDR FileName
.if eax!=0
invoke AddLine,ADDR M_MakeBakRight
.else
invoke AddLine,ADDR M_MakeBakWrong
.endif
.endif
invoke CreateFile,ADDR FileName, GENERIC_READ+GENERIC_WRITE, FILE_SHARE_READ+FILE_SHARE_WRITE,0, 3, FILE_ATTRIBUTE_NORMAL,NULL
cmp eax,INVALID_HANDLE_VALUE
jz OpenFileErr2
mov hFile,eax
mov ReadBuffer,0
invoke SetFilePointer, hFile, 3ch, NULL, FILE_BEGIN
invoke ReadFile, hFile, ADDR ReadBuffer, 4, ADDR NumberOfBytesRW, NULL
mov eax,ReadBuffer
mov esi,eax
;**********取文件映象大小,申请内存
add eax,50h
invoke SetFilePointer, hFile, eax, NULL, FILE_BEGIN
invoke ReadFile, hFile, ADDR PeImageSize, 4, ADDR NumberOfBytesRW, NULL
invoke VirtualAlloc, NULL, PeImageSize, MEM_COMMIT, PAGE_READWRITE
test eax,eax
jz VirtualAllocErr
mov MapOfFile, eax
;**********取PE头大小,读入PE头
mov eax,esi
add eax,54h
invoke SetFilePointer, hFile, eax, NULL, FILE_BEGIN
invoke ReadFile, hFile, ADDR ReadBuffer, 4, ADDR NumberOfBytesRW, NULL
invoke SetFilePointer, hFile, 0, NULL, FILE_BEGIN
invoke ReadFile, hFile, MapOfFile, ReadBuffer, ADDR NumberOfBytesRW, NULL
;**************
mov eax,MapOfFile
add eax,esi
mov PeHeadBase,eax
;**********取PE文件的一些信息
mov edi,PeHeadBase
assume edi : ptr IMAGE_NT_HEADERS
mov eax,dword ptr [edi].OptionalHeader.ImageBase
mov PeImageBase,eax
;**********读入各个区块,并对区块资料取整****
mov edi,PeHeadBase
assume edi : ptr IMAGE_NT_HEADERS
mov eax,dword ptr [edi].OptionalHeader.FileAlignment
mov FileAlignment,eax
.if IsFileAlignment200 == 1
mov FileAlignment,200h
mov dword ptr [edi].OptionalHeader.FileAlignment,200h
.endif
mov eax,dword ptr [edi].OptionalHeader.SectionAlignment
mov SectionAlignment,eax
movzx ecx,word ptr [edi].FileHeader.NumberOfSections
movzx esi,word ptr [edi].FileHeader.SizeOfOptionalHeader
add esi,edi
add esi,18h
mov SecTableBase,esi
LoadSections:
push ecx
mov eax,dword ptr [esi+14h] ;区块文件偏移
invoke SetFilePointer, hFile, eax, NULL, FILE_BEGIN
mov ecx,dword ptr [esi+0ch] ;区块映象偏移
add ecx,MapOfFile
mov ebx,dword ptr [esi+10h] ;区块文件大小
invoke ReadFile, hFile, ecx, ebx, ADDR NumberOfBytesRW, NULL
mov ebx,dword ptr [esi+08h] ;区块映象大小
invoke GetIntegral,ebx,SectionAlignment
mov dword ptr [esi+08h],eax
add esi,28h
pop ecx
loop LoadSections
invoke AddLine,ADDR M_ReadFileOK
invoke GetIntegral,PeImageSize,SectionAlignment
mov PeImageSize,eax
mov dword ptr [edi].OptionalHeader.SizeOfImage,eax
;************保留额外数据吗?
mov eax,IsSaveSData
.if eax == 1
invoke GetFileSize, hFile, 0
sub esi,28h
sub eax,dword ptr [esi+14h]
sub eax,dword ptr [esi+10h]
.if eax != 0
cdq
.if edx == 0
mov edi,eax
invoke VirtualAlloc, NULL, edi, MEM_COMMIT, PAGE_READWRITE
mov MapOfSData,eax
invoke ReadFile, hFile, MapOfSData, edi, ADDR NumberOfBytesRW, NULL
mov eax,NumberOfBytesRW
mov MapOfSDataUsed,eax
invoke AddLine,ADDR M_SaveSDataOK
.else
invoke AddLine,ADDR M_HaveNoSData
.endif
.else
invoke AddLine,ADDR M_HaveNoSData
.endif
.endif
invoke CloseHandle,hFile
;***********去处重定位数据*********
.if IsNoRelocation == 1
invoke ClsRelocation
.endif
;***********特殊代码加密***********
.if IsCodeProt==1
invoke VirtualAlloc, NULL, 5000h, MEM_COMMIT, PAGE_READWRITE
.if eax==0
jmp VirtualAllocErr
.endif
mov MapOfCodeProt,eax
invoke ProtCode
add eax,8h
mov MapOfCodeProtUsed,eax ;最后加一段空白,以示结束
invoke AddLine,ADDR M_CodeProtIsOver
.endif
;************输入表加密***********
.if IsProtImpTable==1
invoke VirtualAlloc, NULL, 0a000h, MEM_COMMIT, PAGE_READWRITE
.if eax==0
jmp VirtualAllocErr
.endif
mov MapOfImpProt,eax
invoke MoveImpTable
mov MapOfImpProtUsed,eax
invoke ClsImpTable
invoke AddLine,ADDR M_ImpTableProtIsOver
.endif
;***********压缩资源******************
.if IsPackRes ==1
invoke FindFirstResADDR
mov FirstResADDR,eax ;最前面的资源的存放偏移
invoke VirtualAlloc, NULL, 5000h, MEM_COMMIT, PAGE_READWRITE
.if eax==0
jmp VirtualAllocErr
.endif
mov MapOfPackRes,eax
mov MapOfPackResUsed,0h
invoke MoveRes,3h,MapOfPackRes,MapOfPackResUsed
mov MapOfPackResUsed,eax
invoke MoveRes,0eh,MapOfPackRes,MapOfPackResUsed
mov MapOfPackResUsed,eax
invoke MoveRes,10h,MapOfPackRes,MapOfPackResUsed
mov MapOfPackResUsed,eax
invoke AddLine,ADDR M_PackResIsOver
.endif
;***********合并区段**********
.if IsMergeSection ==1
invoke MergeSection
invoke AddLine,ADDR M_MergeSectionIsOver
.endif
;***********压缩***************
invoke VirtualAlloc, NULL, 100000h, MEM_COMMIT, PAGE_READWRITE
.if eax==0
jmp VirtualAllocErr
.endif
mov lpPackBuffer,eax
invoke CreateFile,ADDR FileName, GENERIC_READ+GENERIC_WRITE, FILE_SHARE_READ+FILE_SHARE_WRITE,0,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL
mov hFile,eax
;因为还要压缩写入外壳部分和重写文件头,所以上面两个函数不放在PackFile里
invoke PackFile
;*************处理外壳并写入******
invoke VirtualAlloc, NULL, 20000h, MEM_COMMIT, PAGE_READWRITE
.if eax==0
jmp VirtualAllocErr
.endif
mov MapOfShell,eax
invoke DisposeShell
mov MapOfShellUsed,eax
push eax
mov ebx,esp
invoke WriteFile, hFile,MapOfShell ,MapOfShellUsed,ebx, NULL
add esp,4h
;*******清空段名吗?*****************
.if IsClsSecName == 1
invoke ClsSectionName
.endif
;***********重写文件头**************
invoke SetFilePointer, hFile, 0h, NULL, FILE_BEGIN
mov esi,PeHeadBase
assume esi : ptr IMAGE_NT_HEADERS
mov ebx,PeHeadSize
invoke WriteFile, hFile,MapOfFile ,ebx,ADDR NumberOfBytesRW, NULL
;***********写入额外代码************
invoke SetFilePointer, hFile, 0h, NULL, FILE_END
invoke WriteFile, hFile,MapOfSData,MapOfSDataUsed,ADDR NumberOfBytesRW, NULL
;***********加密完成,清理***********
invoke CloseHandle,hFile
invoke VirtualFree, lpPackBuffer, 0, MEM_RELEASE ;释放压缩缓冲
invoke VirtualFree, MapOfFile, 0, MEM_RELEASE
.if MapOfCodeProt != 0
invoke VirtualFree, MapOfCodeProt, 0, MEM_RELEASE
.endif
.if MapOfImpProt != 0
invoke VirtualFree, MapOfImpProt, 0, MEM_RELEASE
.endif
.if MapOfPackRes != 0
invoke VirtualFree, MapOfPackRes, 0, MEM_RELEASE
.endif
.if MapOfSData != 0
invoke VirtualFree, MapOfSData, 0, MEM_RELEASE
.endif
lea edi,hFile
mov ecx,FileDataEnd-hFile
xor eax,eax
rep stosb
popad
ret
OpenFileErr2:
invoke AddLine,ADDR M_FileOpenErr
popad
xor eax,eax
ret
VirtualAllocErr:
invoke AddLine,ADDR M_VirtualAllocErr
popad
xor eax,eax
ret
ProtTheFile ENDP
;*****************创建备份文件*******************************
CreateBakFile PROC SourceFileNameADDR:DWORD
;将SourceFileNameADDR指向的字符串的文件创建一个加后缀'BAK'的备份文件
;返回eax的值表示创建成功与否.
LOCAL BakFileNameADDR:DWORD
push edi
push esi
invoke VirtualAlloc, NULL, 1000h, MEM_COMMIT, PAGE_READWRITE
mov BakFileNameADDR,eax
mov edi,eax
mov esi,SourceFileNameADDR
invoke MoveString,esi,edi
add edi,eax
mov dword ptr [edi],'kab.' ;于原文件名加后缀.bak
invoke CopyFile, SourceFileNameADDR , BakFileNameADDR ,0
push eax
invoke VirtualFree, BakFileNameADDR, 0, MEM_RELEASE
pop eax
pop esi
pop edi
ret
CreateBakFile endp
;***************特殊代码加密部分*****************************
ProtCode PROC
;将调用原输入表的CALL [????]和JMP [????]统一改为CALL ????,
;????指向外壳申请的地址空间的一段代码,由这段代码根据CALL的返回
;地址与原地址记录相比较后找出真正该使用的输入表项,再指向它运行
;加密后的数据结构为" 返回地址:DWORD,原输入表项地址:DWORD "
;为了区别原来的CALL [????]和JMP [????],将原来CALL [????]的返回
;地址的最高位置1作为标记.
LOCAL CodeSectionBase:DWORD
LOCAL CodeSectionSize:DWORD
LOCAL CodeProtSize:DWORD
mov CodeProtSize,0
mov CodeSectionSize,0
mov CodeSectionBase,0
mov edi,PeHeadBase
assume edi : ptr IMAGE_NT_HEADERS
;*********取代码段参数**
mov eax,SecTableBase
mov ebx,dword ptr [eax+8h]
mov CodeSectionSize,ebx
mov ebx,dword ptr [eax+0ch]
add ebx,MapOfFile
mov CodeSectionBase,ebx
;*********取输入表地址***
mov edi,dword ptr [edi].OptionalHeader.DataDirectory[SIZEOF IMAGE_DATA_DIRECTORY].VirtualAddress
add edi,MapOfFile
;************************
ProtNextDllCode:
mov eax,dword ptr [edi+0ch]
.if eax != 0
mov esi,dword ptr [edi+10h]
ProtNextFuncCode:
mov edx,esi
add edx,PeImageBase ;call [edx] or Jmp [edx]
;***********
mov eax,esi
add eax,MapOfFile
mov eax,dword ptr [eax]
;**********
.if eax!=0
push esi
mov esi,CodeSectionBase ;查找起点
mov ecx,CodeSectionSize
sub ecx,3h ;查找范围
SearchNextCall:
mov eax,dword ptr [esi]
.if eax == edx
push edi
mov edi,MapOfCodeProt
add edi,CodeProtSize
lea eax,[esi+4h]
sub eax,MapOfFile
add eax,PeImageBase
push eax ;加密后CALL的返回地址
mov ax,word ptr [esi-2]
.if ax == 15ffh
pop eax
mov dword ptr [edi],eax
mov dword ptr [edi+4h],edx
mov word ptr [esi-2h],0e890h
mov dword ptr [esi],0h ;将原来的CALL [XXXX]和
add CodeProtSize,8h ;JMP [XXXX]统一改为:
.elseif ax == 25ffh ;NOP
pop eax ;CALL XXXX
or eax,80000000h ;原来jmp [xxxx]做一标记
mov dword ptr [edi],eax
mov dword ptr [edi+4h],edx
mov word ptr [esi-2h],0e890h
mov dword ptr [esi],0h
add CodeProtSize,8h
.else
pop eax
.endif
pop edi
.endif
inc esi
loop SearchNextCall
pop esi
.else
jmp AllFuncCodeIsProt
.endif
add esi,4h
jmp ProtNextFuncCode
AllFuncCodeIsProt:
.else
jmp AllDllCodeProt
.endif
add edi,14h
jmp ProtNextDllCode
AllDllCodeProt:
mov eax,CodeProtSize
ret
ProtCode endp
;***************输入表加密部分************************
MoveImpTable PROC
;将一个程序的输入表的所有换种结构方式存储,以达到加密的目的.
;返回eax的值为加密生成数据的大小.
mov edx,PeHeadBase
assume edx : ptr IMAGE_NT_HEADERS
mov edx,dword ptr [edx].OptionalHeader.DataDirectory[SIZEOF IMAGE_DATA_DIRECTORY].VirtualAddress
add edx,MapOfFile ;输入表地址
mov edi,MapOfImpProt
mov eax,dword ptr [edx+10h]
.while eax!=0
mov dword ptr [edi],eax
add edi,4h
inc edi ;空一个字节,放后面dllname字符串的长度
mov esi,dword ptr [edx+0ch]
add esi,MapOfFile
invoke MoveString,esi,edi
mov byte ptr [edi-1],al
add edi,eax
inc edi ;空一字节,作为字符串结束标记
mov ecx,edi ;[ecx]存放后续函数的数量
add edi,4h
mov esi,dword ptr [edx]
.if esi == 0
mov esi,dword ptr [edx+10h]
.endif
add esi,MapOfFile
mov eax,dword ptr [esi]
.while eax
push edx
cdq
.if edx == 0
add eax,MapOfFile
add eax,2h
inc edi
invoke MoveString,eax,edi
mov byte ptr [edi-1],al
add edi,eax
inc edi ;空一字节,作为字符串结束标记
.else
inc edi
and eax,7fffffffh
mov dword ptr [edi],eax
add edi,5h
.endif
pop edx
inc dword ptr [ecx]
add esi,4h
mov eax,dword ptr [esi]
.endw
add edx,14h
mov eax,dword ptr [edx+10h]
.endw
sub edi,MapOfImpProt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -