Code:
HANDLE Native_DuplicateHandleInProcess(wchar_t *pName,ULONG HandleType)
{
THREAD_BASIC_INFORMATION tbi = {0};
POBJECT_NAME_INFORMATION oni = {0};
CLIENT_ID Cid = {0};
OBJECT_ATTRIBUTES oa = {0};
PSYSTEM_HANDLE_INFORMATION_EX buf = {0};
PUNICODE_STRING pnb = 0;
HANDLE hCProcess = INVALID_HANDLE_VALUE,TempHandle = INVALID_HANDLE_VALUE;
NTSTATUS Status = 0;
ULONG Reusable = 0x40960;
BOOLEAN test = 0;
InitializeObjectAttributes(&oa,0,0,0,0);
__try
{
SzMismatch:
buf = (PSYSTEM_HANDLE_INFORMATION_EX)RtlAllocateHeap(RtlProcessHeap(),HEAP_ZERO_MEMORY |HEAP_GROWABLE,Reusable);
Status = NtQuerySystemInformation(SystemHandleInformation,buf,Reusable,&Reusable);
if(Status == 0xC0000004 )
{
if(RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf))
{
__asm jmp SzMismatch;
}
}
if(!NT_SUCCESS(Status))
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
return INVALID_HANDLE_VALUE;
}
for(Reusable = 0;Reusable < buf->NumberOfHandles;Reusable++)
{
if(buf->Information[Reusable].ProcessId != 4)
{
if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_PROCESS)
{
Cid.UniqueProcess = (PVOID)buf->Information[Reusable].ProcessId;
Cid.UniqueThread = 0;
Status = NtOpenProcess(&hCProcess,PROCESS_ALL_ACCESS,&oa,&Cid);
if(hCProcess != INVALID_HANDLE_VALUE)
{
pnb = (PUNICODE_STRING)RtlAllocateHeap(RtlProcessHeap(),HEAP_ZERO_MEMORY|HEAP_GROWABLE,0x1024);
Status = NtQueryInformationProcess(hCProcess,ProcessImageFileName,(PVOID)pnb,0x1024,0);
if(pnb->Buffer != NULL)
{
PWCHAR cpn = (PWCHAR)pnb->Buffer;
USHORT cln = pnb->Length;
do
{
cpn++;
if(wcscmp(pName,cpn)== 0)
{
switch(HandleType)
{
case OB_TYPE_PROCESS:
test = RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
test = RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
return hCProcess;
case OB_TYPE_THREAD :
Reusable = 0;
do
{
if(buf->Information[Reusable].ProcessId == (USHORT)Cid.UniqueProcess)
{
if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_THREAD)
{
Status = NtDuplicateObject(hCProcess,(PHANDLE)buf->Information[Reusable].Handle,NtCurrentProcess(),&TempHandle,0,0,DUPLICATE_SAME_ACCESS);
Status = NtQueryInformationThread(TempHandle,ThreadBasicInformation,&tbi,sizeof(tbi),0);
if(tbi.ClientId.UniqueProcess == (PVOID)Cid.UniqueProcess)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
NtClose(hCProcess);
return TempHandle;
}
}
}
Reusable++;
}while(Reusable != buf->NumberOfHandles);
case OB_TYPE_WINDOW_STATION:
Reusable = 0;
do
{
if(buf->Information[Reusable].ProcessId == (USHORT)Cid.UniqueProcess)
{
if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_WINDOW_STATION)
{
Status = NtDuplicateObject(hCProcess,(PHANDLE)buf->Information[Reusable].Handle,NtCurrentProcess(),&TempHandle,0,0,DUPLICATE_SAME_ACCESS);
if(TempHandle != INVALID_HANDLE_VALUE)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
NtClose(hCProcess);
return TempHandle;
}
}
}
Reusable++;
}while(Reusable != buf->NumberOfHandles);
case OB_TYPE_DESKTOP:
Reusable = 0;
do
{
if(buf->Information[Reusable].ProcessId == (USHORT)Cid.UniqueProcess)
{
if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_DESKTOP)
{
Status = NtDuplicateObject(hCProcess,(PHANDLE)buf->Information[Reusable].Handle,NtCurrentProcess(),&TempHandle,0,0,DUPLICATE_SAME_ACCESS);
if(TempHandle != INVALID_HANDLE_VALUE)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
NtClose(hCProcess);
return TempHandle;
}
}
}
Reusable++;
}while(Reusable != buf->NumberOfHandles);
default :
return INVALID_HANDLE_VALUE;
}
}
cln--;
}while(cln);
}
}
}
}
}
if(pnb)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
}
if(buf)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
}
if(hCProcess)
{
NtClose(hCProcess);
}
if(TempHandle)
{
NtClose(TempHandle);
}
}
__except(1)
{
if(pnb)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
}
if(buf)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
}
if(hCProcess)
{
NtClose(hCProcess);
}
if(TempHandle)
{
NtClose(TempHandle);
}
}
return INVALID_HANDLE_VALUE;
}
added the previously described features and bugfixes and "debugged" it a few times, I also added Handle Leak Prevention and buffer clean up.