Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Decompiled by : Souhail Hammou
- http://rce4fun.blogspot.com/
- */
- typedef BYTE (*OkayToCloseCallback)(PEPROCESS,PVOID,HANDLE,KPROCESSOR_MODE);
- NTSTATUS ObpCloseHandleTableEntry(HANDLE_TABLE* HandleTable, HANDLE_TABLE_ENTRY* HTEntry,PEPROCESS Process,DWORD Handle,KPROCESSOR_MODE PreviousMode, BOOL IgnoreCloseBit){
- OBJECT_HEADER* ObjectHeader;
- int ObAttributes;
- PVOID ObjectBody;
- PVOID Object;
- OBJECT_TYPE* ObjectType;
- PETHREAD CurrentThread;
- KAPC_STATE ApcState;
- BYTE ProcessAttached;
- /*Remove the handle attributes flags to get the object header*/
- ObjectHeader = HTEntry->Object & 0xFFFFFFF8;
- /*Get the object type pointer using the typeindex as an index to ObTypeIndexTable*/
- ObjectType = ObTypeIndexTable[ObjectHeader->TypeIndex];
- PETHREAD CurrentThread = KeGetCurrentThread();
- /*ObjectBody receives a pointer to the object's body*/
- ObjectBody = &ObjectHeader->Body;
- /*Set to 1 later if the current thread is attached to the target process that opened the handle to the object*/
- ProcessAttached = 0;
- if(ObjectType->TypeInfo.OkayToCloseProcedure != NULL){
- /*The OkayToCloseProcedure is already initialized*/
- /*Check if the current process is the same that created the handle to the object
- if it's not attach the current thread to it to be able to run in its context*/
- if(PsGetCurrentProcess() != Process){
- KeStackAttachProcess(Process,&ApcState);
- ProcessAttached = 1;
- }
- OkayToCloseCallback OkayToCloseProcedure = ObjectType->TypeInfo.OkayToCloseProcedure;
- if(OkayToCloseProcedure(Process,ObjectBody,Handle,PreviousMode) == NULL){
- /*Handle can't be closed*/
- ExUnlockHandleTableEntry(HandleTable,HTEntry);
- KeLeaveCriticalRegion();
- if(ProcessAttached == 1)
- KeUnstackDetachProcess(&ApcState);
- return STATUS_HANDLE_NOT_CLOSABLE;
- }
- }
- /*We land here if OkayToCloseProcedure == NULL or if it hasn't returned 0*/
- /*So the handle can be closed as the OkayToCloseProcedure allowed us to do so
- but we need to check if the handle is protected from being closed*/
- ObAttributes = HTEntry->ObAttributes;
- /*ObAttributes & 110b , zero the closebit (less significant bit)*/
- /*If the closebit is set, the handle cannot be closed*/
- ObAttributes &= 6;
- if (HTEntry->GrantedAccess & ObpAccessProtectCloseBit)
- /*The CloseBit is enabled if the ObpAccessProtectCloseBit (0x20000000) is set in the AccessMask*/
- ObAttributes ^= 1;
- /*Test if the closebit is set and the IgnoreCloseBit boolean*/
- /*If the IgnoreCloseBit boolean is true the handle will be closed even if the CloseBit is set*/
- if(ObAttributes & 1 && IgnoreCloseBit == false){
- /*If the closebit is set and the IgnoreCloseBit is false the handle cannot be closed*/
- /*Check the PreviousMode*/
- if(PreviousMode == KernelMode)
- // Kernel Handle
- /*BSOD : INVALID_KERNEL_HANDLE , KeBugCheckEx doesn't return*/
- KeBugCheckEx(0x93,Handle,NULL,NULL,NULL);
- /*if we came from usermode*/
- /*unlock the handle table entry*/
- ExUnlockHandleTableEntry(HandleTable,HTEntry);
- KeLeaveCriticalRegion();
- /*Detach the kernel thread from the process if it was attached*/
- if(ProcessAttached){
- KeUnstackDetachProcess(&ApcState);
- }
- /*FLG_ENABLE_CLOSE_EXCEPTION == 0x400000*/
- /*check if the flag FLG_ENABLE_CLOSE_EXCEPTIONS is set in the NtGlobalFlag*/
- if ( (NtGlobalFlag & FLG_ENABLE_CLOSE_EXCEPTIONS) == 0){
- /*If the flag is not set we will check if the usermode process is being debugged (debugport flag)
- or if the handletable has debuginfo enabled , then raise the exception in usermode (KeRaiseUserException)
- */
- CurrentProc = PsGetCurrentProcess();
- /*If a debugger is present or the handle table's debug info is enabled raise a usermode exception*/
- if(CurrentProc->DebugPort != 0 || HandleTable->DebugInfo != NULL){
- KeRaiseUserException(STATUS_HANDLE_NOT_CLOSABLE);
- return;
- }
- /*if it's not the case just return the error in NTSTATUS*/
- return STATUS_HANDLE_NOT_CLOSABLE;
- }
- else{
- /*If the global flag is set , raise the usermode exception anyway*/
- KeRaiseUserException(STATUS_HANDLE_NOT_CLOSABLE);
- return;
- }
- }
- else{
- /*The handle can be closed because : ObAttributes & 1 == 0 || IgnoreCloseBit == true*/
- /*CloseBit is not set or it is set and the IgnoreCloseBit is true*/
- /*So we will ignore the CloseBit and just close the handle anyways*/
- /*Destroy the handle (Free the handle table entry and decrement the handle count ... check the routine)*/
- ExDestroyHandle(HTEntry,HandleTable,Handle);
- KeLeaveCriticalRegion();
- /*Decrement the handle count*/
- ObDecrementHandleCount(ObjectHeader,Process);
- if(ProcessAttached){
- KeUnstackDetachProcess(&ApcState);
- }
- /*Decrement the reference count*/
- ObfDereferenceObject(ObjectBody);
- return STATUS_SUCCESS;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement