⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 easyunpack.asm

📁 也算是一个通用脱壳软件吧
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;========================
; 一块三毛钱
; 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 + -