A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #17406  by EP_X0FF
 Fri Dec 28, 2012 8:02 am
@myid

No need to spam me with questions. When I will have time I will of course see your posts and advise anything if I can.

Considering your problem.

1. Handle is malformed. Patched in handle table, modified anyhow. This hack also make it unworkable. Possiblity of such situation is around 0.
2. Handle already closed and removed from handle table.
3. Handle has a ProtectFromClose bit set. See MSDN -> SetHandleInformation.
4. Handle is kernel handle (created with OBJ_KERNEL_HANDLE flag in attributes), which means it is inaccessible from any kind of user mode requests and located in ObpKernelHandleTable. Itself kernel handle is just regular handle with its sign bit set.

In your case you didn't showed how you close this handle (hello, where is source code? Calling telepaths?). Every time if someone ask for help with development - post code. How many time this simple default rule should be repeated?

So ZwClose returns STATUS_INVALID_HANDLE and we have Windows Vista 2.0 aka win7 with improved security etc. System process handles are obviously kernel handles. So for example if you have 0x82C handle, it real value will be 0x8000082C. Windows will not mask passed by ZwClose handle and will try to close 0x82C obviously resulting in STATUS_INVALID_HANDLE. But your code will fail even before ExMapHandleToPointer. Because of special check for kernel handle. So we have a driver, inside we are doing attach to System context by KeStackAttachProcess and calling ZwClose from this context passing correct masked value. STATUS_SUCCESS.
 #17409  by EP_X0FF
 Fri Dec 28, 2012 8:41 am
kmd wrote:@EP_X0FF
is this new check?
handle is the pointer, so hows for x64
This is a new check added beginning from Windows 7.

If current process handle table is ObpKernelHandleTable (which means caller is PsInitialSystemProcess) and handle we are trying to manupulate is not kernel handle - then return STATUS_INVALID_HANDLE. The same check present not only for close handle routine ObpCloseHandle, but in ObReferenceObjectByHandleWithTag for example too.

For x64 there will be 0xffffffff80000000.

For more info see ObpCloseHandle.
and why i was able to close handle with PE?
Ask Mark.
 #17413  by myid
 Fri Dec 28, 2012 9:44 am
EP_X0FF wrote:@myid

No need to spam me with questions. When I will have time I will of course see your posts and advise anything if I can.

Considering your problem.

1. Handle is malformed. Patched in handle table, modified anyhow. This hack also make it unworkable. Possiblity of such situation is around 0.
2. Handle already closed and removed from handle table.
3. Handle has a ProtectFromClose bit set. See MSDN -> SetHandleInformation.
4. Handle is kernel handle (created with OBJ_KERNEL_HANDLE flag in attributes), which means it is inaccessible from any kind of user mode requests and located in ObpKernelHandleTable. Itself kernel handle is just regular handle with its sign bit set.

In your case you didn't showed how you close this handle (hello, where is source code? Calling telepaths?). Every time if someone ask for help with development - post code. How many time this simple default rule should be repeated?

So ZwClose returns STATUS_INVALID_HANDLE and we have Windows Vista 2.0 aka win7 with improved security etc. System process handles are obviously kernel handles. So for example if you have 0x82C handle, it real value will be 0x8000082C. Windows will not mask passed by ZwClose handle and will try to close 0x82C obviously resulting in STATUS_INVALID_HANDLE. But your code will fail even before ExMapHandleToPointer. Because of special check for kernel handle. So we have a driver, inside we are doing attach to System context by KeStackAttachProcess and calling ZwClose from this context passing correct masked value. STATUS_SUCCESS.
Thanks for your answer.But I still have some questions:

1.This handle is normal, created by ZwCreateFile:
Code: Select all
HANDLE LockFileHandle;

VOID LockFileProc(PVOID FileName)
{
    NTSTATUS ntStatus;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING UniFileName;
    IO_STATUS_BLOCK IoStatusBlock;
    //PCWSTR FileName = L"\\??\\C:\\LockFileTest.txt";
    RtlInitUnicodeString(&UniFileName, (PCWSTR)FileName);
    InitializeObjectAttributes(&ObjectAttributes,
								&UniFileName,
								OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
								NULL,
								NULL);
    ntStatus = IoCreateFile(&LockFileHandle,
							GENERIC_READ,
							&ObjectAttributes,
							&IoStatusBlock,
							0,
							FILE_ATTRIBUTE_NORMAL,
							0,
							FILE_OPEN_IF,
							FILE_NON_DIRECTORY_FILE,
							NULL,
							0,
							0,
							NULL,
							IO_NO_PARAMETER_CHECKING);
    if(!NT_SUCCESS(ntStatus))
    {
        DbgPrint("[OccupyFile] = %x", ntStatus);
    }
    else 
    {
        DbgPrint("[OccupyFile] Success.");
    }
	PsTerminateSystemThread(STATUS_SUCCESS);
}

VOID LockFile(PCWSTR FileName)
{
	HANDLE hThread=0;
	NTSTATUS status = PsCreateSystemThread(&hThread, 
											0, 
											NULL, 
											NULL, 
											NULL, 
											LockFileProc, 
											(PVOID)FileName);
	if(NT_SUCCESS(status))
		ZwClose(hThread);
}
2.I have modified the highest bit of handle but still cannot close this handle(WIN7 X64):
Code: Select all
VOID ForceCloseHandle(PEPROCESS Process, ULONG64 HandleValue)
{
	HANDLE h;
	NTSTATUS st;
	KAPC_STATE ks={0};
	OBJECT_HANDLE_FLAG_INFORMATION ohfi;
	if( Process==NULL )
		return;
	if( !MmIsAddressValid(Process) )
		return;
	if( Process==SystemProcess )
	{
		DbgPrint("[HandleValue]%llx\n",HandleValue);
		HandleValue=HandleValue | 0x8000000000000000;
		DbgPrint("[HandleValue]%llx\n",HandleValue);
	}
	KeStackAttachProcess(Process, &ks);
	h=(HANDLE)HandleValue;
	ohfi.Inherit=0;
	ohfi.ProtectFromClose=0;
	st=ObSetHandleAttributes(h, &ohfi, KernelMode);	DbgPrint("[ObSetHandleAttributes]%x\n",st);
	st=ZwClose(h);	DbgPrint("[ZwClose]%x\n",st);	//still return STATUS_INVALID_HANDLE
	KeUnstackDetachProcess(&ks);
}
ObSetHandleAttributes return STATUS_SUCCESS, ZwClose still return STATUS_INVALID_HANDLE. What the hell is going on?
 #17415  by EP_X0FF
 Fri Dec 28, 2012 11:04 am
You masked it wrong.

Example of kernel handle.
0xFFFFFFFF800007C4

You have so many DbgPrint's so why you unable to see how handle should be looking?
 #17419  by myid
 Fri Dec 28, 2012 11:42 am
EP_X0FF wrote:You masked it wrong.

Example of kernel handle.
0xFFFFFFFF800007C4

You have so many DbgPrint's so why you unable to see how handle should be looking?
Thank you very much. I close kernel handle successfully!
I think you are the god of Windows Programming. :D :D :D
 #17442  by Buster_BSA
 Sat Dec 29, 2012 12:35 pm
Sometimes Buster Sandbox Analyzer stops analyzing because, as I commented, RegHive file gets locked. SYSTEM (PID 4) process has the lock and I have been unable to find any tool which unlocks the file.

Could someone write a command line tool which accepts as arguments a PID and a handle and tries to close the handle as myid´s code, please?

I want to check if that code can unlock RegHive so Buster Sandbox Analyzer can continue analysis.

Thanks in advance!