进程与端口映射.docx
《进程与端口映射.docx》由会员分享,可在线阅读,更多相关《进程与端口映射.docx(24页珍藏版)》请在冰豆网上搜索。
![进程与端口映射.docx](https://file1.bdocx.com/fileroot1/2023-1/29/c6789d49-d92c-4694-9a3d-11578a8f0467/c6789d49-d92c-4694-9a3d-11578a8f04671.gif)
进程与端口映射
进程与端口映射
文章目录:
1.Demo效果展示:
2.进程和端口乱扯淡:
3.查询进程和端口的API的介绍:
4.根据进程ID获得该进程所打开的TCP和UDP端口:
5.根据端口号来获得打开该端口号的进程:
6.小结:
1.Demo效果展示:
下面的这个Demo我只是用最简单的方式做了个CUI界面来演示一下而已,
支持WindowsXP,WindowsServer2003,Vista,Windows7~
并且使用C++来完成的,所以对于博客园里面这么多的.Net开发者来说不太友好,
但是有兴趣的可以将Demo改写成DLL,然后.Net程序也就可以进行平台调用了,
里面所有的封装都很工整,所有改写DLL以及平台调用的声明也会很简单,有过平台调用经验的都可以改写的。
本文的后面我将会把这个Demo提供链接下载;
本篇博文Demo效果演示:
(关于端口的查询操作,你可以使用netstat命令行进行查询,
也可以使用TCPView这个工具来查询,当然还可以使用360的流量防火墙里面的网络连接来进行查询)
查询指定进程所打开的所有的TCP端口:
查询指定进程所打开的所有的UDP端口:
查询指定TCP端口所属的进程ID:
查询指定UDP端口所属的进程ID:
2.进程和端口乱扯淡:
很久没写博文了,以前跟自己说的,每个月要写那么一两篇还看得下去的博文,
可是去年春节家里出了些事情给耽搁了1个多月,而后人又懒了1个多月,所以算下来有2个多月没有写博文了。
而后今年过来帮一小哥做了个小东西,主要是用来实现伪造端口、伪造远程地址以及进程内存的保护啊之类的动作。
而后呢就是上面提到的这个小东西中中涉及到了端口的知识,
一开始嘛,我也是放狗一搜索,然后发现关于端口这一块的东西,
在2000、XP、Server2003下的资料很多,但惟独到了Vista和7上面就没什么资料了,
似乎一下子端口就完了似的,就好比端口的隐藏吧,在XP上无数端口隐藏工具,
应用层的,内核层的都有,但是在Vista和7上呢就都死绝了(主要是指内核层),
没办法,只能够自己去研究了,研究的成果呢,主要分为内核层和应用层的成果,
当然咯,今天我的这篇博文并不会去介绍内核里面关于端口的什么东西,
而是介绍如何在应用层里面完成端口和进程之间的映射。
所谓的进程与端口映射在我来理解,
简单点就是假如我知道一个进程,那我就要知道这个进程所打开的所有的端口,
又假如我知道一个端口,那我就应该知道是哪一个进程打开了这个端口。
所以要完成端口和进程的映射其实归根结底是一个根据进程查询端口和根据端口查询进程的问题。
然后我稍微解释一下为何到了Vista和7以后,狗上面的关于端口的资源就锐减了,
其实原因是这样的,在Vista之前,我这里摘抄一点在别人博客上的东西出来:
WindowsVista的网络模块较从前发生了很大变化,从而导致很多旧的端口隐藏工具无法使用.
事实上在Vista下netstat.exe调用Iphlpapi.dll导出的InternalGetTcpTable2函数实现对所有打开端口的列举.
InternalGetTcpTable2随后调用由nsi.dll导出的NsiAllocateAndGetTable函数,
nsi.dll则调用NsiEnumerateObjectsAllParametersEx向nsiproxy.sys发送Irp最终转入内核.
而nsiproxy.sys又只是对netio.sys的简单封装,它最终调用了netio.sys导出的内核服务例程.
上面的这些文字多说无益,大体的意思就是从Vista开始,Windows的网络模块发生了大的变化,
不过话说回来,上面的这种变化在应用层体会的不多,不过如果做到内核的话,
你就能够体会到网络层确实变化很大~
安全焦点上的一篇关于在Vista之前的系统上的进程和端口的很古老的文章
《再谈进程与端口的映射》:
3.查询进程和端口的API介绍:
好,上面说的有点离题了,这篇博文的目的在应用层而不在内核层,
所以我们无须去体会Windows网络层的这种变化。
一般来说,要完成进程和端口的映射,我们使用的是由IPHlpapi.dll中导出的API来完成的,
在Vista之前的操作系统中,要查询进程和端口的信息,容易很多,
你可以通过调用IPHlpapi.dll中导出的下面两个API来完成查询TCP和UDP端口的信息,
下面的两个API分别用来查询TCP和UDP端口信息,
(下面的两个API仅适用于XP和Server2003,在Vista以及7中,这两个API被移除)
1:
DWORDWINAPIAllocateAndGetTcpExTableFromStack(
2:
__outPVOID*ppTcpTable,
3:
__inBOOLbOrder,
4:
__inHANDLEhHeap,
5:
__inDWORDdwFlags,
6:
__inDWORDdwFamily
7:
);
8:
9:
DWORDWINAPIAllocateAndGetUdpExTableFromStack(
10:
__outPVOID*ppUDPTable,
11:
__inBOOLbOrder,
12:
__inHANDLEhHeap,
13:
__inDWORDdwFlags,
14:
__inDWORDdwFamily
15:
);
16:
参数说明:
第一个参数:
很显然,为输出参数,带回我们查询到的TCP或者UDP信息;
第二个参数:
也很显然,判断输出结果是否排序;
第三个参数:
指定在哪个Heap上分配内存;
第四个参数:
指定用来控制Heap的标识;
第四个参数:
指定IP_V4还是IP_V6,具体看下面的截图:
不过要完成进程和端口的映射在Vista和7下确实也没那么容易,至于原因呢,
就是IPHlpapi.dll中关于查询进程和端口信息的API没有公开,即为UnDocumentAPI,
不过我们还是可以通过UnDocumentAPI来完成这个查询的工作,具体涉及到下面的两个API,
当然,下面的这两个API由于是UnDocumnetAPI,自然你查什么MSDN啊之类都找不到这个API的声明的,
下面的两个API分别用来查询TCP和UDP端口信息,
1:
//=====================================================================================//
2:
//Name:
DWORDInternalGetTcpTable2()//
3:
////
4:
//Descripion:
该函数在WindowsVista以及Windows7下面效//
5:
////
6:
//=====================================================================================//
7:
typedefDWORD(WINAPI*PFNInternalGetTcpTable2)(
8:
PMIB_TCPEXTABLE_VISTA*pTcpTable_Vista,
9:
HANDLEheap,
10:
DWORDflags
11:
);
12:
13:
//=====================================================================================//
14:
//Name:
DWORDInternalGetUdpTableWithOwnerPid()//
15:
////
16:
//Descripion:
该函数在WindowsVista以及Windows7下面效//
17:
////
18:
//=====================================================================================//
19:
typedefDWORD(WINAPI*PFNInternalGetUdpTableWithOwnerPid)(
20:
PMIB_UDPEXTABLE*pUdpTable,
21:
HANDLEheap,
22:
DWORDflags
23:
);
参数说明:
第一个参数:
pTcpTable_Vista或者pUdpTable则不需要多说,其为输出参数,带回查询到的值;
第二个参数:
heap也不需要多说,其指示要从哪个Heap上面分配内存;
第三个参数:
flags则未知,一般都设置为1,不过貌似设置为2啊之类的好像又多影响不大;
4.根据进程ID获得该进程所打开的所有的TCP和UDP端口:
废话不多少的,直接上代码来得更加容易,注意下面函数中的HeapFree函数的调用,
因为从函数里面分配了内存,并且函数返回指针带出了这片内存,所以必须在外部释放,否则会造成内存泄露。
1:
//=======================================================================================//
2:
//Name:
DWORDGetAllPortByProcessId()//
3:
////
4:
//Descripion:
根据进程ID来求出该进程所打开的所有的端口号,并且在dwAllPort数组中返回所有端口号//
5:
//其中dwMaxLen为数组的长度,函数的返回值为进程所打开的端口的数目//
6:
//(支持XP,Server2003,Vista,Win7)//
7:
////
8:
//=======================================================================================//
9:
DWORDGetAllPortByProcessId(TcpOrUdptype,DWORDdwProcessId,DWORD*dwAllPort,DWORDdwMaxLen)
10:
{
11:
DWORDdwPortCount=0;
12:
HMODULEhModule=LoadLibraryW(L"iphlpapi.dll");
13:
if(hModule==NULL)
14:
{
15:
returndwPortCount;
16:
}
17:
18:
if(type==TcpType)
19:
{
20:
//表明查询的是UDP信息
21:
PFNAllocateAndGetTcpExTableFromStackpAllocateAndGetTcpExTableFromStack;
22:
pAllocateAndGetTcpExTableFromStack=
23:
(PFNAllocateAndGetTcpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetTcpExTableFromStack");
24:
if(pAllocateAndGetTcpExTableFromStack!
=NULL)
25:
{
26:
//表明为XP或者Server2003操作系统
27:
PMIB_TCPEXTABLEpTcpExTable=NULL;
28:
if(pAllocateAndGetTcpExTableFromStack(&pTcpExTable,TRUE,GetProcessHeap(),0,AF_INET)!
=0)
29:
{
30:
if(pTcpExTable)
31:
{
32:
HeapFree(GetProcessHeap(),0,pTcpExTable);
33:
}
34:
35:
FreeLibrary(hModule);
36:
hModule=NULL;
37:
38:
returndwPortCount;
39:
}
40:
41:
for(UINTi=0;idwNumEntries;i++)
42:
{
43:
//过滤掉数据,只获取我们要查询的进程的Port信息
44:
if(dwProcessId==pTcpExTable->table[i].dwProcessId)
45:
{
46:
if(dwPortCount47:
{
48:
dwAllPort[dwPortCount]=ntohs(0x0000FFFF&pTcpExTable->table[i].dwLocalPort);
49:
dwPortCount++;
50:
}
51:
}
52:
}
53:
54:
if(pTcpExTable)
55:
{
56:
HeapFree(GetProcessHeap(),0,pTcpExTable);
57:
}
58:
59:
FreeLibrary(hModule);
60:
hModule=NULL;
61:
62:
returndwPortCount;
63:
}
64:
else
65:
{
66:
//表明为Vista或者7操作系统
67:
PMIB_TCPEXTABLE_VISTApTcpExTable=NULL;
68:
PFNInternalGetTcpTable2pInternalGetTcpTable2=
69:
(PFNInternalGetTcpTable2)GetProcAddress(hModule,"InternalGetTcpTable2");
70:
if(pInternalGetTcpTable2==NULL)
71:
{
72:
if(pTcpExTable)
73:
{
74:
HeapFree(GetProcessHeap(),0,pTcpExTable);
75:
}
76:
77:
FreeLibrary(hModule);
78:
hModule=NULL;
79:
80:
returndwPortCount;
81:
}
82:
83:
if(pInternalGetTcpTable2(&pTcpExTable,GetProcessHeap(),1))
84:
{
85:
if(pTcpExTable)
86:
{
87:
HeapFree(GetProcessHeap(),0,pTcpExTable);
88:
}
89:
90:
FreeLibrary(hModule);
91:
hModule=NULL;
92:
93:
returndwPortCount;
94:
}
95:
96:
for(UINTi=0;idwNumEntries;i++)
97:
{
98:
//过滤掉数据,只获取我们要查询的进程的TCPPort信息
99:
if(dwProcessId==pTcpExTable->table[i].dwProcessId)
100:
{
101:
if(dwPortCount102:
{
103:
dwAllPort[dwPortCount]=ntohs(0x0000FFFF&pTcpExTable->table[i].dwLocalPort);
104:
dwPortCount++;
105:
}
106:
}
107:
}
108:
109:
if(pTcpExTable)
110:
{
111:
HeapFree(GetProcessHeap(),0,pTcpExTable);
112:
}
113:
114:
FreeLibrary(hModule);
115:
hModule=NULL;
116:
117:
returndwPortCount;
118:
}
119:
}
120:
elseif(type==UdpType)
121:
{
122:
//表明查询的是UDP信息
123:
PMIB_UDPEXTABLEpUdpExTable=NULL;
124:
PFNAllocateAndGetUdpExTableFromStackpAllocateAndGetUdpExTableFromStack;
125:
pAllocateAndGetUdpExTableFromStack=
126:
(PFNAllocateAndGetUdpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetUdpExTableFromStack");
127:
if(pAllocateAndGetUdpExTableFromStack!
=NULL)
128:
{
129:
//表明为XP或者Server2003操作系统
130:
if(pAllocateAndGetUdpExTableFromStack(&pUdpExTable,TRUE,GetProcessHeap(),0,AF_INET)!
=0)
131:
{
132:
if(pUdpExTable)
133:
{
134:
HeapFree(GetProcessHeap(),0,pUdpExTable);
135:
}
136:
137:
FreeLibrary(hModule);
138:
hModule=NULL;
139:
140:
returndwPortCount;
141:
}
142:
143:
for(UINTi=0;idwNumEntries;i++)
144:
{
145:
//过滤掉数据,只获取我们要查询的进程的UDPPort信息
146:
if(dwProcessId==pUdpExTable->table[i].dwProcessId)
147:
{
148:
if(dwPortCount149:
{
150:
dwAllPort[dwPortCount]=ntohs(0x0000FFFF&pUdpExTable->table[i].dwLocalPort);
151:
dwPortCount++;
152:
}
153:
}
154:
}
155:
156:
if(pUdpExTable)
157:
{
158:
HeapFree(GetProcessHeap(),0,pUdpExTable);
159:
}
160:
161:
FreeLibrary(hModule);
162:
hModule=NULL;
163:
164:
returndwPortCount;
165:
}
166:
else
167:
{
168:
//表明为Vista或者7操作系统
169:
PFNInternalGetUdpTableWithOwnerPidpInternalGetUdpTableWithOwnerPid;
170:
pInternalGetUdpTableWithOwnerPid=
171:
(PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule,"InternalGetUdpTableWithOwnerPid");
172:
if(pInternalGetUdpTableWithOwnerPid!
=NULL)
173:
{
174:
if(pInternalGetUdpTableWithOwnerPid(&pUdpExTable,GetProcessHeap(),1))
175:
{
176:
if(pUdpExTable)
177:
{
178:
HeapFree(GetProcessHeap(),0,pUdpExTable);
179:
}
180:
181:
FreeLibrary(hModule);
182:
hModule=NULL;