?? mylock.asm
字號:
call encrypt_objects ; encrypt each section
add esi, 28h ; next section in table
loop Next_Section
;Find_Import_Section:
;
; cmp [esi],'adi.' ;查找Import塊
; jnz Next_Section
; or [esi.SFlags], 80000000h ;改塊屬性為可寫
; jmp Find_OK ;跳出查找
;Next_Section:
; add esi, 28h ;下個塊
;
; loop Find_Import_Section
; ----- 添加新塊 ----------------------------------
Find_OK:
mov esi, offset Section_Table ;塊表開始處
movzx eax, [PE_Header.NumberOfSections] ;塊表個數(shù)
mov ecx, 28h ;塊表大小
mul ecx ;塊表個數(shù)*塊表大小
add esi, eax ;指向塊表末
inc [PE_Header.NumberOfSections] ;增加一個塊
mov edi, offset new_section ;指向新的塊表
xchg edi, esi
; ----- 按塊對齊要求對齊新塊/獲得新塊的RVA地址 -----------------------------------------------
mov eax, [edi-28h+8]
add eax, [edi-28h+0Ch] ;VirtualAddress加上VirtualSize=最后一塊末的RVA(未對齊)
mov ecx, [PE_Header.SectionAlignment] ;塊對齊大小
cdq
div ecx
test edx, edx
jz section_aligned ;對齊否(有無小數(shù)部分)
inc eax ;小數(shù)為近為一
section_aligned:
mul ecx ;對齊為FileAlignment(文件塊對齊大小)的整被數(shù)
mov virt_addr, eax ;既是外殼程序的RVA地址
mov Checker_RVA, eax
; ----- 按文件對齊要求對齊 -------------------------------------
mov eax, Checker_Len ;外殼程序長度
mov ecx, [PE_Header.FileAlignment] ;文件塊對齊大小
div ecx ;相除
test edx, edx
jz file_aligned ;對齊否?(有無小數(shù)部分)
inc eax ;小數(shù)為近為一
file_aligned:
mul ecx ;對齊為FileAlignment(文件塊對齊大小)的整被數(shù)
mov [raw_size], eax ;保存
; ----- 對齊以獲得VirtualSize --------------------------------------
mov eax, Checker_Len ;外殼程序長度
mov ecx, [PE_Header.SectionAlignment] ;塊對齊大小
div ecx ;相除
test edx, edx
jz sect_aligned ;對齊否?(有無小數(shù)部分)
inc eax ;小數(shù)為近為一
sect_aligned:
mul ecx ;對齊為SectionAlignment(塊對齊大小)的整被數(shù)
mov virt_size, eax ;保存
; ----- 獲得指向最末的文件指針 -------------------------------------------------
mov eax, [edi-28h+14h] ;最后一個塊的物理偏移(PointerToRawData)
add eax, [edi-28h+10h] ;最后一個塊的物理大小(SizeOfRawData)
mov raw_offset, eax ;相加后為指向最后一塊末
; ----- 獲得Import表的RVA地址和大小 ----------------------------------
mov eax, My_Import-Checker_Start ;外殼程序Import表相對外殼程序的偏移
add eax, Checker_RVA ;加上外殼程序基址RVA地址=外殼程序Import表RVA地址
mov [PE_Header.DataDirectory.(8).VirtualAddress], eax ; data dir中的Import(輸入塊)的RVA地址
mov [PE_Header.DataDirectory.(8).Size], Import_Len ; Import 的大小
add dword ptr My_Import, eax ;都加上Import表RVA地址
add dword ptr k32_dll, eax ;
add dword ptr k32_first, eax ;
add dword ptr func_k32, eax ;
add dword ptr [func_k32+4], eax ;
add dword ptr [func_k32+8], eax ;
add dword ptr [func_k32+0Ch], eax ;
add dword ptr [func_k32+10h], eax ;
add dword ptr [func_k32+14h], eax ;
add dword ptr getproc, eax ;
add dword ptr getmod, eax ;
add dword ptr loadlib, eax ;
add dword ptr CreateF, eax ;
add dword ptr DeviceIo, eax ;
add dword ptr u32_original, eax ;
add dword ptr u32_dll, eax ;
add dword ptr u32_first, eax ;
add dword ptr func_u32, eax ;
add dword ptr msgbox, eax ;
add dword ptr Error_Cap_addr, eax ;
add dword ptr Error_Msg_addr, eax ;
; ----- 調(diào)整并對齊總長 ----------------------------------------
mov eax, virt_size ;外殼程序?qū)R后的大小
add eax, [PE_Header.SizeOfImage] ;加上原來的文件各部分總長
mov ecx, [PE_Header.SectionAlignment] ;塊對齊大小
div ecx
test edx, edx ;是否對齊(有無小數(shù)部分)
jz image_aligned
inc eax ;小數(shù)為近為一
image_aligned:
mul ecx ;對齊為SectionAlignment(塊對齊大小)的整被數(shù)
mov [PE_Header.SizeOfImage], eax ;寫回去
; ----- 添加新塊表 ----------------------------------------
mov ecx, 28h ;添上把新的塊表項
rep movsb
; ----- 保存老的程序入口RVA地址 ---------------------------------------------
mov eax, dword ptr virt_addr ;外殼程序RVA地址
mov ebx, dword ptr [PE_Header.AddressOfEntryPoint] ;原來的程序入口
mov [PE_Header.AddressOfEntryPoint], eax ;保存新的程序入口
mov Old_Entry_RVA, ebx ;保存老的
; ----- 把新的PE文件頭寫入 -------------------------------------------------------
push FILE_BEGIN ;由文件開始處
push 0
push PE_Header_Addr ;PE文件頭的文件指針
push File_Handle ;文件句柄
call SetFilePointer ;設(shè)置文件讀寫指針
push 0
push offset bytes_read
push Header_Len ;文件頭長度
push offset PE_Header File_Handle ;內(nèi)存中的文件頭偏移 和 文件句柄
call WriteFile ;寫到文件中
; ----- 寫入外殼程序------------------------------------------------------
push FILE_BEGIN ;由文件開始處
push 0
push raw_offset ;指向最后一塊末
push File_Handle ;文件句柄
call SetFilePointer ;設(shè)置文件讀寫指針
push 0
push offset bytes_read
push raw_size ;對齊了的外殼程序大小
push offset Checker_Start ;指向外殼程序開始處
push File_Handle ;文件句柄
call WriteFile ;寫到文件中
jmp OK ;到關(guān)閉文件
; ----- 顯示錯誤 --------------------------------------------------
no_space: ;沒有足夠未用空間裝入新塊表
push 0
push offset Error_Msg
push offset Error_nospace
push 0
call MessageBoxA ; 調(diào)用User32!MessageBoxA生成對話框
jmp Close_File
not_valid_pe: ;不是有效的PE文件
push 0
push offset Error_Msg
push offset Error_nope
push 0
call MessageBoxA ; 調(diào)用User32!MessageBoxA生成對話框
jmp Close_File
Format_err:
push 0
push offset Error_Msg
push offset Error_Format
push 0
call MessageBoxA ; 調(diào)用User32!MessageBoxA生成對話框
jmp Close_File
Write_err:
push 0
push offset Error_Msg
push offset Error_Write
push 0
call MessageBoxA ; 調(diào)用User32!MessageBoxA生成對話框
jmp Close_File
file_not_found: ; 文件沒找到
push 0
push offset Error_Msg
push offset Error_nofile
push 0
call MessageBoxA ; 調(diào)用User32!MessageBoxA生成對話框
jmp quit
; ----- 搞定了,關(guān)掉文件 -------------------------------------------------
OK:
push 0
push offset OK_Cap
push offset OK_Msg
push 0
call MessageBoxA ; 調(diào)用User32!MessageBoxA生成對話框
Close_File:
push File_Handle ;文件句柄
call CloseHandle ;關(guān)閉文件
quit:
push 0
call ExitProcess ;退出程序
;------------------------------------------------------------------------------
show_some_info proc
;------------------------------------------------------------------------------
mov eax, [PE_Header.SizeOfCode] ;獲得SizeOfCode
push eax eax
movzx eax, [PE_Header.NumberOfSections] ;獲得NumberOfSections
push eax offset num_secs
mov P_Text,offset Text_Buff ;字符輸出緩沖區(qū)地址
call My_Printf ;調(diào)用printf
mov eax, [PE_Header.SizeOfInitializedData]
push eax eax
mov eax, [PE_Header.ImageBase]
push eax offset img_base
call My_Printf
mov eax, [PE_Header.SizeOfUninitializedData]
push eax eax
mov eax, [PE_Header.AddressOfEntryPoint]
push eax offset ep_rva
call My_Printf
mov eax, [PE_Header.SectionAlignment]
push eax eax
mov eax, [PE_Header.SizeOfImage]
push eax offset size_img
call My_Printf
mov eax, [PE_Header.FileAlignment]
push eax eax
mov eax, [PE_Header.SizeOfHeaders]
push eax offset size_head
call My_Printf
movzx eax, [PE_Header.MinorLinkerVersion]
push eax
movzx eax, [PE_Header.MajorLinkerVersion]
push eax
mov eax, [PE_Header.BaseOfCode]
push eax offset base_code
call My_Printf
movzx eax, [PE_Header.DllCharacteristics]
push eax eax
mov eax, [PE_Header.BaseOfData]
push eax offset base_data
call My_Printf
push 0
push offset Welcome ;對話框標題
push offset Text_Buff ;指向要輸出的字符串
push 0
call MessageBoxA ;生成對話框,顯示文件信息
ret
endp
extrn _wsprintfA:proc
My_Printf proc
pop ebx ;保存返回地址
push P_Text ;輸出緩沖區(qū)
call _wsprintfA ;調(diào)用Printf
add esp, 4*5 ;恢復(fù)棧指針
add eax,P_Text ;修改輸出緩沖區(qū)地址
mov P_Text, eax
push ebx ;返回
ret
endp
extrn VirtualAlloc:proc
extrn VirtualFree:proc
encrypt_objects proc
pusha
cmp [esi], 'rsr.' ; 跳過 .rsrc塊
jz no_encrypt
cmp [esi], 'adr.' ; 跳過 .rdata塊
jz no_encrypt
cmp [esi], 'ade.' ; 跳過 .edata塊
jz no_encrypt
cmp [esi], 'ler.' ; 跳過 .reloc塊
jz no_encrypt
cmp [esi], 'slt.' ; 跳過 .tls塊
jz no_encrypt
cmp dword ptr [esi.SizeOfRawData], 0 ;塊大小是否是零
jz no_encrypt
push PAGE_READWRITE
push MEM_COMMIT
push [esi.SizeOfRawData]
push 0
call VirtualAlloc ;分配一塊內(nèi)存
mov mem_offset, eax ;返回的是內(nèi)存首址
; ----- 讀入該塊數(shù)據(jù) -----------------------------------------------
push 0
push 0
push [esi.PointerToRawData] ; 該塊的物理位置
push File_Handle ; 文件句柄
call SetFilePointer ; 設(shè)置文件指針
push 0
push offset bytes_read
push [esi.SizeOfRawData] ; 該塊大小
push mem_offset ; 在已分配的內(nèi)存處
push File_Handle ; 文件句柄
call ReadFile ; 讀入
; ----- 保存該塊的RVA地址和大小 -------------------------------------------
mov edi, [curr_disp]
mov eax, [esi+SVirtualAddress] ; 獲得該塊的RVA地址
mov [ENsection_RVA+edi], eax ; 保存該塊的RVA地址
mov eax, [esi.SizeOfRawData] ; 獲得該塊的大小
mov [ENsection_Len+edi], eax ; 保存該塊的大小
mov edi, mem_offset ; 已分配的內(nèi)存首址
mov ecx, [esi.SizeOfRawData] ; 塊大小(要加密的字節(jié)數(shù))
mov al, key ; 加密密匙
encrypt:
sub byte ptr [edi], al ; 加密
inc al
inc edi ; 繼續(xù)
loop encrypt
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -