waliedassar

Call64, Issue 64-bit System Calls

Jan 12th, 2013
694
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