;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 错误 Handler
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Handler proc C _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContext
pushad
mov esi,_lpExceptionRecord
mov edi,_lpContext
assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
mov eax,_lpSEH
push [eax + 0ch]
pop [edi].regEbp
push [eax + 8]
pop [edi].regEip
push eax
pop [edi].regEsp
assume esi:nothing,edi:nothing
popad
mov eax,ExceptionContinueExecution
ret
_Handler endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_LoadIsPEFile proc lpFilename,pstMapFile,hWnd
local @hFile,@hMapFile,@ImageBase,@dwFileSize,@lpMemory
invoke RtlZeroMemory,offset stMapFile,sizeof stMapFile
;********************************************************************
; 打开文件并建立文件 Mapping,判断是不是PE格式文件
;********************************************************************
invoke CreateFile,lpFilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL
.if eax != INVALID_HANDLE_VALUE
mov @hFile,eax
invoke GetFileSize,eax,NULL
mov @dwFileSize,eax
.if eax
invoke CreateFileMapping,@hFile,NULL,PAGE_READONLY,0,0,NULL
.if eax
mov @hMapFile,eax
invoke MapViewOfFile,eax,FILE_MAP_READ,0,0,0
.if eax
mov @lpMemory,eax
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
assume fs:nothing
push ebp
push offset _ErrFormat
push offset _Handler
push fs:[0]
mov fs:[0],esp
;********************************************************************
; 检测 PE 文件是否有效
;********************************************************************
mov esi,@lpMemory
assume esi:ptr IMAGE_DOS_HEADER
.if [esi].e_magic != IMAGE_DOS_SIGNATURE
jmp _ErrFormat
.endif
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
.if [esi].Signature != IMAGE_NT_SIGNATURE
jmp _ErrFormat
.endif
push ebx
xor ebx,ebx
mov ebx,pstMapFile
assume ebx:ptr _MAPFILE_STRUCT
mov eax,@hFile
mov [ebx].hFile,eax
mov eax,@hMapFile
mov [ebx].hMapFile,eax
mov eax,@lpMemory
mov [ebx].ImageBase,eax
mov eax,@dwFileSize
mov [ebx].dwFilesize,eax
mov [ebx].lpPEHeader,esi
assume ebx:nothing
pop ebx
jmp _ErrorExit
_ErrFormat:
invoke MessageBox,hWnd,addr szErrFormat,NULL,MB_OK
_ErrorExit:
pop fs:[0]
add esp,0ch
.endif
.endif
.endif
.else
INVOKE MessageBox,0,OFFSET szOpenFileErrorMsg,0,MB_OK
.endif
@@:
ret
_LoadIsPEFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;关闭已经创建的文件
_UnLoadFile proc pstMapFile
push ebx
xor ebx,ebx
mov ebx,pstMapFile
assume ebx:ptr _MAPFILE_STRUCT
.if [ebx].ImageBase
invoke CloseHandle,[ebx].ImageBase
.endif
.if [ebx].hMapFile
invoke CloseHandle,[ebx].hMapFile
.endif
.if [ebx].hFile
invoke CloseHandle,[ebx].hFile
.endif
assume ebx:nothing
pop ebx
ret
_UnLoadFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;RVA转变为offset
_RVAToOffset proc _lpPEHeader,_dwRVA
local @Return:DWORD
pushad
mov esi,_lpPEHeader
assume esi:ptr IMAGE_NT_HEADERS
mov edi,_dwRVA
mov edx,esi
add edx,sizeof IMAGE_NT_HEADERS
assume edx:ptr IMAGE_SECTION_HEADER
movzx ecx,[esi].FileHeader.NumberOfSections
;********************************************************************
; 扫描每个节区并判断 RVA 是否位于这个节区内
;********************************************************************
.repeat
mov eax,[edx].VirtualAddress
add eax,[edx].SizeOfRawData ;eax = Section End
.if (edi >= [edx].VirtualAddress) && (edi < eax)
mov eax,[edx].VirtualAddress ;eax= Section start
sub edi,eax ;edi = offset in section
mov eax,[edx].PointerToRawData
add eax,edi ;eax = file offset
jmp @F
.endif
add edx,sizeof IMAGE_SECTION_HEADER
.untilcxz
assume edx:nothing
assume esi:nothing
mov eax,-1
@@:
mov @Return,eax
popad
mov eax,@Return
ret
_RVAToOffset endp
_GetRVAInSection proc _lpPEHeader,_dwRVA
local @Return
pushad
mov esi,_lpPEHeader
assume esi:ptr IMAGE_NT_HEADERS
mov edi,_dwRVA
mov edx,esi
add edx,sizeof IMAGE_NT_HEADERS
assume edx:ptr IMAGE_SECTION_HEADER
movzx ecx,[esi].FileHeader.NumberOfSections
;********************************************************************
; 扫描每个节区并判断 RVA 是否位于这个节区内
;********************************************************************
.repeat
mov eax,[edx].VirtualAddress
add eax,[edx].SizeOfRawData ;eax = Section End
.if (edi >= [edx].VirtualAddress) && (edi < eax)
mov eax,edx ;eax= Section Name
jmp @F
.endif
add edx,sizeof IMAGE_SECTION_HEADER
.untilcxz
assume edx:nothing
assume esi:nothing
mov eax,offset szNotFound
@@:
mov @Return,eax
popad
mov eax,@Return
ret
_GetRVAInSection endp