详谈操作系统的进程与端口的映射(转)

关于进程与端口映射的文章已经有很多了,我把我对fport的分析也写出来,让大家知道fport是如何工作的.fport.exe是由foundstone team出品的免费软件,可以列出系统中所有开放的端口都是由那些进程打开的.而下面所描述的方法是基于fport v1.33的,如果和你机器上的fport有出入,请检查fport版本.
  
  首先,它检测当前用户是否拥有管理员权限(通过读取当前进程的令牌可知当前用户是否具有管理权限,请参考相关历程),如果没有,打印一句提示后退出,然后设置当前进程的令牌,接着,用ZwOpenSection函数打开内核对象DevicePhysicalMemory,这个对象用于对系统物理内存的访问.ZwOpenSection函数的原型如下:
  
  NTSYSAPI
  NTSTSTUS
  NTAPI
  ZwOpenSection(
   Out PHANDLE sectionHandle;
   IN ACCESS_MASK DesiredAccess;
   IN POBJECT_ATTRIBUTES ObjectAttributes
   };
  (见ntddk.h)
  
  第一个参数得到函数执行成功后的句柄
  第二个参数DesiredAccess为一个常数,可以是下列值:
   #define SECTION_QUERY 0x0001
   #define SECTION_MAP_WRITE0x0002
   #define SECTION_MAP_READ 0x0004
   #define SECTION_MAP_EXECUTE 0x0008
   #define SECTION_EXTEND_SIZE 0x0010
  
   #define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY| SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE)
   (见ntddk.h)
  第三个参数是一个结构,包含要打开的对象类型等信息,结构定义如下:
   typedef struct _OBJECT_ATTRIBUTES {
   ULONG Length;
   HANDLE RootDirectory;
   PUNICODE_STRING ObjectName;
   ULONG Attributes;
   PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
   PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
   } OBJECT_ATTRIBUTES;
   typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
   (见ntdef.h)
  对于这个结构的初始化用一个宏完成:
   #define InitializeObjectAttributes( p, n, a, r, s ) {  (p)->Length = sizeof( OBJECT_ATTRIBUTES );  (p)->RootDirectory = r;  (p)->Attributes = a;  (p)->ObjectName = n;  (p)->SecurityDescriptor = s; (p)->SecurityQualityOfService = NULL; }
   (见ntdef.h)
  那么,打开内核对象DevicePhysicalMemory的语句如下:
  WCHAR PhysmemName[] = L"\Device\PhysicalMemory";
  void * pMapPhysicalMemory;
  HANDLE pHandle;
  
  bool OpenPhysicalMemory()
  {
   NTSTATUS status;
   UNICODE_STRING physmemString;
   OBJECT_ATTRIBUTES attributes;
   RtlInitUnicodeString( &physmemString, PhysmemName ); //初始化Unicode字符串,函数原型见ntddk.h
   InitializeObjectAttributes( &attributes, &physmemString,
  OBJ_CASE_INSENSITIVE, NULL, NULL ); //初始化OBJECT_ATTRIBUTES结构
   status = ZwOpenSection(pHandle, SECTION_MAP_READ, &attributes ); //打开内核对象DevicePhysicalMemory,获得句柄
   if( !NT_SUCCESS( status ))
   return false;
   pMapPhysicalMemory=MapViewOfFile(pHandle,FILE_MAP_READ,
  0,0x30000,0x1000);
   //从内存地址0x30000开始映射0x1000个字节
   if( GetLastError()!=0)
   return false;
   return true;
  }
  
   为什么要从0x30000开始映射呢,是这样,我们知道,在Windows NT/2000下,系统分为内核模式和用户模式,也就是我们所说的Ring0和Ring3,在Windows NT/2000下,我们所能够看到的进程都运行在Ring3下,一般情况下,系统进程(也就是System进程)的页目录(PDE)所在物理地址地址为0x30000,或者说,系统中最小的页目录所在的物理地址为0x30000.而页目录(PDE)由1024项组成,每项均指向一页表(PTE),每一页表也由1024个页组成,而每页的大小为4K,1024*4=4096(0x1000),所以,上面从物理地址0x30000开始映射了0x1000个字节.(具体描述见WebCrazy的文章<>)
  
   程序打开打开内核对象DevicePhysicalMemory后,继续用函数ZwOpenFile打开内核对象DeviceTcp和DeviceUdp,ZwOpenFile
  函数的原型如下:
  NTSYSAPI
  NTSTATUS
  NTAPI
  ZwOpenFile(
   OUT PHANDLE FileHandle,
   IN ACCESS_MASK DesiredAccess,
   IN POBJECT_ATTRIBUTES ObjectAttributes,
   OUT PIO_STATUS_BLOCK IoStatusBlock,
   IN ULONG ShareAccess,
   IN ULONG OpenOptions
   );
  (见ntddk.h)
  
  第一个参数返回打开对象的句柄
  第二个参数DesiredAccess为一个常数,可以是下列值:
   #define FILE_READ_DATA( 0x0001 ) // file & pipe
   #define FILE_LIST_DIRECTORY ( 0x0001 ) // directory
   #define FILE_WRITE_DATA ( 0x0002 ) // file & pipe
   #define FILE_ADD_FILE ( 0x0002 ) // directory
   #define FILE_APPEND_DATA ( 0x0004 ) // file
   #define FILE_ADD_SUBDIRECTORY ( 0x0004 ) // directory
   #define FILE_CREATE_PIPE_INSTANCE ( 0x0004 ) // named pipe
   #define FILE_READ_EA ( 0x0008 ) // file & directory
   #define FILE_WRITE_EA ( 0x0010 ) // file & directory
   #define FILE_EXECUTE ( 0x0020 ) // file
   #define FILE_TRAVERSE ( 0x0020 ) // directory
   #define FILE_DELETE_CHILD( 0x0040 ) // directory
   #define FILE_READ_ATTRIBUTES( 0x0080 ) // all
   #define FILE_WRITE_ATTRIBUTES ( 0x0100 ) // all
   #define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
   #define FILE_GENERIC_READ(STANDARD_RIGHTS_READ |FILE_READ_DATA |FILE_READ_ATTRIBUTES |FILE_READ_EA |SYNCHRONIZE)
   #define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |FILE_WRITE_DATA |FILE_WRITE_ATTRIBUTES |FILE_WRITE_EA|FILE_APPEND_DATA|SYNCHRONIZE)
   #define FILE_GENERIC_EXECUTE(STANDARD_RIGHTS_EXECUTE |FILE_READ_ATTRIBUTES |FILE_EXECUTE |SYNCHRONIZE)
   (见ntdef.h)
  第三个参数是一个结构,包含要打开的对象类型等信息,结构定义见上面所述
  第四个参数返回打开对象的属性,是一个结构,定义如下:
   typedef struct _IO_STATUS_BLOCK {
   union {
  NTSTATUS Status;
  PVOID Pointer;
   };
  
   ULONG_PTR Information;
   } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
  
   #if defined(_WIN64)
   typedef struct _IO_STATUS_BLOCK32 {
   NTSTATUS Status;
   ULONG Information;
   } IO_STATUS_BLOCK32, *PIO_STATUS_BLOCK32;
   #endif
   (见ntddk.h)
  第五个参数ShareAccess是一个常数,可以是下列值:
   #define FILE_SHARE_READ 0x00000001 // winnt
   #define FILE_SHARE_WRITE 0x00000002 // winnt
   #define FILE_SHARE_DELETE0x00000004 // winnt
   (见ntddk.h)
  第六个参数OpenOptions也是一个常数,可以是下列的值:
   #define FILE_DIRECTORY_FILE0x00000001
   #define FILE_WRITE_THROUGH 0x00000002
   #define FILE_SEQUENTIAL_ONLY 0x00000004
   #define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
   #define FILE_SYNCHRONOUS_IO_ALERT0x00000010
   #define FILE_SYNCHRONOUS_IO_NONALERT0x00000020
   #define FILE_NON_DIRECTORY_FILE 0x00000040
   #define FILE_CREATE_TREE_CONNECTION 0x00000080
   #define FILE_COMPLETE_IF_OPLOCKED0x00000100
   #define FILE_NO_EA_KNOWLEDGE 0x00000200
   #define FILE_OPEN_FOR_RECOVERY0x00000400
   #define FILE_RANDOM_ACCESS 0x00000800
   #define FILE_DELETE_ON_CLOSE 0x00001000
   #define FILE_OPEN_BY_FILE_ID 0x00002000
   #define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
   #define FILE_NO_COMPRESSION0x00008000
   #define FILE_RESERVE_OPFILTER 0x00100000
   #define FILE_OPEN_REPARSE_POINT 0x00200000
   #define FILE_OPEN_NO_RECALL0x00400000
   #define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
   #define FILE_COPY_STRUCTURED_STORAGE0x00000041
   #define FILE_STRUCTURED_STORAGE 0x00000441
   #define FILE_VALID_OPTION_FLAGS 0x00ffffff
   #define FILE_VALID_PIPE_OPTION_FLAGS0x00000032
   #define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
   #define FILE_VALID_SET_FLAGS 0x00000036
   (见ntddk.h)
   
  那么,打开内核对象DeviceTcp和DeviceUdp的语句如下:
  WCHAR physmemNameTcp[]=L"\Device\TCP";
  WCHAR physmemNameUdp[]=L"\Device\UDP";
  HANDLE pTcpHandle;
  HANDLE pUdpHandle;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10294527/viewspace-123487/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10294527/viewspace-123487/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值