📄 mylock.asm
字号:
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,
; ®s, sizeof(regs), ®s, 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 + -