Advertisement
waliedassar

The "ZwContinue" Function Anti-Attaching Trick

Sep 10th, 2012
1,819
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.83 KB | None | 0 0
  1. //http://waleedassar.blogspot.com - (@waleedassar)
  2. //This code shows how to hook the "ZwContinue" function in order to detect debuggers trying to attach.
  3. //Tested with Windows XP SP2/SP3 and Windows 7 SP1.
  4. #include "stdafx.h"
  5. #include "windows.h"
  6. #include "stdio.h"
  7.  
  8. unsigned long relativeOffset(unsigned long from,unsigned long to)
  9. {
  10.     unsigned long diff=0;
  11.     if(from>to)
  12.     {
  13.          //  5-byte jump instruction
  14.          diff=((unsigned long)from+5)-(unsigned long)to;
  15.          diff=-diff;
  16.     }
  17.     else
  18.     {
  19.           diff=(unsigned long)to-((unsigned long)from+5);
  20.     }
  21.     return diff;
  22. }
  23.  
  24. struct OSVERSIONINFOEx
  25. {
  26.   DWORD dwOSVersionInfoSize;
  27.   DWORD dwMajorVersion;
  28.   DWORD dwMinorVersion;
  29.   DWORD dwBuildNumber;
  30.   DWORD dwPlatformId;
  31.   TCHAR szCSDVersion[128];
  32.   WORD  wServicePackMajor;
  33.   WORD  wServicePackMinor;
  34.   WORD  wSuiteMask;
  35.   BYTE  wProductType;
  36.   BYTE  wReserved;
  37. };
  38.  
  39. unsigned long ver;   //0 if XP, 1 if win7, -1 otherwise.
  40. unsigned char* p;  //holds address of ZwContinue
  41. unsigned long addr_Dbg;   //holds address of DbgUiRemoteBreakin
  42. unsigned long addr_DbgPnt;   //holds address of DbgBreakPoint
  43. unsigned long addr_RtlUserThreadStart; ////holds address of RtlUserThreadStart
  44.  
  45. char* backup;    //here we backup the first 5 bytes of ZwContinue.
  46.  
  47. void HookFunc(char* pCOntext)
  48. {
  49.        unsigned long eip_=*(unsigned long*)(pCOntext+0xB8);   //StartAddress
  50.        unsigned long eax_=*(unsigned long*)(pCOntext+0xB0);   //Win32StartAddress
  51.        if(ver==0)  //xp
  52.        {
  53.            //Since the attaching thread is created via RtlCreateUserThread, then eip should be DbgUiRemoteBreakin and eax should be zero
  54.            if(eip_==addr_Dbg) ExitProcess(0);
  55.            //Heuristics (Smart guy may use DbgBreakPoint instead of DbgUiRemoteBreakin
  56.            if(eip_==addr_DbgPnt) ExitProcess(0);
  57.            //Smarter guy may manipulate DebugActiveProcess and replace RtlCreateUserThread with CreateRemoteThread
  58.            if(eax_==addr_Dbg || eax_==addr_DbgPnt) ExitProcess(0);
  59.        }
  60.        else if(ver==1)  //Win7
  61.        {
  62.            //No matter whether RtlCreateUserThread or CreateRemoteThread is used, the eip is ntdll.RtlUserThreadStart and eax is thread entrypoint
  63.            if(eip_==addr_RtlUserThreadStart)
  64.            {
  65.                if(eax_==addr_Dbg || eax_==addr_DbgPnt) ExitProcess(0);
  66.            }
  67.        }
  68.  
  69.        //For this to work, plz don't optimize
  70.        __asm
  71.        {
  72.            leave
  73.            jmp dword ptr[backup]
  74.        }
  75. }
  76. int main(int argc, char* argv[])
  77. {
  78.     //---------------version info---------------------------------------
  79.     OSVERSIONINFOEx OSI={sizeof(OSI)};
  80.     GetVersionEx((OSVERSIONINFO*)&OSI);
  81.     if(OSI.dwMajorVersion==5 && OSI.dwMinorVersion==1) ver=0;
  82.     else if(OSI.dwMajorVersion==6 && OSI.dwMinorVersion==1) ver=1;
  83.     else ver=-1;
  84.     //------------------------------------------------------------------
  85.           addr_RtlUserThreadStart=(unsigned long)GetProcAddress(GetModuleHandle("ntdll.dll"),"RtlUserThreadStart");
  86.           addr_Dbg=(unsigned long)GetProcAddress(GetModuleHandle("ntdll.dll"),"DbgUiRemoteBreakin");
  87.           addr_DbgPnt=(unsigned long)GetProcAddress(GetModuleHandle("ntdll.dll"),"DbgBreakPoint");
  88.           p=(unsigned char*)GetProcAddress(GetModuleHandle("ntdll.dll"),"ZwContinue");
  89.           unsigned long old;
  90.  
  91.           backup=(char*)VirtualAlloc(0,0x1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  92.           memcpy(backup,p,0x5);
  93.           backup[0x5]=0x68;  //push
  94.           *(unsigned long*)(&backup[0x6])=(unsigned long)(p+0x5);
  95.           backup[0xA]=0xC3;  //retn
  96.  
  97.           VirtualProtect(p,5,PAGE_EXECUTE_READWRITE,&old);
  98.           *p=0xE9;  //opcode for jmp
  99.           *(unsigned long*)(p+1)=relativeOffset((unsigned long)p,(unsigned long)&HookFunc);
  100.  
  101.           VirtualProtect(p,5,old,&old);
  102.           //----------------------Shitty stuff------------------------------------
  103.           int x=0;
  104.           while(1)
  105.           {
  106.                Sleep(1000);
  107.                printf("%s %d\r\n","walied",x);
  108.                x++;
  109.           }
  110.  return 0;
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement