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

📄 main.asm

📁 Nbw加密锁源代码,一个用汇编编写的加密锁源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
				add	esi,[esi+003ch]
				.if word ptr [esi] == IMAGE_NT_SIGNATURE
					mov	eax,edi  
					.break
				.endif
			.endif
			_PageError:
			sub	edi,010000h
			.break	.if edi < 070000000h
		.endw
;********eax指向Kernel32.dll的模块首地址
;********查找GetProcAddress的入口地址
		mov	[ebp+_hModule],eax
		lea	eax,[ebp+szGetProcAddress]
		mov	[ebp+_lpszApi],eax
		mov	eax,[ebp+_hModule]
		pushad			
		mov	[ebp+@dwReturn],0
;********计算函数名称的长度
		mov	edi,[ebp+_lpszApi]
		mov	ecx,-1
		xor	al,al
		cld
		repnz	scasb
		mov	ecx,edi
		sub	ecx,[ebp+_lpszApi]
		mov	[ebp+@dwStringLength],ecx
;********计算函数名称的长度
		mov	esi,[ebp+_hModule]
		add	esi,[esi + 3ch]
		assume	esi:ptr IMAGE_NT_HEADERS
		mov	esi,[esi].OptionalHeader.DataDirectory.VirtualAddress
		add	esi,[ebp+_hModule]
		assume	esi:ptr IMAGE_EXPORT_DIRECTORY
		mov	ebx,[esi].AddressOfNames
		add	ebx,[ebp+_hModule]
		xor	edx,edx
		.repeat
			push	esi
			mov	edi,[ebx]
			add	edi,[ebp+_hModule]	;这里edi指向的是Kernel32的到处表中的函数名,可以动态调试看一下,增强对导出表的认识
			mov	esi,[ebp+_lpszApi]
			mov	ecx,[ebp+@dwStringLength]
			repz	cmpsb		;比较[edi]和[esi]的字符串,长度是ecx
			.if	ZERO?
				pop	esi
				jmp	@F
			.endif
			pop	esi
			add	ebx,4
			inc	edx
		.until	edx >=	[esi].NumberOfNames
		jmp	_Error
@@:
		sub	ebx,[esi].AddressOfNames
		sub	ebx,[ebp+_hModule]
		shr	ebx,1
		add	ebx,[esi].AddressOfNameOrdinals
		add	ebx,[ebp+_hModule]
		movzx	eax,word ptr [ebx]
		shl	eax,2
		add	eax,[esi].AddressOfFunctions
		add	eax,[ebp+_hModule]
		mov	eax,[eax]
		add	eax,[ebp+_hModule]
		mov	[ebp+@dwReturn],eax		;保存GetProcAddress的入口地址
		assume	esi:nothing		;取消对esi的定义,很容易忽略
		popad
		mov	eax,[ebp+@dwReturn]
;*******通过动态连接库的导出表查找函数的入口地址
_goon:
		mov	[ebp+_GetProcAddress],eax
		lea	eax,[ebp+szLoadLibrary]	;获取LoadLibrary入口
		push	eax
		push	[ebp+_hModule]
		call	[ebp+_GetProcAddress]				
		mov	[ebp+_LoadLibrary],eax
		lea	eax,[ebp+szCounter]	;获取Counter.dll基址
		invoke	[ebp+_LoadLibrary],eax
		mov	[ebp+hDllCounter],eax
		lea	eax,[ebp+szInitialize]	;获取Initialize入口
		invoke	[ebp+_GetProcAddress],[ebp+hDllCounter],eax
		mov	[ebp+_Initialize],eax
		invoke	[ebp+_Initialize],[ebp+return],addr [ebp+password]
		test	eax,eax
		jnz	_Error
		ret
_Error:
;		jmp	[ebp+return]	;返回程序原来的入口,return变量已经在前面被写入了.在程序中我没有采取这种方法,而是由counter.dll来执行这个命令.
		ret
VEnd		equ	this byte
_exit:
		ret
_ChangeFile	endp
;****************************************************************
_Repair		proc	hwnd		;把被需要解锁的文件中的密码和oep去掉.
		LOCAL   hFile    : DWORD
		push	eax
		invoke	CreateFile,addr szFileName,GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ + \
			FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
		.if	eax ==	INVALID_HANDLE_VALUE
			invoke	MessageBox,hwnd,addr szErr1,NULL,MB_OK or MB_ICONWARNING
			jmp	_exit
		.endif
		mov	hFile,eax
		xor	eax,eax
		sub	eax,0CH
		invoke	SetFilePointer,hFile,eax,NULL,FILE_END
		invoke	SetEndOfFile,hFile
		push    hFile
		call    CloseHandle
_exit:
		pop	eax
		ret
_Repair		endp
;****************************************************************
;下面是给加锁文件进行解锁
;文件打开部分完全照搬上面的函数.
_ReChangeFile	proc	hwnd
		LOCAL   hFile    : DWORD
		LOCAL   hMapping : DWORD
		LOCAL   pMapping : DWORD
		LOCAL   ByteWrite: DWORD
		LOCAL	HostEntry: DWORD
		pushad
		invoke	CreateFile,addr szFileName,GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ + \
			FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
		.if	eax ==	INVALID_HANDLE_VALUE
			invoke	MessageBox,hwnd,addr szErr1,NULL,MB_OK or MB_ICONWARNING
			jmp	_exit
		.endif
		mov	hFile,eax
		invoke	CreateFileMapping,hFile,NULL,PAGE_READWRITE,0,0,NULL
		or	eax,eax
		jz	IF_F3
		mov	hMapping , eax 
		xor	edi,edi
		push	edi              
		push	edi
		push	edi                  
		push	FILE_MAP_READ+FILE_MAP_WRITE 
		push	hMapping
		call	MapViewOfFile
		or	eax,eax
		jnz	@F
		invoke	MessageBox,hwnd,addr szErr2,NULL,MB_OK or MB_ICONWARNING
		jmp	IF_F2
@@:
		mov	pMapping,eax  
		mov	esi,eax 
		assume	esi:ptr IMAGE_DOS_HEADER 	
		cmp	[esi].e_magic,IMAGE_DOS_SIGNATURE
		jnz	IF_F1
		cmp	[esi].e_lfarlc,040h  
		jnz	IF_F1
		add	esi,[esi].e_lfanew
		assume	esi:ptr IMAGE_NT_HEADERS
		cmp	[esi].Signature,IMAGE_NT_SIGNATURE    ;是PE文件吗?
		jnz	IF_F1
		cmp	[esi].OptionalHeader.Subsystem,2
		jnz	IF_F1           
		cmp	[esi].OptionalHeader.CheckSum,0	;判断文件校验和
		jnz	IF_F1                    ;合法性判断完毕,开始修改文件
		movzx	eax,[esi].FileHeader.NumberOfSections         
		mov	ecx,sizeof IMAGE_SECTION_HEADER 
		mul	ecx			;计算所有节表的长度
		add	eax,sizeof IMAGE_NT_HEADERS                
		add	eax,esi		
;******************
;令eax指向文件最后一个节表,并判断节表名称是不是77626e2e(即.nbw)
		sub	eax,sizeof  IMAGE_SECTION_HEADER 
		push	eax
		mov	eax,[eax]
		cmp	eax,77626e2eh 
		pop	eax
		jz	@F
		invoke	MessageBox,hwnd,addr szErr6,NULL,MB_OK or MB_ICONWARNING
		jmp	IF_F1
@@:
;******************
		mov	edi,eax			;edi指向文件头的尾部
		assume	edi:ptr IMAGE_SECTION_HEADER         
		mov	eax,[edi].Misc.VirtualSize 
		push	eax			;保存节区大小

		mov	ecx,[esi].OptionalHeader.SectionAlignment 
		div	ecx 
		inc	eax 
		mul	ecx 
		sub	[esi].OptionalHeader.SizeOfImage,eax      ;文件NT头修改

		push	FILE_BEGIN
		push    0 
		push    [edi].PointerToRawData
		push    hFile
		call    SetFilePointer		;重新把文件指针指到新节的开始,把程序原来的入口地址写入新节中的return变量处
		invoke	ReadFile,hFile,addr HostEntry,4,addr ByteWrite,NULL
		invoke	ReadFile,hFile,addr _pass1,8,addr ByteWrite,NULL	;读入密码
										;这里2次读取数据导致最后无法把这2个部分切除.
										;因此本过程后面调用_Repair函数来解决这个问题
		invoke	GetDlgItemText,hwnd,IDC_PASS1,addr _pass2,8
		invoke	lstrcmp, addr _pass1, addr _pass2			;比较用户输入的解锁密码和文件中的密码是否一样.这里没有用到text2
		.if	eax != 0		;两次密码如果不相同便进行处理		
			invoke	MessageBox,hwnd,addr szErrCheck,NULL,MB_OK or MB_ICONWARNING
			pop	eax
			jmp	IF_F1
		.endif
		lea	eax, HostEntry
		mov	eax,[eax]
		mov	ebx, [esi].OptionalHeader.ImageBase
		sub	eax,ebx
		push	eax
		pop	[esi].OptionalHeader.AddressOfEntryPoint     ;修改文件eop完毕
		dec	[esi].FileHeader.NumberOfSections                      
		xor	eax,eax
		mov	dword ptr[edi],eax         ;把原来的".nbw"节表名称去掉
		mov	[edi].Misc.VirtualSize,eax        ;填写要添加的代码的长度
		mov	[edi].VirtualAddress,eax		
		mov	[edi].SizeOfRawData,eax
		mov	[edi].PointerToRawData,eax
		mov	[edi].Characteristics,eax	;把.nbw节表的一些属性都去掉,一般来说这些东西不删除也不影响程序的正确性
							;但是别人看到这里不是0可能以为这里是有用信息而影响其工作.	

		pop	eax			;重新获取节区大小,请看上面的那个push	eax
		mov	ecx,eax
		sub	eax,ecx
		sub	eax,ecx			;求eax的相反数
		push	FILE_END
		push    eax
		push    [edi].PointerToRawData
		push    hFile
		call    SetFilePointer		;重新把文件指针指到新节的开始,把程序原来的入口地址写入新节中的return变量处
						;用getfilesize找到函数大小再减去解表一样可以定位到.nbw街区,但我感觉这样不用api函数效率更高些
		invoke	SetEndOfFile,hFile	;把.nbw节区截去	
		invoke	SetWindowText,hWinEdit,addr szzz
;*****************************************
;更新文件头,使新节可以正确加载并首先执行 
IF_F1:
		assume	edi:nothing
		assume	esi:nothing
		push    pMapping
		call    UnmapViewOfFile
IF_F2: 
		push    hMapping
		call    CloseHandle
IF_F3:
		push    hFile
		call    CloseHandle
IF_Exit:
		popad
_exit:
		invoke	_Repair,hwnd
		ret
_ReChangeFile	endp
;****************************************************************
;****************************************************************
_ProcDlgMain	proc	uses ebx edi esi hWnd,wMsg,wParam,lParam 
		mov	eax,wMsg
		.if	eax == WM_CLOSE
			invoke	EndDialog,hWnd,NULL
			.elseif	eax == WM_INITDIALOG
				push	hWnd
				pop	hWinMain
				call	_Init
			.elseif	eax == WM_COMMAND
				mov	eax,wParam
				.if	ax ==	IDM_OPEN
					invoke	_OpenFileA,hWnd
				.elseif	ax ==	IDM_EXIT
					invoke	EndDialog,hWnd,NULL
				.elseif	ax==	IDC_BROWSE
					invoke	_OpenFileA,hWnd
				.elseif	ax==	IDC_UNCHAN
						invoke	_ReChangeFile,hWnd
				.elseif	ax==	IDC_CHANGE
					invoke	GetDlgItemText,hWnd,IDC_PASS1,addr _pass1,32
					invoke	GetDlgItemText,hWnd,IDC_PASS2,addr _pass2,32
					invoke lstrcmp, addr _pass1, addr _pass2
					.if eax != 0		;两次密码如果不相同便进行处理		
						invoke	MessageBox,hWnd,addr szErrPass,NULL,MB_OK or MB_ICONWARNING
					.else
						invoke	_ChangeFile,hWnd
					.endif
			.endif
		.else
			mov	eax,FALSE
			ret
		.endif
		mov	eax,TRUE
		ret
_ProcDlgMain	endp
;********************************************************************
start:
		assume	fs:nothing		;挂接seh
		push	offset _Handler
		push	fs:[0]
		mov	fs:[0],esp

		invoke	LoadLibrary,offset szDllEdit
		mov	hRichEdit,eax
		invoke	GetModuleHandle,NULL
		mov	hInstance,eax
		invoke	DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
		invoke	FreeLibrary,hRichEdit
		jmp	_Nexi
_SafePlace:
		invoke	MessageBox,NULL,addr _SehM,addr _SehT,MB_OK
		pop	fs:[0]						; 恢复原来的 SEH 链
		pop	eax
_Nexi:
		invoke	ExitProcess,NULL
;********************************************************************
		end	start

⌨️ 快捷键说明

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