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

📄 rebuilder.asm

📁 这是脱壳 PE-ARMOR 的程序源代码汇编的
💻 ASM
字号:
;优化 PE 文件,分两方面优化文件
;第一: 去掉 Dos Stub 来压缩文件头的大小,第二: 去掉每个节中的无用字节来压缩节的大小
_RebuildPE proc lpszFile:DWORD
        LOCAL   hFile, hMapFile, pMemory
        LOCAL   lpMem, dwFileSize, dwReturn
        LOCAL   lpDosHeader
        LOCAL   lpNewSection
        
        pushad
        
;--------------------------------------------------------------------------------
        ;打开文件,创建内存映射文件
        invoke  CreateFile, lpszFile, GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ,
                        0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0
        .if eax==INVALID_HANDLE_VALUE
                ;invoke  _OutputInfo, g_hOutputCtl, CTXT("打开文件出错!!!")
                popad
                ret
        .endif
        mov     hFile, eax
        invoke  CreateFileMapping, hFile, 0, PAGE_READWRITE, 0, 0, 0
        .if !eax
                ;invoke  _OutputInfo, g_hOutputCtl, CTXT("创建内存映射文件出错!!!")
                invoke  CloseHandle, hFile
                popad
                ret
        .endif
        mov     hMapFile, eax
        invoke  MapViewOfFile, hMapFile, FILE_MAP_WRITE, 0, 0, 0
        .if !eax
                ;invoke  _OutputInfo, g_hOutputCtl, CTXT("把文件映射进内存时出错!!!")
                invoke  CloseHandle, hMapFile
                invoke  CloseHandle, hFile
                popad
                ret
        .endif
        mov     pMemory, eax
        
        invoke  GetFileSize, hFile, 0
        invoke  GlobalAlloc, GMEM_FIXED + GMEM_ZEROINIT, eax
        .if !eax
                ;invoke  _OutputInfo, g_hOutputCtl, CTXT("内存分配出错,文件优化不成功!!!")
                invoke  UnmapViewOfFile, pMemory
                invoke  CloseHandle, hMapFile
                invoke  CloseHandle, hFile
                popad
                ret
        .endif
        mov     lpMem, eax
        
;--------------------------------------------------------------------------------
        ;检查 PE 文件是否合法
        mov     eax, pMemory
        mov     lpDosHeader, eax
        assume  eax : ptr IMAGE_DOS_HEADER
        .if [eax].e_magic == IMAGE_DOS_SIGNATURE
                mov     ebx, eax
                add     ebx, [eax].e_lfanew
                assume  ebx : ptr IMAGE_NT_HEADERS
                .if [ebx].Signature == IMAGE_NT_SIGNATURE
                        jmp     @F
                .endif
        .endif
        ;invoke  _OutputInfo, g_hOutputCtl, CTXT("不是合法的 PE 文件!!!")
        invoke  UnmapViewOfFile, pMemory
        invoke  CloseHandle, hMapFile
        invoke  CloseHandle, hFile
        invoke  GlobalFree, lpMem
        popad
        ret
        @@:
        
;--------------------------------------------------------------------------------
        ;计算第一个节调整后的位置
        movzx   eax, [ebx].FileHeader.NumberOfSections
        inc     eax
        imul    eax, sizeof IMAGE_SECTION_HEADER
        movzx   ecx, [ebx].FileHeader.SizeOfOptionalHeader
        add     ecx, 18h
        add     eax, ecx
        add     eax, sizeof IMAGE_DOS_HEADER    ;eax = DosHeader+NtHeader+SectionHeader 的大小
        
        cdq
        mov     ecx, 200h
        div     ecx
        test    edx, edx
        jz      @F
        inc     eax
        @@:
        mul     ecx                             ;依 200h 对齐
        add     eax, lpMem
        mov     lpNewSection, eax
        
;--------------------------------------------------------------------------------
        ;计算节的位置和大小,构造节
        movzx   edx, [ebx].FileHeader.NumberOfSections
        movzx   ecx, [ebx].FileHeader.SizeOfOptionalHeader
        lea     ebx, [ebx+ecx+18h]
        assume  ebx : ptr IMAGE_SECTION_HEADER
        
        ;edx = 节的个数,ebx 指向节表。然后循环每个节,从节的末尾开始
        ;查找节中的无用字节(00h 就是无用字节)

	
        .while edx
                push    edx
                
                ;从节的末尾开始倒序查找 00h 字节
                mov     edi, [ebx].PointerToRawData		
                add     edi, [ebx].SizeOfRawData		
                add     edi, lpDosHeader

		mov	eax, edi
		sub	eax, [ebx].SizeOfRawData
		push	eax	;***

                mov     edx, edi
                dec     edi
                xor     eax, eax
                mov     ecx, eax
                dec     ecx
                std
                repz scasb
		pop	eax	;***
                
                ;在节的末尾的 4 个 00h 字节有可能是指令的一部分
                add     edi, 6
		.if	SDWORD ptr edi<eax
			mov	edi, eax
		.endif

                .if	edi>edx
                        mov     edi, edx
                .endif
                mov     ecx, edi	;calc err?
                
                ;把有用字节保存起来
                mov     esi, [ebx].PointerToRawData
                add     esi, lpDosHeader
                sub     ecx, esi
                mov     eax, ecx
                mov     edi, lpNewSection
                cld
                rep movsb;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BUG?????????????/
                
                ;计算下一个节的开始位置
                mov     ecx, lpNewSection
                sub     ecx, lpMem
                mov     [ebx].PointerToRawData, ecx
                mov     [ebx].SizeOfRawData, eax
                cdq
                mov     ecx, 200h
                div     ecx
                test    edx, edx
                jz      @F
                inc     eax
                @@:
                mul     ecx
                add     lpNewSection, eax
                
                add     ebx, sizeof IMAGE_SECTION_HEADER
                pop     edx
                dec     edx
        .endw
        assume  ebx : nothing
        
        ;计算优化后的文件大小
        mov     eax, lpNewSection
        sub     eax, lpMem
        mov     dwFileSize, eax
        
;--------------------------------------------------------------------------------
        ;去掉 Dos Stub,构造 Nt Header 和 Section Header
        mov     ebx, lpDosHeader
        assume  ebx : ptr IMAGE_DOS_HEADER
        add     ebx, [ebx].e_lfanew
        assume  ebx : ptr IMAGE_NT_HEADERS
        mov     [ebx].OptionalHeader.FileAlignment, 200h        ;修正文件对齐
        movzx   ecx, [ebx].FileHeader.NumberOfSections
        inc     ecx
        imul    ecx, sizeof IMAGE_SECTION_HEADER
        movzx   edx, [ebx].FileHeader.SizeOfOptionalHeader
        add     edx, 18h
        add     ecx, edx
        
        mov     esi, ebx
        mov     edi, lpMem
        add     edi, sizeof IMAGE_DOS_HEADER
        rep movsb
        
;--------------------------------------------------------------------------------
        ;构造 Dos Header
        mov     esi, lpDosHeader
        mov     edi, lpMem
        mov     ecx, sizeof IMAGE_DOS_HEADER
        assume  esi : ptr IMAGE_DOS_HEADER
        mov     [esi].e_lfanew, ecx                             ;修正 Dos Header
        rep movsb
        
        invoke  UnmapViewOfFile, pMemory
        invoke  CloseHandle, hMapFile
        invoke  CloseHandle, hFile
        
;--------------------------------------------------------------------------------
        ;打开文件把优化后的数据写入
        invoke  CreateFile, lpszFile, GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ,
                        0, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0
        .if eax==INVALID_HANDLE_VALUE
                ;invoke  _OutputInfo, g_hOutputCtl, CTXT("打开文件出错!!!")
                ret
        .endif
        mov     hFile, eax
        invoke  WriteFile, hFile, lpMem, dwFileSize, addr dwReturn, 0
        invoke  CloseHandle, hFile
        
        invoke  GlobalFree, lpMem
        popad
        ret
_RebuildPE endp
assume	esi:nothing
assume	eax:nothing
assume	ebx:nothing

⌨️ 快捷键说明

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