SHARE
TWEET

ObpCloseHandleTableEntry

Souhail_Hammou Jul 8th, 2014 185 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. Decompiled by : Souhail Hammou
  3. http://rce4fun.blogspot.com/
  4. */
  5. typedef BYTE (*OkayToCloseCallback)(PEPROCESS,PVOID,HANDLE,KPROCESSOR_MODE);
  6. NTSTATUS ObpCloseHandleTableEntry(HANDLE_TABLE* HandleTable, HANDLE_TABLE_ENTRY* HTEntry,PEPROCESS Process,DWORD Handle,KPROCESSOR_MODE PreviousMode, BOOL IgnoreCloseBit){
  7.         OBJECT_HEADER* ObjectHeader;
  8.         int ObAttributes;
  9.         PVOID ObjectBody;
  10.         PVOID Object;
  11.         OBJECT_TYPE* ObjectType;
  12.         PETHREAD CurrentThread;
  13.         KAPC_STATE ApcState;
  14.         BYTE ProcessAttached;
  15.         /*Remove the handle attributes flags to get the object header*/
  16.         ObjectHeader = HTEntry->Object & 0xFFFFFFF8;
  17.         /*Get the object type pointer using the typeindex as an index to ObTypeIndexTable*/
  18.         ObjectType = ObTypeIndexTable[ObjectHeader->TypeIndex];
  19.         PETHREAD CurrentThread = KeGetCurrentThread();
  20.         /*ObjectBody receives a pointer to the object's body*/
  21.         ObjectBody = &ObjectHeader->Body;
  22.         /*Set to 1 later if the current thread is attached to the target process that opened the handle to the object*/
  23.         ProcessAttached = 0;
  24.         if(ObjectType->TypeInfo.OkayToCloseProcedure != NULL){
  25.                 /*The OkayToCloseProcedure is already initialized*/
  26.                 /*Check if the current process is the same that created the handle to the object
  27.                 if it's not attach the current thread to it to be able to run in its context*/
  28.                 if(PsGetCurrentProcess() != Process){
  29.                         KeStackAttachProcess(Process,&ApcState);
  30.                         ProcessAttached = 1;
  31.                 }
  32.                 OkayToCloseCallback OkayToCloseProcedure = ObjectType->TypeInfo.OkayToCloseProcedure;
  33.                 if(OkayToCloseProcedure(Process,ObjectBody,Handle,PreviousMode) == NULL){
  34.                         /*Handle can't be closed*/
  35.                         ExUnlockHandleTableEntry(HandleTable,HTEntry);
  36.                         KeLeaveCriticalRegion();
  37.                         if(ProcessAttached == 1)
  38.                                 KeUnstackDetachProcess(&ApcState);
  39.                         return STATUS_HANDLE_NOT_CLOSABLE;
  40.                 }
  41.                        
  42.         }
  43.         /*We land here if OkayToCloseProcedure == NULL or if it hasn't returned 0*/
  44.         /*So the handle can be closed as the OkayToCloseProcedure allowed us to do so
  45.         but we need to check if the handle is protected from being closed*/
  46.         ObAttributes = HTEntry->ObAttributes;
  47.         /*ObAttributes & 110b , zero the closebit (less significant bit)*/
  48.         /*If the closebit is set, the handle cannot be closed*/
  49.         ObAttributes &= 6;
  50.         if (HTEntry->GrantedAccess & ObpAccessProtectCloseBit)
  51.                 /*The CloseBit is enabled if the ObpAccessProtectCloseBit (0x20000000) is set in the AccessMask*/
  52.                 ObAttributes ^= 1;
  53.         /*Test if the closebit is set and the IgnoreCloseBit boolean*/
  54.         /*If the IgnoreCloseBit boolean is true the handle will be closed even if the CloseBit is set*/
  55.         if(ObAttributes & 1 && IgnoreCloseBit == false){
  56.                 /*If the closebit is set and the IgnoreCloseBit is false the handle cannot be closed*/
  57.                 /*Check the PreviousMode*/
  58.                 if(PreviousMode == KernelMode)
  59.                         // Kernel Handle
  60.                         /*BSOD : INVALID_KERNEL_HANDLE , KeBugCheckEx doesn't return*/
  61.                         KeBugCheckEx(0x93,Handle,NULL,NULL,NULL);
  62.                 /*if we came from usermode*/
  63.                 /*unlock the handle table entry*/
  64.                 ExUnlockHandleTableEntry(HandleTable,HTEntry);
  65.                 KeLeaveCriticalRegion();
  66.                 /*Detach the kernel thread from the process if it was attached*/
  67.                 if(ProcessAttached){
  68.                         KeUnstackDetachProcess(&ApcState);
  69.                 }
  70.                 /*FLG_ENABLE_CLOSE_EXCEPTION == 0x400000*/
  71.                 /*check if the flag FLG_ENABLE_CLOSE_EXCEPTIONS is set in the NtGlobalFlag*/
  72.                 if ( (NtGlobalFlag & FLG_ENABLE_CLOSE_EXCEPTIONS) == 0){
  73.                         /*If the flag is not set we will check if the usermode process is being debugged (debugport flag)
  74.                         or if the handletable has debuginfo enabled , then raise the exception in usermode (KeRaiseUserException)
  75.                         */
  76.                         CurrentProc = PsGetCurrentProcess();
  77.                         /*If a debugger is present or the handle table's debug info is enabled raise a usermode exception*/
  78.                         if(CurrentProc->DebugPort != 0 || HandleTable->DebugInfo != NULL){
  79.                                 KeRaiseUserException(STATUS_HANDLE_NOT_CLOSABLE);
  80.                                 return;
  81.                         }
  82.                         /*if it's not the case just return the error in NTSTATUS*/
  83.                         return STATUS_HANDLE_NOT_CLOSABLE;
  84.                 }
  85.                 else{
  86.                         /*If the global flag is set , raise the usermode exception anyway*/
  87.                         KeRaiseUserException(STATUS_HANDLE_NOT_CLOSABLE);
  88.                         return;
  89.                 }
  90.                
  91.         }
  92.         else{  
  93.                 /*The handle can be closed because : ObAttributes & 1 == 0 || IgnoreCloseBit == true*/
  94.                 /*CloseBit is not set or it is set and the IgnoreCloseBit is true*/
  95.                 /*So we will ignore the CloseBit and just close the handle anyways*/
  96.                 /*Destroy the handle (Free the handle table entry and decrement the handle count ... check the routine)*/
  97.                 ExDestroyHandle(HTEntry,HandleTable,Handle);
  98.                 KeLeaveCriticalRegion();
  99.                 /*Decrement the handle count*/
  100.                 ObDecrementHandleCount(ObjectHeader,Process);
  101.                 if(ProcessAttached){
  102.                         KeUnstackDetachProcess(&ApcState);
  103.                 }
  104.                 /*Decrement the reference count*/
  105.                 ObfDereferenceObject(ObjectBody);
  106.                 return STATUS_SUCCESS;
  107.         }
  108. }
RAW Paste Data
Top