boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
阅读:2042回复:5

获取进程完整路径-2000DDK+VM6[2K Sp4]

楼主#
更多 发布于:2008-07-25 16:27
驱动网要源码是可耻的
驱动网发源码是光荣的
NTSTATUS
SfNtNameToDosName(
    IN PUNICODE_STRING NtName,
    OUT PUNICODE_STRING DosName)
{
    OBJECT_ATTRIBUTES attributes;
    UNICODE_STRING driveLetterName, linkTarget;
    HANDLE linkHandle;
    WCHAR c;
    
    linkTarget.Length = 0;
    linkTarget.MaximumLength = 256;
    linkTarget.Buffer = ExAllocatePool(PagedPool, linkTarget.MaximumLength);
    
    RtlInitUnicodeString(&driveLetterName, L"\\??\\C:");
    for (c = L'A'; c <= L'Z'; c++)
    {
        driveLetterName.Buffer[4] = c;
        InitializeObjectAttributes(&attributes, &driveLetterName, OBJ_CASE_INSENSITIVE, 0, NULL);
        
        if (!NT_SUCCESS(ZwOpenSymbolicLinkObject(&linkHandle, GENERIC_READ, &attributes))) continue;
        if (!NT_SUCCESS(ZwQuerySymbolicLinkObject(linkHandle, &linkTarget, NULL))) continue;
        
        //KdPrint(("%wZ->%wZ\n", &driveLetterName, &linkTarget));
        
        if (_wcsnicmp(NtName->Buffer, linkTarget.Buffer, linkTarget.Length>>1) == 0)
        {
            DosName->Length = 4 + NtName->Length - linkTarget.Length;
            DosName->MaximumLength = DosName->Length + 2;
            DosName->Buffer = ExAllocatePool(PagedPool, DosName->MaximumLength);
            if (!DosName->Buffer) return STATUS_INSUFFICIENT_RESOURCES;

            memcpy((PBYTE)DosName->Buffer + 4, (PBYTE)NtName->Buffer + linkTarget.Length, NtName->Length - linkTarget.Length);

            DosName->Buffer[0] = c;
            DosName->Buffer[1] = L':';
            DosName->Buffer[DosName->Length>>1] = 0;

            RtlFreeUnicodeString(&linkTarget);
            return STATUS_SUCCESS;
        }
    }
    
    RtlFreeUnicodeString(&linkTarget);
    return STATUS_NOT_FOUND;
}

ULONG
GetProcessDosPath(
    IN PEPROCESS Process,
    IN OUT PUNICODE_STRING DosPath
    )
{
    //获取指定进程的完整文件路径
    ULONG Ret;
    PVOID SectionObject;

    ASSERT(Process);
    
    SectionObject = (PVOID)(*(PULONG)((PBYTE)Process + g_EProcessOffset.wOffsetSection));

    if (4 == (ULONG)SectionObject)
    {
        //Win2K里面对应的是句柄
        KeAttachProcess(Process);
        if (!NT_SUCCESS(ObReferenceObjectByHandle(SectionObject, 0, NULL, KernelMode, &SectionObject, NULL)))
        {
            KeDetachProcess();
            return 0;
        }
        Ret = GetSectionObjectDosPath(SectionObject, DosPath);
        ObfDereferenceObject(SectionObject);
        KeDetachProcess();
    }
    else
    {
        Ret = GetSectionObjectDosPath(SectionObject, DosPath);
    }
    
    //KdPrint(("SectionObject:%08x\n", SectionObject));
    return Ret;
}

ULONG
GetSectionObjectDosPath(
    IN HANDLE SectionObject,
    IN OUT PUNICODE_STRING DosPath
    )
{
    HANDLE Segment, ControlArea;
    PFILE_OBJECT FilePointer;

    if (!SectionObject) return 0;

    Segment = (PVOID)(*(PULONG)((ULONG)SectionObject + 0x14));
    ControlArea = (PVOID)(*(PULONG)Segment);
    FilePointer = (PFILE_OBJECT) *(PULONG)((ULONG) ControlArea + 0x24);

    //KdPrint(("Segment %08x ControlArea %08x: FilePointer At %08x\n", Segment, ControlArea, FilePointer));

    if (FilePointer && MmIsAddressValid(FilePointer))
    {
        BYTE nameInfo[512];
        ULONG ret;
        POBJECT_NAME_INFORMATION objInfo = (POBJECT_NAME_INFORMATION)nameInfo;

        if (!NT_SUCCESS(ObQueryNameString(FilePointer, (POBJECT_NAME_INFORMATION)nameInfo, sizeof(nameInfo), &ret)))
        {
            KdPrint(("ObQueryNameString Fail %08x!\n", FilePointer));
            return 0;
        }
        if (!NT_SUCCESS(SfNtNameToDosName(&objInfo->Name, DosPath)))
        {
            KdPrint(("SfNtNameToDosName Fail %wZ!\n", &objInfo->Name));
            return 0;
        }
        /*
        if (!NT_SUCCESS(RtlVolumeDeviceToDosName(FilePointer->DeviceObject, &dosName)))
        {
            //映射网络驱动器会有问题
            KdPrint(("RtlVolumeDeviceToDosName Failed DeviceObject:%08x\n", FilePointer->DeviceObject));
            return 0;
        }
        */        
        return DosPath->Length;
    }
    return 0;
}
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2008-07-28 20:44
貌似大家都知道比较好的方法了?也不发个代码,害我到处找,有怕问了让人耻笑
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2008-07-29 09:42
硬编码太多,切换不同OS繁死你。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
地板#
发布于:2008-07-29 11:00
wowowowowocock 有没有好的方法 啊?比较保险的方法是调用API,但是API不熟啊
wenyurs
驱动牛犊
驱动牛犊
  • 注册日期2006-02-15
  • 最后登录2011-02-25
  • 粉丝2
  • 关注0
  • 积分190分
  • 威望128点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-09-09 10:49
呵呵
fancylf
驱动牛犊
驱动牛犊
  • 注册日期2007-07-29
  • 最后登录2016-06-21
  • 粉丝1
  • 关注0
  • 积分61分
  • 威望501点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2008-10-12 11:16
filemon里面的有一个根据system获得EPROCESS的中进程名的偏要地址的通用代码,思路很好,当不是全路径,但是也可以参考一下!
游客

返回顶部