|
![]() | 作者: code [chinaroot]
![]() |
登录 |
前天在网上找了一篇关于进程的端口映射的文章,加去看了看. 并且把学有源码也拿到了,但是在调试的时候总是失败. 仔细看了一下原来是在调用过程中GetCurrentProcess总是失败. 我就把把GetCurrentProcess改为GetCurrentProcessId可以有返回值,但是当 我再用这个返回值调用OpenProcessToken是同样返回失败. 与此相关源码: #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; BYTE ObjType; BYTE HandleAttributes; USHORT HndlOffset; DWORD dwKeObject; ULONG GrantedAccess; USHORT dwPid; USHORT CreatorBackTraceIndex; }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, 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 int main( ) { printf( "\t=*= GPort Beta1(Shotgun@xici.net) =*=\n\n" ); int iRet; WSADATA wsaData; iRet = WSAStartup(MAKEWORD(1,1), &wsaData ); if ( iRet ) printf( "WSAStartup Error:%d\n", GetLastError() ); HANDLE hCurrentProc=(HANDLE)GetCurrentProcessId(); if(hCurrentProc==INVALID_HANDLE_VALUE) { printf("GetCurrentProcess is falied!\r\n"); } 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("SetPrivlegesSE_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; } DWORD dwNumBytes =MAX_HANDLE_LIST_BUF; PDWORD pdwHandleList =(PDWORD)malloc( dwNumBytes ); if ( !pdwHandleList ) { printf("Malloc forHandle List Error:%d\n",GetLastError() ); return false; } DWORD dwNumBytesRet =0; iRet =(*NtQuerySystemInformation)(NT_HANDLE_LIST, pdwHandleList, dwNumBytes, &dwNumBytesRet); 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) && (pHandleInfo->dwPid ) ) { hProc = OpenProcess(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_DUP_HANDLE, true, pHandleInfo->dwPid ); if ( hProc ) { DuplicateHandle(hProc, (HANDLE)pHandleInfo->HndlOffset, hCurrentProc, &hMyHandle, STANDARD_RIGHTS_REQUIRED, true, 0 ); CloseHandle( hProc ); } else printf( "OpenProcess %dError:%d\n", pHandleInfo->dwPid, GetLastError() ); if ( !hMyHandle ) { Sleep( 0 ); //printf( "DuplicateHandlePID=%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 ); if ( iRet != SOCKET_ERROR ) { int sockType = 0; int optlen = 4; iRet =getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&sockType, &optlen ); printf( "PID=%4d PORT=%5d%s\n", pHandleInfo->dwPid, ntohs( name.sin_port ), szSockType[sockType] ); } } } pHandleInfo++; } } if ( pdwHandleList ) free( pdwHandleList ); if ( hCurrentProc ) CloseHandle( hCurrentProc ); return 0; } |
地主 发表时间: 07-09-13 17:38 |
![]() | 回复: jhkdiy [jhkdiy] ![]() |
登录 |
进程端口映射我没看过,但看了你所说的情况和代码后就觉得GetCurrentProcess有点问题,因为根据MSDN所说该函数返回的句柄是假进程句柄,使用OpenProcess函数才可以获取进程真句柄,所以我做了修改,程序在vc6 英文版上测试过,没发现编译问题,下次贴代码记得要使用[ code]代码标签,还有代码的排版要注意。你看看代码:代码: [此贴被 jhkdiy(jhkdiy) 在 09月13日21时09分 编辑过] |
B1层 发表时间: 07-09-13 21:07 |
![]() | 回复: code [chinaroot] ![]() |
登录 |
老大你想说什么呀?? 我的问题已经解决了. 但是还是有些不明白,为什么我按着文章上编译了代码, 并且编译通过,可就是得不到结果. 而用相应的软件就完全可以达到效果. |
B2层 发表时间: 07-09-14 09:00 |
![]() | 回复: code [chinaroot] ![]() |
登录 |
各位 : 问题 已经 解决。 主要 问题还是在我这里。 回去好好看了一下MSDN发现GetCurrentProcess的返回值是-1很正常。 因为他返回 的 是一个伪句柄。 |
B3层 发表时间: 07-09-17 14:37 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号