首页
社区
课程
招聘
cyclotron's Win32 PE Library
发表于: 2005-5-6 19:12 11827

cyclotron's Win32 PE Library

2005-5-6 19:12
11827

Pamqara写过一个PELibrary,但自己写的东西毕竟用起来比较顺手,所以自己建了一个简单的library,给写壳提供了一些特别的方便性.
时间关系,注释不是很详细,让代码来说话吧,欢迎报告bug和扩充库:)

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;>>>>>>>>             Win32 PE Library            >>>>>>>>>>>>>>>

;>>>>>>>>               by cyclotron              >>>>>>>>>>>>>>>

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.486
.model flat, stdcall
option casemap:none

include windows.inc
include user32.inc
include kernel32.inc
include comdlg32.inc
includelib user32.lib
includelib kernel32.lib
includelib comdlg32.lib

InitFileMap        proto
CheckPEValidity        proto
CloseFileMap        proto
GetPeInfo        proto        :dword
RVA2Offset        proto        :dword
Offset2RVA        proto        :dword
GetImportsInfo        proto        :dword
GetCodeScnInfo        proto        :dword
ObfuscateOEP        proto        :dword
UpdateEntryPoint        proto        :dword
AlignFile        proto        :dword
AlignScn        proto        :dword
AddSection        proto        :dword,:dword,:dword
GetScnInfo        proto        :dword,:dword
GetExtraDataInfo        proto        :dword
MergeScns        proto        :dword,:dword,:dword
OpenFileDialog        proto
CreateOutFile        proto
AppendScnCode        proto        :dword,:dword,:dword,:dword
UpdatePackedScnHeader        proto        :dword,:dword,:dword
CheckPackingFlag        proto        :dword
SetPackingFlag        proto        :dword
UpdateImportRVA        proto        :dword
GetStrLen        proto        :dword
tEHash                proto        :dword,:dword,:dword
crc32                proto        :dword,:dword

.data
hInFile                dd        0
hOutFile        dd        0
dwFileSize        dd        0
lpBytesRead        dd        0
lpPeHeader        dd        0
lpFileHeader        dd        0
szPeFileName        db        MAX_PATH dup(0)
szFilter        db        'eXeFiles',0,'*.exe',0,'All Files',0,'*.*',0,0
szCurrentDir        db        '.',0
szTitle                db        'Win32 PE Library - Proudly Presented by cyclotron',0
CurrentHashOffset        dd        0

;STRUCTURES
PE_INFO        struct
        dwEntryPointRVA        dd        ?
        dwImageBase        dd        ?
        dwSectionAlignment        dd        ?
        dwFileAlignment        dd        ?
        dwSizeOfImage        dd        ?
        dwCheckSum        dd        ?
        dwNumberOfSections        dd        ?
PE_INFO        ends

IMPORTS_INFO        struct
        dwImportDirRVA        dd        ?
        dwImportDirSize        dd        ?
        lpImportDir        dd        ?
        dwIATDirRVA        dd        ?
        dwIATDirSize        dd        ?
        lpIATDir        dd        ?
IMPORTS_INFO        ends

SCN_INFO        struct
        szName                dq        0
        dwVirtualSize        dd        ?
        dwVirtualAddress        dd        ?
        dwRawSize        dd        ?
        dwRawAddress        dd        ?
        dwCharacteristics        dd        ?
        lpScn                dd        ?
SCN_INFO        ends

EXTRADATA_INFO        struct
        dwRawAddress        dd        ?
        dwSize                dd        ?
        lpExtraData        dd        ?
EXTRADATA_INFO        ends

.code
InitFileMap        proc
        invoke        CreateFile,offset szPeFileName,\
                       GENERIC_READ,\
                       FILE_SHARE_READ,\
                       NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,\
                       NULL       
        .if        eax == INVALID_HANDLE_VALUE
                mov        eax,FALSE
                ret
        .else
                mov        hInFile,eax
        .endif
        invoke        GetFileSize,hInFile,NULL
        mov        dwFileSize,eax
        invoke        VirtualAlloc,NULL,eax,MEM_COMMIT,PAGE_READWRITE
        mov        lpFileHeader,eax
        invoke        ReadFile,hInFile,eax,dwFileSize,offset lpBytesRead,NULL
        .if        eax != 0
                mov        eax,TRUE
        .else
                mov        eax,FALSE
        .endif
        ret
InitFileMap        endp

CheckPEValidity        proc        uses esi
        mov        esi,lpFileHeader
        .if        word ptr [esi] == IMAGE_DOS_SIGNATURE
                assume        esi:ptr IMAGE_DOS_HEADER
                add        esi,[esi].e_lfanew
                assume        esi:nothing
                .if        word ptr [esi] == IMAGE_NT_SIGNATURE
                        mov        lpPeHeader,esi
                .else
                        mov        eax,FALSE
                        ret
                .endif
        .else
                mov        eax,FALSE
                ret
        .endif
        mov        eax,TRUE
        ret
CheckPEValidity        endp

CloseFileMap        proc
        invoke        VirtualFree,lpFileHeader,0,MEM_RELEASE
        .if        eax==0
                mov        eax,FALSE
                       ret
        .endif
        mov        lpFileHeader,0
        invoke        CloseHandle,hInFile
        mov        hInFile,0
        mov        eax,TRUE
        ret
CloseFileMap        endp

GetPeInfo        proc        uses esi edi @lpPeInfo:dword
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        edi,@lpPeInfo
        assume        edi:ptr PE_INFO
        push        [esi].OptionalHeader.AddressOfEntryPoint
        pop        [edi].dwEntryPointRVA
        push        [esi].OptionalHeader.ImageBase
        pop        [edi].dwImageBase
        push        [esi].OptionalHeader.SectionAlignment
        pop        [edi].dwSectionAlignment
        push        [esi].OptionalHeader.FileAlignment
        pop        [edi].dwFileAlignment
        push        [esi].OptionalHeader.SizeOfImage
        pop        [edi].dwSizeOfImage
        push        [esi].OptionalHeader.CheckSum
        pop        [edi].dwCheckSum
        mov        ax,[esi].FileHeader.NumberOfSections
        cwd
        mov        [edi].dwNumberOfSections,eax
        assume        esi:nothing
        assume        edi:nothing
        ret
GetPeInfo        endp

RVA2Offset        proc        uses ebx ecx edx edi esi @dwRVA:dword
        mov        esi,lpFileHeader
        assume        esi:ptr IMAGE_DOS_HEADER
        add        esi,[esi].e_lfanew
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        edi,@dwRVA
        mov        edx,esi
        add        edx,sizeof IMAGE_NT_HEADERS
        mov        cx,[esi].FileHeader.NumberOfSections
        movzx        ecx,cx
        assume        edx:ptr IMAGE_SECTION_HEADER
        .while        ecx > 0
                .if        edi >= [edx].VirtualAddress
                        mov        eax,[edx].VirtualAddress
                        add        eax,[edx].SizeOfRawData
                        .if        edi < eax
                                mov        eax,[edx].VirtualAddress
                                sub        edi,eax
                                mov        eax,[edx].PointerToRawData
                                add        eax,edi
                                ret
                        .endif
                .endif
                add        edx,sizeof IMAGE_SECTION_HEADER
                dec        ecx
        .endw
        assume        edx:nothing
        assume        esi:nothing
        mov        eax,FALSE
        ret
RVA2Offset        endp

Offset2RVA        proc        uses ebx ecx edx edi esi @dwOffset:dword
        mov        esi,lpFileHeader
        assume        esi:ptr IMAGE_DOS_HEADER
        add        esi,[esi].e_lfanew
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        edi,@dwOffset
        mov        edx,esi
        add        edx,sizeof IMAGE_NT_HEADERS
        mov        cx,[esi].FileHeader.NumberOfSections
        movzx        ecx,cx
        assume        edx:ptr IMAGE_SECTION_HEADER
        .while        ecx > 0
                .if        edi >= [edx].PointerToRawData
                        mov        eax,[edx].PointerToRawData
                        add        eax,[edx].SizeOfRawData
                        .if        edi < eax
                                mov        eax,[edx].PointerToRawData
                                sub        edi,eax
                                mov        eax,[edx].VirtualAddress
                                add        eax,edi
                                ret
                        .endif
                .endif
                add edx,sizeof IMAGE_SECTION_HEADER
                dec ecx
        .endw
        assume        edx:nothing
        assume        esi:nothing
        mov        eax,FALSE
        ret
Offset2RVA        endp

GetImportsInfo        proc        uses ebx esi edi @lpImportsInfo:dword
        local        @dwIATMin:dword
        local        @dwIATMax:dword
       
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        lea        eax,[esi].OptionalHeader.DataDirectory\
                        [IMAGE_DIRECTORY_ENTRY_IMPORT*sizeof IMAGE_DATA_DIRECTORY]
        mov        esi,eax
        assume        esi:ptr IMAGE_DATA_DIRECTORY
        mov        edi,@lpImportsInfo
        assume        edi:ptr IMPORTS_INFO
        mov        eax,[esi].VirtualAddress
        mov        [edi].dwImportDirRVA,eax
        invoke        RVA2Offset,eax
        add        eax,lpFileHeader
        mov        [edi].lpImportDir,eax
        push        [esi].isize
        pop        [edi].dwImportDirSize
       
        xor        eax,eax
        mov        @dwIATMax,eax
        or        eax,7FFFFFFFh
        mov        @dwIATMin,eax
       
        mov        eax,[esi].VirtualAddress
        invoke        RVA2Offset,eax
        add        eax,lpFileHeader
        mov        esi,eax
        assume        esi:ptr IMAGE_IMPORT_DESCRIPTOR
        .while        [esi].OriginalFirstThunk || [esi].TimeDateStamp || \
                        [esi].ForwarderChain || [esi].Name1 || [esi].FirstThunk
                .if        [esi].OriginalFirstThunk
                        mov        ebx,[esi].OriginalFirstThunk
                .else
                        mov        ebx,[esi].FirstThunk
                .endif
                invoke        RVA2Offset,ebx
                mov        ebx,eax
                add        ebx,lpFileHeader
                mov        eax,[esi].FirstThunk
                .while        dword ptr [ebx]
                        .if        eax < @dwIATMin
                                mov        @dwIATMin,eax
                        .endif
                        .if        eax > @dwIATMax
                                mov        @dwIATMax,eax
                        .endif
                        add        eax,4
                        add        ebx,4
                .endw
                add        esi,sizeof IMAGE_IMPORT_DESCRIPTOR
        .endw
        push        @dwIATMin
        pop        [edi].dwIATDirRVA
        mov        eax,@dwIATMax
        sub        eax,@dwIATMin
        add        eax,4
        mov        [edi].dwIATDirSize,eax
        invoke        RVA2Offset,@dwIATMin
        add        eax,lpFileHeader
        mov        [edi].lpIATDir,eax
        assume        esi:nothing
        assume        edi:nothing
        ret
GetImportsInfo        endp

GetCodeScnInfo        proc        uses ebx ecx edx esi edi @lpCodeScnInfo:dword
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        ebx,[esi].OptionalHeader.AddressOfEntryPoint
       
        mov        edx,esi
        add        edx,sizeof IMAGE_NT_HEADERS
        mov        cx,[esi].FileHeader.NumberOfSections
        movzx        ecx,cx
        assume        edx:ptr IMAGE_SECTION_HEADER
        .while        ecx > 0
                .if        ebx >= [edx].VirtualAddress
                        mov        eax,[edx].VirtualAddress
                        add        eax,[edx].SizeOfRawData
                        .if        ebx < eax
                                mov        edi,@lpCodeScnInfo
                                assume        edi:ptr SCN_INFO
                                push        [edx].VirtualAddress
                                pop        [edi].dwVirtualAddress
                                push        [edx].Misc.VirtualSize
                                pop        [edi].dwVirtualSize
                                push        [edx].SizeOfRawData
                                pop        [edi].dwRawSize
                                push        [edx].Characteristics
                                pop        [edi].dwCharacteristics
                                mov        eax,[edx].PointerToRawData
                                mov        [edi].dwRawAddress,eax
                                add        eax,lpFileHeader
                                mov        [edi].lpScn,eax
                                mov        esi,edx
                                mov        ecx,8
                                rep        movsb
                                mov        eax,TRUE
                                ret
                        .endif
                .endif
                add        edx,sizeof IMAGE_SECTION_HEADER
                dec        ecx
        .endw
        assume        esi:nothing
        assume        edi:nothing
        assume        edx:nothing
        mov        eax,FALSE
        ret
GetCodeScnInfo        endp

; 偷取原始入口点的部分指令,经变形后存储在指定区域,清除原来的指令,返回值为结束偷取后第一条指令的RVA
ObfuscateOEP        proc        uses ecx esi edi @lpSubstitution:dword
        mov        esi,lpPeHeader
        mov        edi,@lpSubstitution
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        eax,[esi].OptionalHeader.AddressOfEntryPoint
        assume        esi:nothing
        invoke        RVA2Offset,eax
        add        eax,lpFileHeader
        mov        esi,eax
        mov        eax,[esi]
        .while        al != 0E8h && ax != 15FFh && ax != 25FFh &&\
                al != 74h && al != 75h && al != 76h && al != 77h && al != 0E9h && al != 0EBh
                .if        al == 55h                ;push ebp
                        mov        eax,4EC8303h        ;sub esp,4        //3 bytes
                        stosd
                        mov        eax,242C8903h        ;mov [esp],ebp        //3 bytes
                        stosd
                        xor        al,al
                        mov        [esi],al
                        inc        esi
                .elseif        ax == 0EC8Bh                ;mov ebp,esp
                        mov        ax,5401h        ;push esp        //1 byte
                        stosw
                        mov        ax,5D01h        ;pop ebp        //1 byte
                        stosw
                        xor        ax,ax
                        mov        [esi],ax
                        add        esi,2
                .elseif        al == 6Ah                ;push byte        //2 bytes
                        mov        byte ptr [edi],2
                        inc        edi
                        movsw
                        xor        ax,ax
                        mov        [esi-2],ax
                .elseif        al == 68h                ;push dword
                        mov        ax,5001h        ;push eax        //1 byte
                        stosw
                        mov        eax,2404C707h        ;mov dword ptr [esp],XXXXXXXXX        //7 bytes
                        stosd
                        xor        eax,eax
                        mov        [esi],al
                        inc        esi
                        movsd
                        sub        esi,4
                        mov        [esi],eax
                        add        esi,4
                .elseif        al == 64h
                        inc        esi
                        mov        ax,[esi]
                        .if        ax == 0A1h        ;mov eax,fs:[0]
                                mov        byte ptr [edi],2
                                inc        edi
                                mov        ax,0C033h        ;xor eax,eax        //2 bytes
                                stosw
                                mov        eax,30FF6403h        ;push dword ptr fs:[eax]        //3 bytes
                                stosd
                                mov        ax,5801h        ;pop eax        //1 byte
                                stosw
                                inc        esi
                                xor        eax,eax
                                mov        [esi-2],ax
                                mov        [esi],eax
                                add        esi,4
                        .elseif        ax == 2589h        ;mov fs:[0],esp
                                mov        ax,5401h        ;push esp        //1 byte
                                stosw
                                mov        eax,58F6407h        ;pop dword ptr fs:[0]        //7 bytes
                                stosd
                                xor        eax,eax
                                stosd
                                add        esi,2
                                mov        [esi-4],eax
                                mov        [esi],eax
                                add        esi,4
                        .endif
                .elseif        al == 50h        ;push eax
                        mov        eax,4EC8303h        ;sub esp,4        //3 bytes
                        stosd
                        mov        eax,24048903h        ;mov [esp],eax        //3 bytes
                        stosd
                        xor        al,al
                        mov        [esi],al
                        inc        esi
                .elseif        al == 53h        ;push ebx
                        mov        eax,4EC8303h        ;sub esp,4        //3 bytes
                        stosd
                        mov        eax,241C8903h        ;mov [esp],ebx        //3 bytes
                        stosd
                        xor        al,al
                        mov        [esi],al
                        inc        esi
                .elseif        al == 56h        ;push esi
                        mov        eax,4EC8303h        ;sub esp,4        //3 bytes
                        stosd
                        mov        eax,24348903h        ;mov [esp],edi        //3 bytes
                        stosd
                        xor        al,al
                        mov        [esi],al
                        inc        esi
                .elseif        al == 57h        ;push edi
                        mov        eax,4EC8303h        ;sub esp,4        //3 bytes
                        stosd
                        mov        eax,243C8903h        ;mov [esp],esi        //3 bytes
                        stosd
                        xor        al,al
                        mov        [esi],al
                        inc        esi
                .elseif        ax == 0C483h        ;add esp,XX
                        mov        eax,[esi]
                        shl        eax,8
                        mov        al,3
                        stosd
                        dec        esi
                        xor        eax,eax
                        mov        [esi],eax
                        add        esi,4
                .elseif        ax == 0EC83h        ;sub esp,XX
                        mov        ax,5101h        ;push ecx        //1 byte
                        stosw
                        lodsd
                        shl        eax,8                ;sub esp,(XX-4)        //3 bytes
                        mov        al,3
                        sub        eax,4000000h
                        stosd
                        sub        esi,5
                        xor        eax,eax
                        mov        [esi],eax
                        add        esi,4
                .elseif        ax == 6589h        ;mov [ebp+XX],esp
                        mov        eax,[esi]
                        shl        eax,8
                        mov        al,3
                        stosd
                        dec        esi
                        xor        eax,eax
                        mov        [esi],eax
                        add        esi,4
                .elseif        ax == 45C7h        ;mov [ebp+XX],XXXXXXXX
                        mov        ax,6805h        ;push XXXXXXXX        //5 bytes
                        stosw
                        add        esi,3
                        movsd
                        sub        esi,5
                        lodsb
                        shl        eax,16
                        mov        ax,458Fh        ;pop [ebp+XX]        //3 bytes
                        shl        eax,8
                        mov        al,3
                        stosd
                        xor        eax,eax
                        mov        [esi-4],eax
                        mov        [esi],eax
                        add        esi,4
                .elseif        ax == 0DB33h        ;xor ebx,ebx
                        mov        byte ptr [edi],2
                        mov        ax,0DB2Bh
                        stosw
                        xor        ax,ax
                        mov        [esi],ax
                        add        esi,2
                .elseif        ax == 5D89h        ;mov [ebp+XX],ebx
                        mov        eax,[esi]
                        shl        eax,8
                        mov        al,3
                        stosd
                        dec        esi
                        xor        eax,eax
                        mov        [esi],eax
                        add        esi,4
                .else
                        .break
                .endif
                mov        eax,[esi]
        .endw
        xor        al,al
        stosb
        sub        esi,lpFileHeader
        invoke        Offset2RVA,esi
        ret
ObfuscateOEP        endp

; 更新入口点RVA,返回值为原入口点RVA
UpdateEntryPoint        proc        uses esi @dwNewEntryPoint:dword        ;Return OEP
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        eax,[esi].OptionalHeader.AddressOfEntryPoint
        push        @dwNewEntryPoint
        pop        [esi].OptionalHeader.AddressOfEntryPoint
        assume        esi:nothing
        ret
UpdateEntryPoint        endp

; 将输入双子按磁盘文件对齐值对齐
AlignFile        proc        uses ecx edx esi @OrgSize:dword
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        ecx,[esi].OptionalHeader.FileAlignment
        assume        esi:nothing
        mov        eax,@OrgSize
        cdq
        div        ecx
        .if        edx != 0
                inc        eax
        .endif
        mul        ecx
        ret
AlignFile        endp

; 将输入双子按区块对齐值对齐
AlignScn        proc        uses ecx edx esi @OrgSize:dword
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        ecx,[esi].OptionalHeader.SectionAlignment
        assume        esi:nothing
        mov        eax,@OrgSize
        cdq
        div        ecx
        .if        edx != 0
                inc        eax
        .endif
        mul        ecx
        ret
AlignScn        endp

; 增加一个区块的块头信息,可以指定区块名称、大小和属性,同时更新NumberOfSections字段和ImageSize字段,调用了GetScnInfo
AddSection        proc        uses ebx ecx edx esi edi @szScnName:dword,@dwSize:dword,@dwCharacteristics:dword
        local        @stNewScnInfo:SCN_INFO
        local        @dwImageSize
       
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        lea        ebx,[esi].OptionalHeader.DataDirectory\
                        [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT*sizeof IMAGE_DATA_DIRECTORY]
        mov        edi,[ebx]
        .if        edi != 0
                add        edi,lpFileHeader
                mov        ecx,[ebx+4]
                rep        stosb
                mov        edi,ebx
                mov        ecx,sizeof IMAGE_DATA_DIRECTORY
                rep        stosb
        .endif
        xor        ecx,ecx
        mov        cx,[esi].FileHeader.NumberOfSections
        add        esi,sizeof IMAGE_NT_HEADERS
        assume        esi:ptr IMAGE_SECTION_HEADER
        mov        edi,[esi].PointerToRawData
        add        edi,lpFileHeader
        mov        eax,sizeof IMAGE_SECTION_HEADER
        mul        ecx
        add        esi,eax
        add        esi,sizeof IMAGE_SECTION_HEADER
        .if        esi <= edi
                sub        esi,sizeof IMAGE_SECTION_HEADER
                invoke        GetScnInfo,0,addr @stNewScnInfo
                push        @dwSize
                pop        [esi].Misc.VirtualSize
                mov        eax,@stNewScnInfo.dwVirtualSize
                invoke        AlignScn,eax
                add        eax,@stNewScnInfo.dwVirtualAddress
                mov        [esi].VirtualAddress,eax
                add        eax,@dwSize
                mov        @dwImageSize,eax
                invoke        AlignFile,@dwSize
                mov        [esi].SizeOfRawData,eax
                mov        eax,@stNewScnInfo.dwRawSize
                invoke        AlignFile,eax
                add        eax,@stNewScnInfo.dwRawAddress
                mov        [esi].PointerToRawData,eax
                push        @dwCharacteristics
                pop        [esi].Characteristics
                mov        edi,@szScnName
                xchg        esi,edi
                mov        ecx,8
                rep        movsb
                mov        esi,lpPeHeader
                assume        esi:ptr IMAGE_NT_HEADERS
                inc        [esi].FileHeader.NumberOfSections
                push        @dwImageSize
                pop        [esi].OptionalHeader.SizeOfImage
                mov        eax,TRUE
        .else
                mov        eax,FALSE
        .endif
        assume        esi:nothing
        assume        edi:nothing
        ret
AddSection        endp

; 取得指定区块的信息,0表示最后一个区块,同时如果输入区块序号大于区块数,也取得最后一个区块的信息
GetScnInfo        proc        uses ecx edx esi edi @nScn:dword,@lpScnInfo:dword       
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        xor        ecx,ecx
        mov        cx,[esi].FileHeader.NumberOfSections
        add        esi,sizeof IMAGE_NT_HEADERS
        .if        @nScn == 0 || @nScn > ecx
                dec        ecx
                mov        @nScn,0
        .else
                mov        ecx,@nScn
                dec        ecx
        .endif
        mov        eax,sizeof IMAGE_SECTION_HEADER
        mul        ecx
        add        esi,eax
        assume        esi:ptr IMAGE_SECTION_HEADER
        mov        edi,@lpScnInfo
        assume        edi:ptr SCN_INFO
        push        [esi].Misc.VirtualSize
        pop        [edi].dwVirtualSize
        push        [esi].VirtualAddress
        pop        [edi].dwVirtualAddress
        push        [esi].SizeOfRawData
        pop        [edi].dwRawSize
        mov        eax,[esi].PointerToRawData
        mov        [edi].dwRawAddress,eax
        add        eax,lpFileHeader
        mov        [edi].lpScn,eax
        push        [esi].Characteristics
        pop        [edi].dwCharacteristics
        mov        ecx,8
        rep        movsb
        .if        @nScn == 0
                mov        eax,FALSE                ;got the last section
        .else
                mov        eax,TRUE
        .endif
        assume        esi:nothing
        assume        edi:nothing
        ret
GetScnInfo        endp

; 取得附加数据的信息
GetExtraDataInfo        proc        uses ecx edx esi @lpExtraDataInfo:dword
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        xor        ecx,ecx
        mov        cx,[esi].FileHeader.NumberOfSections
        add        esi,sizeof IMAGE_NT_HEADERS
        mov        eax,sizeof IMAGE_SECTION_HEADER
        dec        ecx
        mul        ecx
        add        esi,eax
        assume        esi:ptr IMAGE_SECTION_HEADER
        mov        edx,[esi].PointerToRawData
        add        edx,[esi].SizeOfRawData
        push        edx
        invoke        GetFileSize,hInFile,NULL
        pop        edx
        mov        esi,@lpExtraDataInfo
        assume        esi:ptr EXTRADATA_INFO
        .if        eax > edx
                mov        [esi].dwRawAddress,edx
                sub        eax,edx
                mov        [esi].dwSize,eax
                add        edx,lpFileHeader
                mov        [esi].lpExtraData,edx
                mov        eax,TRUE
        .else
                mov        [esi].dwRawAddress,0
                mov        eax,FALSE
        .endif
        assume        esi:nothing
        ret
GetExtraDataInfo        endp

; 合并区块,输入参数包括起始区块序号(从1开始)和终止区块序号,并可以指定合并后的区块名称
MergeScns        proc        uses ebx ecx edx esi edi @nStart:dword,@nEnd:dword,@szScnName:dword
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        xor        ecx,ecx
        mov        cx,[esi].FileHeader.NumberOfSections
        mov        ebx,@nStart
        .if        ecx > ebx || ecx > @nEnd || ebx >= @nEnd
                mov        eax,FALSE
                ret
        .endif
       
        xor        eax,eax
        mov        ax,[esi].FileHeader.NumberOfSections
        add        eax,@nStart
        sub        eax,@nEnd
        mov        [esi].FileHeader.NumberOfSections,ax
        add        esi,sizeof IMAGE_NT_HEADERS
        assume        esi:ptr IMAGE_SECTION_HEADER
        mov        eax,sizeof IMAGE_SECTION_HEADER
        mov        ecx,ebx
        dec        ecx
        mul        ecx
        add        esi,eax
        mov        edi,esi
        add        edi,sizeof IMAGE_SECTION_HEADER
        assume        edi:ptr IMAGE_SECTION_HEADER
        .while        ebx < @nEnd
                mov        eax,[edi].VirtualAddress
                add        eax,[edi].Misc.VirtualSize
                sub        eax,[esi].VirtualAddress
                mov        [esi].Misc.VirtualSize,eax
                mov        eax,[edi].SizeOfRawData
                add        [esi].SizeOfRawData,eax
                mov        eax,[edi].Characteristics
                or        [esi].Characteristics,eax
                add        edi,sizeof IMAGE_SECTION_HEADER
                inc        ebx
        .endw
        mov        ebx,@nEnd
        sub        ebx,@nStart
        push        esi
        add        esi,sizeof IMAGE_SECTION_HEADER
        .while        ebx > 0
                xchg        esi,edi
                mov        ecx,sizeof IMAGE_SECTION_HEADER
                rep        movsb
                xor        al,al
                xchg        esi,edi
                sub        edi,sizeof IMAGE_SECTION_HEADER
                rep        stosb
                dec        ebx
        .endw
        pop        esi
        mov        edi,@szScnName
        mov        ecx,8
        xchg        esi,edi
        rep        movsb
        assume        esi:nothing
        assume        edi:nothing
        mov        eax,TRUE
        ret
MergeScns        endp

; 调用通用对话框打开PE文件
OpenFileDialog        proc        uses ecx edi
        local        stofn:OPENFILENAME
       
        xor        al,al
        lea        edi,stofn
        mov        ecx,sizeof OPENFILENAME
        rep        stosb
        mov        stofn.lStructSize,sizeof OPENFILENAME
        mov        stofn.lpstrFilter,offset szFilter
        mov        stofn.lpstrFile,offset szPeFileName
        mov        stofn.nMaxFile,sizeof szPeFileName
        mov        stofn.lpstrInitialDir,offset szCurrentDir
        mov        stofn.lpstrTitle,offset szTitle
        mov        stofn.Flags,OFN_FILEMUSTEXIST or OFN_LONGNAMES or OFN_PATHMUSTEXIST
        invoke        GetOpenFileName,addr stofn
        .if        eax == 0
                mov        eax,FALSE
        .else
                mov        eax,TRUE
        .endif
        ret
OpenFileDialog        endp

; 输出文件命名为xxx_.exe,并创建该文件,返回值为该文件的句柄
CreateOutFile        proc        uses ecx edi
        lea        edi,szPeFileName
        xor        ecx,ecx
        dec        ecx
        mov        al,'.'
        repnz        scasb
        dec        edi
        mov        al,'_'
        stosb
        mov        eax,'exe.'
        stosd
        xor        al,al
        stosb
        invoke        CreateFile,offset szPeFileName,GENERIC_READ or GENERIC_WRITE,\
                                        FILE_SHARE_READ,\
                                        NULL,CREATE_ALWAYS,\
                                        FILE_ATTRIBUTE_NORMAL,NULL
        .if        eax == INVALID_HANDLE_VALUE
                mov        eax,FALSE
        .endif
        ret
CreateOutFile        endp

; 在新文件中写入新增区块并补上附加数据
AppendScnCode        proc        uses ebx esi edi @lpOrgLastScnInfo:dword,@lpExtraDataInfo:dword,\
                                        @lpNewScnData:dword,@dwNewScnSize:dword
        local        lpBytesWritten:dword
       
        mov        esi,@lpOrgLastScnInfo
        assume        esi:ptr SCN_INFO
        mov        ebx,[esi].dwRawSize
        add        ebx,[esi].dwRawAddress
        invoke        WriteFile,hOutFile,lpFileHeader,ebx,addr lpBytesWritten,NULL
        invoke        AlignFile,@dwNewScnSize
        mov        ebx,eax
        invoke        WriteFile,hOutFile,@lpNewScnData,ebx,addr lpBytesWritten,NULL
        mov        edi,@lpExtraDataInfo
        assume        edi:ptr EXTRADATA_INFO
        .if        [edi].dwRawAddress != 0
                invoke        WriteFile,hOutFile,[edi].lpExtraData,[edi].dwSize,addr lpBytesWritten,NULL
        .endif
        invoke        SetEndOfFile,hOutFile
        assume        esi:nothing
        assume        edi:nothing
        ret
AppendScnCode        endp

; 当区块被压缩以后,其参数要作相应的调整
UpdatePackedScnHeader        proc        uses ecx edx esi edi @nScn:dword,@dwSize:dword,@dwCharacteristics:dword
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        xor        ecx,ecx
        mov        cx,[esi].FileHeader.NumberOfSections
        .if        @nScn > ecx
                mov        eax,FALSE
                ret
        .endif
        add        esi,sizeof IMAGE_NT_HEADERS
        assume        esi:ptr IMAGE_SECTION_HEADER
        .if        @nScn == 1
                push        @dwSize
                pop        [esi].Misc.VirtualSize
                invoke        AlignFile,@dwSize
                mov        [esi].SizeOfRawData,eax
                push        @dwCharacteristics
                pop        [esi].Characteristics
        .else
                mov        ecx,@nScn
                dec        ecx
                mov        eax,sizeof IMAGE_SECTION_HEADER
                mul        ecx
                add        esi,eax
                mov        edi,esi
                sub        esi,sizeof IMAGE_SECTION_HEADER
                assume        edi:ptr IMAGE_SECTION_HEADER
                push        @dwSize
                pop        [edi].Misc.VirtualSize
                invoke        AlignScn,@dwSize
                add        eax,[esi].VirtualAddress
                mov        [edi].VirtualAddress,eax
                invoke        AlignFile,@dwSize
                mov        [edi].SizeOfRawData,eax
                add        eax,[esi].PointerToRawData
                mov        [edi].PointerToRawData,eax
                push        @dwCharacteristics
                pop        [edi].Characteristics               
        .endif
        assume        esi:nothing
        assume        edi:nothing
        mov        eax,TRUE
        ret
UpdatePackedScnHeader        endp

CheckPackingFlag        proc        uses esi @dwFlag:dword
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        eax,[esi].FileHeader.NumberOfSymbols
        .if        eax == @dwFlag
                mov        eax,TRUE
        .else
                mov        eax,FALSE
        .endif
        assume        esi:nothing
        ret
CheckPackingFlag        endp

SetPackingFlag        proc        uses esi @dwFlag:dword
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        push        @dwFlag
        pop        [esi].FileHeader.NumberOfSymbols
        assume        esi:nothing
        ret
SetPackingFlag        endp

; 更新输入表RVA,返回值为原来的RVA
UpdateImportRVA        proc        uses ebx esi @NewImportRVA
        mov        esi,lpPeHeader
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        eax,@NewImportRVA
        lea        ebx,[esi].OptionalHeader.DataDirectory\
                        [IMAGE_DIRECTORY_ENTRY_IMPORT*sizeof IMAGE_DATA_DIRECTORY]
        xchg        eax,[ebx]
        assume        esi:nothing
        ret
UpdateImportRVA        endp

GetStrLen        proc        uses ecx edi @lpString:dword
        or        ecx,0FFFFFFFFh
        xor        al,al
        mov        edi,@lpString
        repnz        scasb
        not        ecx
        dec        ecx
        mov        eax,ecx
        ret
GetStrLen        endp

; tElock中提取出来的校验算法修改版,@dwKey一般可以传入循环计数值
tEHash        proc        uses ebx ecx edx esi edi @SrcStart:dword,@SrcSize:dword,@dwKey:dword
        mov        esi,@SrcStart
        mov        ebx,@SrcSize
        xor        ecx,ecx
        lea        eax,[ecx-1]
        mov        edi,@dwKey
HasheLoop:
        xor        edx,edx
        mov        dl,[esi]
        xor        dl,al
HashiLoop:
        shr        edx,1
        jnb        @F
        add        edx,edi
@@:
        inc        ecx
        and        cl,7
        jnz        HashiLoop
        shr        eax,8
        xor        eax,edx
        inc        esi
        dec        ebx
        jg        HasheLoop
        not        eax
        ret
tEHash        endp

crc32        proc        @lData:dword,@ptrData:dword
        push        esi
        push        ecx
        push        edx

        mov        esi, @ptrData
        xor        edx, edx
        or        eax, -1
        mov        ecx, @lData

crc32_loop:
        mov        dl, byte ptr [esi]
        xor        dl, al
        shr        eax, 8
        xor        eax, dword ptr [crc32_table + 4*edx]
        inc        esi
        dec        ecx
        jnz        crc32_loop

        not        eax

        pop        edx
        pop        ecx
        pop        esi
        ret

crc32_table        dd        000000000h, 077073096h, 0EE0E612Ch, 0990951BAh, 0076DC419h
                dd        0706AF48Fh, 0E963A535h, 09E6495A3h, 00EDB8832h, 079DCB8A4h
                dd        0E0D5E91Eh, 097D2D988h, 009B64C2Bh, 07EB17CBDh, 0E7B82D07h
                dd        090BF1D91h, 01DB71064h, 06AB020F2h, 0F3B97148h, 084BE41DEh
                dd        01ADAD47Dh, 06DDDE4EBh, 0F4D4B551h, 083D385C7h, 0136C9856h
                dd        0646BA8C0h, 0FD62F97Ah, 08A65C9ECh, 014015C4Fh, 063066CD9h
                dd        0FA0F3D63h, 08D080DF5h, 03B6E20C8h, 04C69105Eh, 0D56041E4h
                dd        0A2677172h, 03C03E4D1h, 04B04D447h, 0D20D85FDh, 0A50AB56Bh
                dd        035B5A8FAh, 042B2986Ch, 0DBBBC9D6h, 0ACBCF940h, 032D86CE3h
                dd        045DF5C75h, 0DCD60DCFh, 0ABD13D59h, 026D930ACh, 051DE003Ah
                dd        0C8D75180h, 0BFD06116h, 021B4F4B5h, 056B3C423h, 0CFBA9599h
                dd        0B8BDA50Fh, 02802B89Eh, 05F058808h, 0C60CD9B2h, 0B10BE924h
                dd        02F6F7C87h, 058684C11h, 0C1611DABh, 0B6662D3Dh, 076DC4190h
                dd        001DB7106h, 098D220BCh, 0EFD5102Ah, 071B18589h, 006B6B51Fh
                dd        09FBFE4A5h, 0E8B8D433h, 07807C9A2h, 00F00F934h, 09609A88Eh
                dd        0E10E9818h, 07F6A0DBBh, 0086D3D2Dh, 091646C97h, 0E6635C01h
                dd        06B6B51F4h, 01C6C6162h, 0856530D8h, 0F262004Eh, 06C0695EDh
                dd        01B01A57Bh, 08208F4C1h, 0F50FC457h, 065B0D9C6h, 012B7E950h
                dd        08BBEB8EAh, 0FCB9887Ch, 062DD1DDFh, 015DA2D49h, 08CD37CF3h
                dd        0FBD44C65h, 04DB26158h, 03AB551CEh, 0A3BC0074h, 0D4BB30E2h
                dd        04ADFA541h, 03DD895D7h, 0A4D1C46Dh, 0D3D6F4FBh, 04369E96Ah
                dd        0346ED9FCh, 0AD678846h, 0DA60B8D0h, 044042D73h, 033031DE5h
                dd        0AA0A4C5Fh, 0DD0D7CC9h, 05005713Ch, 0270241AAh, 0BE0B1010h
                dd        0C90C2086h, 05768B525h, 0206F85B3h, 0B966D409h, 0CE61E49Fh
                dd        05EDEF90Eh, 029D9C998h, 0B0D09822h, 0C7D7A8B4h, 059B33D17h
                dd        02EB40D81h, 0B7BD5C3Bh, 0C0BA6CADh, 0EDB88320h, 09ABFB3B6h
                dd        003B6E20Ch, 074B1D29Ah, 0EAD54739h, 09DD277AFh, 004DB2615h
                dd        073DC1683h, 0E3630B12h, 094643B84h, 00D6D6A3Eh, 07A6A5AA8h
                dd        0E40ECF0Bh, 09309FF9Dh, 00A00AE27h, 07D079EB1h, 0F00F9344h
                dd        08708A3D2h, 01E01F268h, 06906C2FEh, 0F762575Dh, 0806567CBh
                dd        0196C3671h, 06E6B06E7h, 0FED41B76h, 089D32BE0h, 010DA7A5Ah
                dd        067DD4ACCh, 0F9B9DF6Fh, 08EBEEFF9h, 017B7BE43h, 060B08ED5h
                dd        0D6D6A3E8h, 0A1D1937Eh, 038D8C2C4h, 04FDFF252h, 0D1BB67F1h
                dd        0A6BC5767h, 03FB506DDh, 048B2364Bh, 0D80D2BDAh, 0AF0A1B4Ch
                dd        036034AF6h, 041047A60h, 0DF60EFC3h, 0A867DF55h, 0316E8EEFh
                dd        04669BE79h, 0CB61B38Ch, 0BC66831Ah, 0256FD2A0h, 05268E236h
                dd        0CC0C7795h, 0BB0B4703h, 0220216B9h, 05505262Fh, 0C5BA3BBEh
                dd        0B2BD0B28h, 02BB45A92h, 05CB36A04h, 0C2D7FFA7h, 0B5D0CF31h
                dd        02CD99E8Bh, 05BDEAE1Dh, 09B64C2B0h, 0EC63F226h, 0756AA39Ch
                dd        0026D930Ah, 09C0906A9h, 0EB0E363Fh, 072076785h, 005005713h
                dd        095BF4A82h, 0E2B87A14h, 07BB12BAEh, 00CB61B38h, 092D28E9Bh
                dd        0E5D5BE0Dh, 07CDCEFB7h, 00BDBDF21h, 086D3D2D4h, 0F1D4E242h
                dd        068DDB3F8h, 01FDA836Eh, 081BE16CDh, 0F6B9265Bh, 06FB077E1h
                dd        018B74777h, 088085AE6h, 0FF0F6A70h, 066063BCAh, 011010B5Ch
                dd        08F659EFFh, 0F862AE69h, 0616BFFD3h, 0166CCF45h, 0A00AE278h
                dd        0D70DD2EEh, 04E048354h, 03903B3C2h, 0A7672661h, 0D06016F7h
                dd        04969474Dh, 03E6E77DBh, 0AED16A4Ah, 0D9D65ADCh, 040DF0B66h
                dd        037D83BF0h, 0A9BCAE53h, 0DEBB9EC5h, 047B2CF7Fh, 030B5FFE9h
                dd        0BDBDF21Ch, 0CABAC28Ah, 053B39330h, 024B4A3A6h, 0BAD03605h
                dd        0CDD70693h, 054DE5729h, 023D967BFh, 0B3667A2Eh, 0C4614AB8h
                dd        05D681B02h, 02A6F2B94h, 0B40BBE37h, 0C30C8EA1h, 05A05DF1Bh
                dd        02D02EF8Dh

crc32                endp

附件:Win32PELib.rar


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (16)
雪    币: 258
活跃值: (230)
能力值: ( LV12,RANK:770 )
在线值:
发帖
回帖
粉丝
2
谢谢共享....
2005-5-6 19:38
0
雪    币: 266
活跃值: (191)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
支持的说。。。
2005-5-6 20:05
0
雪    币: 383
活跃值: (786)
能力值: ( LV12,RANK:730 )
在线值:
发帖
回帖
粉丝
4
继续...
2005-5-6 20:44
0
雪    币: 221
活跃值: (55)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
好东西,可惜汇编不好,要是有C版本的就好了。
2005-5-7 00:12
0
雪    币: 98761
活跃值: (201044)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
6
语言不能,中文不好,sorry,i see you today...
2005-5-7 00:29
0
雪    币: 398
活跃值: (1078)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
7
ctrl+v, ctrl+c
2005-5-7 07:09
0
雪    币: 204
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
最初由 simonzh2000 发布
ctrl+v, ctrl+c


乐的都颠三倒四了,应该ctrl+c,ctrl+v。
2005-5-7 08:42
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
9
最初由 Sen 发布
好东西,可惜汇编不好,要是有C版本的就好了。

虽然我一直坚持汇编是操作PE的最好语言,但以后可能会在学习C++的时候另外写一个库作为练习吧
实际上这个lib可以编译成供C调用的库的,只是全局变量处理起来有点麻烦.
2005-5-7 08:47
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
10
最初由 simonzh2000 发布
ctrl+v, ctrl+c

后面有压缩包啊~
BTW:兄弟的壳进展如何了?
2005-5-7 08:48
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
11
最初由 linhanshi 发布
语言不能,中文不好,sorry,i see you today...

I just cannot quite catch your words
2005-5-7 08:50
0
雪    币: 557
活跃值: (2303)
能力值: ( LV9,RANK:2130 )
在线值:
发帖
回帖
粉丝
12
Good,Thanks DownLoading......
2005-5-7 09:15
0
雪    币: 266
活跃值: (191)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
2005-5-7 21:55
0
雪    币: 214
活跃值: (70)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
最初由 二点 发布
c 的附件:pelibrary.zip


谢谢
2005-5-8 03:12
0
雪    币: 603
活跃值: (617)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
15
不懂~
学习~
支持~
2005-5-8 21:24
0
雪    币: 255
活跃值: (165)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
基于OOP的PE class 可能更实用,面向过程的库就是简洁,但原始、不利于数据的封装,我本来想写一个基于OOP的类PE库,但我现在放弃了,原因是一切即将淘汰了!
2005-5-9 00:00
0
雪    币: 214
活跃值: (100)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
17
2005-5-10 16:04
0
游客
登录 | 注册 方可回帖
返回
//