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