-
-
[旧帖] [求助]汇编跳转入口问题 0.00雪花
-
发表于: 2014-7-1 16:54 1613
-
问题在这段
push [esi].OptionalHeader.AddressOfEntryPoint
pop @dwEntry
mov eax,@dwAddCodeBase
add eax,(offset _ToOldEntry-offset APPEND_CODE+5)
sub @dwEntry,eax
mov ecx,@dwAddCodeFile
add ecx,(offset _ToOldEntry-offset APPEND_CODE)
invoke SetFilePointer,@hFile,ecx,NULL,FILE_BEGIN
invoke WriteFile,@hFile,addr @dwEntry,4,addr @dwTemp,NULL
请问我把病毒入口后面一条jmp为源程序入口,但实际在执行的时候不会返回原入口执行源程序是不是跳转jmp的地方值不对
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 3rd Edition>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; AddCode 例子的功能模块
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
szErrCreate db '创建文件错误!',0dh,0ah,0
szErrNoRoom db '程序中没有多余的空间可供加入代码!',0dh,0ah,0
szMySection db '.adata',0
szExt db '_new.exe',0
szSuccess db '在文件后附加代码成功,新文件:',0dh,0ah
db '%s',0dh,0ah,0
.code
include _AddCode.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 计算按照指定值对齐后的数值
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Align proc _dwSize,_dwAlign
push edx
mov eax,_dwSize
xor edx,edx
div _dwAlign
.if edx
inc eax
.endif
mul _dwAlign
pop edx
ret
_Align endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcessPeFile proc _lpFile,_lpPeHead,_dwSize
local @szNewFile[MAX_PATH]:byte
local @hFile,@dwTemp,@dwEntry,@lpMemory
local @dwAddCodeBase,@dwAddCodeFile
local @szBuffer[256]:byte
pushad
;********************************************************************
; (Part 1)准备工作:1-建立新文件,2-打开文件
;********************************************************************
invoke lstrcpy,addr @szNewFile,addr szFileName
invoke lstrlen,addr @szNewFile
lea ecx,@szNewFile
mov byte ptr [ecx+eax-4],0
;invoke lstrcat,addr @szNewFile,addr szExt
;invoke CopyFile,addr szFileName,addr @szNewFile,FALSE
invoke CreateFile,addr szFileName,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or \
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax == INVALID_HANDLE_VALUE
invoke SetWindowText,hWinEdit,addr szErrCreate
jmp _Ret
.endif
mov @hFile,eax
;********************************************************************
;(Part 2)进行一些准备工作和检测工作
; esi --> 原PeHead,edi --> 新的PeHead
; edx --> 最后一个节表,ebx --> 新加的节表
;********************************************************************
mov esi,_lpPeHead
assume esi:ptr IMAGE_NT_HEADERS,edi:ptr IMAGE_NT_HEADERS
invoke GlobalAlloc,GPTR,[esi].OptionalHeader.SizeOfHeaders
mov @lpMemory,eax
mov edi,eax
invoke RtlMoveMemory,edi,_lpFile,[esi].OptionalHeader.SizeOfHeaders
add edi,esi
sub edi,_lpFile
movzx eax,[esi].FileHeader.NumberOfSections
dec eax
mov ecx,sizeof IMAGE_SECTION_HEADER
mul ecx
mov edx,edi
add edx,eax
add edx,sizeof IMAGE_NT_HEADERS
mov ebx,edx
add ebx,sizeof IMAGE_SECTION_HEADER
assume ebx:ptr IMAGE_SECTION_HEADER,edx:ptr IMAGE_SECTION_HEADER
;********************************************************************
; (Part 2.1)检查是否有空闲的位置可供插入节表
;********************************************************************
pushad
mov edi,ebx
xor eax,eax
mov ecx,IMAGE_SECTION_HEADER
repz scasb
popad
.if ! ZERO?
;********************************************************************
; (Part 3.1)如果没有新的节表空间的话,则查看现存代码节的最后
; 是否存在足够的全零空间,如果存在则在此处加入代码
;********************************************************************
xor eax,eax
mov ebx,edi
add ebx,sizeof IMAGE_NT_HEADERS
.while ax <= [esi].FileHeader.NumberOfSections
mov ecx,[ebx].SizeOfRawData
.if ecx && ([ebx].Characteristics & IMAGE_SCN_MEM_EXECUTE)
sub ecx,[ebx].Misc.VirtualSize
.if ecx > offset APPEND_CODE_END-offset APPEND_CODE
or [ebx].Characteristics,IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
jmp @F
.endif
.endif
add ebx,IMAGE_SECTION_HEADER
inc ax
.endw
invoke CloseHandle,@hFile
invoke DeleteFile,addr @szNewFile
invoke SetWindowText,hWinEdit,addr szErrNoRoom
jmp _Ret
@@:
;********************************************************************
; 将新增代码加入代码节的空隙中
;********************************************************************
mov eax,[ebx].VirtualAddress
add eax,[ebx].Misc.VirtualSize
mov @dwAddCodeBase,eax
mov eax,[ebx].PointerToRawData
add eax,[ebx].Misc.VirtualSize
mov @dwAddCodeFile,eax
add [ebx].Misc.VirtualSize,offset APPEND_CODE_END-offset APPEND_CODE
invoke SetFilePointer,@hFile,@dwAddCodeFile,NULL,FILE_BEGIN
mov ecx,offset APPEND_CODE_END-offset APPEND_CODE
invoke WriteFile,@hFile,offset APPEND_CODE,ecx,addr @dwTemp,NULL
.else
;********************************************************************
; (Part 3.2)如果有新的节表空间的话,加入一个新的节
;********************************************************************
inc [edi].FileHeader.NumberOfSections
push edx
@@:
mov eax,[edx].PointerToRawData
;********************************************************************
; 当最后一个节是未初始化数据时,PointerToRawData和SizeOfRawData等于0
; 这时应该取前一个节的PointerToRawData和SizeOfRawData数据
;********************************************************************
.if ! eax
sub edx,sizeof IMAGE_SECTION_HEADER
jmp @B
.endif
add eax,[edx].SizeOfRawData
pop edx
mov [ebx].PointerToRawData,eax
mov ecx,offset APPEND_CODE_END-offset APPEND_CODE
invoke _Align,ecx,[esi].OptionalHeader.FileAlignment
mov [ebx].SizeOfRawData,eax
invoke _Align,ecx,[esi].OptionalHeader.SectionAlignment
add [edi].OptionalHeader.SizeOfCode,eax ;修正SizeOfCode
add [edi].OptionalHeader.SizeOfImage,eax ;修正SizeOfImage
invoke _Align,[edx].Misc.VirtualSize,[esi].OptionalHeader.SectionAlignment
add eax,[edx].VirtualAddress
mov [ebx].VirtualAddress,eax
mov [ebx].Misc.VirtualSize,offset APPEND_CODE_END-offset APPEND_CODE
mov [ebx].Characteristics,IMAGE_SCN_CNT_CODE\
or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
invoke lstrcpy,addr [ebx].Name1,addr szMySection
;********************************************************************
; 将新增代码作为一个新的节写到文件尾部
;********************************************************************
invoke SetFilePointer,@hFile,[ebx].PointerToRawData,NULL,FILE_BEGIN
invoke WriteFile,@hFile,offset APPEND_CODE,[ebx].Misc.VirtualSize,\
addr @dwTemp,NULL
mov eax,[ebx].PointerToRawData
add eax,[ebx].SizeOfRawData
invoke SetFilePointer,@hFile,eax,NULL,FILE_BEGIN
invoke SetEndOfFile,@hFile
;********************************************************************
push [ebx].VirtualAddress ;eax = 新加代码的基地址
pop @dwAddCodeBase
push [ebx].PointerToRawData
pop @dwAddCodeFile
.endif
;********************************************************************
; (Part 4)修正文件入口指针并写入新的文件头
;********************************************************************
mov eax,@dwAddCodeBase
add eax,(offset _NewEntry-offset APPEND_CODE)
mov [edi].OptionalHeader.AddressOfEntryPoint,eax
invoke SetFilePointer,@hFile,0,NULL,FILE_BEGIN
invoke WriteFile,@hFile,@lpMemory,[esi].OptionalHeader.SizeOfHeaders,\
addr @dwTemp,NULL
;********************************************************************
; (Part 5)修正新加代码中的 Jmp oldEntry 指令
;********************************************************************
push [esi].OptionalHeader.AddressOfEntryPoint
pop @dwEntry
mov eax,@dwAddCodeBase
add eax,(offset _ToOldEntry-offset APPEND_CODE+5)
sub @dwEntry,eax
mov ecx,@dwAddCodeFile
add ecx,(offset _ToOldEntry-offset APPEND_CODE)
invoke SetFilePointer,@hFile,ecx,NULL,FILE_BEGIN
invoke WriteFile,@hFile,addr @dwEntry,4,addr @dwTemp,NULL
;********************************************************************
; (Part 6)关闭文件
;********************************************************************
invoke GlobalFree,@lpMemory
invoke CloseHandle,@hFile
invoke wsprintf,addr @szBuffer,Addr szSuccess,addr szFileName
invoke SetWindowText,hWinEdit,addr @szBuffer
_Ret:
assume esi:nothing
popad
ret
_ProcessPeFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 3rd Edition>
; by 罗云彬, http://www.win32asm.com.cn
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Main.asm
; PE 文件操作演示的主程序,提供对话框界面和文件打开功能
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Main.asm
; rc Main.rc
; Link /subsystem:windows Main.obj Main.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000
DLG_MAIN equ 1000
IDC_INFO equ 1001
IDM_MAIN equ 2000
IDM_OPEN equ 2001
IDM_EXIT equ 2002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hRichEdit dd ?
hWinMain dd ?
hWinEdit dd ?
szFileName db MAX_PATH dup (?)
.const
szDllEdit db 'RichEd20.dll',0
szClassEdit db 'RichEdit20A',0
szFont db '宋体',0
szExtPe db 'PE Files',0,'*.exe;*.dll;*.scr;*.fon;*.drv',0
db 'All Files(*.*)',0,'*.*',0,0
szErr db '文件格式错误!',0
szErrFormat db '这个文件不是PE格式的文件!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_AppendInfo proc _lpsz
local @stCR:CHARRANGE
pushad
invoke GetWindowTextLength,hWinEdit
mov @stCR.cpMin,eax
mov @stCR.cpMax,eax
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stCR
invoke SendMessage,hWinEdit,EM_REPLACESEL,FALSE,_lpsz
popad
ret
_AppendInfo endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include _ProcessPeFile.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Init proc
local @stCf:CHARFORMAT
invoke GetDlgItem,hWinMain,IDC_INFO
mov hWinEdit,eax
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWinMain,WM_SETICON,ICON_BIG,eax
invoke SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0
invoke RtlZeroMemory,addr @stCf,sizeof @stCf
mov @stCf.cbSize,sizeof @stCf
mov @stCf.yHeight,9 * 20
mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLD
invoke lstrcpy,addr @stCf.szFaceName,addr szFont
invoke SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCf
invoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
ret
_Init endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 错误 Handler
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Handler proc _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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_OpenFile proc
local @stOF:OPENFILENAME
local @hFile,@dwFileSize,@hMapFile,@lpMemory
invoke RtlZeroMemory,addr @stOF,sizeof @stOF
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
pop @stOF.hwndOwner
mov @stOF.lpstrFilter,offset szExtPe
mov @stOF.lpstrFile,offset szFileName
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST
invoke GetOpenFileName,addr @stOF
.if ! eax
jmp @F
.endif
;********************************************************************
; 打开文件并建立文件 Mapping
;********************************************************************
invoke CreateFile,addr szFileName,GENERIC_READ,FILE_SHARE_READ or \
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,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
invoke _ProcessPeFile,@lpMemory,esi,@dwFileSize
jmp _ErrorExit
_ErrFormat:
invoke MessageBox,hWinMain,addr szErrFormat,NULL,MB_OK
_ErrorExit:
pop fs:[0]
add esp,0ch
invoke UnmapViewOfFile,@lpMemory
.endif
invoke CloseHandle,@hMapFile
.endif
invoke CloseHandle,@hFile
.endif
.endif
@@:
ret
_OpenFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinMain
call _Init
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDM_OPEN
call _OpenFile
.elseif ax == IDM_EXIT
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke LoadLibrary,offset szDllEdit
mov hRichEdit,eax
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke FreeLibrary,hRichEdit
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
push [esi].OptionalHeader.AddressOfEntryPoint
pop @dwEntry
mov eax,@dwAddCodeBase
add eax,(offset _ToOldEntry-offset APPEND_CODE+5)
sub @dwEntry,eax
mov ecx,@dwAddCodeFile
add ecx,(offset _ToOldEntry-offset APPEND_CODE)
invoke SetFilePointer,@hFile,ecx,NULL,FILE_BEGIN
invoke WriteFile,@hFile,addr @dwEntry,4,addr @dwTemp,NULL
请问我把病毒入口后面一条jmp为源程序入口,但实际在执行的时候不会返回原入口执行源程序是不是跳转jmp的地方值不对
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 3rd Edition>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; AddCode 例子的功能模块
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
szErrCreate db '创建文件错误!',0dh,0ah,0
szErrNoRoom db '程序中没有多余的空间可供加入代码!',0dh,0ah,0
szMySection db '.adata',0
szExt db '_new.exe',0
szSuccess db '在文件后附加代码成功,新文件:',0dh,0ah
db '%s',0dh,0ah,0
.code
include _AddCode.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 计算按照指定值对齐后的数值
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Align proc _dwSize,_dwAlign
push edx
mov eax,_dwSize
xor edx,edx
div _dwAlign
.if edx
inc eax
.endif
mul _dwAlign
pop edx
ret
_Align endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcessPeFile proc _lpFile,_lpPeHead,_dwSize
local @szNewFile[MAX_PATH]:byte
local @hFile,@dwTemp,@dwEntry,@lpMemory
local @dwAddCodeBase,@dwAddCodeFile
local @szBuffer[256]:byte
pushad
;********************************************************************
; (Part 1)准备工作:1-建立新文件,2-打开文件
;********************************************************************
invoke lstrcpy,addr @szNewFile,addr szFileName
invoke lstrlen,addr @szNewFile
lea ecx,@szNewFile
mov byte ptr [ecx+eax-4],0
;invoke lstrcat,addr @szNewFile,addr szExt
;invoke CopyFile,addr szFileName,addr @szNewFile,FALSE
invoke CreateFile,addr szFileName,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or \
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax == INVALID_HANDLE_VALUE
invoke SetWindowText,hWinEdit,addr szErrCreate
jmp _Ret
.endif
mov @hFile,eax
;********************************************************************
;(Part 2)进行一些准备工作和检测工作
; esi --> 原PeHead,edi --> 新的PeHead
; edx --> 最后一个节表,ebx --> 新加的节表
;********************************************************************
mov esi,_lpPeHead
assume esi:ptr IMAGE_NT_HEADERS,edi:ptr IMAGE_NT_HEADERS
invoke GlobalAlloc,GPTR,[esi].OptionalHeader.SizeOfHeaders
mov @lpMemory,eax
mov edi,eax
invoke RtlMoveMemory,edi,_lpFile,[esi].OptionalHeader.SizeOfHeaders
add edi,esi
sub edi,_lpFile
movzx eax,[esi].FileHeader.NumberOfSections
dec eax
mov ecx,sizeof IMAGE_SECTION_HEADER
mul ecx
mov edx,edi
add edx,eax
add edx,sizeof IMAGE_NT_HEADERS
mov ebx,edx
add ebx,sizeof IMAGE_SECTION_HEADER
assume ebx:ptr IMAGE_SECTION_HEADER,edx:ptr IMAGE_SECTION_HEADER
;********************************************************************
; (Part 2.1)检查是否有空闲的位置可供插入节表
;********************************************************************
pushad
mov edi,ebx
xor eax,eax
mov ecx,IMAGE_SECTION_HEADER
repz scasb
popad
.if ! ZERO?
;********************************************************************
; (Part 3.1)如果没有新的节表空间的话,则查看现存代码节的最后
; 是否存在足够的全零空间,如果存在则在此处加入代码
;********************************************************************
xor eax,eax
mov ebx,edi
add ebx,sizeof IMAGE_NT_HEADERS
.while ax <= [esi].FileHeader.NumberOfSections
mov ecx,[ebx].SizeOfRawData
.if ecx && ([ebx].Characteristics & IMAGE_SCN_MEM_EXECUTE)
sub ecx,[ebx].Misc.VirtualSize
.if ecx > offset APPEND_CODE_END-offset APPEND_CODE
or [ebx].Characteristics,IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
jmp @F
.endif
.endif
add ebx,IMAGE_SECTION_HEADER
inc ax
.endw
invoke CloseHandle,@hFile
invoke DeleteFile,addr @szNewFile
invoke SetWindowText,hWinEdit,addr szErrNoRoom
jmp _Ret
@@:
;********************************************************************
; 将新增代码加入代码节的空隙中
;********************************************************************
mov eax,[ebx].VirtualAddress
add eax,[ebx].Misc.VirtualSize
mov @dwAddCodeBase,eax
mov eax,[ebx].PointerToRawData
add eax,[ebx].Misc.VirtualSize
mov @dwAddCodeFile,eax
add [ebx].Misc.VirtualSize,offset APPEND_CODE_END-offset APPEND_CODE
invoke SetFilePointer,@hFile,@dwAddCodeFile,NULL,FILE_BEGIN
mov ecx,offset APPEND_CODE_END-offset APPEND_CODE
invoke WriteFile,@hFile,offset APPEND_CODE,ecx,addr @dwTemp,NULL
.else
;********************************************************************
; (Part 3.2)如果有新的节表空间的话,加入一个新的节
;********************************************************************
inc [edi].FileHeader.NumberOfSections
push edx
@@:
mov eax,[edx].PointerToRawData
;********************************************************************
; 当最后一个节是未初始化数据时,PointerToRawData和SizeOfRawData等于0
; 这时应该取前一个节的PointerToRawData和SizeOfRawData数据
;********************************************************************
.if ! eax
sub edx,sizeof IMAGE_SECTION_HEADER
jmp @B
.endif
add eax,[edx].SizeOfRawData
pop edx
mov [ebx].PointerToRawData,eax
mov ecx,offset APPEND_CODE_END-offset APPEND_CODE
invoke _Align,ecx,[esi].OptionalHeader.FileAlignment
mov [ebx].SizeOfRawData,eax
invoke _Align,ecx,[esi].OptionalHeader.SectionAlignment
add [edi].OptionalHeader.SizeOfCode,eax ;修正SizeOfCode
add [edi].OptionalHeader.SizeOfImage,eax ;修正SizeOfImage
invoke _Align,[edx].Misc.VirtualSize,[esi].OptionalHeader.SectionAlignment
add eax,[edx].VirtualAddress
mov [ebx].VirtualAddress,eax
mov [ebx].Misc.VirtualSize,offset APPEND_CODE_END-offset APPEND_CODE
mov [ebx].Characteristics,IMAGE_SCN_CNT_CODE\
or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
invoke lstrcpy,addr [ebx].Name1,addr szMySection
;********************************************************************
; 将新增代码作为一个新的节写到文件尾部
;********************************************************************
invoke SetFilePointer,@hFile,[ebx].PointerToRawData,NULL,FILE_BEGIN
invoke WriteFile,@hFile,offset APPEND_CODE,[ebx].Misc.VirtualSize,\
addr @dwTemp,NULL
mov eax,[ebx].PointerToRawData
add eax,[ebx].SizeOfRawData
invoke SetFilePointer,@hFile,eax,NULL,FILE_BEGIN
invoke SetEndOfFile,@hFile
;********************************************************************
push [ebx].VirtualAddress ;eax = 新加代码的基地址
pop @dwAddCodeBase
push [ebx].PointerToRawData
pop @dwAddCodeFile
.endif
;********************************************************************
; (Part 4)修正文件入口指针并写入新的文件头
;********************************************************************
mov eax,@dwAddCodeBase
add eax,(offset _NewEntry-offset APPEND_CODE)
mov [edi].OptionalHeader.AddressOfEntryPoint,eax
invoke SetFilePointer,@hFile,0,NULL,FILE_BEGIN
invoke WriteFile,@hFile,@lpMemory,[esi].OptionalHeader.SizeOfHeaders,\
addr @dwTemp,NULL
;********************************************************************
; (Part 5)修正新加代码中的 Jmp oldEntry 指令
;********************************************************************
push [esi].OptionalHeader.AddressOfEntryPoint
pop @dwEntry
mov eax,@dwAddCodeBase
add eax,(offset _ToOldEntry-offset APPEND_CODE+5)
sub @dwEntry,eax
mov ecx,@dwAddCodeFile
add ecx,(offset _ToOldEntry-offset APPEND_CODE)
invoke SetFilePointer,@hFile,ecx,NULL,FILE_BEGIN
invoke WriteFile,@hFile,addr @dwEntry,4,addr @dwTemp,NULL
;********************************************************************
; (Part 6)关闭文件
;********************************************************************
invoke GlobalFree,@lpMemory
invoke CloseHandle,@hFile
invoke wsprintf,addr @szBuffer,Addr szSuccess,addr szFileName
invoke SetWindowText,hWinEdit,addr @szBuffer
_Ret:
assume esi:nothing
popad
ret
_ProcessPeFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 3rd Edition>
; by 罗云彬, http://www.win32asm.com.cn
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Main.asm
; PE 文件操作演示的主程序,提供对话框界面和文件打开功能
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Main.asm
; rc Main.rc
; Link /subsystem:windows Main.obj Main.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000
DLG_MAIN equ 1000
IDC_INFO equ 1001
IDM_MAIN equ 2000
IDM_OPEN equ 2001
IDM_EXIT equ 2002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hRichEdit dd ?
hWinMain dd ?
hWinEdit dd ?
szFileName db MAX_PATH dup (?)
.const
szDllEdit db 'RichEd20.dll',0
szClassEdit db 'RichEdit20A',0
szFont db '宋体',0
szExtPe db 'PE Files',0,'*.exe;*.dll;*.scr;*.fon;*.drv',0
db 'All Files(*.*)',0,'*.*',0,0
szErr db '文件格式错误!',0
szErrFormat db '这个文件不是PE格式的文件!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_AppendInfo proc _lpsz
local @stCR:CHARRANGE
pushad
invoke GetWindowTextLength,hWinEdit
mov @stCR.cpMin,eax
mov @stCR.cpMax,eax
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stCR
invoke SendMessage,hWinEdit,EM_REPLACESEL,FALSE,_lpsz
popad
ret
_AppendInfo endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include _ProcessPeFile.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Init proc
local @stCf:CHARFORMAT
invoke GetDlgItem,hWinMain,IDC_INFO
mov hWinEdit,eax
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWinMain,WM_SETICON,ICON_BIG,eax
invoke SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0
invoke RtlZeroMemory,addr @stCf,sizeof @stCf
mov @stCf.cbSize,sizeof @stCf
mov @stCf.yHeight,9 * 20
mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLD
invoke lstrcpy,addr @stCf.szFaceName,addr szFont
invoke SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCf
invoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
ret
_Init endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 错误 Handler
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Handler proc _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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_OpenFile proc
local @stOF:OPENFILENAME
local @hFile,@dwFileSize,@hMapFile,@lpMemory
invoke RtlZeroMemory,addr @stOF,sizeof @stOF
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
pop @stOF.hwndOwner
mov @stOF.lpstrFilter,offset szExtPe
mov @stOF.lpstrFile,offset szFileName
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST
invoke GetOpenFileName,addr @stOF
.if ! eax
jmp @F
.endif
;********************************************************************
; 打开文件并建立文件 Mapping
;********************************************************************
invoke CreateFile,addr szFileName,GENERIC_READ,FILE_SHARE_READ or \
FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,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
invoke _ProcessPeFile,@lpMemory,esi,@dwFileSize
jmp _ErrorExit
_ErrFormat:
invoke MessageBox,hWinMain,addr szErrFormat,NULL,MB_OK
_ErrorExit:
pop fs:[0]
add esp,0ch
invoke UnmapViewOfFile,@lpMemory
.endif
invoke CloseHandle,@hMapFile
.endif
invoke CloseHandle,@hFile
.endif
.endif
@@:
ret
_OpenFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinMain
call _Init
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDM_OPEN
call _OpenFile
.elseif ax == IDM_EXIT
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke LoadLibrary,offset szDllEdit
mov hRichEdit,eax
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke FreeLibrary,hRichEdit
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
看原图
赞赏
雪币:
留言: