SHARE
TWEET

Call64, Issue 64-bit System Calls

waliedassar Jan 12th, 2013 392 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //http://waleedassar.blogspot.com
  2. //http://www.twitter.com/waleedassar
  3.      
  4. //Use this function to issue 64-bit system calls without passing
  5. //through Wow64 emulation layer.
  6.  
  7. #include "stdafx.h"
  8. #include "windows.h"
  9. #include "stdio.h"
  10. #include "malloc.h"
  11.  
  12. #define ProcessConsoleHostProcess 0x31
  13.  
  14. //------------------------------------------------------
  15.  
  16. void* _aligned_malloc(unsigned long size,unsigned long alignment)
  17. {
  18.         if(size==0) return 0;
  19.         unsigned long total_size=size+alignment+4;
  20.         if(total_size<size) return 0;
  21.         unsigned long pReal=(unsigned long)LocalAlloc(LMEM_ZEROINIT,total_size);
  22.         unsigned long pRunner=pReal+4;
  23.         if(pReal==0) return 0;
  24.  
  25.         while(pRunner & (alignment-1)) pRunner++;
  26.         *(unsigned long*)(pRunner-4)=pReal;
  27.         return (void*)pRunner;
  28. }
  29.  
  30. void _aligned_free(void* pMem)
  31. {
  32.         if(!pMem) return;
  33.         unsigned long p=*(((unsigned long*)pMem)-1);
  34.         LocalFree((void*)p);
  35. }
  36.  
  37.  
  38. unsigned short Get64CSValue()
  39. {
  40.                 unsigned short cs_64=0x33; //default
  41.                 unsigned long X86SwitchTo64BitMode=0;
  42.                 __asm
  43.                 {
  44.                                         push eax
  45.                                         mov eax,dword ptr fs:[0xC0]
  46.                                         mov X86SwitchTo64BitMode,eax
  47.                                         pop eax
  48.                 }
  49.                 if(!X86SwitchTo64BitMode) return 0;
  50.                 if(*(unsigned char*)X86SwitchTo64BitMode==0xEA) //Jmp Far
  51.                 {
  52.                          cs_64=*(unsigned short*)(X86SwitchTo64BitMode+5);
  53.                 }
  54.                 return cs_64;
  55. }
  56. //------------------------------------------------------
  57.  
  58.  
  59. //You can change this value.
  60. #define MAX_NUMBER_ARGUMENTS 0x30
  61.  
  62.  
  63. struct LARGE_INTEGER_
  64. {
  65.         unsigned long Low;
  66.         unsigned long High;
  67. };
  68.  
  69. bool Call64(LARGE_INTEGER_* pReturnValue,unsigned long syscallNum,unsigned long numArg,...);
  70.  
  71. char shellcode64[]=
  72. "\x48\x8B\x0C\x24\x48\x89\x0F\x48\x83\xC4\x08\x48\x8B\x0C\x24"
  73. "\x90\x90\x48\x8B\x54\x24\x08\x4C\x8B\x44\x24\x10\x4C\x8B\x4C"
  74. "\x24\x18\xE8\x08\x00\x00\x00\x48\x89\x06\x48\x8B\x0F\x51\xCB"
  75. "\x4C\x8B\xD1\xB8\xCE\xCE\xCE\xCE\x0F\x05\xC3";
  76.  
  77. //I will see AdditionalIndex later.
  78. bool Call64(LARGE_INTEGER_* pReturnValue,unsigned long syscallNum,unsigned long numArg,...)
  79. {
  80.         //---------------Sanity checks-------------------------------------
  81.         if(numArg>MAX_NUMBER_ARGUMENTS) return false;
  82.         //-----------------------------------------------------------------
  83.         va_list arguments;
  84.         va_start(arguments,numArg);
  85.         //-----------Initialize first four arguments------------------------
  86.         unsigned long rem=0;
  87.         unsigned long extra_stack_size=0x20;
  88.         unsigned long* pStack=0;
  89.         if(numArg>4)
  90.         {
  91.                 rem=numArg-4;
  92.                 extra_stack_size+=(rem*sizeof(LARGE_INTEGER_));
  93.                 pStack=(unsigned long*)_alloca(extra_stack_size);
  94.             memset(pStack,0x0,extra_stack_size);
  95.  
  96.         }
  97.         else
  98.         {
  99.                 pStack=(unsigned long*)_alloca(extra_stack_size);
  100.             memset(pStack,0x0,extra_stack_size);
  101.         }
  102.  
  103.         LARGE_INTEGER_* pR=0;
  104.         LARGE_INTEGER_* pStack_=(LARGE_INTEGER_*)pStack;
  105.         for(unsigned long i=0;i<numArg;i++)
  106.         {
  107.                         pR=va_arg(arguments,LARGE_INTEGER_*);
  108.                         pStack_->Low=pR->Low;
  109.                         pStack_->High=pR->High;
  110.                         pStack_++;
  111.         }
  112.         //-----------------------------------------------------------------
  113.         if(!pReturnValue) return false;
  114.         char* p64Code=(char*)LocalAlloc(LMEM_ZEROINIT,0x100);  //This holds code
  115.         memcpy(p64Code,shellcode64,sizeof(shellcode64));
  116.                *(unsigned long*)(&p64Code[0x31])=syscallNum;       
  117.                    memset(pReturnValue,0,sizeof(LARGE_INTEGER_));
  118.  
  119.                    char* pGate=&p64Code[0x50];
  120.                    *(unsigned long*)pGate=(unsigned long)p64Code;
  121.                    *(unsigned short*)(pGate+0x4)=Get64CSValue();
  122.                    LARGE_INTEGER_ HouseKeeping;
  123.                    LARGE_INTEGER_* pHouseKeeping=&HouseKeeping;
  124.                    __asm
  125.                    {
  126.                            mov eax,pGate
  127.                            mov esi,pReturnValue
  128.                            mov edi,pHouseKeeping
  129.                            call fword ptr[eax]
  130.                    }
  131.         LocalFree(p64Code);
  132.         return true;
  133. }
  134.  
  135.  
  136. //-------------------------------------Examples--------------------------------------
  137. void ZwClose64(HANDLE h)
  138. {
  139.         //------------------------------------------
  140.         LARGE_INTEGER_ ret;
  141.         LARGE_INTEGER_ handle={(unsigned long)h,0};
  142.         Call64(&ret,0xC /*System call ordinal of ZwClose*/,0x1,&handle);
  143. }
  144.  
  145. void ZwDelayExecution64(BOOL bAlertable,LARGE_INTEGER* Interval)
  146. {
  147.         LARGE_INTEGER_ argAlertable={(unsigned long)bAlertable,0};
  148.         LARGE_INTEGER_ argInterval ={(unsigned long)Interval,  0};
  149.         LARGE_INTEGER_ ret;
  150.         Call64(&ret,0x31 /*System call ordinal of ZwDelayExecution*/,0x2,&argAlertable,&argInterval);
  151.  
  152. }
  153.  
  154. int ZwSetInformationProcess64(HANDLE hProcess,unsigned long ProcessInformationClass,
  155.                                                          void*  ProcessInformation,unsigned long ProcessInformationLength)
  156. {
  157.         LARGE_INTEGER_ loc_hProcess={0};
  158.         if((unsigned long)hProcess==0xFFFFFFFF)
  159.         {
  160.                 loc_hProcess.Low=0xFFFFFFFF;
  161.                 loc_hProcess.High=0xFFFFFFFF;
  162.         }
  163.         else loc_hProcess.Low=(unsigned long)hProcess;
  164.         LARGE_INTEGER_ loc_ProcessInformationClass      ={(unsigned long)ProcessInformationClass,0};
  165.         LARGE_INTEGER_ loc_ProcessInformation           ={(unsigned long)ProcessInformation,0};
  166.         LARGE_INTEGER_ loc_ProcessInformationLength     ={(unsigned long)ProcessInformationLength,0};
  167.        
  168.         LARGE_INTEGER_ ret;
  169.         bool B=Call64(&ret,0x19,0x4,&loc_hProcess,&loc_ProcessInformationClass,&loc_ProcessInformation,&loc_ProcessInformationLength);
  170.         if(B) return ret.Low;
  171. }
  172. int ZwQueryInformationThread64(HANDLE hThread,unsigned long ThreadInformationClass,
  173.                                                            void* ThreadInformation,unsigned long ThreadInformationLength,
  174.                                                            unsigned long* pResultLength)
  175. {
  176.         LARGE_INTEGER_ loc_hThread={0};
  177.         if((unsigned long)hThread==0xFFFFFFFE)
  178.         {
  179.                 loc_hThread.Low=0xFFFFFFFE;
  180.                 loc_hThread.High=0xFFFFFFFF;
  181.         }
  182.         else loc_hThread.Low=(unsigned long)hThread;
  183.  
  184.         LARGE_INTEGER_ loc_ThreadInformationClass      ={(unsigned long)ThreadInformationClass,0};
  185.         LARGE_INTEGER_ loc_ThreadInformation           ={(unsigned long)ThreadInformation,0};
  186.         LARGE_INTEGER_ loc_ThreadInformationLength     ={(unsigned long)ThreadInformationLength,0};
  187.         LARGE_INTEGER_ loc_pResultLength               ={(unsigned long)pResultLength,0};
  188.  
  189.         LARGE_INTEGER_ ret;
  190.         bool B=Call64(&ret,0x22,0x5,&loc_hThread,&loc_ThreadInformationClass,&loc_ThreadInformation,&loc_ThreadInformationLength,&loc_pResultLength);
  191.         if(B) return ret.Low;
  192. }
  193.  
  194. void main()
  195. {
  196.         HANDLE h=OpenProcess(PROCESS_ALL_ACCESS,FALSE,GetCurrentProcessId());
  197.         if(!h) return;
  198.         ZwClose64(h);
  199.         //-------------------------------------------------
  200.         /*LARGE_INTEGER_* pNewId=(LARGE_INTEGER_*)_aligned_malloc(sizeof(LARGE_INTEGER_),0x8);
  201.         pNewId->Low=CsrGetProcessId();
  202.         pNewId->High=0;
  203.         int ret=ZwSetInformationProcess64(GetCurrentProcess(),ProcessConsoleHostProcess,(void*)pNewId,0x8);
  204.         printf("return value is %x\r\n",ret);
  205.         _aligned_free(pNewId);
  206.         */
  207.         //-------------------------------------------------
  208.         unsigned long Req_Len=0;
  209.         unsigned long IsTerminated=0;
  210. #define ThreadIsTerminated 0x14
  211.         int ret=ZwQueryInformationThread64(GetCurrentThread(),ThreadIsTerminated,&IsTerminated,0x4,&Req_Len);
  212.         printf("return value is %x Required length  %x\r\n",ret,Req_Len);
  213.         //-------------------------------------------------
  214.         LARGE_INTEGER interv={0,0x80000000};
  215.         ZwDelayExecution64(FALSE,&interv);
  216. }
RAW Paste Data
Top