HeavenSea 发表于 2010-6-28 01:20:57

由EProcess从最底层获取进程路径

获取进程路径的方法很多,如读命令行、GetModuleFileNameEx,PsSetLoadImageNotify等,不管Ring0还是3,这些都不是从根本上得到,周日闲暇蛋疼时研究了下,若该方法已经被广泛使用而只有我小菜鸟自作多情请高手谅解。…主要参考了Win2K的PspCreateProcess等代码。方法:ObQueryNameString EProcess.SectionObject-〉Segment-〉ControlArea-〉FilePointer,可以自己实ObQuery...

乔丹二世 发表于 2010-6-28 01:33:13

http://www.kanxue.com/showthread.php?t=111060
extern POBJECT_TYPE *PsProcessType;

NTKERNELAPI
UCHAR *
PsGetProcessImageFileName(
            PEPROCESS Process);

NTKERNELAPI
NTSTATUS
ObQueryNameString(
          INPVOID Object,
          OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
          INULONG Length,
          OUT PULONG ReturnLength);

//路径解析出子进程名
VOIDGetSonName( char *ProcessPath, char *ProcessName )
{
ULONG n = strlen( ProcessPath) - 1;
ULONG i = n;
//KdPrint(("%d",n));
while( ProcessPath != '\\')
{
    i = i-1;
}
strncpy( ProcessName,ProcessPath+i+1,n-i);
}

//依据EPROCESS得到进程全路径
VOID GetFullPathByEprocess( ULONG eprocess,PCHAR ProcessImageName )
{
//原理Eprocess->sectionobject(0x138)->Segment(0x014)->ControlAera(0x000)->FilePointer(0x024)->(FileObject->FileName,FileObject->DeviceObject)
ULONG object;
PFILE_OBJECT FileObject;
UNICODE_STRING FilePath;
UNICODE_STRING DosName;
STRING AnsiString;

FileObject = NULL;
FilePath.Buffer = NULL;
FilePath.Length = 0;
*ProcessImageName = 0;

if(MmIsAddressValid((PULONG)(eprocess+0x138)))//Eprocess->sectionobject(0x138)
{
    object=(*(PULONG)(eprocess+0x138));
      //KdPrint((" sectionobject :0x%x\n",object));
    if(MmIsAddressValid((PULONG)((ULONG)object+0x014)))
    {
      object=*(PULONG)((ULONG)object+0x014);
      //KdPrint((" Segment :0x%x\n",object));
      if(MmIsAddressValid((PULONG)((ULONG)object+0x0)))
      {
      object=*(PULONG)((ULONG_PTR)object+0x0);
      //KdPrint((" ControlAera :0x%x\n",object));
      if(MmIsAddressValid((PULONG)((ULONG)object+0x024)))
      {
          object=*(PULONG)((ULONG)object+0x024);
          //KdPrint((" FilePointer :0x%x\n",object));
      }
      else
          return ;
      }
      else
      return ;
    }
    else
      return ;
}
else
    return ;
    FileObject=(PFILE_OBJECT)object;

FilePath.Buffer = ExAllocatePool(PagedPool,0x200);
FilePath.MaximumLength = 0x200;
    //KdPrint((" FilePointer :%wZ\n",&FilePointer->FileName));
ObReferenceObjectByPointer((PVOID)FileObject,0,NULL,KernelMode);//引用计数+1,操作对象

RtlVolumeDeviceToDosName(FileObject-> DeviceObject, &DosName);
RtlCopyUnicodeString(&FilePath, &DosName);
RtlAppendUnicodeStringToString(&FilePath, &FileObject->FileName);
ObDereferenceObject(FileObject);
   
RtlUnicodeStringToAnsiString(&AnsiString, &FilePath, TRUE);
if ( AnsiString.Length >= 216 )
{
    memcpy(ProcessImageName, AnsiString.Buffer, 0x100u);
    *(ProcessImageName + 215) = 0;
}
else
{
    memcpy(ProcessImageName, AnsiString.Buffer, AnsiString.Length);
    ProcessImageName = 0;
}
RtlFreeAnsiString(&AnsiString);
ExFreePool(DosName.Buffer);
ExFreePool(FilePath.Buffer);
}
//
VOID GetCurrentProcess(PULONG pid, PCHAR name, PCHAR path)
{
PEPROCESS Cprocess;
Cprocess = PsGetCurrentProcess();
*pid = *(PULONG)((ULONG)Cprocess+0x84);
strcpy(name ,PsGetProcessImageFileName(Cprocess));
GetFullPathByEprocess((ULONG)Cprocess,path);
}

//根据SectionHandle得到进程全路径
VOID GetFullPathBySectionHandle( HANDLE SectionHandle, PCHAR ProcessImageName )
{
PVOID SectionObject;
PFILE_OBJECT FileObject;
UNICODE_STRING FilePath;
UNICODE_STRING DosName;
NTSTATUS Status;
STRING AnsiString;

SectionObject = NULL;
FileObject = NULL;
FilePath.Buffer = NULL;
FilePath.Length = 0;
*ProcessImageName = 0;
Status = ObReferenceObjectByHandle(SectionHandle, 0, NULL, KernelMode, &SectionObject, NULL);

if ( NT_SUCCESS(Status) )
{
    FilePath.Buffer = ExAllocatePool(PagedPool,0x200);
    FilePath.MaximumLength = 0x200;
    FileObject = (PFILE_OBJECT)(*((ULONG *)SectionObject + 5)); // PSEGMENT
    FileObject = *(PFILE_OBJECT *)FileObject; // CONTROL_AREA
    FileObject = *(PFILE_OBJECT *)((ULONG)FileObject + 36); // FILE_OBJECT
    ObReferenceObjectByPointer((PVOID)FileObject, 0, NULL, KernelMode);
    RtlVolumeDeviceToDosName(FileObject-> DeviceObject, &DosName);
    RtlCopyUnicodeString(&FilePath, &DosName);
    RtlAppendUnicodeStringToString(&FilePath, &FileObject->FileName);
    ObDereferenceObject(FileObject);
    ObDereferenceObject(SectionObject);
    RtlUnicodeStringToAnsiString(&AnsiString, &FilePath, TRUE);
    if ( AnsiString.Length >= 216 )
    {
      memcpy(ProcessImageName, AnsiString.Buffer, 0x100u);
      *(ProcessImageName + 215) = 0;
    }
    else
    {
      memcpy(ProcessImageName, AnsiString.Buffer, AnsiString.Length);
      ProcessImageName = 0;
    }
    RtlFreeAnsiString(&AnsiString);
    ExFreePool(DosName.Buffer);
    ExFreePool(FilePath.Buffer);
}
}
//根据ProcessHandle得到EPROCESS然后得到进程全路径
VOID GetFullPathByProcessHandle( HANDLE ProcessHandle, PCHAR ProcessImageName , PULONG pid )
{
NTSTATUS status;
PVOID ProcessObject;
ULONG eprocess;
/*__asm
{
    int 3
}*/
status = ObReferenceObjectByHandle( ProcessHandle ,0,*PsProcessType,KernelMode, &ProcessObject, NULL);
if(!NT_SUCCESS(status))   //失败
{
    DbgPrint("Object Error");
    KdPrint((" error status:0x%x\n",status));
    return;
}
//KdPrint((" Eprocess :0x%x\n",(ULONG)ProcessObject));
//Object转换成EPROCESS: object低二位清零
eprocess = ((ULONG)ProcessObject) & 0xFFFFFFFC;
*pid = *(PULONG)((ULONG)eprocess+0x84);
ObDereferenceObject(ProcessObject);
GetFullPathByEprocess( eprocess ,ProcessImageName);
}
//根据FileObject得到全路径
VOID GetFullPathByFileObject( PFILE_OBJECT FileObject, PCHAR ProcessImageName)
{

UNICODE_STRING FilePath;
UNICODE_STRING DosName;
STRING AnsiString;

FilePath.Buffer = NULL;
FilePath.Length = 0;
*ProcessImageName = 0;

FilePath.Buffer = ExAllocatePool(PagedPool,0x200);
FilePath.MaximumLength = 0x200;
    //KdPrint((" FilePointer :%wZ\n",&FilePointer->FileName));
ObReferenceObjectByPointer((PVOID)FileObject,0,NULL,KernelMode);//引用计数+1,操作对象

RtlVolumeDeviceToDosName(FileObject-> DeviceObject, &DosName);
RtlCopyUnicodeString(&FilePath, &DosName);
RtlAppendUnicodeStringToString(&FilePath, &FileObject->FileName);
ObDereferenceObject(FileObject);
   
RtlUnicodeStringToAnsiString(&AnsiString, &FilePath, TRUE);
if ( AnsiString.Length >= 216 )
{
    memcpy(ProcessImageName, AnsiString.Buffer, 0x100u);
    *(ProcessImageName + 215) = 0;
}
else
{
    memcpy(ProcessImageName, AnsiString.Buffer, AnsiString.Length);
    ProcessImageName = 0;
}
RtlFreeAnsiString(&AnsiString);
ExFreePool(DosName.Buffer);
ExFreePool(FilePath.Buffer);
}
//解析
BOOLEAN StandardPrintHkey(char * path,char *realpath)
{

int judgeTop;
int judgeSecond;
int judgeThird;
inti;
int j;
int t;
int k;
int lencur;
char realname={0};
j=0;
k=0;
t=0;
judgeTop=strncmp("\\REGISTRY\\USER",path,14);

if(judgeTop==0)
{

      lencur=strlen(path);
      for(i=0;i<lencur;i++)
      {
          if(path=='-')
          {
          if(path=='5')
          {
            if(path=='0')
            {
            if(path=='0')
            {if(path=='_')
                {
                k=i+12;
                t=1;
                }
                else
                {
                j=i+4;
                t=1;
                }
            }
            }
          }
          }
      }

      DbgPrint("%d\n",j);
      DbgPrint("%d\n",k);
      if((k==0)&&(t==1))
      {
      strcpy(realname,"HKEY_CURRENT_USER");
      strncat(realname,&path,sizeof(path)-j);
      DbgPrint("%s",path);
      }
      if((j==0)&&(t==1))
      {
      strcpy(realname,"HKEY_CLASSES_ROOT");
      strncat(realname,&path,sizeof(path)-k);
      DbgPrint("%s",path);
      }
      if(t==0)
      {
      strcpy(realname,"HKEY_USERS");
      strncat(realname,&path,sizeof(path)-14);
      DbgPrint("%s",path);
      }
}
else
{
    judgeThird=strncmp("\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Hardware Profiles\\0001",path,61);
    if(judgeThird==0)
    {
      strcpy(realname,"HKEY_CURRENT_CONFIG");
      strncat(realname,&path,sizeof(path)-61);
      DbgPrint("%s",path);
    }
    else
    {

   
      strcpy(realname,"HKEY_LOCAL_MACHINE");
      strncat(realname,&path,sizeof(path)-17);
      DbgPrint("%s",path);


    }
}
strcpy(realpath,realname);
return TRUE;
}
//注册表根据KeyHandle得到键
BOOLEAN GetRegKeyNameByHandle(HANDLE handle, char *realpath)
{

ULONG uactLength;
POBJECT_NAME_INFORMATIONpustr;
ANSI_STRING astr;
PVOID pObj;
NTSTATUS ns;
char pch={0};
ns = ObReferenceObjectByHandle( handle, 0, NULL, KernelMode, &pObj, NULL );
if (!NT_SUCCESS(ns))
{
    KdPrint(("111!\n"));
    KdPrint(("0x%x\n",ns));
    return FALSE;
}
pustr = ExAllocatePool(NonPagedPool,1024+4);

if (pObj==NULL||pch==NULL)
    return FALSE;

ns = ObQueryNameString(pObj,pustr,512,&uactLength);

if (NT_SUCCESS(ns))
{
    RtlUnicodeStringToAnsiString(&astr,(PUNICODE_STRING)pustr,TRUE);
    strncpy(pch,astr.Buffer,256);
}
ExFreePool(pustr);
RtlFreeAnsiString( &astr );
if (pObj)
{
    ObDereferenceObject(pObj);
}
StandardPrintHkey(pch,realpath);
return TRUE;
}
//UnicodeTochar
VOID UnicodeTochar(PUNICODE_STRING dst , char *src)
{
ANSI_STRING string;
RtlUnicodeStringToAnsiString(&string,dst, TRUE);
strcpy(src,string.Buffer);
RtlFreeAnsiString(&string);
}
//wcharTochar
VOID WcharToChar(PWCHAR src,PCHAR dst)
{
UNICODE_STRING uString;
ANSI_STRING aString;
RtlInitUnicodeString(&uString,src);
RtlUnicodeStringToAnsiString(&aString,&uString,TRUE);
strcpy(dst,aString.Buffer);
RtlFreeAnsiString(&aString);
}

HeavenSea 发表于 2010-6-28 01:44:13

呵呵,有种被ls嘲讽的感觉…ls' qq i wonna... 今天第一天手机上,以后常来学习哈

马大哈 发表于 2010-6-28 12:50:58

;P支持技术火拼

364589886 发表于 2010-6-28 14:19:45

回复 2# 乔丹二世


    这个功能的话。。。。。PsLookProcessByProcessId活的EPROCESS,然后EPROCESS的结构体里有相应的字段。。。你这么做太麻烦了

乔丹二世 发表于 2010-6-28 16:50:40

呵呵,有种被ls嘲讽的感觉…ls' qq i wonna... 今天第一天手机上,以后常来学习哈
HeavenSea 发表于 2010-6-28 01:44 http://www.m5home.com/bbs/images/common/back.gif


我可没有嘲讽你的意思。

乔丹二世 发表于 2010-6-28 16:51:07

回复乔丹二世


    这个功能的话。。。。。PsLookProcessByProcessId活的EPROCESS,然后EPROCESS的结 ...
364589886 发表于 2010-6-28 14:19 http://www.m5home.com/bbs/images/common/back.gif

那您的意思是?
直接使用ZwQueryInformationProcess获得?

HeavenSea 发表于 2010-6-28 22:59:04

Re:364589886 是指EProcess.ImageName。这里可不是要那个哦。

HeavenSea 发表于 2010-6-28 23:01:30

不知换调FilePointer能否骗过ARKs,没空弄了,纸上谈并中…

乔丹二世 发表于 2010-6-29 00:10:07

不知换调FilePointer能否骗过ARKs,没空弄了,纸上谈并中…
HeavenSea 发表于 2010-6-28 23:01 http://www.m5home.com/bbs/images/common/back.gif


可以,不过要小心,很有可能蓝屏。
如果要骗过ARKs,听TA说,可以使用“进程注入”的方式创建进程。

HeavenSea 发表于 2010-6-29 00:47:11

所谓“进程注入” ?大牛说下

乔丹二世 发表于 2010-6-29 01:08:29

所谓“进程注入” ?大牛说下
HeavenSea 发表于 2010-6-29 00:47 http://www.m5home.com/bbs/images/common/back.gif

你自己网上搜索一下呗。
页: [1]
查看完整版本: 由EProcess从最底层获取进程路径