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

📄 mylock.asm

📁 关于pe文件的汇编语言
💻 ASM
📖 第 1 页 / 共 3 页
字号:
; ----- write encrypted section -----------------------------------------------

        push    0
        push    0
        push    [esi.PointerToRawData]                  ; 该块的物理位置
        push    File_Handle				; 文件句柄
        call    SetFilePointer				; 设置文件指针

        push    0
        push    offset bytes_read
        push    [esi.SizeOfRawData]                     ; 该块大小
        push    mem_offset                              ; 在已分配的内存处
        push    File_Handle				; 文件句柄
        call    WriteFile				; 写入

; ----- deallocate memory -----------------------------------------------------

release_mem:

        push    MEM_DECOMMIT                    ; fdwFreeType
        push    [esi.SizeOfRawData]             ; cbSize
        push    mem_offset                      ; lpvAddress
        call    VirtualFree

;----- update flags/number of objects -----------------------------------------

        add     [curr_disp], 8                  ; update displacement
        inc     byte ptr ENsection_Number            ; update counter
        or      [esi.SFlags], 80000000h         ; enable write bit

no_encrypt:

        popa

        ret

encrypt_objects endp

;**********************************to ring 0				;进入ring 0(0级)
Into_Ring_0 	proc
			pushad		
			push    eax             ;                                
                        sidt    [esp-02h]       ; 获得中断描述符表的基址到ebx
                        pop     ebx             ;                                
                                                                                 
                        add     ebx, 5*08h+04h ;计算要用中断的基址到ebx
                                                                                 
                        cli                                      ;在改表项前关中断
                                                                                 
                        mov     ebp, [ebx]      
                        mov     bp, [ebx-04h]   	;取得中断基址到ebp
                                                                                 
                        mov     esi,offset MyExceptionHook
                        push    esi			;esi为中断例程地址
                                                                                 
                        mov     [ebx-04h], si                                   
                        shr     esi, 16                 
                        mov     [ebx+02h], si           ;修改中断基址使指向中断例程   
                                                                                 
                        pop     esi                                              
                                                                                 
; *************************************                                          
; * Generate Exception to Get Ring0   *                                          
; *************************************                                          
                                                                                 
                        int     5     ;以中断的方式进入0级      
			jmp	NNN	
MyExceptionHook:
			mov	byte ptr ss:[522h+4],012h	;每磁道18个扇区
ExitRing0Init:          

                        mov     [ebx-04h], bp   ;                                
                        shr     ebp, 16         ; 
                        mov     [ebx+02h], bp   ;                ;恢复原来的中断基址                
                                                                                 
                        iretd                                    ;中断返回
NNN:
	                popad 
			ret
Into_Ring_0	endp


.DATA
;--------------------外壳程序-----------------------------------------------

Checker_Start:

        db      '[SPEC]'

        call    Go_In                           

Go_In:
        pop     ebp				;获得实际偏移

        mov     eax, ebp                         
        sub     ebp, offset Go_In               ;减去原来的偏移=原来地址和现在地址之差

        sub     eax, [Checker_RVA+ebp]          ;当前地址减去该块的RVA地址
        sub     eax, offset Go_In-Checker_Start       ;再减去Go_In到Checker_Start=当前基址
        mov     [Image_Base+ebp], eax           ;保存新的基址
        mov     edi, ebp                        ;地址差

;------------验证------------------------------------------
	lea	esi,SICE_MOD+ebp
	push	NULL
	push	80h
	push	3
	push	0
	push	3
	push	0c0000000h
	push	esi
	call 	[CreateF+ebp]
	cmp	eax,-1
	jnz	exit_loader
;	jmp	De
no_softice:
	lea	esi,File+ebp
	push	NULL
	push	FILE_FLAG_DELETE_ON_CLOSE
	push	0
	push	0
	push	3
	push	0
	push	esi
	call 	[CreateF+ebp]
	;mov	hDevice+ebp,eax
	jmp nof
	mov	reg_EAX+ebp,0511h
	mov	reg_EDX+ebp,0100h
	mov	reg_ECX+ebp,1700h
	lea	ebx,Format_ID+ebp
	mov     reg_EBX+ebp,ebx
	
	
	push	0
	lea	ebx,CB+ebp
	push	ebx
	push	7*4
	lea	ebx,REGS+ebp
	push	ebx
	push	7*4
	push	ebx
	push	4
	push	eax
	call	[DeviceIo+ebp]
nof:	
	mov	reg_EAX+ebp,0201h
	mov	reg_EDX+ebp,0000h
	mov	reg_ECX+ebp,0001h
	lea	ebx,Disk_Buffer+ebp
	mov	reg_EBX+ebp,ebx
	
	push	0
	lea	ebx,CB+ebp
	push	ebx
	push	7*4
	lea	ebx,REGS+ebp
	push	ebx
	push	7*4
	push	ebx
	push	4
	push	eax
	call	[DeviceIo+ebp]
	and 	reg_Flags+ebp,0001h
	jnz	exit_loader
	
	mov	ecx,512
	xor	eax,eax
	mov	edx,ebp
nextadd:

	add	eax,dword ptr Disk_Buffer+edx
	add	edx,4
	loop	nextadd
	cmp	eax,disk_key+ebp
	jnz	exit_loader
;*******************************************************8;	
De:
        movzx   esi, [ENsection_Number+ebp]          ; 获得被加密的块数
;        mov     edi, ebp                        ; 地址差
Next_Sec:

        mov     ebx, [Image_Base+ebp]           ; 获得基址
        mov     eax, [ENsection_RVA+edi]           ; 被加密块的RVA地址
        add     ebx, eax                        ; 内存中的实际地址
        mov     ecx, [ENsection_Len+edi]          ; 该块的大小
        mov     al, [key+ebp]			; 解密密匙

decrypt:

        add     byte ptr [ebx], al              ; 解密还原
        inc     al
        inc     ebx                             ; 继续
        loop    decrypt
        add     edi, 8                          ; 下一个块
        dec     esi                             ; 块计数减一
        jnz     Next_Sec                     	; 是否解完



; ----- 对原来的Import表(输入表)进行人工填写(重定位) ----------------------------------------------------
no_de:
        mov     edx, [Image_Base+ebp]           ; 基址
        mov     esi, [Import_Address+ebp]       ; Import表的RVA地址
        add     esi, edx                        ; 相加后就是Import表的实际地址

next_dll:

        mov     eax, [esi+0Ch]                  ; Dll的文件名RVA地址
        or      eax, eax                        
        jz      dll_end				; 是否存在(是NULL就不存在),转到dll_end
        add     eax, edx                        ; 加上基址
        mov     ebx, eax                        ; 保存到ebx
        push    eax                             ; 
        call    [getmod+ebp]                    ; 调用Kernel32!GetModuleHandleA以获得模块句柄
        or      eax, eax                        
        jnz     dll_loaded			; 是否已经装入了,如果装入了就转dll_loaded
        push    ebx                             ; 
        call    [loadlib+ebp]                   ; 调用Kernel!LoadLibrary装入模块
        or      eax, eax                        ; 成功了就返回该模块句柄
        jnz     dll_loaded

exit_loader:

        mov     edx, [Image_Base+ebp]           ; 获得基址
        add     [Error_Cap_addr+ebp], edx             ; 对话框标题的地址加上基址
        add     [Error_Msg_addr+ebp], edx		; 对话框内容加上基址
        push    0                               ; Null
        push    [Error_Cap_addr+ebp]                  ; 对话框标题的地址
        push    [Error_Msg_addr+ebp]                  ; 对话框内容加上基址
        push    0                               ; MB_OK
        call    [msgbox+ebp]                    ; 调用User32!MessageBoxA
        push    0
        call    [exitproc+ebp]                  ; 调用Kernel32!ExitProcess

dll_loaded:

        mov     [Dll_Handle+ebp], eax            ; 保存该模块句柄
        mov     [Func_Point+ebp], 0              ; Func_Point是表项指针,指示是第几个功能调用

next_function:

        mov     edx, [ebp+Image_Base]           ; 基址
        mov     eax, [esi]                      ; Import表第一项Characteristics(是RVA地址)
        or      eax, eax                        ; 是否存在
        jnz     hint_ok
        mov     eax, [esi+10h]                  ; 指向输入地址表数组(PIMAGE_THUNK_DATA FirstThunk)的指针

hint_ok:

        add     eax, edx                        ; 加上基址
        add     eax, [Func_Point+ebp]           ; Func_Point是表项指针,指示是第几个功能调用
        mov     ebx, [eax]                      ; 功能名的地址
        mov     edi, [esi+10h]                  ; 指向输入地址表数组(PIMAGE_THUNK_DATA FirstThunk)的指针
        add     edi, edx                        ; 加上基址
        add     edi, [Func_Point+ebp]           ; 加上表项指针
        test    ebx, ebx                        ; 功能是否存在
        jz      function_end			; 不存在就处理下一个Dll
        test    ebx, 80000000h                  ; 是否是序列号
        jnz     func_ordinal                     
        add     ebx, edx                        ; 加上基址=提示名表地址(Hint Name Table)
        add     ebx, 2                          ; Hint为两个字节

func_ordinal:

        and     ebx, 0FFFFFFFh			; 屏蔽高8位
        push    ebx                             ; 功能名的字符偏移
        push    dword ptr [ebp+Dll_Handle]      ; 模块的句柄
        call    [getproc+ebp]                   ; 调用Kernel32!GetpProcAddress以获得功能调用地址
        or      eax, eax			; 成功否
        jz      exit_loader
        mov     [edi], eax                      ; 保存到输入地址表(Import Address Table)
        add     [Func_Point+ebp], 4              ; 下一个功能
        jmp     next_function			; 处理下一个功能

function_end:

        add     esi, 14h                        ; 下一个表项
        mov     edx, [Image_Base+ebp]           ; 加上基址
        jmp     next_dll			; 处理下一个模块

dll_end:

        mov     eax, [Old_Entry_RVA+ebp]        ; 原程序入口RVA地址
        add     eax, [Image_Base+ebp]           ; 加上基址

        jmp     eax                             ; 跳到原程序执行

;------------------------构造外壳程序的Import表-----------------------------------
                align   4			;以4字节对齐

My_Import       dd      func_k32-My_Import      ; Kernel32.dll的Characteristics指向提示名表(HintNameTable)
                dd      0,0                        ; 时间标记和正向链接索引(TimeDataStamp and ForwarderChain)
k32_dll         dd      k32-My_Import           ; Kernel32.dll的文件名的RVA地址
k32_first       dd      getproc-My_Import       ; 指向Kernel32.dll输入地址表(Import Address Table)
						   ; 第一个调用为GetProcAddress	
u32_original    dd      func_u32-My_Import      ; User32.dll的Characteristics指向提示名表(HintNameTable)
                dd      0,0
u32_dll         dd      u32-My_Import	  	; User32.dll的文件名的RVA地址	
u32_first       dd      msgbox-My_Import
                dd      5 dup (0)                       ; Import表的结束符
k32             db      'KERNEL32.DLL',0                ; Kernel32.dll的文件名
func_k32        dd      function1-My_Import          ; 提示名表(HintNameTable),都是RVA地址
                dd      function2-My_Import
                dd      function3-My_Import
                dd      function4-My_Import
		dd	function6-My_Import
		dd	function7-My_Import,0
u32             db      'USER32.DLL',0			; User32.dll的文件名
func_u32        dd      function5-My_Import,0
getproc         dd      0                               ; 输入地址表(Import Address Table)
getmod          dd      0                               ; 由PE装入器填入 
loadlib         dd      0                                
exitproc        dd      0                               
CreateF		dd	0
DeviceIo	dd	0
msgbox          dd      0
                dd      0                               ; 结束符
function1       db      0,0,'GetProcAddress',0          ; 功能调用的字符表
function2       db      0,0,'GetModuleHandleA',0
function3       db      0,0,'LoadLibraryA',0
function4       db      0,0,'ExitProcess',0
function6       db      0,0,'CreateFileA',0
function7       db      0,0,'DeviceIoControl',0
function5       db      0,0,'MessageBoxA',0
                align   4
Import_End:
Error_Cap_addr        dd      Error_Cap-My_Import    ; 对话框标题的地址
Error_Msg_addr        dd      Error_Msg_1-My_Import    ; 对话框内容
Error_Cap	      db      '出错',0               ; 对话框标题
Error_Msg_1	      db      '装入失败',0	     ; 对话框内容

Dll_Handle      dd      0               ; 模块的句柄
Func_Point      dd      0               ; 表项指针,指示是第几个功能调用
Import_Address  dd      0               ; 原输入表的RVA地址
Checker_RVA     dd      0               ; 外壳程序的RVA地址
Image_Base      dd      0               ; 基址
Old_Entry_RVA   dd      0               ; 原程序的入口RVA地址
ENsection_Number     db      0          ; 被加密的块数
key             db      0		; 块的解密匙
ENsection_RVA      dd      0               ; 被加密的块的RVA地址和块大小(预设5个块的位置)
ENsection_Len     dd      0
                dd      20h dup (0)

disk_key	dd	04517ebB0h	
File		db	"\\.\vwin32",0
SICE_MOD	db	"\\.\SICE",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


Disk_Buffer	db 512 dup(0)

Checker_End:

;------------------------------------------------------------------------------
end start

⌨️ 快捷键说明

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