[创建时间:2016-04-13 22:37:00]

NetAnalyzer下载地址

起因

最近因为NetAnalyzer2016的发布,好多人都提出是否可以在NetAnalyzer中加入一个基于进程的抓包功能。所以最近研究了一下大概有这样一个想法:

获取系统打开端口的所有进程,并获取进程所开启的端口、IP地址以及使用的协议等信息,然后生成对应的过滤表达式,然后给NetAnalyzer设置该过滤表达式,然后开始抓包。

开始

虽然.Net中提供了进程信息查看的相关库,但是却没有提供相关网络端口查询的功能,所以也没有过多深入的研究,就把注意打到了Windows API 的头上。最后经过一番查找与总结,最后找到了两个方法,

在iphlpapi.dll 针对于TCP和UDP分别是

DWORD GetExtendedTcpTable(
_Out_ PVOID pTcpTable,
_Inout_ PDWORD pdwSize,
_In_ BOOL bOrder,
_In_ ULONG ulAf,
_In_ TCP_TABLE_CLASS TableClass,
_In_ ULONG Reserved
);
DWORD GetExtendedUdpTable(
_Out_ PVOID pUdpTable,
_Inout_ PDWORD pdwSize,
_In_ BOOL bOrder,
_In_ ULONG ulAf,
_In_ UDP_TABLE_CLASS TableClass,
_In_ ULONG Reserved
);

找到了对应的接口方法,那么接下来要做的就是对这个接口进行c#封装,因为这两个接口还带一些结构体,此处就不卖关子了,先看图,后面直接把可用的代码贴出来

以下是核心代码

 using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text; namespace ProcessViewer
{
public class NetProcessAPI
{ /// <summary>
/// 获取TCP连接对象
/// </summary>
/// <param name="pTcpTable"></param>
/// <param name="dwOutBufLen"></param>
/// <param name="sort"></param>
/// <param name="ipVersion"></param>
/// <param name="tblClass"></param>
/// <param name="reserved"></param>
/// <returns></returns>
[DllImport("iphlpapi.dll", SetLastError = true)]
private static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, uint reserved = ); /// <summary>
/// 获取UDP连接对象
/// </summary>
/// <param name="pTcpTable"></param>
/// <param name="dwOutBufLen"></param>
/// <param name="sort"></param>
/// <param name="ipVersion"></param>
/// <param name="tblClass"></param>
/// <param name="reserved"></param>
/// <returns></returns>
[DllImport("iphlpapi.dll", SetLastError = true)]
private static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int dwOutBufLen, bool sort, int ipVersion, UDP_TABLE_CLASS tblClass, uint reserved = ); /// <summary>
///获取TCP连接对象
/// </summary>
/// <returns></returns>
public static TcpRow[] GetAllTcpConnections()
{
TcpRow[] tTable;
int AF_INET = ; // IP_v4
int buffSize = ;
uint ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
IntPtr buffTable = Marshal.AllocHGlobal(buffSize);
try
{
ret = GetExtendedTcpTable(buffTable, ref buffSize, true, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
if (ret != )
{
return null;
}
TcpTable tab = (TcpTable)Marshal.PtrToStructure(buffTable, typeof(TcpTable));
IntPtr rowPtr = (IntPtr)((long)buffTable + Marshal.SizeOf(tab.dwNumEntries));
tTable = new TcpRow[tab.dwNumEntries]; for (int i = ; i < tab.dwNumEntries; i++)
{
TcpRow tcpRow = (TcpRow)Marshal.PtrToStructure(rowPtr, typeof(TcpRow));
tTable[i] = tcpRow;
rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(tcpRow)); // next entry
}
}
finally
{
Marshal.FreeHGlobal(buffTable);
}
return tTable;
} /// <summary>
///获取udp连接对象
/// </summary>
/// <returns></returns>
public static UdpRow[] GetAllUdpConnections()
{
UdpRow[] tTable;
int AF_INET = ; // IP_v4
int buffSize = ;
uint ret = GetExtendedUdpTable(IntPtr.Zero, ref buffSize, true, AF_INET, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
IntPtr buffTable = Marshal.AllocHGlobal(buffSize);
try
{
ret = GetExtendedUdpTable(buffTable, ref buffSize, true, AF_INET, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
if (ret != )
{
return null;
}
UdpTable tab = (UdpTable)Marshal.PtrToStructure(buffTable, typeof(UdpTable));
IntPtr rowPtr = (IntPtr)((long)buffTable + Marshal.SizeOf(tab.dwNumEntries));
tTable = new UdpRow[tab.dwNumEntries]; for (int i = ; i < tab.dwNumEntries; i++)
{
UdpRow udpRow = (UdpRow)Marshal.PtrToStructure(rowPtr, typeof(UdpRow));
tTable[i] = udpRow;
rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(udpRow)); // next entry
}
}
finally
{
Marshal.FreeHGlobal(buffTable);
}
return tTable;
} #region 针对于TCP管理
/** 由于该部分使用到了Linq查询 需要.Net版本较高(当前使用的是.Net2.0),再着该部分代码在现有功能点并不需要, 所以注释了(主要是我懒得改了 ^_^)
/// <summary>
/// 设置
/// </summary>
/// <param name="pRow"></param>
/// <returns></returns>
[DllImport("iphlpapi.dll", SetLastError = true)]
public static extern uint SetTcpEntry(IntPtr pRow);
public static void CloseConnByLocalPort(int port)
{
var tcpRows = GetAllTcpConnections();
var tmpRows = from i in tcpRows
where i.LocalPort == port
select i;
TcpRow[] tcpArry = tmpRows.ToArray();
for (int i = 0; i < tcpArry.Length; i++)
{
tcpArry[i].state = ConnectionState.Delete_TCB;
SetTcpEntry(GetPtrToNewObject(tcpArry[i]));
}
}
public static IntPtr GetPtrToNewObject(object obj)
{
IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(obj));
Marshal.StructureToPtr(obj, ptr, false);
return ptr;
}
* */
#endregion
} #region TCP返回的数据结构
/// <summary>
/// TCP表类型
/// </summary>
public enum TCP_TABLE_CLASS
{
TCP_TABLE_BASIC_LISTENER,
TCP_TABLE_BASIC_CONNECTIONS,
TCP_TABLE_BASIC_ALL,
TCP_TABLE_OWNER_PID_LISTENER,
TCP_TABLE_OWNER_PID_CONNECTIONS,
TCP_TABLE_OWNER_PID_ALL,
TCP_TABLE_OWNER_MODULE_LISTENER,
TCP_TABLE_OWNER_MODULE_CONNECTIONS,
TCP_TABLE_OWNER_MODULE_ALL
}
/// <summary>
/// TCP当前状态
/// </summary>
public enum ConnectionState : int
{
/// <summary> All </summary>
All = ,
/// <summary> Closed </summary>
Closed = ,
/// <summary> Listen </summary>
Listen = ,
/// <summary> Syn_Sent </summary>
Syn_Sent = ,
/// <summary> Syn_Rcvd </summary>
Syn_Rcvd = ,
/// <summary> Established </summary>
Established = ,
/// <summary> Fin_Wait1 </summary>
Fin_Wait1 = ,
/// <summary> Fin_Wait2 </summary>
Fin_Wait2 = ,
/// <summary> Close_Wait </summary>
Close_Wait = ,
/// <summary> Closing </summary>
Closing = ,
/// <summary> Last_Ack </summary>
Last_Ack = ,
/// <summary> Time_Wait </summary>
Time_Wait = ,
/// <summary> Delete_TCB </summary>
Delete_TCB =
} /// <summary>
/// TCP列结构(行)
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct TcpRow
{
// DWORD is System.UInt32 in C#
public ConnectionState state;
public uint localAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public byte[] localPort;
public uint remoteAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public byte[] remotePort;
public int owningPid;
public System.Net.IPAddress LocalAddress
{
get
{
return new System.Net.IPAddress(localAddr);
}
}
public ushort LocalPort
{
get
{
return BitConverter.ToUInt16(
new byte[] { localPort[], localPort[] }, );
}
}
public System.Net.IPAddress RemoteAddress
{
get
{
return new System.Net.IPAddress(remoteAddr);
}
}
public ushort RemotePort
{
get
{
return BitConverter.ToUInt16(
new byte[] { remotePort[], remotePort[] }, );
}
}
} /// <summary>
/// TCP表结构
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct TcpTable
{
public uint dwNumEntries;
TcpRow table;
}
#endregion #region UDP结构 /// <summary>
/// UDP表类型
/// </summary>
public enum UDP_TABLE_CLASS
{
UDP_TABLE_BASIC,
UDP_TABLE_OWNER_PID,
UDP_TABLE_OWNER_MODULE
} /// <summary>
/// TCP列结构(行)
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct UdpRow
{
public uint localAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public byte[] localPort;
public int owningPid;
public System.Net.IPAddress LocalAddress
{
get
{
return new System.Net.IPAddress(localAddr);
}
}
public ushort LocalPort
{
get
{
return BitConverter.ToUInt16(
new byte[] { localPort[], localPort[] }, );
}
}
} /// <summary>
/// UDP表结构
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct UdpTable
{
public uint dwNumEntries;
UdpRow table;
}
#endregion }

分别通过上面的GetAllTcpConnections()方法和GetAllUdpConnections() 可获得TCP和UDP的所有当前在线的进程,

额外给一段通过进程号获取应用图标的代码

 using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text; namespace ProcessViewer
{ /// <summary>
/// 通过API获取进程图标
/// </summary>
public class ProcessAPI
{
[DllImport("Shell32.dll")]
private static extern int SHGetFileInfo
(
string pszPath,
uint dwFileAttributes,
out SHFILEINFO psfi,
uint cbfileInfo,
SHGFI uFlags
); [StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero; iIcon = ; dwAttributes = ; szDisplayName = ""; szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.LPStr, SizeConst = )]
public string szDisplayName;
[MarshalAs(UnmanagedType.LPStr, SizeConst = )]
public string szTypeName;
}; private enum SHGFI
{
SmallIcon = 0x00000001,
LargeIcon = 0x00000000,
Icon = 0x00000100,
DisplayName = 0x00000200,
Typename = 0x00000400,
SysIconIndex = 0x00004000,
UseFileAttributes = 0x00000010
}
//获取进程图标
public static Icon GetIcon(string strPath, bool bSmall)
{
SHFILEINFO info = new SHFILEINFO(true);
int cbFileInfo = Marshal.SizeOf(info);
SHGFI flags;
if (bSmall)
flags = SHGFI.Icon | SHGFI.SmallIcon | SHGFI.UseFileAttributes;
else
flags = SHGFI.Icon | SHGFI.LargeIcon | SHGFI.UseFileAttributes; SHGetFileInfo(strPath, , out info, (uint)cbFileInfo, flags);
return Icon.FromHandle(info.hIcon);
} //获取进程图标
public static Icon GetIcon(int pid, bool bSmall)
{ try
{
var p = System.Diagnostics.Process.GetProcessById(pid); return GetIcon(p.MainModule.FileName, bSmall);
}
catch (Exception ex)
{
return null;
}
} //获取进程名称
public static string GetProcessNameByPID(int processID)
{
//could be an error here if the process die before we can get his name
try
{
Process p = Process.GetProcessById((int)processID);
return p.ProcessName;
}
catch (Exception ex)
{
return "Unknown";
}
}
}
}

我们已经完成了进程信息的获取

那么接下来就是使用了,其实使用起来还是非常容易的

         private void loadProcess()
{
dataGridProcess.Rows.Clear();
//tcp
foreach (var p in NetProcessAPI.GetAllTcpConnections())
{
var icon=ProcessAPI.GetIcon(p.owningPid, true);
dataGridProcess.Rows.Add(new object[] { icon==null?Properties.Resources.app:icon, ProcessAPI.GetProcessNameByPID(p.owningPid), "TCP", p.LocalAddress.ToString(), p.LocalPort.ToString(), p.RemoteAddress.ToString(), p.RemotePort.ToString() });
}
//udp
foreach (var p in NetProcessAPI.GetAllUdpConnections())
{
var icon = ProcessAPI.GetIcon(p.owningPid, true);
dataGridProcess.Rows.Add(new object[] { icon == null ? Properties.Resources.app : icon, ProcessAPI.GetProcessNameByPID(p.owningPid), "UDP", p.LocalAddress.ToString(), p.LocalPort.ToString(), "-", "-" });
}
}

好了就写到这里了

欢迎关注NetAnalyzer公众平台,感谢使用NetAnalyzer2016

示例代码下载:http://files.cnblogs.com/files/twzy/MyTcpView.zip

NetAnalyzer笔记 之 六 用C#打造自己的网络连接进程查看器(为进程抓包做准备)的更多相关文章

  1. GAN实战笔记——第六章渐进式增长生成对抗网络(PGGAN)

    渐进式增长生成对抗网络(PGGAN) 使用 TensorFlow和 TensorFlow Hub( TFHUB)构建渐进式增长生成对抗网络( Progressive GAN, PGGAN或 PROGA ...

  2. Silverlight项目笔记6:Linq求差集、交集&检查网络连接状态&重载构造函数复用窗口

    1.使用Linq求差集.交集 使用场景: 需要从数据中心获得用户数据,并以此为标准,同步系统的用户信息,对系统中多余的用户进行删除操作,缺失的用户进行添加操作,对信息更新了的用户进行编辑操作更新. 所 ...

  3. Kafka技术内幕 读书笔记之(二) 生产者——服务端网络连接

    KafkaServer是Kafka服务端的主类, KafkaServer中和网络层有关的服务组件包括 SocketServer.KafkaApis 和 KafkaRequestHandlerPool后 ...

  4. NetAnalyzer笔记 目录

    目录 NetAnalyzer笔记 之 一 开篇语 NetAnalyzer笔记 之 二 简单的协议分析 NetAnalyzer笔记 之 三 用C++做一个抓包程序 NetAnalyzer笔记 之 四 C ...

  5. NetAnalyzer笔记 之 八 NetAnalyzer2016使用方法(2)

    [创建时间:2016-05-06 22:07:00] NetAnalyzer下载地址 在写本篇的时候,NetAnalyzer 3.1版本已经发布,所以本篇就以最新版本的为例继续使用,并且顺带说明一下, ...

  6. Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable

    酒,是个好东西,前提要适量.今天参加了公司的年会,主题就是吃.喝.吹,除了那些天生话唠外,大部分人需要加点酒来作催化剂,让一个平时沉默寡言的码农也能成为一个喷子!在大家推杯换盏之际,难免一些画面浮现脑 ...

  7. opencv学习笔记(六)直方图比较图片相似度

    opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...

  8. python学习笔记(六)文件夹遍历,异常处理

    python学习笔记(六) 文件夹遍历 1.递归遍历 import os allfile = [] def dirList(path): filelist = os.listdir(path) for ...

  9. NetAnalyzer笔记 之 二. 简单的协议分析

    [创建时间:2015-08-27 22:15:17] NetAnalyzer下载地址 上篇我们回顾完了NetAnalyzer一些可有可无的历史,在本篇,我决定先不对NetAnalyzer做介绍,而是先 ...

随机推荐

  1. onActivityResult不执行 或者 onActivityResult的解决方法

    开发人员都知道,可以通过使用 startActivityForResult() 和 onActivityResult() 方法来传递或接收参数.然而在一次使用中,还没等到被调用的 Activity 返 ...

  2. [React Testing] Children with Shallow Rendering

    When testing React components, we often want to make sure the rendered output of the component match ...

  3. 怎么样学好C++

    声明:这篇文章非本人所写,转自:http://coolshell.cn/articles/4119.html 昨天写了一篇如何学好C语言,就有人回复问我如何学好C++,所以,我把我个人的一些学习经验写 ...

  4. 使用Teleport Pro离线下载网页所有内容

    在学习生活中,碰到网页中内容太多,如何讲其保存到本地,已方便随时查看呢? 使用Teleport Pro就可以解决问题:     首先下载Teleport Pro V1.54 汉化绿色版的,解压完之后 ...

  5. Resharper

    http://baike.baidu.com/link?url=H8DVtrvKV1Cg-Hrz82C6ZiJOUXbi_3BfoROe-RlHhctPna4-BFfglPh2OsR-KmCqRZ7_ ...

  6. cocos2dx 帧动画(iOS)

    植物大战僵尸的植物摇摆效果 //帧动画 Animation *animation = Animation::create(); Sprite *sprite = Sprite::create(&quo ...

  7. javascrip中setTimeout和setInterval

    1: http://www.jb51.net/article/68258.htm 2: http://www.jb51.net/article/26679.htm

  8. 你好,C++(19)“老师,我这次四级考试过了没有?”——4.2 条件选择语句

    4.2  条件选择语句 “老师,我这次四级考试过了没有?” 如果老师被问到这个问题,他会如何回答?是的,他会根据不同的条件选择不同的回答: 如果考试成绩大于等于60,那就回答:“恭喜你,你通过了这次考 ...

  9. hdoj 1233 还是畅通工程---最小生成树---prime算法

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1233 可以用Kruskal来做,不过当图的边比较稠密的时候用prime会更快一些. AC代码:296MS ...

  10. 对于js原型和原型链继承的简单理解(第三种,复制继承)

    复制继承:简单理解,就是把父对象上的所有属性复制到自身对象上: function Cat(){ this.climb = function(){ alert("我会爬树"); } ...