[创建时间: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. hdu 1724 Ellipse simpson积分

    /* hdu 1724 Ellipse simpson积分 求椭圆的部分面积 simpson积分法 http://zh.wikipedia.org/zh-tw/%E8%BE%9B%E6%99%AE%E ...

  2. [置顶] Win8.1慎用360优化,可能导致安装驱动出现数据无效的问题。附解决方法

    2013年9月30日,更新说明: 不知道是不是我禁用了其他驱动造成 今天开机后连接手机,我的电脑里没出现MTP设备 于是打开设备管理器,发现MTP,也就是我的XPERIA U出现了感叹号图标 右键更新 ...

  3. 差别client、offset、scroll系列以及event的几个距离属性

    element元素结点属性 一. offset系列 1.offsetWidth 和offsetHeight element.offsetWidth是一个仅仅读属性,它包含了: css width + ...

  4. c#中的面向对象基础知识总结

    面向对象 1.面向过程----->面向对象 1.  面向过程:面向的是完成这件事儿的过程,强调的是完成这件事儿的动作. 面向对象:意在写出一个通用的代码,屏蔽差异. 我们在代码中描述一个对象,通 ...

  5. inline-block容器的高度撑开位置

    block的高度是从最上面撑开的 那么inline-block呢? 直接上代码 <!doctype html> <html> <head> <meta cha ...

  6. (转)使用Microsoft Web Application Stress Tool对web进行压力测试

    http://www.blogjava.net/crespochen/archive/2009/06/02/279538.html Web压力测试是目前比较流行的话题,利用Web压力测试可以有效地测试 ...

  7. SICP 阅读笔记(二)

    Chapter 1: Building Abstractions with Procedures 2015-09-29 016 Preface of this chapter QUOTE: The a ...

  8. 浅谈MDX处理空值NULL及格式化结果

    MDX查询结果中往往会含有"NULL"值,这是某维度下对应的的量值不存在导致的,为了让报表呈现更好的效果,在有些情况下,需要将"NULL"的切片值置换成0,这些 ...

  9. Linux下makefile(一)

    makefile关系到了整个工程的编译规则.一个工程中的源文件不计数,其按类型.功能.模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文 ...

  10. Codeforces Round #318(Div 1) 573A, 573B,573C

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 这场的前两题完全是手速题...A题写了7分钟,交的时候已经500+了,好在B题出的 ...