分析学习【1】—— Anti-debug分析及Snapshot学习

来源:互联网 发布:rmvb编辑软件绿色版 编辑:程序博客网 时间:2024/06/16 10:02

学着分析一个老样本的时候,发现了这个段anti-debug函数,鉴于WinSDK掌握不足,所以就慢慢分析了下。

概述:1、简单分析了这个anti-debug的流程;2、介绍下用到的Win函数,其中重点是如何获取运行中进程snapshot。

一、这个anti-debug非常老,如今OD的一堆插件绝对可以秒杀掉。只是简单的调用了"IsDebuggerPresent"函数,判断父进程,还有遍历所有进程判断是否有调试器(通过进程标题名称)。

1、LoadLibraryW函数原型(http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx)如下:

Syntax

HMODULE WINAPI LoadLibrary(  __in  LPCTSTR lpFileName);
w是Unicode版本的。该函数加载一个指定模块进入当前地址空间。因为被加载的模块可能依赖其它模块,所以,可能会同时加载其余模块。

2、GetProcAddress函数原型(http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx)如下:

Syntax

FARPROC WINAPI GetProcAddress(  __in  HMODULE hModule,  __in  LPCSTR lpProcName);

返回指定DLL的输入函数或者变量地址。

代码如下:

.text:71001000.text:71001000 ; Attributes: bp-based frame fpd=78h.text:71001000.text:71001000 Anti_debug      proc near               ; CODE XREF: kill_SecProcess+4Cp.text:71001000                                         ; DllEntryPoint+11p ....text:71001000.text:71001000 pe              = PROCESSENTRY32 ptr -128h.text:71001000.text:71001000                 push    ebp.text:71001001                 lea     ebp, [esp-78h].text:71001005                 sub     esp, 128h.text:7100100B                 push    ebx.text:7100100C                 push    esi.text:7100100D                 mov     esi, ds:LoadLibraryW.text:71001013                 push    edi.text:71001014                 push    offset ProcName ; "IsDebuggerPresent".text:71001019                 mov     ebx, offset LibFileName ; "kernel32.dll".text:7100101E                 push    ebx             ; lpLibFileName.text:7100101F                 call    esi ; LoadLibraryW.text:71001021                 mov     edi, ds:GetProcAddress ; 得到IsDebuggerPresent的地址.text:71001027                 push    eax             ; hModule.text:71001028                 call    edi ; GetProcAddress.text:7100102A                 push    offset aGetcurrentproc ; "GetCurrentProcessId".text:7100102F                 push    ebx             ; lpLibFileName.text:71001030                 mov     g_Kernel, eax.text:71001035                 call    esi ; LoadLibraryW.text:71001037                 push    eax             ; hModule.text:71001038                 call    edi ; GetProcAddress.text:7100103A                 xor     edi, edi.text:7100103C                 push    edi             ; th32ProcessID.text:7100103D                 push    2               ; dwFlags.text:7100103F                 mov     ebx, eax.text:71001041                 call    CreateToolhelp32Snapshot.text:71001046                 mov     esi, eax.text:71001048                 lea     eax, [ebp+78h+pe].text:7100104E                 push    eax             ; lppe.text:7100104F                 push    esi             ; hSnapshot.text:71001050                 mov     [ebp+78h+pe.dwSize], 128h.text:7100105A                 call    Process32First.text:7100105F.text:7100105F DO_BEGIN:                               ; CODE XREF: Anti_debug+78j.text:7100105F                 call    ebx.text:71001061                 cmp     [ebp+78h+pe.th32ProcessID], eax ; 获得本进程信息.text:71001067                 jz      short Break     ; 检测父进程ID.text:71001069                 lea     eax, [ebp+78h+pe].text:7100106F                 push    eax             ; lppe.text:71001070                 push    esi             ; hSnapshot.text:71001071                 call    Process32Next.text:71001076                 test    eax, eax.text:71001078                 jnz     short DO_BEGIN.text:7100107A                 jmp     short loc_71001094.text:7100107C ; ---------------------------------------------------------------------------.text:7100107C.text:7100107C Break:                                  ; CODE XREF: Anti_debug+67j.text:7100107C                 mov     edi, [ebp+78h+pe.th32ParentProcessID] ; 检测父进程ID.text:71001082                 cmp     edi, 4          ; 如果父进程System进程,表明正常运行.text:71001085                 jz      Security        ; 安全,没有被调试.text:7100108B                 cmp     edi, 8          ; ID号为8的是哪个进程.text:7100108E                 jz      Security.text:71001094.text:71001094 loc_71001094:                           ; CODE XREF: Anti_debug+7Aj.text:71001094                 lea     eax, [ebp+78h+pe].text:7100109A                 push    eax             ; lppe.text:7100109B                 push    esi             ; hSnapshot.text:7100109C                 call    Process32First  ; 再次检测当前进程.text:710010A1.text:710010A1 loc_710010A1:                           ; CODE XREF: Anti_debug+14Aj.text:710010A1                 cmp     [ebp+78h+pe.th32ProcessID], edi.text:710010A7                 jnz     loc_7100113B.text:710010AD                 lea     eax, [ebp+78h+pe.szExeFile].text:710010B3                 push    eax             ; int.text:710010B4                 push    offset String   ; "OllyDbg.exe".text:710010B9                 call    Is_EqualString.text:710010BE                 test    eax, eax.text:710010C0                 pop     ecx.text:710010C1                 pop     ecx.text:710010C2                 jz      Security.text:710010C8                 lea     eax, [ebp+78h+pe.szExeFile].text:710010CE                 push    eax             ; int.text:710010CF                 push    offset aOllyice_exe ; "OllyICE.exe".text:710010D4                 call    Is_EqualString.text:710010D9                 test    eax, eax.text:710010DB                 pop     ecx.text:710010DC                 pop     ecx.text:710010DD                 jz      short Security.text:710010DF                 lea     eax, [ebp+78h+pe.szExeFile].text:710010E5                 push    eax             ; int.text:710010E6                 push    offset aPeditor_exe ; "PEditor.exe".text:710010EB                 call    Is_EqualString.text:710010F0                 test    eax, eax.text:710010F2                 pop     ecx.text:710010F3                 pop     ecx.text:710010F4                 jz      short Security.text:710010F6                 lea     eax, [ebp+78h+pe.szExeFile].text:710010FC                 push    eax             ; int.text:710010FD                 push    offset aLordpe_exe ; "LordPE.exe".text:71001102                 call    Is_EqualString.text:71001107                 test    eax, eax.text:71001109                 pop     ecx.text:7100110A                 pop     ecx.text:7100110B                 jz      short Security.text:7100110D                 lea     eax, [ebp+78h+pe.szExeFile].text:71001113                 push    eax             ; int.text:71001114                 push    offset aC32asm_exe ; "C32Asm.exe".text:71001119                 call    Is_EqualString.text:7100111E                 test    eax, eax.text:71001120                 pop     ecx.text:71001121                 pop     ecx.text:71001122                 jz      short Security.text:71001124                 lea     eax, [ebp+78h+pe.szExeFile].text:7100112A                 push    eax             ; int.text:7100112B                 push    offset aImportrec_exe ; "ImportREC.exe".text:71001130                 call    Is_EqualString.text:71001135                 test    eax, eax.text:71001137                 pop     ecx.text:71001138                 pop     ecx.text:71001139                 jz      short Security.text:7100113B.text:7100113B loc_7100113B:                           ; CODE XREF: Anti_debug+A7j.text:7100113B                 lea     eax, [ebp+78h+pe].text:71001141                 push    eax             ; lppe.text:71001142                 push    esi             ; hSnapshot.text:71001143                 call    Process32Next.text:71001148                 test    eax, eax.text:7100114A                 jnz     loc_710010A1.text:71001150                 call    g_Kernel.text:71001156                 test    eax, eax.text:71001158                 pop     edi.text:71001159                 pop     esi.text:7100115A                 pop     ebx.text:7100115B                 jz      short loc_71001165.text:7100115D.text:7100115D Security:                               ; CODE XREF: Anti_debug+85j.text:7100115D                                         ; Anti_debug+8Ej ....text:7100115D                 push    0               ; uExitCode.text:7100115F                 call    ds:ExitProcess.text:71001165 ; ---------------------------------------------------------------------------.text:71001165.text:71001165 loc_71001165:                           ; CODE XREF: Anti_debug+15Bj.text:71001165                 xor     eax, eax.text:71001167                 add     ebp, 78h.text:7100116A                 leave.text:7100116B                 retn.text:7100116B Anti_debug      endp ; sp-analysis failed.text:7100116B.text:7100116C


二、这个snapshot术语刚刚接触到,值得学习。

(另一种获取当前进程信息方法在博文http://blog.csdn.net/betabin/article/details/7483939)

1、接触PROCESSENTRY32结构,其原型如下:

Syntax

typedef struct tagPROCESSENTRY32 {  DWORD     dwSize;  DWORD     cntUsage;  DWORD     th32ProcessID;  ULONG_PTR th32DefaultHeapID;  DWORD     th32ModuleID;  DWORD     cntThreads;  DWORD     th32ParentProcessID;  LONG      pcPriClassBase;  DWORD     dwFlags;  TCHAR     szExeFile[MAX_PATH];} PROCESSENTRY32, *PPROCESSENTRY32;

w是Unicode版本,这个PROCESSENTRY32是Ansi版本。

这个结构是用于进行快照时,描述一个驻留于系统地址空间的进程列表。其中size在使用前要初始化为sizeof(PROCESSENTRY32)。

2、至于接下来的Process32First函数,则是开始遍历进程了。原型如下:

Syntax

BOOL WINAPI Process32First(  __in     HANDLE hSnapshot,  __inout  LPPROCESSENTRY32 lppe);


也果断摘录了MSDN里的一个例程代码如下:

#include <windows.h>#include <tlhelp32.h>#include <tchar.h>//  Forward declarations:BOOL GetProcessList( );BOOL ListProcessModules( DWORD dwPID );BOOL ListProcessThreads( DWORD dwOwnerPID );void printError( TCHAR* msg );int main( void ){  GetProcessList( );  return 0;}BOOL GetProcessList( ){  HANDLE hProcessSnap;  HANDLE hProcess;  PROCESSENTRY32 pe32;  DWORD dwPriorityClass;  // Take a snapshot of all processes in the system.  hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );  if( hProcessSnap == INVALID_HANDLE_VALUE )  {    printError( TEXT("CreateToolhelp32Snapshot (of processes)") );    return( FALSE );  }  // Set the size of the structure before using it.  pe32.dwSize = sizeof( PROCESSENTRY32 );  // Retrieve information about the first process,  // and exit if unsuccessful  if( !Process32First( hProcessSnap, &pe32 ) )  {    printError( TEXT("Process32First") ); // show cause of failure    CloseHandle( hProcessSnap );          // clean the snapshot object    return( FALSE );  }  // Now walk the snapshot of processes, and  // display information about each process in turn  do  {    _tprintf( TEXT("\n\n=====================================================" ));    _tprintf( TEXT("\nPROCESS NAME:  %s"), pe32.szExeFile );    _tprintf( TEXT("\n-------------------------------------------------------" ));    // Retrieve the priority class.    dwPriorityClass = 0;    hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );    if( hProcess == NULL )      printError( TEXT("OpenProcess") );    else    {      dwPriorityClass = GetPriorityClass( hProcess );      if( !dwPriorityClass )        printError( TEXT("GetPriorityClass") );      CloseHandle( hProcess );    }    _tprintf( TEXT("\n  Process ID        = 0x%08X"), pe32.th32ProcessID );    _tprintf( TEXT("\n  Thread count      = %d"),   pe32.cntThreads );    _tprintf( TEXT("\n  Parent process ID = 0x%08X"), pe32.th32ParentProcessID );    _tprintf( TEXT("\n  Priority base     = %d"), pe32.pcPriClassBase );    if( dwPriorityClass )      _tprintf( TEXT("\n  Priority class    = %d"), dwPriorityClass );    // List the modules and threads associated with this process    ListProcessModules( pe32.th32ProcessID );    ListProcessThreads( pe32.th32ProcessID );  } while( Process32Next( hProcessSnap, &pe32 ) );  CloseHandle( hProcessSnap );  return( TRUE );}BOOL ListProcessModules( DWORD dwPID ){  HANDLE hModuleSnap = INVALID_HANDLE_VALUE;  MODULEENTRY32 me32;  // Take a snapshot of all modules in the specified process.  hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );  if( hModuleSnap == INVALID_HANDLE_VALUE )  {    printError( TEXT("CreateToolhelp32Snapshot (of modules)") );    return( FALSE );  }  // Set the size of the structure before using it.  me32.dwSize = sizeof( MODULEENTRY32 );  // Retrieve information about the first module,  // and exit if unsuccessful  if( !Module32First( hModuleSnap, &me32 ) )  {    printError( TEXT("Module32First") );  // show cause of failure    CloseHandle( hModuleSnap );           // clean the snapshot object    return( FALSE );  }  // Now walk the module list of the process,  // and display information about each module  do  {    _tprintf( TEXT("\n\n     MODULE NAME:     %s"),   me32.szModule );    _tprintf( TEXT("\n     Executable     = %s"),     me32.szExePath );    _tprintf( TEXT("\n     Process ID     = 0x%08X"),         me32.th32ProcessID );    _tprintf( TEXT("\n     Ref count (g)  = 0x%04X"),     me32.GlblcntUsage );    _tprintf( TEXT("\n     Ref count (p)  = 0x%04X"),     me32.ProccntUsage );    _tprintf( TEXT("\n     Base address   = 0x%08X"), (DWORD) me32.modBaseAddr );    _tprintf( TEXT("\n     Base size      = %d"),             me32.modBaseSize );  } while( Module32Next( hModuleSnap, &me32 ) );  CloseHandle( hModuleSnap );  return( TRUE );}BOOL ListProcessThreads( DWORD dwOwnerPID ) {   HANDLE hThreadSnap = INVALID_HANDLE_VALUE;   THREADENTRY32 te32;    // Take a snapshot of all running threads    hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );   if( hThreadSnap == INVALID_HANDLE_VALUE )     return( FALSE );    // Fill in the size of the structure before using it.   te32.dwSize = sizeof(THREADENTRY32);    // Retrieve information about the first thread,  // and exit if unsuccessful  if( !Thread32First( hThreadSnap, &te32 ) )   {    printError( TEXT("Thread32First") ); // show cause of failure    CloseHandle( hThreadSnap );          // clean the snapshot object    return( FALSE );  }  // Now walk the thread list of the system,  // and display information about each thread  // associated with the specified process  do   {     if( te32.th32OwnerProcessID == dwOwnerPID )    {      _tprintf( TEXT("\n\n     THREAD ID      = 0x%08X"), te32.th32ThreadID );       _tprintf( TEXT("\n     Base priority  = %d"), te32.tpBasePri );       _tprintf( TEXT("\n     Delta priority = %d"), te32.tpDeltaPri );       _tprintf( TEXT("\n"));    }  } while( Thread32Next(hThreadSnap, &te32 ) );   CloseHandle( hThreadSnap );  return( TRUE );}void printError( TCHAR* msg ){  DWORD eNum;  TCHAR sysMsg[256];  TCHAR* p;  eNum = GetLastError( );  FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,         NULL, eNum,         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language         sysMsg, 256, NULL );  // Trim the end of the line and terminate it with a null  p = sysMsg;  while( ( *p > 31 ) || ( *p == 9 ) )    ++p;  do { *p-- = 0; } while( ( p >= sysMsg ) &&                          ( ( *p == '.' ) || ( *p < 33 ) ) );  // Display the message  _tprintf( TEXT("\n  WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg );}


原创粉丝点击