[原创]一个网络工具(简单用户层实现添加进程信息网络嗅探端口查看等)
文章作者:kiki信息来源:邪恶八进制信息安全团队
一个小程序,加了些乱七八糟的功能,在Winxp sp2下测试可以运行,主要功能如下:
1:查看进程列表以及进程模块信息
2:控制进程访问网络,允许/拒绝.
3:禁用/启用 当前网络适配器
4:利用嗅探查看当前网络数据流向
5:参考fport的一个端口与进程关联以及状态查看
以上功能都在用户层实现,界面做得比较丑,功能也很低,感兴趣的就下来看看吧.
没有加壳或者绑定其他程序,请放心测试使用... 下载测试了下,发现如下问题:
1。初始化时间长
2。点网络状态后弹出错误框(openProcess(WRITE_DAC) Error),关闭后反复弹出,得到任务管理器中结束PFW.exe进程才行。
3。在点过网络状态后退出程序,残留HookAll.exe进程,需手动结束。
4。导致一次xpsp2死机(不过不能确定就是初始化该程序所引起) 这个查看进程与端口关联的部分,我在自己机器上测试也存在问题,一点击qq.exe就会发生错误并自动关闭,但是其他程序不会发生错误.我把这部分代码贴出来,大家看看吧(跟网上那个fport差不多):
[code]
#include <stdlib.h>
#include <Aclapi.h>
#include <iphlpapi.h>
#include <Psapi.h>
#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "IPHlpApi.lib")
#pragma comment(lib, "ws2_32.lib")
char* GetNameByPid(DWORD pid, char * FilePath)
{
HMODULE hmod;
DWORD cb = 0;
HANDLE hdl = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pid);
EnumProcessModules(hdl, &hmod, sizeof(hmod), &cb);
GetModuleFileNameEx( hdl, hmod, FilePath, MAX_PATH);
return FilePath;
}
BOOL AdjustProcessPrivileges(LPCSTR szPrivilegesName)
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
return FALSE;
}
if(!LookupPrivilegeValue(NULL,szPrivilegesName,
&tkp.Privileges[0].Luid))
{
CloseHandle(hToken);
return FALSE;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL))
{
CloseHandle(hToken);
return FALSE;
}
CloseHandle(hToken);
return TRUE;
}
void GetUdpState(DWORD port, char *temp, DWORD pid)
{
DWORD i;
PMIB_UDPTABLE pUdpTable;
char FilePath[MAX_PATH];
pUdpTable = (MIB_UDPTABLE*) malloc(sizeof(MIB_UDPTABLE));
DWORD dwSize = 0;
if (GetUdpTable(pUdpTable, &dwSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
{
GlobalFree(pUdpTable);
pUdpTable = (MIB_UDPTABLE*)malloc((UINT)dwSize);
}
GetUdpTable(pUdpTable, &dwSize, TRUE);
for(i = 0; i < pUdpTable->dwNumEntries; i++)
{
struct in_addr ia;
ia.S_un.S_addr = pUdpTable->table[i].dwLocalAddr;
DWORD localport = pUdpTable->table[i].dwLocalPort;
if(((localport<<16)>>24)+((localport<<24)>>16) == port)
{
wsprintf(temp, "UDP:%s:%d %s------------->%s\0", inet_ntoa(ia), port, "LISTEN", GetNameByPid(pid, FilePath));
GlobalFree(pUdpTable);
return;
}
}
return;
}
void GetPortState(DWORD port, char *temp, DWORD pid)
{
DWORD i;
PMIB_TCPTABLE pTcpTable;
char FilePath[MAX_PATH];
pTcpTable = (MIB_TCPTABLE*) malloc(sizeof(MIB_TCPTABLE));
DWORD dwSize = 0;
if (GetTcpTable(pTcpTable, &dwSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
{
GlobalFree(pTcpTable);
pTcpTable = (MIB_TCPTABLE*)malloc((UINT) dwSize);
}
GetTcpTable(pTcpTable, &dwSize, TRUE);
for(i = 0; i < pTcpTable->dwNumEntries; i++)
{
struct in_addr ia;
ia.S_un.S_addr = pTcpTable->table[i].dwLocalAddr;
struct in_addr ib;
ib.S_un.S_addr = pTcpTable->table[i].dwRemoteAddr;
DWORD localport = pTcpTable->table[i].dwLocalPort;
DWORD remoteport = pTcpTable->table[i].dwRemotePort;
if(((localport<<16)>>24)+((localport<<24)>>16) == port)
{
switch(pTcpTable->table[i].dwState)
{
case MIB_TCP_STATE_CLOSED:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "CLOSED", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_CLOSING:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "CLOSING", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_CLOSE_WAIT:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "CLOSE_WAIT", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_DELETE_TCB:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s--%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "DELETE_TCB", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_ESTAB:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "ESTAB", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_FIN_WAIT1:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "FIN_WAIT1", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_FIN_WAIT2:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "FIN_WAIT2", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_LAST_ACK:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "LAST_ACK", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_LISTEN:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "LISTEN", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_SYN_RCVD:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "SYN_RCVD", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_SYN_SENT:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "SYN_SENT", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
case MIB_TCP_STATE_TIME_WAIT:
wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "TIME_WAIT", GetNameByPid(pid, FilePath));
// MessageBox(NULL, temp, "PFW", 0);
GlobalFree(pTcpTable);
return;
}
}
}
return;
}
int GetSystemVersion(void)
{
OSVERSIONINFO OsVersionInfo = {sizeof(OSVERSIONINFO)};
GetVersionEx(&OsVersionInfo);
if(OsVersionInfo.dwMajorVersion == 5)
{
if(OsVersionInfo.dwMinorVersion == 0)
return 2; //win2000
if(OsVersionInfo.dwMinorVersion == 1)
return 1; //winxp
else
return 0; //win2003
}
else
return 0; //others
}
BYTE ObjectType = 0;
void SetObjectBySystem(void)
{
if(GetSystemVersion() == 2)
{
ObjectType = 0x1A;
return;
}
if(GetSystemVersion() == 1)
{
ObjectType = 0x1C;
return;
}
MessageBox(NULL, "需要2000或者Xp系统!", "PFW", 0);
return;
}
// NtQuerySystemInformation record type 16
#define NT_HANDLE_LIST 16
//#define OBJECT_TYPE_SOCKET 0x1C //2000: 0x1A
#define MAX_HANDLE_LIST_BUF 0x200000
// 定义HanleInfo数据结构
typedef struct _HandleInfo
{
USHORT dwPid;
USHORT CreatorBackTraceIndex;
BYTE ObjType;
BYTE HandleAttributes;
USHORT HndlOffset;
DWORD dwKeObject;
ULONG GrantedAccess;
}HANDLEINFO, *PHANDLEINFO;
// 申明NtQuerySystemInformation()函数
typedef DWORD (__stdcall* NTQUERYSYSTEMINFORMATION)( DWORD, PDWORD, DWORD, PVOID );
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
// 判断SOCKET类型的数组
char szSockType[6][6] = { "NUL", "TCP", "UDP", "RAW", "RDM", "SEQ" };
// AdjustDacl用来调整目标进程的DACL
void AdjustDacl( HANDLE hProcess )
{
SID world = { SID_REVISION, 1, SECURITY_WORLD_SID_AUTHORITY, 0 };
LPTSTR ptstrName = (LPTSTR)&world;
EXPLICIT_ACCESS ea = {STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, SET_ACCESS, NO_INHERITANCE,
{ 0,
NO_MULTIPLE_TRUSTEE,
TRUSTEE_IS_SID,
TRUSTEE_IS_USER,
ptstrName
}
};
ACL * pdacl = 0;
if ( SetEntriesInAcl(1, &ea, 0, &pdacl) != ERROR_SUCCESS )
MessageBox(NULL, "SetEntriesInAcl Error", "PFW", 0);
if ( SetSecurityInfo(hProcess,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
0,
0,
pdacl,
0) != ERROR_SUCCESS )
MessageBox(NULL, "SetSecurityInfo Error", "PFW", 0);
LocalFree(pdacl);
}//end of AdjustDacl
BOOL FindNetHandle(HWND hwnd)
{
SetObjectBySystem();
int iRet;
HANDLE hCurrentProc = GetCurrentProcess();
HMODULE hNtdll = NULL;
hNtdll = LoadLibrary( "ntdll.dll" );
if ( !hNtdll )
{
MessageBox(NULL, "LoadLibrary( NTDLL.DLL ) Error", "PFW", 0);
CloseHandle(hCurrentProc);
return false;
}
NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll, "NtQuerySystemInformation");
if ( !NtQuerySystemInformation )
{
MessageBox(NULL, "GetProcess( NtQuerySystemInformation ) Error", "PFW", 0);
CloseHandle(hCurrentProc);
FreeLibrary(hNtdll);
return false;
}
DWORD dwNumBytes = MAX_HANDLE_LIST_BUF;
PDWORD pdwHandleList = (PDWORD)malloc(dwNumBytes);
if (!pdwHandleList)
{
MessageBox(NULL, "Malloc for Handle List Error", "PFW", 0);
CloseHandle(hCurrentProc);
FreeLibrary(hNtdll);
return false;
}
DWORD dwNumBytesRet = 0;
iRet = NtQuerySystemInformation(NT_HANDLE_LIST,
pdwHandleList,
dwNumBytes,
&dwNumBytesRet);
DWORD dwNumEntries;
PHANDLEINFO pHandleInfo;
if ( iRet )
{
MessageBox(NULL, "NtQuerySystemInformation return Error", "PFW", 0);
CloseHandle(hCurrentProc);
FreeLibrary(hNtdll);
return false;
}
else
{
HANDLE hProc;
dwNumEntries = pdwHandleList[0];
pHandleInfo = (PHANDLEINFO)( pdwHandleList + 1 );
for ( DWORD i = 0; i < dwNumEntries; i++ )
{
if ((pHandleInfo->ObjType == ObjectType) && (pHandleInfo->dwPid))
{
hProc = OpenProcess(WRITE_DAC,false,pHandleInfo->dwPid);
if ( hProc )
{
AdjustDacl( hProc );
CloseHandle( hProc );
}
else
{
MessageBox(NULL, "OpenProcess(WRITE_DAC) Error", "PFW", 0);
pHandleInfo++;
continue;
}
HANDLE hMyHandle = NULL;
hProc = OpenProcess(PROCESS_DUP_HANDLE, true, pHandleInfo->dwPid);
if ( hProc )
{
DuplicateHandle(hProc,
(HANDLE)pHandleInfo->HndlOffset,
hCurrentProc,
&hMyHandle,
STANDARD_RIGHTS_REQUIRED,
true,
0);
CloseHandle( hProc );
}
else
{
MessageBox(NULL, "OpenProcess Error", "PFW", 0);
pHandleInfo++;
continue;
}
if ( !hMyHandle )
{
pHandleInfo++;
continue;
}
else
{
sockaddr_in name = {0};
name.sin_family = AF_INET;
int namelen = sizeof(sockaddr_in);
SOCKET s = (SOCKET)hMyHandle;
iRet = getsockname( s,
(sockaddr*)&name,
&namelen );
if ( iRet != SOCKET_ERROR )
{
int sockType = 0;
int optlen = 4;
iRet = getsockopt(s,
SOL_SOCKET,
SO_TYPE,
(char*)&sockType,
&optlen );
if(iRet == 0)
{
char szPortInfo[128];
char szFmr[] = "%s:0.0.0.0:%d-------------%s ";
// wsprintf(szPortInfo, szFmr, pHandleInfo->dwPid,ntohs( name.sin_port ),szSockType[sockType]);
if(sockType == 1)
{
GetPortState(ntohs(name.sin_port), szPortInfo, pHandleInfo->dwPid);
SendMessage(GetDlgItem(hwnd,IDC_LIST1),LB_ADDSTRING,0,(LPARAM)szPortInfo);
}
if(sockType == 2)
{
GetUdpState(ntohs(name.sin_port), szPortInfo, pHandleInfo->dwPid);
SendMessage(GetDlgItem(hwnd,IDC_LIST1),LB_ADDSTRING,0,(LPARAM)szPortInfo);
}
else
{
char FileName[MAX_PATH];
GetNameByPid(pHandleInfo->dwPid, FileName);
wsprintf(szPortInfo, szFmr,szSockType[sockType], ntohs(name.sin_port), FileName);
SendMessage(GetDlgItem(hwnd,IDC_LIST1),LB_ADDSTRING,0,(LPARAM)szPortInfo);
}
memset(szPortInfo,0,128);
}
}
CloseHandle(hMyHandle);
closesocket(s);
}
}
pHandleInfo++;
}
}
free( pdwHandleList );
CloseHandle( hCurrentProc );
FreeLibrary(hNtdll);
return 0;
}
[/code] windows XP SP1测试通过 运行之后,我qq自动关闭哦。。。。 [quote][b]这里是引用第[/b][color=#ff0000][4 楼][/color][b]的[color=#000066]xiaocool[/color]于[/b]2006-09-23 18:56[b]发表的:[/b]
运行之后,我qq自动关闭哦。。。。[/quote]
这个问题我也不知道如何解决,具体处理的代码就是上面所帖的那部分,期待高手解答.
步骤:
NtQuerySysteminformation枚举所有HANDLE.
依次判断某句柄是否为SOCKET句柄
将该句柄转换成进程可处理的句柄变量(DuplicateHandle),t同时根据句柄信息结构中的Pid获取其所属进程信息.
然后用iphlpapi中的部分函数对该句柄操作获取其状态....
就这样一个过程,会造成qq程序无故地死掉,请知道的告知. [s:51] 测试一下,运行就有那么一点点卡! 这个程序还是用轮询的方式来监视程序的,貌似
while(true)
{
checkProcess();
Sleep(n);
}
所以,效率很低...
如果采用前面我提到的监视NTCreateProcessEx的方法,则会好很多.写这个的时候,还没有写上面那个,所以,有机会就改吧.因为原理都清楚了,有时候懒得动手^_^ [quote][b]这里是引用第[/b][color=#ff0000][1 楼][/color][b]的[color=#000066]adson[/color]于[/b]2006-09-22 13:19[b]发表的:[/b]
下载测试了下,发现如下问题:
1。初始化时间长
2。点网络状态后弹出错误框(openProcess(WRITE_DAC) Error),关闭后反复弹出,得到任务管理器中结束PFW.exe进程才行。
3。在点过网络状态后退出程序,残留HookAll.exe进程,需手动结束。
4。导致一次xpsp2死机(不过不能确定就是初始化该程序所引起)[/quote]
运行后
NetAcl.txt文件无法删除,郁闷~~
页:
[1]