zoukankan      html  css  js  c++  java
  • Sysinternals工具—pipelist分析

    这段时间用到了SysinternalsSuite中的pipelist工具来查看使用的NamedPipe是什么,用过之后就想自己了解下它是怎样工作,于是就反汇编一下,没想到却意外的简单。

    下面是反汇编出的伪代码

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      int result; // eax@2
      HMODULE v4; // eax@3
      HMODULE v5; // eax@6
      HANDLE hHandle; // ebp@9
      DWORD v7; // eax@10
      FILE_DIRECTORY_INFORMATION *FileInformation; // edi@11
      int v9; // eax@12
      FILE_DIRECTORY_INFORMATION *i; // esi@13
      int v11; // [sp+34h] [bp-94Ch]@12
      int IoStatusBlock; // [sp+38h] [bp-948h]@12
      char v13; // [sp+40h] [bp-940h]@14
      char v14; // [sp+E0h] [bp-8A0h]@14
      __int16 v15[1024]; // [sp+180h] [bp-800h]@14
    
      LOBYTE(v11) = 1;
      printf("\nPipeList v1.01\n");
      printf("by Mark Russinovich\n");
      printf("http://www.sysinternals.com\n\n");
      if ( EulaAccept((LPARAM)"PipeList") )
      {
        v4 = GetModuleHandleA("ntdll.dll");
        pfnNtQueryDirectoryFile = (int (__stdcall *)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))GetProcAddress(v4, "NtQueryDirectoryFile");
        if ( !pfnNtQueryDirectoryFile )
        {
          printf("\nCould not find NtQueryDirectoryFile entry point in NTDLL.DLL\n");
          exit(1);
        }
        v5 = GetModuleHandleA("ntdll.dll");
        pfnRtlNtStatusToDosError = (int)GetProcAddress(v5, "RtlNtStatusToDosError");
        if ( !pfnRtlNtStatusToDosError )
        {
          printf("\nCould not find RtlNtStatusToDosError entry point in NTDLL.DLL\n");
          exit(1);
        }
        hHandle = CreateFileA("\\\\.\\Pipe\\", 0x80000000u, 7u, 0, 3u, 0, 0);
        if ( hHandle == (HANDLE)-1 )
        {
          v7 = GetLastError();
          sub_401050((int)"Pipe error", v7);
          result = 0;
        }
        else
        {
          printf("%-40s%14s%20s\n", "Pipe Name", "Instances", "Max Instances");
          printf("%-40s%14s%20s\n", "---------", "---------", "-------------");
          FileInformation = (FILE_DIRECTORY_INFORMATION *)malloc(0x1000u);
          while ( 1 )
          {
            v9 = pfnNtQueryDirectoryFile(hHandle, 0, 0, 0, &IoStatusBlock, FileInformation, 4096, 1, 0, 0, v11);
            if ( v9 < 0 )
              break;
            for ( i = FileInformation; ; i = (FILE_DIRECTORY_INFORMATION *)((char *)i + i->NextEntryOffset) )
            {
              swprintf((wchar_t *)&v14, (size_t)L"%d   ", (const wchar_t *)i->EndOfFile.LowPart);
              swprintf((wchar_t *)&v13, (size_t)L"%d      ", (const wchar_t *)i->AllocationSize.LowPart);
              wcsncpy((wchar_t *)v15, i->FileName, i->FileNameLength >> 1);
              v15[i->FileNameLength >> 1] = 0;
              wprintf(L"%-40s%14s%20s\n", v15, &v14, &v13);
              if ( !i->NextEntryOffset )
                break;
            }
            LOBYTE(v11) = 0;
          }
          if ( v9 != -2147483642 )
            sub_401000((int)"Error querying pipe directory:", v9);
          free(FileInformation);
          CloseHandle(hHandle);
          result = 0;
        }
      }
      else
      {
        result = 1;
      }
      return result;
    }
    

    Named Pipes是一种简单的进程间通信(IPC)机制。可在同一台计算机的不同进程之间,或在跨越一个网络的不同计算机的不同进程之间,支持可靠的、单向或双向的数据通信。命名管道是围绕Windows文件系统设计的一种机制,采用“命名管道文件系统”(Named Pipe File System,NPFS)接口,客户机和服务器应用可利用标准的Win32文件系统相关API函数。

    命名管道的标识采用UNC格式的进行命名的:

    \\server\pipe\[path]name

    从上面反汇编出代码可以看出,它是使用NtQueryDirectoryFile来查询\\.\pipe\下的File Information。查看NtQueryDirectoryFile的声明(在Window NT 2000 Native API这文档中可以找到,叫做ZwQueryDirectoryFile)

    ZwQueryDirectoryFile retrieves information about the contents of a directory.
    NTSYSAPI
    NTSTATUS
    NTAPI
    ZwQueryDirectoryFile(
    	IN HANDLE FileHandle,
    	IN HANDLE Event OPTIONAL,
    	IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
    	IN PVOID ApcContext OPTIONAL,
    	OUT PIO_STATUS_BLOCK IoStatusBlock,
    	OUT PVOID FileInformation,
    	IN ULONG FileInformationLength,
    	IN FILE_INFORMATION_CLASS FileInformationClass,
    	IN BOOLEAN ReturnSingleEntry,
    	IN PUNICODE_STRING FileName OPTIONAL,
    	IN BOOLEAN RestartScan
    );

    这个功能的关键在于:

    1、CreateFileA("\\\\.\\Pipe\\", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);

    2、NtQueryDirectoryFile(hHandle, 0, 0, 0, &IoStatusBlock, FileInformation, 4096, FileDirectoryInformation /*=1*/, 0, 0, v11);

    当然除了枚举本地计算机的Named Pipes,也可以枚举其他机器的,只要把对应的服务器名加到路径中,如\ \ m y s e r v e r \ pipe \ ,这样可枚举出服务器\ \ m y s e r v e r 的Named Pipes,当然要有权限才行。

  • 相关阅读:
    Something I know about WebDynpro
    Details about support package implementation
    CRM Middleware Performance Topics
    Way to configure the logon navigaion layouts via Business Roles in CRM
    DOM 常用节点类型和方法
    第一届 xdef 会议日程
    去除百度音乐盒广告的chrome插件 持续更新
    从人人网抓取高校数据信息,包括,省份 高校 院系 (提供最终SQL文件下载)
    PHP 与 JSON
    解决HTTPS 发送请求走socket问题
  • 原文地址:https://www.cnblogs.com/Quincy/p/1746816.html
Copyright © 2011-2022 走看看