?? easyunpack.asm
字號:
;========================
; 一塊三毛錢
; 2004.3.16
;========================
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
include EasyUnpack.inc
.code
start:
invoke GetModuleHandle, NULL
mov g_hInst, eax
invoke InitCommonControls
invoke DialogBoxParam, g_hInst, DLG_MAIN, NULL, addr DlgProc, NULL
invoke ExitProcess, 0
DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov eax, uMsg
.if eax==WM_INITDIALOG
invoke _Init, hWnd
.elseif eax==WM_COMMAND
invoke _Command, hWnd, wParam, lParam
.elseif eax==WM_PAINT
invoke _Paint, hWnd
.elseif eax==WM_DROPFILES
invoke DragQueryFile, wParam, 0, addr g_buffer, sizeof g_buffer
invoke GetFileAttributes, addr g_buffer
and eax, FILE_ATTRIBUTE_DIRECTORY
.if !eax ;如果不是文件夾
invoke SetWindowText, g_hFileCtl, addr g_buffer
.endif
invoke DragFinish, wParam
.elseif eax==WM_CLOSE
invoke EndDialog, hWnd, 0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
;處理按鈕消息
_Command proc hWnd:DWORD, wParam:DWORD, lParam:DWORD
pushad
mov eax, wParam
and eax, 0ffffh
.if eax==IDC_BTN_OPENFILE
invoke RtlZeroMemory, addr g_buffer, sizeof g_buffer
mov g_ofn.lStructSize, sizeof g_ofn
m2m g_ofn.hwndOwner, hWnd
m2m g_ofn.hInstance, g_hInst
lea eax, g_buffer
mov g_ofn.lpstrFile, eax
mov g_ofn.nMaxFile, sizeof g_buffer
mov g_ofn.Flags, OFN_FILEMUSTEXIST + OFN_PATHMUSTEXIST
mov g_ofn.lpstrFilter, offset g_szFilter
mov g_ofn.lpstrTitle, offset g_szOpenTitle
invoke GetOpenFileName, addr g_ofn
.if eax
invoke SetWindowText, g_hFileCtl, addr g_buffer
.endif
.elseif eax==IDC_CHK_OEP
invoke SendMessage, g_hChkOEP, BM_GETCHECK, 0, 0
.if eax
invoke EnableWindow, g_hOEP, TRUE
.else
invoke EnableWindow, g_hOEP, FALSE
.endif
.elseif eax==IDC_BTN_START
invoke _Unpack, hWnd
.endif
popad
ret
_Command endp
;脫殼過程
_Unpack proc hWnd:DWORD
LOCAL szFile[1024] : BYTE
LOCAL hFile, hMapFile, pMemory
LOCAL dwImageBase, dwSizeOfImage, dwOrgOEP
LOCAL StartupInfo : STARTUPINFO
LOCAL ProcInfo : PROCESS_INFORMATION
LOCAL ProcInfo2: PROCESS_INFORMATION
LOCAL ProcInfo3: PROCESS_INFORMATION
LOCAL buf[256] : BYTE
LOCAL lpMem, dwOEP
LOCAL int3 : BYTE, org_code : BYTE
LOCAL dwCountBP
LOCAL DbgEvent : DEBUG_EVENT
LOCAL hFileDumped, dwSizeReturn
;--------------------------------------------------------------------------------
;初始化局部變量
invoke RtlZeroMemory, addr szFile, sizeof szFile
xor eax, eax
mov hFile, eax
mov hMapFile, eax
mov pMemory, eax
mov lpMem, eax
mov dwOEP, eax
mov int3, al
mov org_code, al
mov dwCountBP, eax
mov hFileDumped, eax
mov dwSizeReturn, eax
invoke RtlZeroMemory, addr StartupInfo, sizeof StartupInfo
invoke RtlZeroMemory, addr ProcInfo, sizeof ProcInfo
invoke RtlZeroMemory, addr ProcInfo2, sizeof ProcInfo2
invoke RtlZeroMemory, addr ProcInfo3, sizeof ProcInfo3
invoke RtlZeroMemory, addr DbgEvent, sizeof DbgEvent
;--------------------------------------------------------------------------------
;取得文件名
invoke SendMessage, g_hOutputCtl, LB_RESETCONTENT, 0, 0
invoke GetWindowText, g_hFileCtl, addr szFile, sizeof szFile
.if eax==0
invoke _OutputInfo, g_hOutputCtl, CTXT("沒有指定文件!!!")
jmp l_exit
.endif
;--------------------------------------------------------------------------------
;打開文件,創建內存映射文件,檢查文件是不是合法的 PE 文件
invoke CreateFile, addr szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0
.if eax==INVALID_HANDLE_VALUE
invoke _OutputInfo, g_hOutputCtl, CTXT("打開文件出錯!!!")
jmp l_exit
.endif
mov hFile, eax
invoke CreateFileMapping, hFile, 0, PAGE_READONLY, 0, 0, 0
.if !eax
invoke _OutputInfo, g_hOutputCtl, CTXT("創建內存映射文件出錯!!!")
jmp l_exit
.endif
mov hMapFile, eax
invoke MapViewOfFile, hMapFile, FILE_MAP_READ, 0, 0, 0
.if !eax
invoke _OutputInfo, g_hOutputCtl, CTXT("把文件映射進內存時出錯!!!")
jmp l_exit
.endif
mov pMemory, eax
mov esi, eax
assume esi : ptr IMAGE_DOS_HEADER
.if [esi].e_magic == IMAGE_DOS_SIGNATURE
add esi, [esi].e_lfanew
assume esi : ptr IMAGE_NT_HEADERS
.if [esi].Signature == IMAGE_NT_SIGNATURE
jmp @F
.endif
.endif
invoke _OutputInfo, g_hOutputCtl, CTXT("不是合法的 PE 文件!!!")
jmp l_exit
@@:
m2m dwImageBase, [esi].OptionalHeader.ImageBase
m2m dwSizeOfImage, [esi].OptionalHeader.SizeOfImage
m2m dwOrgOEP, [esi].OptionalHeader.AddressOfEntryPoint
mov eax, dwImageBase
add dwOrgOEP, eax
;--------------------------------------------------------------------------------
;關閉內存映射文件,關閉文件
invoke UnmapViewOfFile, pMemory
mov pMemory, 0
invoke CloseHandle, hMapFile
mov hMapFile, 0
invoke CloseHandle, hFile
mov hFile, 0
;--------------------------------------------------------------------------------
invoke wsprintf, addr buf, CTXT("基地址: %08lXh"), dwImageBase
invoke _OutputInfo, g_hOutputCtl, addr buf
invoke wsprintf, addr buf, CTXT("映象大小: %08lXh"), dwSizeOfImage
invoke _OutputInfo, g_hOutputCtl, addr buf
invoke wsprintf, addr buf, CTXT("原始入口點: %08lXh"), dwOrgOEP
invoke _OutputInfo, g_hOutputCtl, addr buf
invoke _OutputInfo, g_hOutputCtl, CTXT("開始脫殼...")
;--------------------------------------------------------------------------------
;創建進程,準備查找入口點
invoke GetStartupInfo, addr StartupInfo
mov StartupInfo.dwFlags, STARTF_USESHOWWINDOW
mov StartupInfo.wShowWindow, SW_HIDE
invoke CreateProcess, NULL, addr szFile, NULL, NULL, NULL, NORMAL_PRIORITY_CLASS, \
NULL, NULL, addr StartupInfo, addr ProcInfo
.if !eax
invoke _OutputInfo, g_hOutputCtl, CTXT("不能創建進程!!!")
jmp l_exit
.endif
invoke WaitForInputIdle, ProcInfo.hProcess, INFINITE
invoke SuspendThread, ProcInfo.hThread
invoke wsprintf, addr buf, CTXT("已創建進程: PID=%08lXh"), ProcInfo.dwProcessId
invoke _OutputInfo, g_hOutputCtl, addr buf
invoke _OutputInfo, g_hOutputCtl, CTXT("查找入口點...")
;--------------------------------------------------------------------------------
;讀取進程內存
invoke GlobalAlloc, GMEM_ZEROINIT + GMEM_FIXED, dwSizeOfImage
.if !eax
invoke _OutputInfo, g_hOutputCtl, CTXT("分配內存出錯!!!")
jmp l_exit
.endif
mov lpMem, eax
invoke ReadProcessMemory, ProcInfo.hProcess, dwImageBase, lpMem, dwSizeOfImage, 0
.if !eax
invoke wsprintf, addr buf, CTXT("讀取進程 (%08lXh) 內存出錯!!!"), ProcInfo.dwProcessId
invoke _OutputInfo, g_hOutputCtl, addr buf
jmp l_exit
.endif
invoke TerminateProcess, ProcInfo.hProcess, 0
invoke CloseHandle, ProcInfo.hThread
invoke CloseHandle, ProcInfo.hProcess
mov ProcInfo.hProcess, 0
;--------------------------------------------------------------------------------
;查找入口點
invoke SendMessage, g_hChkOEP, BM_GETCHECK, 0, 0
.if eax
invoke GetWindowText, g_hOEP, addr buf, 9
invoke htodw, addr buf
.else
invoke _GetOEP, lpMem, dwSizeOfImage
add eax, dwImageBase
.endif
.if eax==0
invoke _OutputInfo, g_hOutputCtl, CTXT("找不到入口點")
jmp l_exit
.endif
mov dwOEP, eax
invoke wsprintf, addr buf, CTXT("找到入口點: %08lXh"), eax
invoke _OutputInfo, g_hOutputCtl, addr buf
;--------------------------------------------------------------------------------
;創建調試進程
invoke CreateProcess, 0, addr szFile, 0, 0, 0, DEBUG_PROCESS + DEBUG_ONLY_THIS_PROCESS,
0, 0, addr StartupInfo, addr ProcInfo2
.if !eax
invoke _OutputInfo, g_hOutputCtl, CTXT("不能創建進程!!!")
jmp l_exit
.endif
.while TRUE
invoke WaitForDebugEvent, addr DbgEvent, INFINITE
.if DbgEvent.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT
;下面這一行代碼很重要,否則被調試進程不會完全退出
invoke ContinueDebugEvent, DbgEvent.dwProcessId, DbgEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED
.break
.elseif DbgEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT
.if DbgEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT
inc dwCountBP
.if dwCountBP==1 ;第一次中斷時在原始入口點處設置斷點
invoke _OutputInfo, g_hOutputCtl, CTXT("在原始入口點設置斷點...")
mov int3, 0CCh
invoke ReadProcessMemory, ProcInfo2.hProcess, dwOrgOEP, addr org_code, 1, 0
invoke WriteProcessMemory, ProcInfo2.hProcess, dwOrgOEP, addr int3, 1, 0
.elseif dwCountBP==2 ;第二次中斷,這次是中斷在原始入口點,在 OEP 處設置硬件斷點
invoke _OutputInfo, g_hOutputCtl, CTXT("到達原始入口點")
mov g_context.ContextFlags, CONTEXT_CONTROL
invoke GetThreadContext, ProcInfo2.hThread, addr g_context
dec g_context.regEip
invoke WriteProcessMemory, ProcInfo2.hProcess, dwOrgOEP, addr org_code, 1, 0
invoke SetThreadContext, ProcInfo2.hThread, addr g_context
mov g_context.ContextFlags, CONTEXT_DEBUG_REGISTERS
invoke GetThreadContext, ProcInfo2.hThread, addr g_context
m2m g_context.iDr0, dwOEP
mov g_context.iDr7, 1
invoke SetThreadContext, ProcInfo2.hThread, addr g_context
invoke wsprintf, addr buf, CTXT("在 OEP: %08lXh 處設置硬件斷點..."), dwOEP
invoke _OutputInfo, g_hOutputCtl, addr buf
.endif
invoke ContinueDebugEvent, DbgEvent.dwProcessId, DbgEvent.dwThreadId, DBG_CONTINUE
.continue
.elseif DbgEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP
;第三次中斷,來到真正的入口點,抓取進程,然后終止進程
invoke wsprintf, addr buf, CTXT("中斷在 OEP: %08lXh 處"), dwOEP
invoke _OutputInfo, g_hOutputCtl, addr buf
invoke _OutputInfo, g_hOutputCtl, CTXT("清除硬件斷點...")
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -