得到本地端口和进程
unit Unit1;
interface
uses
windows,Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Tlhelp32,ShellAPI, PSAPI, CommCtrl,winsock;
const
SYSTEMTIMEINFORMATION = 3;
NT_HANDLE_LIST = 16;
OBJECT_TYPE_SOCKET = 28;
MAX_HANDLE_LIST_BUF = $200000;
// 定义HanleInfo数据结构
type
pHandleInfo = ^HandleInfo;
HandleInfo = record
dwPid : SHORT;
CreatorBackTraceIndex : SHORT;
ObjType : BYTE ;
HandleAttributes : BYTE ;
HndlOffset : SHORT;
dwKeObject : DWORD ;
GrantedAccess : ULONG ;
end;
PTSystemTimeInfo = ^TSystemTimeInfo;
TSystemTimeInfo = record
liKeBootTime : TLargeInteger;
liKeSystemTime : TLargeInteger;
liExpTimeZoneBias : TLargeInteger;
uCurrentTimeZoneId : ULONG;
dwReserved : DWORD;
end;
TNTQUERYSYSTEMINFORMATION = function(dwRecordType: DWORD; pdwHandleList: pDWORD;
dwNumBytes: DWORD; pdwNumBytesRet: pDWORD): DWORD; stdcall;
const
szSockType : Array[0..5] of string[4] =('NUL','TCP','UDP','RAW','RDM','SEQ');
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Memo2: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// GetProcessPath 根据进程ID得到进程全路径名称
function GetProcessPath(PID : Integer): String;
var hProcess: THandle;
hMod : hModule;
cbNeeded: DWORD;
szProcessName: array[0..1024] of Char;
begin
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION OR PROCESS_VM_READ,
FALSE, PID );
szProcessName := 'unknown';
if (hProcess<>0) then begin
if(EnumProcessModules(hProcess,@hMod,sizeof(hMod),cbNeeded)) then begin
GetModuleFileNameEx(hProcess,hMod,szProcessName,sizeof(szProcessName));
Result := StrPas(szProcessName);
end;
end;
CloseHandle(hProcess);
end;
// SetPrivilege 函数用来提升本进程的特权
function SetPrivilege():BOOL;
const
ADJUST_PRIV = TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES;
PRIV_SIZE = SizeOf(TTokenPrivileges);
var
Len : DWORD;
TokenPriv, Dummy : TTokenPrivileges;
Token : THandle;
begin
Result:=False;
try
if not OpenProcessToken(GetCurrentProcess(), ADJUST_PRIV, Token) then Exit;
if not LookupPrivilegeValue(nil,
'SeDebugPrivilege',
TokenPriv.Privileges[0].Luid) then exit;
TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
TokenPriv.PrivilegeCount := 1;
if not AdjustTokenPrivileges(Token, False, TokenPriv, PRIV_SIZE,Dummy, Len) then Exit;
Result:=True;
except
end;
end;
// AdjustDacl用来调整目标进程的DACL
procedure AdjustDacl(hProcess: THANDLE);
{var
world : SID;
ptstrName : pChar;
ea : EXPLICIT_ACCESS;
pdacl : PACL;}
begin
{ world.Revision :=SID_REVISION;
world.SubAuthorityCount:= 1;
world.IdentifierAuthority := SECURITY_WORLD_SID_AUTHORITY;
world.SubAuthority[0] := 0;
ptstrName := @world;
ea.grfAccessPermissions:= STANDARD_RIGHTS_ALL+SPECIFIC_RIGHTS_ALL;
ea.grfAccessMode := SET_ACCESS;
ea.grfInheritance := NO_INHERITANCE;
ea.Trustee.pMultipleTrustee := nil;
ea.Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
ea.Trustee.TrusteeForm := TRUSTEE_IS_SID;
ea.Trustee.TrusteeType := TRUSTEE_IS_USER;
ea.Trustee.ptstrName := ptstrName;
pdacl := nil; }
{
function SetEntriesInAcl(cCountOfExplicitEntries: ULONG;
pListOfExplicitEntries: PEXPLICIT_ACCESS_A; OldAcl: PACL;
var NewAcl: PACL): DWORD; stdcall;
}
{ if ( SetEntriesInAcl(1, @ea, nil, pdacl) <> ERROR_SUCCESS ) then
begin
ShowMessage(format('SetEntriesInAcl Error:%d', [GetLastError]));
if ( SetSecurityInfo(hProcess,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
nil , nil, pdacl, nil ) <> ERROR_SUCCESS ) then
ShowMessage(format('SetSecurityInfo Error:%d', [GetLastError]));
LocalFree(DWORD(pdacl));
end;}
end;//end of AdjustDacl
// GetBootTime 得到系统启动时间
function GetBootTime: string;
var
iRet : integer;
dwNumBytesRet : DWORD;
hCurrentProc,hToken : THANDLE;
hNtdll : HMODULE;
NtQuerySystemInformation : TNTQUERYSYSTEMINFORMATION;
Sti: TSystemTimeInfo;
ftSystemBoot: FILETIME;
stSystemBoot: SYSTEMTIME;
begin
hCurrentProc := GetCurrentProcess;
if ( not OpenProcessToken( hCurrentProc,
TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES,
hToken )) then
begin
Result := Result + format('OpenProcessToken Error:%d', [GetLastError]);
WsaCleanUp;
exit;
end else
if ( not SetPrivilege( )) then
begin
Result := Result + format('SetPrivleges SE_DEBUG_NAME Error:%d', [GetLastError]);
exit;
end;
if hToken <> 0 then
CloseHandle( hToken );
if hCurrentProc <> 0 then
CloseHandle( hCurrentProc );
hNtdll := LoadLibrary( 'ntdll.dll' );
if (hNtdll = 0) then
begin
Result := Result + format('LoadLibrary( NTDLL.DLL ) Error:%d', [GetLastError]);
exit;
end;
NtQuerySystemInformation := TNTQUERYSYSTEMINFORMATION(
GetProcAddress( hNtdll, 'NtQuerySystemInformation'));
if not Assigned(NtQuerySystemInformation)then
begin
Result := Result + format('GetProcess( NtQuerySystemInformation ) Error:%d', [GetLastError]);
exit;
end;
dwNumBytesRet := 0;
iRet := NtQuerySystemInformation(SYSTEMTIMEINFORMATION,
@Sti,
SizeOf(Sti),
@dwNumBytesRet);
if iRet <> 0 then
begin
Result := Result + format('NtQuerySystemInformation return %d, Error:%d'#13#10,
[dwNumBytesRet, GetLastError]);
end else begin
ftSystemBoot := FILETIME((@Sti.liKeBootTime)^);
FileTimeToLocalFileTime(ftSystemBoot,ftSystemBoot);
FileTimeToSystemTime(ftSystemBoot,stSystemBoot);
Result := Result + format(' %04d年%02d月%02d日'#9' %02d:%02d:%02d',
[stSystemBoot.wYear,stSystemBoot.wMonth,stSystemBoot.wDay,
stSystemBoot.wHour,stSystemBoot.wMinute,stSystemBoot.wSecond]);
end;
if hNtdll <> 0 then
freeLibrary(hNtdll);
end;
// GetPortInfo 将SOCK端口与程序对应起来
function GetPortInfo: string;
var
iRet: integer;
wsaData: Winsock.WSADATA;
hCurrentProc,hToken : THANDLE;
hNtdll : HMODULE;
NtQuerySystemInformation : TNTQUERYSYSTEMINFORMATION;
dwNumBytes : DWORD;
pdwHandleList
DWORD;
dwNumBytesRet : DWORD;
dwNumEntries: DWORD;
pHInfo: PHANDLEINFO;
hProc: THANDLE;
i : DWORD;
hMyHandle : THandle;
name,remote : sockaddr_in;
s : TSOCKET;
namelen : integer;
sockType : integer;
optlen : integer;
begin
iRet := WSAStartup(MAKEWORD(1,1), wsaData );
if iRet<>0 then
begin
Result := format('WSAStartup Error:%d', [GetLastError]);
exit;
end;
hCurrentProc := GetCurrentProcess;
if (not OpenProcessToken( hCurrentProc,
TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES,
hToken )) then
begin
Result := Result + format('OpenProcessToken Error:%d', [GetLastError]);
WsaCleanUp;
exit;
end else
if ( not SetPrivilege()) then
begin
Result := Result + format('SetPrivleges SE_DEBUG_NAME Error:%d', [GetLastError]);
WsaCleanUp;
exit;
end;
if hToken <> 0 then
CloseHandle( hToken );
hNtdll := LoadLibrary( 'ntdll.dll' );
if (hNtdll = 0) then
begin
Result := Result + format('LoadLibrary( NTDLL.DLL ) Error:%d', [GetLastError]);
WSACleanup;
exit;
end;
NtQuerySystemInformation := TNTQUERYSYSTEMINFORMATION(
GetProcAddress( hNtdll, 'NtQuerySystemInformation'));
if not Assigned(NtQuerySystemInformation)then
begin
Result := Result + format('GetProcess( NtQuerySystemInformation ) Error:%d', [GetLastError]);
WSACleanup;
exit;
end;
dwNumBytes := MAX_HANDLE_LIST_BUF;
GetMem(pdwHandleList,dwNumBytes);
if not Assigned(pdwHandleList) then
begin
Result := Result + format('Malloc for Handle List Error:%d'#13#10, [GetLastError]);
WSACleanup;
exit;
end;
dwNumBytesRet := 0;
iRet := NtQuerySystemInformation(NT_HANDLE_LIST,
pdwHandleList,
dwNumBytes,
@dwNumBytesRet);
if iRet <> 0 then
begin
Result := Result + format('NtQuerySystemInformation return %d, Error:%d'#13#10,
[dwNumBytesRet, GetLastError]);
end else begin
dwNumEntries := pdwHandleList^;
pHInfo := PHANDLEINFO((DWORD(pdwHandleList) + sizeof(pdwHandleList) ));
for i := 0 to dwNumEntries -1 do
begin
//此进程含有SOCKET对象 OK
if phInfo^.dwPid=432 then
form1.Memo2.Lines.Add(inttostr(phInfo^.ObjType));
if (( phInfo^.ObjType = OBJECT_TYPE_SOCKET )
and ( phInfo^.dwPid <> 0 ) ) then
begin
hProc := OpenProcess(WRITE_DAC,
false,
phInfo.dwPid );
if hProc <> 0 then
begin
AdjustDacl( hProc );
CloseHandle( hProc );
end else
Result := Result + format('OpenProcess(WRITE_DAC) %d Error:%d'#13#10,
[phInfo^.dwPid,
GetLastError]);
hMyHandle := 0;
//根据 ProcessID 打开相应的进程
hProc := OpenProcess(PROCESS_DUP_HANDLE or PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
true,
phInfo.dwPid );
if hProc <>0 then
begin
//获取Socket句柄
DuplicateHandle(hProc, //源进程句柄
THANDLE(phInfo^.HndlOffset), //源SOCKET对象
hCurrentProc, //本进程句柄
@hMyHandle, //复制到这里
STANDARD_RIGHTS_REQUIRED,
true,
0 ); //使用 DUPLICATE_CLOSE_SOURCE 则关闭源socket
// DUPLICATE_SAME_ACCESS 象源进程一样操作SOCKET
CloseHandle( hProc );
end else
Result := Result + format( 'OpenProcess %d Error:%d'#13#10,
[phInfo.dwPid,
GetLastError]);
if hMyHandle = 0 then
begin
//form1.Memo1.Lines.Add(format('DuplicateHandle PID=%4d HANDLE:%4d Error:%d',
// [pHInfo^.dwPid, phInfo^.HndlOffset, GetLastError] ));
end else
begin
ZeroMemory(@name,sizeof(name));
name.sin_family := AF_INET;
namelen := sizeof(sockaddr_in);
s := TSOCKET(hMyHandle);
//获得SOCKET的本地名
iRet := getsockname(s, //SOCKET
name, //返回 name
namelen );
ZeroMemory(@remote,sizeof(remote));
remote.sin_family := AF_INET;
getpeername(s,
remote,
namelen);
//form1.Memo1.Lines.Add(inttostr(hMyHandle)+' '+inttostr(pHInfo^.dwPid)+' '+inttostr(phInfo^.HndlOffset)+' '+inttostr(iRet));
if iRet <> SOCKET_ERROR then
begin
sockType := 0;
optlen := 4;
//取得端口类型
getsockopt(s,
SOL_SOCKET,
SO_TYPE,
@sockType,
optlen );
Result := Result + format('ProcessID=%4d '#9+
GetProcessPath(pHInfo^.dwPid)+ #9+
'本地地址: %s'#9+
'本地端口: %5d'#9+
'远程地址: %s'#9+
'远程端口: %5d %s'#13#10,
[pHInfo^.dwPid,
inet_ntoa(name.sin_addr),
ntohs(name.sin_port),
inet_ntoa(remote.sin_addr),
ntohs(remote.sin_port),
(szSockType[sockType])]);
end;
end;
end;
pHInfo := PHANDLEINFO(DWORD(phInfo) +sizeOf(HANDLEINFO));
if s<>0 then
closesocket(s);
end;
end;
if Assigned(pdwHandleList) then
freeMem( pdwHandleList );
if hCurrentProc <> 0 then
CloseHandle( hCurrentProc );
freeLibrary(hNtdll);
WSACleanup;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Clear;
Memo1.Lines.Add(GetPortInfo);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Caption := GetBootTime;
end;
end.