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

📄 mylock.asm

📁 关于pe文件的汇编语言
💻 ASM
📖 第 1 页 / 共 3 页
字号:
include w32.inc				;Win32头文件
.386p
;
;  系统时间结构定义
;

SYSTEMTIME              struct
st_wYear                WORD      0             ;年
st_wMonth               WORD      0             ;月
st_wDayOfWeek           WORD      0             ;星期几
st_wDay                 WORD      0             ;日
st_wHour                WORD      0             ;小时
st_wMinute              WORD      0             ;分
st_wSecond              WORD      0             ;秒
st_wMilliseconds        WORD      0             ;毫秒
SYSTEMTIME              ends


IMAGE_NT_SIGNATURE  	       EQU     000004550h	;PE文件标识'PE'

;
;  目录表结构定义
;

IMAGE_DATA_DIRECTORY                   STRUC
  VirtualAddress      DD      ?				;RVA地址
  Size                DD      ?				;长度
IMAGE_DATA_DIRECTORY                   ENDS


;*****************************************************
;****              PE文件头结构定义               ****
;*****************************************************


IMAGE_NT_HEADERS   STRUC

;-----------------PE文件标识'PE'
Signature           		DD      ?	; 4	;PE文件标识'PE'
;-----------------PE文件头
Machine             		DW      ?	; 6
NumberOfSections    		DW      ?	; 8	; 块数目
TimeDateStamp       		DD      ?	; 12	; 文件时间
PointerToSymbolTable    	DD      ?	; 16
NumberOfSymbols     		DD      ?	; 20	; 符号表中符号个数
SizeOfOptionalHeader    	DW      ?	; 22	; 可选部首长度 
Characteristics     		DW      ?	; 24	; 信息标志 
;-----------------可选部首
Magic               		DW      ?       ; 26	; 标志字(总是010bh)
MajorLinkerVersion  		DB      ?       ; 27	; 连接器版本号
MinorLinkerVersion  		DB      ?       ; 28
SizeOfCode          		DD      ?       ; 32	; 代码段大小
SizeOfInitializedData           DD      ?       ; 36	; 已初始化数据块大小
SizeOfUninitializedData         DD      ?       ; 40	; 未初始化数据块大小
AddressOfEntryPoint 		DD      ?       ; 44	; 程序起始RVA
BaseOfCode          		DD      ?       ; 48	; 代码段起始RVA
BaseOfData          		DD      ?       ; 52	; 数据段起始RVA
ImageBase           		DD      ?       ; 56	; 装入基址RVA
SectionAlignment    		DD      ?       ; 60	; 块对齐
FileAlignment       		DD      ?       ; 64	; 文件块对齐
MajorOperatingSystemVersion     DW      ?       ; 66	; 所需操作系统版本号
MinorOperatingSystemVersion     DW      ?       ; 68
MajorImageVersion   		DW      ?       ; 70	; 用户自定义版本号
MinorImageVersion   		DW      ?       ; 72
MajorSubsystemVersion           DW      ?       ; 74	; 所需子系统版本号
MinorSubsystemVersion           DW      ?       ; 76
Win32VersionValue   		DD      ?       ; 80	; 保留
SizeOfImage         		DD      ?       ; 84	; 文件各部分总长  
SizeOfHeaders       		DD      ?       ; 88	; 部首及块表大小 
CheckSum            		DD      ?       ; 92	; 累加和
Subsystem           		DW      ?       ; 94
DllCharacteristics  		DW      ?       ; 96	
SizeOfStackReserve  		DD      ?       ; 100
SizeOfStackCommit   		DD      ?       ; 104
SizeOfHeapReserve   		DD      ?       ; 108
SizeOfHeapCommit    		DD      ?       ; 112
LoaderFlags         		DD      ?       ; 116
NumberOfRvaAndSizes 		DD      ?       ; 120
DataDirectory           IMAGE_DATA_DIRECTORY             16 DUP (<0>)	;目录表
IMAGE_NT_HEADERS   ENDS

;*****************************************************
;****         块表结构定义		          ****
;*****************************************************

IMAGE_SIZEOF_SHORT_NAME                 EQU     8

IMAGE_SECTION_HEADER                    STRUC
  Name                    DB      8 DUP (0)		; 块名
  SVirtualSize            DD      ?			; 该段真实长度
  SVirtualAddress      	  DD      ?			; 该块的RVA
  SizeOfRawData       	  DD      ?			; 该块物理长度
  PointerToRawData    	  DD      ?			; 该块物理偏移
  PointerToRelocations    DD      0			; 重定位的偏移
  PointerToLinenumbers    DD      0			; 行号表的偏移 
  NumberOfRelocations 	  DW      0			; 重定位项数目
  NumberOfLinenumbers 	  DW      0			; 行号表的数目
  SFlags		  DD      ?			; 块属性  
IMAGE_SECTION_HEADER                    ENDS

.DATA
mem_offset	        dd      0               ; address of allocated memory
curr_disp       dd      0               ; displacement
bytes_read       	dd	?		; 计数内存单元
File_Handle		dd      0               ; 文件句柄
Section_Addr      	dd      0               ; 块表地址
PE_Header_Addr      	dd      0               ; PE文件头数据地址

sys_time        SYSTEMTIME              <0>             ; 系统时间定义的结构
PE_Header	    IMAGE_NT_HEADERS        <0>             ; PE文件头的结构
Section_Table       IMAGE_SECTION_HEADER    0Fh dup (<0>)   ; 块表的结构

Header_Len      	equ     size PE_Header + size Section_Table     ; PE文件头和块表的长度
Checker_Len 		equ     Checker_End - Checker_Start 		; 外壳程序的长度
Import_Len          	equ     Import_End - My_Import          	; 外壳程序的Import表(输入表)的长度

Error_Msg	db	'出错',0
Error_Cmd	db	'命令行有错!',0dh,0ah,0dh,0ah,'Usage: Cheaker filename',0
OK_Cap		db	'成功!',0
OK_Msg		db	'搞定了,Mission Complete!',0
Welcome		db	'执行文件有关信息: ',80h dup(?)
num_secs        db      10,13,'块数目 : %02i                    代码段大小 : %08lX',0
img_base        db      10,13,'装入基址RVA : %08lX         已初始化数据块大小 : %08lX',0
ep_rva          db      10,13,'程序入口RVA : %08lX         未初始化数据块大小 : %08lX',0
size_img        db      10,13,'文件各部分总长 : %08lX      块对齐 : %08lX',0
size_head       db      10,13,'部首及块表大小 : %08lX      文件块对齐 : %08lX',0
base_code       db      10,13,'代码段起始RVA : %08lX       连接器版本号 : %i.%02i',0
base_data       db      10,13,'数据段起始RVA : %08lX       Dll的属性字 : %i',0
size_udata      db      10,13,'未初始化数据块大小 : %08lX',0
Error_nofile	db	'文件没找到!',0
Error_nospace	db	'没有足够未用空间装入新块表!',0
Error_nope	db	'不是有效的PE文件!',0
Error_Format	db	'格式化软盘出错!',0
Error_Write	db	'写盘出错!',0
Text_Buff	db 	1d0h dup(?)			;输出字符串缓冲区
P_Text		dd	?				;字符串缓冲区指针

new_section:

obj_name        db      '.ZD_CHK',0     ; 块名
virt_size       dd      0               ; 块长
virt_addr       dd      0               ; 该块RVA地址
raw_size        dd      0               ; 该块物理长度
raw_offset      dd      0               ; 该块物理偏移
unused          dd      0,0,0           ; 未用
obj_flags       dd      0E0000020h      ; 属性 (r/w/c/x)

hDevice		dd	?
;_File		db	"\\.\vwin32",0
;	_CB	dd	0h
;	_REGS	= $
;	_reg_EBX		dd	0
;   	_reg_EDX		dd	0
;  	_reg_ECX		dd	0
;    	_reg_EAX		dd	0
;      	_reg_EDI		dd	0
;	_reg_ESI		dd	0
;	_reg_Flags	dd	0
;
	Format_ID	db 18h,1h,1h,2h
			db 18h,1h,2h,2h
			db 18h,1h,3h,2h
			db 18h,1h,4h,2h
			db 18h,1h,5h,2h
			db 18h,1h,6h,2h
			db 18h,1h,7h,2h
			db 18h,1h,8h,2h
			db 18h,1h,9h,2h
			db 18h,1h,0ah,2h
			db 18h,1h,0bh,2h
			db 18h,1h,0ch,2h	
			db 18h,1h,0dh,2h
			db 18h,1h,0eh,2h
			db 18h,1h,0fh,2h
			db 18h,1h,10h,2h
			db 18h,1h,11h,2h
			db 18h,1h,12h,2h				


.CODE
start:
; ----- 处理命令行 ------------------------------------------------------

        call    GetCommandLineA		; 获得命令行字符串指针
        mov     edi,eax                 ; 保存到edi
        mov     ecx, -1                 ; 计数器
        mov     al, 0                   ; 查找0(结束符)
        push    edi                     ; 保存
        repnz   scasb                   ; 查找结束符
        not     ecx                     ; 返回整个字符串长度
        pop     edi                     ; 
        mov     al, 20h                 ; 查找20h(第一个空格后就是目标文件名)
        repnz   scasb                   ; 查找
        dec     ecx                     ; 获得命令行字符串指针
        test    ecx,ecx                 ; 是否有效
        jnz     Mov_Filename

no_commandline:

        push    0                               ; Null
        push    offset Error_Msg                ; 对话框标题的地址
        push    offset Error_Cmd                ; 对话框内容加上基址
        push    0                               ; MB_OK
        call    MessageBoxA                     ; 调用User32!MessageBoxA生成对话框
        jmp     quit

Mov_Filename:					;在对话框的标题后加上文件名
	push	edi				;保存文件名指针
	lea 	esi,Welcome+18			;目的地址
Loop_Mov:
	mov	al,byte ptr [edi]		;读入一个字节
	mov	byte ptr [esi],al		;写一个字节
	test	al,al				;是否结束
	jz	open_file
	inc	edi
	inc	esi				
	jmp	Loop_Mov			
; ----- 打开文件 -------------------------------------------------------------
open_file:
	pop	edi
        push    0                               ; 临时文件句柄
        push    FILE_ATTRIBUTE_NORMAL           ; 文件属性
        push    OPEN_EXISTING                   ; 打开方式
        push    0                               ; 安全属性指针
        push    0                               ; 共享模式
        push    GENERIC_READ + GENERIC_WRITE    ; 读写方式
        push    edi                             ; 文件名指针
        call    CreateFile

        cmp     eax, INVALID_HANDLE_VALUE       ; 是否成功
        jz      file_not_found

        mov     File_Handle, eax                ; 保存文件句柄

; ----- 读3ch处的PE文件头文件指针 -----------------------------------------------

        push    FILE_BEGIN              ; 移动方式(由文件开始处计数)
        push    0                       ; 
        push    3Ch                     ; 文件指针(3ch处为PE文件头文件指针)
        push    File_Handle             ; 文件句柄
        call    SetFilePointer		; 移动文件指针

        push    0                       ; lpOverlapped指针为空
        push    offset bytes_read       ; 计数内存单元
        push    4                       ; 读4个字节(一个dword)
        push    offset PE_Header_Addr   ; 读到PE_Header_Addr处
        push    File_Handle             ; 文件句柄
        call    ReadFile		; 读文件	

; ----- 读PE文件头 -----------------------------------------------

        push    FILE_BEGIN		; 由文件开始处计数
        push    0
        push    PE_Header_Addr		; PE文件头文件指针
        push    File_Handle		; 文件句柄
        call    SetFilePointer		; 移动文件指针

        push    0			; lpOverlapped指针为空
        push    offset bytes_read	; 计数内存单元
        push    Header_Len		; 文件头长度=PE文件头大小+块表大小
        push    offset PE_Header	; 读到PE_Header处
        push    File_Handle		; 文件句柄
        call    ReadFile		; 读文件

; ----- 检查PE文件标识 ----------------------------------------------------

        cmp     [PE_Header.Signature], IMAGE_NT_SIGNATURE    ; 检查是否是PE文件
        jnz     not_valid_pe

; ----- 显示文件有关信息 ----------------------------------------------------

        call    show_some_info                          ; 显示文件有关信息

; ----- 获得块表偏移 --------------------------------------------

        movzx   eax, [PE_Header.SizeOfOptionalHeader]        ; 可选部首的长度
        add     eax, 18h                                ; 块表地址(18h为目录表大小)
        mov     Section_Addr, eax			; 保存之

; ----- 检查是否有足够的未用空间装入新的块表 ---------------------------------------

        movzx   eax, [PE_Header.NumberOfSections]            ; 块的个数
        inc     eax                                     ; 加上1个新块
        mov     ecx, 28h                                ; 每个块表项的大小(28h个字节)
        mul     ecx                                     ; 块的个数乘以每个块表项的大小=块表大小
        add     eax, Section_Addr                       ; 加上块表的地址
        add     eax, PE_Header_Addr                     ; 加上PE文件头文件指针=新的文件头总长
        cmp     eax, [PE_Header.SizeOfHeaders]		; 和原文件头比较大小
        jg      no_space				; 如果大于就说明没有文件未用空间装新的块表

; ----- 保存输入表(Import表)的RVA地址 -------------------------------------------

        mov     eax, [PE_Header.DataDirectory.(8).VirtualAddress]	;获得Import表的RVA地址
        mov     Import_Address, eax					;保存之
; ----- 格式化密匙盘 -------------------------------------------
;	call	Into_Ring_0
	
extrn   DeviceIoControl:proc
	push	NULL
	push	FILE_FLAG_DELETE_ON_CLOSE
	push	0
	push	0
	push	3
	push	0
	push	Offset File
	call 	CreateFileA
	mov	hDevice,eax
;DeviceIoControl (hVWin32, VWIN32_DIOC_DOS_IOCTL,
;                              &regs, sizeof(regs), &regs, sizeof(regs),
;                              &cb, 0);
jmp	write
	mov	reg_EAX,0500h
	mov	reg_EDX,0100h
	mov	reg_ECX,1800h
	mov	reg_EBX,offset	Format_ID

	push	0
	push	offset CB
	push	7*4
	push	offset REGS
	push	7*4
	push	offset REGS
	push	4
	push	hDevice
	call	DeviceIoControl
	and 	reg_Flags,0001h
	jnz	Format_err
write:
	mov	reg_EAX,0201h
	mov	reg_EDX,0000h
	mov	reg_ECX,0001h
	mov	reg_EBX,offset	Disk_Buffer

	push	0
	push	offset CB
	push	7*4
	push	offset REGS
	push	7*4
	push	offset REGS
	push	4
	push	hDevice
	call	DeviceIoControl
	and 	reg_Flags,0001h
	jnz	Write_err
	mov	ecx,512
	xor	eax,eax
	xor	edx,edx
_nextadd:

	
	add	eax,dword ptr Disk_Buffer+edx
	add	edx,4
	loop	_nextadd
	mov 	disk_key,eax

; ----- 产生密匙 -----------------------------------------------
extrn   GetSystemTime:proc
        push    offset sys_time                         ; SYSTEMTIME struc
        call    GetSystemTime

        movzx   ax, [sys_time.st_wMilliseconds]         ; get millisecond
        mov     key, al                                 ; save as encryption key

        mov     esi, offset Section_Table           ; 块表起始地址
        movzx   ecx, [PE_Header.NumberOfSections]    ; 块的个数
; ----- 对块进行加密 -----------------------------------------------
Next_Section:

⌨️ 快捷键说明

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