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

📄 prot.asm

📁 一个简单的软件加壳程序
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	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 + -