|
关于进程与端口映射的文章已经有很多了,我把我对fport的分析也写出来,让大家知道fport是如何工作的.fport.exe是由foundstone team出品的免费软件,可以列出系统中所有开放的端口都是由那些进程打开的.而下面所描述的方法是基于fport v1.33的,如果和你机器上的fport有出入,请检查fport版本. 首先,它检测当前用户是否拥有管理员权限(通过读取当前进程的令牌可知当前用户是否具有管理权限,请参考相关历程),如果没有,打印一句提示后退出,然后设置当前进程的令牌,接着,用ZwOpenSection函数打开内核对象\Device\PhysicalMemory,这个对象用于对系统物理内存的访问.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_WRITE 0x0002 #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) 那么,打开内核对象\Device\PhysicalMemory的语句如下: 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 ); //打开内核对象\Device\PhysicalMemory,获得句柄 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的文章《小议Windows NT/2000的分页机制》) 程序打开打开内核对象\Device\PhysicalMemory后,继续用函数ZwOpenFile打开内核对象\Device\Tcp和Device\Udp,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_DELETE 0x00000004 // winnt (见ntddk.h) 第六个参数OpenOptions也是一个常数,可以是下列的值: #define FILE_DIRECTORY_FILE 0x00000001 #define FILE_WRITE_THROUGH 0x00000002 #define FILE_SEQUENTIAL_ONLY 0x00000004 #define | |
| 文章评论 | |||