📄 nthandle的实现过程和反汇编的c源代码.txt
字号:
unsigned long ret;
p8->Status = 0;
p8->Information = 0;
if(p7==0x83350000)
{
//83350000就是我们查句柄信息的操作请求
//p6就是输出长度字段的地址
p8->Information = *p6;
ret = getinfo(p3,p5,(unsigned long)(&(p8->Information)));
p8->Status = ret;
return p8->Status;
}
else if(p7==0x83350008)
{
if(*(unsigned long *)p3==0xc8)
{
*(unsigned long *)p3=0xc8;
p8->Information=0x4;
return p8->Status;
}
else
{
p8->Status=0xC0000059;
return p8->Status;
}
}
else if(p7==0x8335000c)
{
//8335000c可以用来实现对0,8进程查找运行用户 身份的请求,直接返回内核模式下打开的句柄令牌的信息,避免用户模式下打开失败
p8->Status = ZwOpenProcessToken(*(HANDLE *)p3,8,(PHANDLE)p5);
p8->Information = 4;
}
else
{
return p8->Status;
}
return 0;
}
unsigned long getinfo(PVOID p1,PVOID p2,unsigned long p3)
{
//具体的查询句柄信息的程序
HANDLE oph;
HANDLE dh;
CLIENT_ID a2;
OBJECT_ATTRIBUTES a1;
long ret;
unsigned long pid;
unsigned long handaddr;
unsigned long handleid;
PVOID Object;
PVOID o2;
unsigned long a4;
unsigned long a5;
ANSI_STRING aObjName;
a4 = 0;
try
{
try{
*(unsigned long *)p3=0;
pid = ((PMYOBJECTINFO)p1)->pid;
handleid = ((PMYOBJECTINFO)p1)->objhandle;
handaddr = ((PMYOBJECTINFO)p1)->objaddr;
if(pid<8)
{
//处理小于8的系统进程
PsLookupProcessByProcessId(pid,&oph);
if(oph>=0)
{
KeAttachProcess(oph);
ret = ObReferenceObjectByHandle((HANDLE)handleid,0x80000000,0,0,&Object,0);
ZwClose(oph);
if(ret<0 || ret>0x80000000)
{
KeDetachProcess();
return 0x0C0000022;
}
if(*(unsigned long *)Object!=handaddr)
{
ObfDereferenceObject(Object);
KeDetachProcess();
return 0x0C0000022;
}
KeDetachProcess();
}
else
return 0xC0000022;
}
else
{
//大于等于8的进程在此处理
a2.UniqueProcess = (HANDLE)pid;
a2.UniqueThread = 0;
a1.Length = 0x18;
a1.RootDirectory = 0;
a1.Attributes = 0;
a1.ObjectName = 0;
a1.SecurityDescriptor = 0;
a1.SecurityQualityOfService = 0;
ret = ZwOpenProcess(&oph,0x40,&a1,&a2);
if(ret<0 || ret > 0x80000000)
return 0xc0000022;
else
{
ZwDuplicateObject(oph,(HANDLE)handleid,(HANDLE)0xFFFFFFFF,&dh,0,0,2);
ZwClose(oph);
if(dh!=0)
{
ret = ObReferenceObjectByHandle(dh,0x80000000,0,0,&Object,0);
ZwClose(dh);
if(ret<0 || ret>0x80000000)
return 0xc0000022;
if((unsigned long)Object!=handaddr)
{
ObfDereferenceObject(Object);
return 0xc0000022;
}
}
else
return 0xc0000022;
}
}
a4=0x800;
((PUNICODE_STRING)p2)->Length = 0;
//OK,都执行到这点上,判断内核对象的地址上第一个4字节的内容,如果是0x700005,说明其组成是由一个链表组成的,需要调用链表处理的过程来处理
if((unsigned long)Object==0x700005)
{
ret = callmap(Object,p2,p3);
if(ret==0)
{
ObfDereferenceObject(Object);
return 0;
}
else
{
ObfDereferenceObject(Object);
return 0xFFFFFFFF;
}
}
else
{
ret=ObQueryNameString(Object,(PUNICODE_STRING)p2,a4,&a5);
if(ret>=0 && ((PUNICODE_STRING)p2)->Length>0)
{
//DbgPrint(L"%S\n",ObjName.Buffer);
if(RtlUnicodeStringToAnsiString(&aObjName,(PUNICODE_STRING)p2,1)==0)
{
*(unsigned long *)p2 = 0;
strncpy(p2,aObjName.Buffer,aObjName.Length);
((char *)(p2))[aObjName.Length]=0;
*(unsigned long*)p3=aObjName.Length+1;
RtlFreeAnsiString(&aObjName);
}
else
{
ObfDereferenceObject(Object);
return 0xFFFFFFFF;
}
}
else
{
//如果ObQueryNameString失败,检查内核对象内容的组成是否是一个有效的连表组成形式
o2 = (PVOID)((unsigned long)Object+0x14);
if(MmIsAddressValid(o2))
{
if(MmIsAddressValid(*(PVOID *)(o2)))
{
o2 = (PVOID)(*(unsigned long *)(o2)+0x18);
if(MmIsAddressValid(o2))
{
if(MmIsAddressValid(*(PVOID *)(o2)))
{
o2 = (PVOID)(*(unsigned long *)(o2)+0x24);
if(MmIsAddressValid(o2))
{
if(MmIsAddressValid(*(PVOID *)(o2)))
{
o2 =*(PVOID *)(o2);
if(*(USHORT *)o2==0x7005)
{
//然后判断是否是0x700005,调用连表处理的过程函数
ret = callmap(o2,p2,p3);
if(ret==0)
{
ObfDereferenceObject(Object);
return 0;
}
}
}
}
}
}
}
}
ObfDereferenceObject(Object);
return 0xFFFFFFFF;
}
}
ObfDereferenceObject(Object);
}
except(EXCEPTION_EXECUTE_HANDLER){
return 0xc0000005;
}
}finally
{
}
return 0;
}
unsigned long callmap(PVOID Object,PVOID p2,unsigned long p3)
{
//连表处理的函数
unsigned long o1;
PVOID o2;
unsigned long o3;
PVOID o4;
USHORT o5;
ANSI_STRING aObjName;
unsigned long a4;
unsigned long a5;
long ret;
try{
*(unsigned long *)p3=0;
a4 = 0x800;
o2=*(PVOID *)((unsigned long)Object+4);
if((unsigned long)o2!=0)
{
o1=(unsigned long)p2;
ret=ObQueryNameString(o2,(PUNICODE_STRING)p2,a4,&a5);
if(ret>=0 && ((PUNICODE_STRING)p2)->Length>0)
{
RtlUnicodeStringToAnsiString(&aObjName,(PUNICODE_STRING)p2,1);
*(unsigned long *)p2 = 0;
strncpy((char *)p2,aObjName.Buffer,aObjName.Length+1);
((char *)(p2))[aObjName.Length]=0;
o1=(unsigned long)p2+aObjName.Length;
*(unsigned long *)p2=(unsigned long)o1;
RtlFreeAnsiString(&aObjName);
}
}
else
o1=(unsigned long)p2;
a5 = *(USHORT *)((unsigned long)Object+0x30);
a5 = a5>>1;
o3 = *(unsigned long *)((unsigned long)Object+0x20);
if(a5!=0 || o3!=0)
{
//获得总的长度
o4 = *(PVOID *)((unsigned long)Object+0x34);
if(*(char *)o4!='\\')
{
do{
if(o3==0)
break;
a5 = a5+1+((*(USHORT *)(o3+0x30))>>1);
o3 = *(unsigned long *)(o3+0x20);
}while(1);
}
}
o1=o1+a5-((*(USHORT *)((unsigned long)Object+0x30))>>1);
RtlUnicodeStringToAnsiString(&aObjName,(PUNICODE_STRING)((unsigned long)Object+0x30),1);
strncpy((char *)(o1),aObjName.Buffer,aObjName.Length+1);
RtlFreeAnsiString(&aObjName);
o3 = *(unsigned long *)((unsigned long)Object+0x20);
o4 = *(PVOID *)((unsigned long)Object+0x34);
if(*(char *)o4!='\\')
{
//依次拷贝各个链表上的内容到输出缓冲区
do{
if(o3==0)
break;
*(char *)(o1-1)='\\';
o5 = (*(USHORT *)(o3+0x30))>>1;
o1 = o1-o5-1;
RtlUnicodeStringToAnsiString(&aObjName,(PUNICODE_STRING)((unsigned long)o3+0x30),1);
strncpy((char *)o1,aObjName.Buffer,aObjName.Length);
RtlFreeAnsiString(&aObjName);
o3 = *(unsigned long *)(o3+0x20);
}while(1);
}
if(a5>3)
{
if(((char *)p2)[2]=='\\')
if(((char *)p2)[3]=='\\')
memcpy((PVOID)((unsigned long)p2+2),(PVOID)((unsigned long)p2+3),a5-3);
}
*(unsigned long *)p3=a5;
}except(EXCEPTION_EXECUTE_HANDLER){
return 0xc0000005;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -