以下是ShutGun写的关于进程与端口映射的代码,可以列出哪些进程打开了哪些端口,现我改写了下,当我循环输入viewport命令时以前保存在我分配的缓冲区里的所有系统当前的句柄好像并没有释放的,再次输入viewport你就会发现这个进程里的句柄数翻倍的,请问该怎么关闭前面的句柄呢~~~~???#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <Aclapi.h>#pragma comment ( lib, "ws2_32.lib" )// NtQuerySystemInformation record type 16
#define NT_HANDLE_LIST 16
#define OBJECT_TYPE_SOCKET 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 (CALLBACK* NTQUERYSYSTEMINFORMATION)( DWORD, PDWORD, DWORD, PVOID );
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;// 判断SOCKET类型的数组
char szSockType[6][6] = { "NUL", "TCP", "UDP", "RAW", "RDM", "SEQ" };//--------------------------------------------------------------------------------------------
//
// RaisePrivleges()函数用来提升本进程的特权
//
//--------------------------------------------------------------------------------------------
bool RaisePrivleges( HANDLE hToken, char *pPriv )
{
TOKEN_PRIVILEGES tkp;
if ( !LookupPrivilegeValue( NULL, pPriv, &tkp.Privileges[0].Luid ) )
{
printf( "LookupPrivilegeValue Error:%d\n", GetLastError() );
return false;
}tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
int iRet = AdjustTokenPrivileges(hToken,false,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);if ( iRet == NULL )//AdjustTokenPrivileges函数调用失败
{
printf( "AdjustTokenPrivileges Error:%d\n", GetLastError() );
return false;
}
else//AdjustTokenPrivileges调用成功
{//使用GetLastError()获得返回值
iRet = GetLastError();
switch ( iRet )
{
case ERROR_NOT_ALL_ASSIGNED://未指派所有的特权
printf( "AdjustTokenPrivileges ERROR_NOT_ALL_ASSIGNED\n" );
return false;
case ERROR_SUCCESS://成功地指派了所有的特权
return true;
default://不知名的错误
printf( "AdjustTokenPrivileges Unknow Error:%d\n", iRet );
return false;
}
}
}//end of RaisePrivleges//--------------------------------------------------------------------------------------------
//
// 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,//指出一个ACCESS_ALLOWED_ACE结构同意声明的权利
NO_INHERITANCE,//
{0, NO_MULTIPLE_TRUSTEE,TRUSTEE_IS_SID,TRUSTEE_IS_USER,ptstrName} };
ACL * pdacl = 0;if ( SetEntriesInAcl(1, &ea, 0, &pdacl) != ERROR_SUCCESS )
printf( "SetEntriesInAcl Error:%d", GetLastError() );if ( SetSecurityInfo(hProcess,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,0,0,pdacl,0)!= ERROR_SUCCESS )
printf( "SetSecurityInfo Error:%d", GetLastError() );LocalFree(pdacl);
}//end of AdjustDacl
#include <stdlib.h>
#include <winsock2.h>
#include <Aclapi.h>#pragma comment ( lib, "ws2_32.lib" )// NtQuerySystemInformation record type 16
#define NT_HANDLE_LIST 16
#define OBJECT_TYPE_SOCKET 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 (CALLBACK* NTQUERYSYSTEMINFORMATION)( DWORD, PDWORD, DWORD, PVOID );
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;// 判断SOCKET类型的数组
char szSockType[6][6] = { "NUL", "TCP", "UDP", "RAW", "RDM", "SEQ" };//--------------------------------------------------------------------------------------------
//
// RaisePrivleges()函数用来提升本进程的特权
//
//--------------------------------------------------------------------------------------------
bool RaisePrivleges( HANDLE hToken, char *pPriv )
{
TOKEN_PRIVILEGES tkp;
if ( !LookupPrivilegeValue( NULL, pPriv, &tkp.Privileges[0].Luid ) )
{
printf( "LookupPrivilegeValue Error:%d\n", GetLastError() );
return false;
}tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
int iRet = AdjustTokenPrivileges(hToken,false,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);if ( iRet == NULL )//AdjustTokenPrivileges函数调用失败
{
printf( "AdjustTokenPrivileges Error:%d\n", GetLastError() );
return false;
}
else//AdjustTokenPrivileges调用成功
{//使用GetLastError()获得返回值
iRet = GetLastError();
switch ( iRet )
{
case ERROR_NOT_ALL_ASSIGNED://未指派所有的特权
printf( "AdjustTokenPrivileges ERROR_NOT_ALL_ASSIGNED\n" );
return false;
case ERROR_SUCCESS://成功地指派了所有的特权
return true;
default://不知名的错误
printf( "AdjustTokenPrivileges Unknow Error:%d\n", iRet );
return false;
}
}
}//end of RaisePrivleges//--------------------------------------------------------------------------------------------
//
// 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,//指出一个ACCESS_ALLOWED_ACE结构同意声明的权利
NO_INHERITANCE,//
{0, NO_MULTIPLE_TRUSTEE,TRUSTEE_IS_SID,TRUSTEE_IS_USER,ptstrName} };
ACL * pdacl = 0;if ( SetEntriesInAcl(1, &ea, 0, &pdacl) != ERROR_SUCCESS )
printf( "SetEntriesInAcl Error:%d", GetLastError() );if ( SetSecurityInfo(hProcess,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,0,0,pdacl,0)!= ERROR_SUCCESS )
printf( "SetSecurityInfo Error:%d", GetLastError() );LocalFree(pdacl);
}//end of AdjustDacl
解决方案 »
- 线程里获取cdc里的位图会出错
- thebyte |= (char) (1 << curbit)的作用是什么?
- 关于文件读写,文件体积
- 关于视频监控窗口分割的报错
- 请教:如何在满足一个变量条件下,调出一个对话框(已经建好类了)
- 控制面版与显示区域
- 图像编程高手请进......
- 现在要做三维分子和原子模型的程序,不知道都用哪些技术,望高手指点!
- vs2008生成不了对话框exe文件了,求助
- 出现这句话时可能是那里出问题了?
- 向高手请教:如何调用dll中的位图?
- 三个问题:全局 hook 函数是运行在那个进程空间中?在 hook 函数中 new 的数据又是存在哪里?为什么所有的应用程序 instance 都是 0x4000
//
//Qport()
//主调函数
//--------------------------------------------------------------------------------------------
DWORD WINAPI qport( void *s )
{
printf( "\t=*= GPort Beta1 ([email protected]) =*=\n\n" );int iRet;
WSADATA wsaData;DWORD (__stdcall *GMFNE)(HANDLE hProcess,HMODULE hModule,LPTSTR lpFilename,DWORD nSize);
//嘿嘿!!这里是动态的加载了GetModuleFileNameExA函数,这个在后面有用到的
iRet = WSAStartup( MAKEWORD(1,1), &wsaData );//初始化WSAStartup
if ( iRet )
printf( "WSAStartup Error:%d\n", GetLastError() );HANDLE hCurrentProc = GetCurrentProcess();//得到当前的进程
HANDLE hToken;if(!OpenProcessToken(hCurrentProc,TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken))
printf( "OpenProcessToken Error:%d\n", GetLastError() );else
{
if ( !RaisePrivleges( hToken, SE_DEBUG_NAME ) )
printf( "SetPrivleges SE_DEBUG_NAME Error:%d\n", GetLastError() );
}if ( hToken )
CloseHandle( hToken );HMODULE hNtdll = NULL;hNtdll = LoadLibrary( "ntdll.dll" );if ( !hNtdll )
{
printf( "LoadLibrary( NTDLL.DLL ) Error:%d\n", GetLastError() );
return false;
}NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll,"NtQuerySystemInformation");if ( !NtQuerySystemInformation )
{
printf( "GetProcess( NtQuerySystemInformation ) Error:%d\n", GetLastError() );
return false;
}HMODULE hPsapi=LoadLibrary("PSAPI");if(!hPsapi)
{
printf("Cannot load PSAPI.\n");
return 0;
}GMFNE=(DWORD (__stdcall *) (HANDLE, HMODULE,LPTSTR,DWORD))GetProcAddress(hPsapi,"GetModuleFileNameExA");//加载GetModuleFileNameExAif(!GMFNE)
{
printf("Cannot GetProcess(GetModuleFileNameExA) Error:%d\n", GetLastError() );
return 0;
}DWORD dwNumBytes = MAX_HANDLE_LIST_BUF;
PDWORD pdwHandleList = (PDWORD)malloc( dwNumBytes );//分配空间,必需足够大if ( !pdwHandleList )
{
printf( "Malloc for Handle List Error:%d\n", GetLastError() );
return false;
}DWORD dwNumBytesRet = 0;
iRet = (*NtQuerySystemInformation)(NT_HANDLE_LIST,pdwHandleList,dwNumBytes,&dwNumBytesRet);//使用未公开的API--NtQuerySystemInformation. NtQuerySystemInformation这个函数有四个参数,第一个参数是dwRecordType,这个参数指定了我们所查询的系统信息类型,为了查询系统HANDLE列表,我们定义一个常量#define NT_HANDLE_LIST 16(这个数值我是查资料得到的,如果谁有更详细的资料,也请让我共享一下);第二个参数是一个指针,这个指针用来返回系统句柄列表,在调用NtQuerySystemInformation函数之前,必须为这个指针分配足够的内存空间,否则函数调用会出错;第三个参数是指定你为HandleList所分配的内存空间大小,单位是byte;第四个参数是NtQuerySystemInformation返回的HandleList的大小;如果NtQuerySystemInformation函数调用成功,返回值将是0. 一旦NtQuerySystemInformation函数调用成功,系统中所有的句柄将被存放在pdwHandleList所指向内存空间中,其中,pdwHandleList所指向的第一个32位数,是这个buf所包含的句柄数量,之后是顺序排列的句柄指针pHandleInfo,指向的是HANDLEINFO结构:这个结构也是未公开的,已在前面定义DWORD dwNumEntries;
PHANDLEINFO pHandleInfo;if ( iRet )
{
printf( "NtQuerySystemInformation return %d, Error:%d\n",dwNumBytesRet,GetLastError() );
}
else
{
HANDLE hProc;
dwNumEntries = pdwHandleList[0];
pHandleInfo = (PHANDLEINFO)( pdwHandleList + 1 ); for ( DWORD i = 0; i < dwNumEntries; i++ )
{
if ( (pHandleInfo->ObjType == OBJECT_TYPE_SOCKET)//判端句柄类型是否为SOCKET句柄
&&
(pHandleInfo->dwPid) )//是否得到PID
{
hProc = OpenProcess( PROCESS_ALL_ACCESS,//WRITE_DAC,
false,
pHandleInfo->dwPid );//打开进程
if ( hProc )
{
AdjustDacl( hProc );
CloseHandle( hProc );
}
else
printf( "OpenProcess(WRITE_DAC) %d Error:%d\n",pHandleInfo->dwPid,GetLastError());
HANDLE hMyHandle = NULL;
hProc = OpenProcess(PROCESS_ALL_ACCESS,//PROCESS_DUP_HANDLE,//用PROCESS_DUP_HANDLE访问标志使得可以用 //DuplicateHandle函数去复制句柄
true,//可以继承
pHandleInfo->dwPid ); if ( hProc )
{
DuplicateHandle( hProc,//指向源进程的句柄
(HANDLE)pHandleInfo->HndlOffset,//指向被复制的句柄
hCurrentProc,//指向得到复制句柄的进程
&hMyHandle,//用来存放复制的句柄的缓冲区
STANDARD_RIGHTS_REQUIRED,//复制句柄的访问请求
false,//指定为不可继承的
0 );//
CloseHandle( hProc );
//CloseHandle( (HANDLE)pHandleInfo->HndlOffset );
}
else
printf( "OpenProcess %d Error:%d\n",pHandleInfo->dwPid,GetLastError()); if ( !hMyHandle )
{
Sleep( 0 );
//printf( "DuplicateHandle PID=%4d HANDLE:%4d Error:%d\n",pHandleInfo->dwPid,pHandleInfo->HndlOffset, GetLastError() );
}
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 );//getsockname取得SOCKET的本地名 if ( iRet != SOCKET_ERROR )
{
int sockType = 0;
int optlen = 4;
char fn[128];
iRet = getsockopt( s,//SOCKET名
SOL_SOCKET,//工作层
SO_TYPE,//哪种类型的SOCKET将被返回
(char*)&sockType,//得到反回的请求的属性的缓冲区地址,这里得到的属性 //好像是以数值表示的
&optlen );
hProc=OpenProcess(PROCESS_ALL_ACCESS,false,pHandleInfo->dwPid);
GMFNE( hProc,//进程句柄
NULL,//模块句柄
fn,//用来得到返回的缓冲区
128);//GetModuleFileNameEx函数得到指定模块的真实路径
CloseHandle( hProc );
CloseHandle( hMyHandle );
printf( "PID=%4d ---> PORT=%5d %s %s\n",
pHandleInfo->dwPid,
ntohs( name.sin_port),
szSockType[sockType],
fn );
} } }
pHandleInfo++;
}
}if ( pdwHandleList )
free( pdwHandleList );if ( hCurrentProc )
CloseHandle( hCurrentProc );FreeLibrary(hPsapi);
FreeLibrary(hNtdll);ExitThread(0);
return 0;
}
int main()
{
char command[20];
printf("please input the command: ");
while(1)
{
gets(command);
if( strcmp(command,"viewport")==0 )
{
DWORD dwport=0;
CreateThread(NULL,0,qport,(LPVOID)1,0,&dwport);
}
if( strcmp(command,"exit")==0 )
{
exit( 0 );
}
printf("please input the command: ");
}
}
进程端口关联已经讨论的很多了,而且这个方法也不好。
http://www.xfocus.net/xfocus_doc.php
你看看这个东西,能学到很多东西。