netStat和Fport的功能差不多,据说xp上比fport少某些功能,但是我的xp可能比较特殊,fport的功能netStat上的都有,一头雾水地抓起WIn7的netStat就开始分析。
目标是五个功能
- 本地地址 [ip + 端口]
- 外部地址 [ip + 端口]
- 状态
- PID
- 所有权信息
还是先通过IDA和OD,找到程序关键的函数 DoConnection():
主要的逻辑就在这儿,先通过InternalGetTcpTableWithOwnerModule()获取Tcp表,这点和Fport的AllocateAndGetTcpExTableFromStack分厂相似,这两个函数都属于 iphlpapi.dll,只不过后者最高支持xp系统,而前者在xp后才支持。
通过OD调试查看输出信息可以确定所有有用的信息应该都在这个表里面,在MSDN上没有查到(能力问题)合适的数据结构,还可以发现输出是在DisplayTcpConnEntry里完成的,每一个while循环输出一个表项,所以确定了while循环的退出条件也就是返回的表的第一个四字节显示了表中表项的个数。最开始以为DisplayTcpConnEntry的参数就是具体的ip、port之类的,后来发现其实是传入了表项的首地址,通过IDA反的C代码可以确定第一个表项是从返回的表偏移两个四字节处开始,并且表项长度为0XA0个字节,由此可以确定数据结构的结构。进入displayTcpConnEntry查看。
通过与输出信息的比对可以发现v6为本地地址port,v7为本地地址ip,所以表项偏移一个四字节为本地ip,偏移两个四字节为port的大端存储【第一项√】(事后发现高兴的太早了)。
然后是一长串的switch,通过比对函数的返回值发现执行了这个函数之后出现了状态字串(如LISTENLING),然后发现给FormatMessage()传入适当参数可以返回这个状态字串(这儿偷了个懒没有调用这个接口,通过更改即时的数据获得了TCP表项中的数字与状态的关系)【第三项√】,之后的函数调用发现他喵的有点眼熟啊
这他喵的就是传本地ip和port的那个函数啊,大胆猜测是外部地址好吧【第二项√】(还是太天真)。
之后调用了一个output的函数输出了上述的三种信息,继续跟踪发现在DisplayOwnerInfo里面输出了pid和所有权信息,进入
在里面看到一个老朋友,dwProcessId就是pid,而这个参数是函数的形参,再回去看函数调用
哦你他吗就是偏移五个四字节嘛【第四项√】,回到displayOwnerInfo()
K32GetModuleBaseNameA()就返回了所有者的那个*.exe的信息【第五项√】,这儿有个判断,如果是svchost.exe或者rundll32.exe就会输出相应的模块信息,用后面的那啥不说的打开一个advapi32.dll然后使用I_QueryTagInformation,这儿偷懒了没做这个功能
至此Tcp表所有信息解析完毕,与此类似的还有Tcp6表、Udp表、Udp6表。感觉马上就可以写程序好吧,但是