Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.04.01;
Скачать: CL | DM;

Вниз

Определение IP пользователя пытающегося подключиться ко мне   Найти похожие ветки 

 
cleverman   (2006-10-18 17:03) [0]

Итак, уважаемые мастера, помогите советом.
Суть такая.
На моей машине есть серверная часть некоей проги удаленного управления (Real VNC). Каким образом я программно могу определить IP подключающихся к этому серверу пользователей, использующих клиентскую часть. Порт подключения известен.


 
Ketmar ©   (2006-10-18 17:23) [1]

снифер. искать у Rouse_(c).


 
cleverman   (2006-10-19 09:02) [2]

Хм... Сниффер - это понятно. Это первое, что пришло мне в голову. Но тут проблемка немного другая. Мне нужно зашить немалую обработку события подключения, если IP подключающегося соответствует определенному списку IP. Поэтому я имел ввиду определение IP средствами Delphi, а не посторонними снифферами.


 
Ketmar ©   (2006-10-19 09:07) [3]

слазим с бронепоезда. идём на сайт Rouse_(c). качаем снифер. о, чудо -- он на Delphi написан, оказывается!

зыж ты бы сначала, всё же, ходил на сайты, а потом говорил "не подходит!" ага?


 
Rouse_ ©   (2006-10-19 09:53) [4]

Можно конечно и сниффером, перебрать открытые хэндлы гнезд в системе, отфильтровать из них те, которые принадлежат процессу Real VNC и из них вытащить RemoteHost, но на написание демки сейчас нет времени, поэтому самое простое конечно же сделать так:

////////////////////////////////////////////////////////////////////////////////
//
//  ****************************************************************************
//  * Unit Name : Unit1
//  * Purpose   : Демо получения ТСР статистики
//  * Author    : Александр (Rouse_) Багель
//  * Version   : 1.02
//  ****************************************************************************
//

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, Winsock;

// так как в примере используются недокументированные функции присутствующие
// только в ХР и выше - то часть кода сделал через директивы компилятора
// (лень было делать динамическую загрузку)
// Если они вам нужны раскоментируйте директиву USES_NATIVE_API

{$DEFINE USES_NATIVE_API}

const
 TH32CS_SNAPPROCESS  = $00000002;

 // Константы состояний порта
 MIB_TCP_STATE_CLOSED     = 1;
 MIB_TCP_STATE_LISTEN     = 2;
 MIB_TCP_STATE_SYN_SENT   = 3;
 MIB_TCP_STATE_SYN_RCVD   = 4;
 MIB_TCP_STATE_ESTAB      = 5;
 MIB_TCP_STATE_FIN_WAIT1  = 6;
 MIB_TCP_STATE_FIN_WAIT2  = 7;
 MIB_TCP_STATE_CLOSE_WAIT = 8;
 MIB_TCP_STATE_CLOSING    = 9;
 MIB_TCP_STATE_LAST_ACK   = 10;
 MIB_TCP_STATE_TIME_WAIT  = 11;
 MIB_TCP_STATE_DELETE_TCB = 12;

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   function PortStateToStr(const State: DWORD): String;
 end;

 // Стандартная структура для получения ТСР статистики
 PTMibTCPRow = ^TMibTCPRow;
 TMibTCPRow = packed record
   dwState: DWORD;
   dwLocalAddr: DWORD;
   dwLocalPort: DWORD;
   dwRemoteAddr: DWORD;
   dwRemotePort: DWORD;
 end;

 // В данную структуру будет передаваться результат GetTcpTable
 PTMibTCPTable = ^TMibTCPTable;
 TMibTCPTable = packed record
   dwNumEntries: DWORD;
   Table: array[0..0] of TMibTCPRow;
 end;

 // Стандартная структура для получения UDP статистики
 PTMibUdpRow = ^TMibUdpRow;
 TMibUdpRow = packed record
   dwLocalAddr: DWORD;
   dwLocalPort: DWORD;
 end;

 // В данную структуру будет передаваться результат GetUDPTable
 PTMibUdpTable = ^TMibUdpTable;
 TMibUdpTable = packed record
   dwNumEntries: DWORD;
   table: array [0..0] of TMibUdpRow;
 end;

 {$IFDEF USES_NATIVE_API}
   // Расширенные варианты данных структур

   PTMibTCPExRow = ^TMibTCPExRow;
   TMibTCPExRow = packed record
     dwState: DWORD;
     dwLocalAddr: DWORD;
     dwLocalPort: DWORD;
     dwRemoteAddr: DWORD;
     dwRemotePort: DWORD;
     dwProcessID: DWORD;
   end;

   PTMibTCPExTable = ^TMibTCPExTable;
   TMibTCPExTable = packed record
     dwNumEntries: DWORD;
     Table: array[0..0] of TMibTCPExRow;
   end;

   PTMibUdpExRow = ^TMibUdpExRow;
   TMibUdpExRow = packed record
     dwLocalAddr: DWORD;
     dwLocalPort: DWORD;
     dwProcessID: DWORD;
   end;

   PTMibUdpExTable = ^TMibUdpExTable;
   TMibUdpExTable = packed record
     dwNumEntries: DWORD;
     table: array [0..0] of TMibUdpExRow;
   end;

   // Структура для получения списка текущий процессов и их параметров
   TProcessEntry32 = packed record
     dwSize: DWORD;
     cntUsage: DWORD;
     th32ProcessID: DWORD;
     th32DefaultHeapID: DWORD;
     th32ModuleID: DWORD;
     cntThreads: DWORD;
     th32ParentProcessID: DWORD;
     pcPriClassBase: Longint;
     dwFlags: DWORD;
     szExeFile: array [0..MAX_PATH - 1] of WideChar;
   end;

 {$ENDIF}

 function GetTcpTable(pTCPTable: PTMibTCPTable; var pDWSize: DWORD;
   bOrder: BOOL): DWORD; stdcall; external "IPHLPAPI.DLL";

 function GetUdpTable(pUDPTable: PTMibUDPTable; var pDWSize: DWORD;
   bOrder: BOOL): DWORD; stdcall; external "IPHLPAPI.DLL";

 {$IFDEF USES_NATIVE_API}

   function AllocateAndGetTcpExTableFromStack(pTCPExTable: PTMibTCPExTable;
     bOrder: BOOL; heap: THandle; zero: DWORD; flags: DWORD): DWORD; stdcall;
     external "IPHLPAPI.DLL";

   function AllocateAndGetUdpExTableFromStack(pUDPExTable: PTMibUDPExTable;
     bOrder: BOOL; heap: THandle; zero: DWORD; flags: DWORD): DWORD; stdcall;
     external "IPHLPAPI.DLL";

   function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle;
     stdcall; external "KERNEL32.DLL";

   function Process32First(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL;
     stdcall; external "KERNEL32.DLL" name "Process32FirstW";

   function Process32Next(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL;
     stdcall; external "KERNEL32.DLL" name "Process32NextW";

 {$ENDIF}

var
 Form1: TForm1;


 
Rouse_ ©   (2006-10-19 09:53) [5]


implementation

{$R *.dfm}

// Получение TCP/UDP статистики при помощи стандартных методов
procedure TForm1.Button1Click(Sender: TObject);
var
 Size: DWORD;
 TCPTable: PTMibTCPTable;
 UDPTable: PTMibUdpTable;
 I: DWORD;
begin
 // для успешного получения стстаистики первоначально необходимо определиться
 // сколько памяти потребует данная операция
 // для этого делаем так:
 // Вделяем память под TCP таблицу (под один элемент)
 GetMem(TCPTable, SizeOf(TMibTCPTable));
 try
   // Показываем что памяти у нас не выделено
   Size := 0;
   // Выполняем функцию и после этого переменная Size
   // будет содержать кол-во необходимой памяти
   if GetTcpTable(TCPTable, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
 finally
   // освобождаем память занятую под один элемент
   FreeMem(TCPTable);
 end;
 // Теперь выделяем уже требуемое кол-во памяти
 GetMem(TCPTable, Size);
 try
   // Выполняем функцию
   if GetTcpTable(TCPTable, Size, True) = NO_ERROR then
   begin
     Memo1.Lines.Add("");
     Memo1.Lines.Add("Standart TCP Stats");
     Memo1.Lines.Add(Format("%15s: | %5s | %15s: | %11s | %-12s",
       ["Host", "Port", "Remote Host", "Remote Port", "State"]));
     Memo1.Lines.Add("=============================================================== =========");
   // и начинаем выводить данные по ТСР
   for I := 0 to TCPTable^.dwNumEntries - 1 do
     Memo1.Lines.Add(Format("%15s: | %5d | %15s: | %11d | %s",
       [inet_ntoa(in_addr(TCPTable^.Table[I].dwLocalAddr)),
       htons(TCPTable^.Table[I].dwLocalPort),
       inet_ntoa(in_addr(TCPTable^.Table[I].dwRemoteAddr)),
       htons(TCPTable^.Table[I].dwRemotePort),
       PortStateToStr(TCPTable^.Table[I].dwState)]));
   end;
 finally
   // Не забываем освободить память
   FreeMem(TCPTable);
 end;

 // По аналогии поступаем и с UDP статистикой
 GetMem(UDPTable, SizeOf(TMibUDPTable));
 try
   Size := 0;
   if GetUdpTable(UDPTable, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
 finally
   FreeMem(UDPTable);
 end;
 GetMem(UDPTable, Size);
 try
   if GetUdpTable(UDPTable, Size, True) = NO_ERROR then
   begin
     Memo1.Lines.Add("");
     Memo1.Lines.Add("Standart UDP Stats");
     Memo1.Lines.Add(Format("%15s: | %5s", ["Host", "Port"]));
     Memo1.Lines.Add("======================================");
   for I := 0 to UDPTable^.dwNumEntries - 1 do
     Memo1.Lines.Add(Format("%15s: | %5d", [inet_ntoa(in_addr(UDPTable^.Table[I].dwLocalAddr)),
       htons(UDPTable^.Table[I].dwLocalPort)]));
   end;
 finally
   FreeMem(UDPTable);
 end;
end;

{$IFNDEF USES_NATIVE_API}
procedure TForm1.Button2Click(Sender: TObject);
begin
 Memo1.Lines.Add("");
 Memo1.Lines.Add("USES_NATIVE_API are disabled.");
end;

{$ELSE}

// Получение TCP/UDP статистики при помощи недокументрированных методов
// Работает только на ХР или Win 2003
procedure TForm1.Button2Click(Sender: TObject);

 // данная функция ищет процесс с th32ProcessID совпадающий с ProcessId
 // и возвращает его имя
 function ProcessPIDToName(const hProcessSnap: THandle; ProcessId: DWORD): String;
 var
   processEntry: TProcessEntry32;
 begin
   // Подготовительные действия
   Result := "";
   FillChar(processEntry, SizeOf(TProcessEntry32), #0);
   processEntry.dwSize := SizeOf(TProcessEntry32);
   // Прыгаем на первый процесс в списке
   if not Process32First(hProcessSnap, processEntry) then Exit;
   repeat
     // Сравнение
     if processEntry.th32ProcessID = ProcessId then
     begin
       // Если нашли нужный процесс - выводим результат и выходим
       Result := String(processEntry.szExeFile);
       Exit;
     end;
   // ищем пока не кончатся процессы
   until not Process32Next(hProcessSnap, processEntry);
 end;


 
Rouse_ ©   (2006-10-19 09:54) [6]


var
 TCPExTable: PTMibTCPExTable;
 UDPExTable: PTMibUdpExTable;
 I: DWORD;
 hProcessSnap: THandle;
begin
 // для определения каким процессом открыт тот или иной порт
 // получаем список процессов
 hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 if (hProcessSnap = INVALID_HANDLE_VALUE) then
 begin
   Memo1.Lines.Add("");
   Memo1.Lines.Add("CreateToolhelp32Snapshot failed");
   Exit;
 end;
 try
   // Выполняем вот такую вот функцию
   // она не документтрованна, но как видно из названия - она сама выделяет необходимую для работы
   // память и нам остается только прочитать результат по завершении ее выполнения
   if AllocateAndGetTcpExTableFromStack(@TCPExTable, False, GetProcessHeap, 2, 2) = NO_ERROR then
   try
     Memo1.Lines.Add("");
     Memo1.Lines.Add("Extended TCP Stats");
     Memo1.Lines.Add(Format("%15s: | %5s | %15s: | %11s | %-12s | %20s | (%s)",
       ["Host", "Port", "Remote Host", "Remote Port", "State", "Process name", "ID"]));
     Memo1.Lines.Add(
       "=============================================================================== ============================");
     // начинаем выводить информацию
     for I := 0 to TCPExTable^.dwNumEntries - 1 do
       Memo1.Lines.Add(Format("%15s: | %5d | %15s: | %11d | %-12s | %20s | (%d)",
         [inet_ntoa(in_addr(TCPExTable^.Table[I].dwLocalAddr)),
         htons(TCPExTable^.Table[I].dwLocalPort),
         inet_ntoa(in_addr(TCPExTable^.Table[I].dwRemoteAddr)),
         htons(TCPExTable^.Table[I].dwRemotePort),
         PortStateToStr(TCPExTable^.Table[I].dwState),
         // Вот здесь у нас происходит сопоставление процесса открытому порту
         ProcessPIDToName(hProcessSnap, TCPExTable^.Table[I].dwProcessID),
         TCPExTable^.Table[I].dwProcessID]));
   finally
     // Не забываем освободить память занятую функцией
     GlobalFreePtr(TCPExTable);
   end;

   // По аналогии поступаем и с UDP статистикой
   if AllocateAndGetUdpExTableFromStack(@UDPExTable, False, GetProcessHeap, 2, 2) = NO_ERROR then
   try
     Memo1.Lines.Add("");
     Memo1.Lines.Add("Extended UDP Stats");
     Memo1.Lines.Add(Format("%15s: | %5s | %20s | (%s)", ["Host", "Port", "Process name", "ID"]));
     Memo1.Lines.Add("==============================================================" );
     // начинаем выводить информацию
     for I := 0 to UDPExTable^.dwNumEntries - 1 do
       Memo1.Lines.Add(Format("%15s: | %5d | %20s | (%d)",
         [inet_ntoa(in_addr(UDPExTable^.Table[I].dwLocalAddr)),
         htons(UDPExTable^.Table[I].dwLocalPort),
         ProcessPIDToName(hProcessSnap, UDPExTable^.Table[I].dwProcessID),
         UDPExTable^.Table[I].dwProcessID]));
   finally
     GlobalFreePtr(UDPExTable);
   end;
 finally
   // Закрываем хэндл полученый от CreateToolhelp32Snapshot
   CloseHandle(hProcessSnap);
 end;
end;

{$ENDIF}

// Функция преобразует состояние порта в строковый эквивалент
function TForm1.PortStateToStr(const State: DWORD): String;
begin
 case State of
   MIB_TCP_STATE_CLOSED: Result := "CLOSED";
   MIB_TCP_STATE_LISTEN: Result := "LISTEN";
   MIB_TCP_STATE_SYN_SENT: Result := "SYN SENT";
   MIB_TCP_STATE_SYN_RCVD: Result := "SYN RECEIVED";
   MIB_TCP_STATE_ESTAB: Result := "ESTABLISHED";
   MIB_TCP_STATE_FIN_WAIT1: Result := "FIN WAIT 1";
   MIB_TCP_STATE_FIN_WAIT2: Result := "FIN WAIT 2";
   MIB_TCP_STATE_CLOSE_WAIT: Result := "CLOSE WAIT";
   MIB_TCP_STATE_CLOSING: Result := "CLOSING";
   MIB_TCP_STATE_LAST_ACK: Result := "LAST ACK";
   MIB_TCP_STATE_TIME_WAIT: Result := "TIME WAIT";
   MIB_TCP_STATE_DELETE_TCB: Result := "DELETE TCB";
 else
   Result := "UNKNOWN";
 end;
end;

end.


 
Rouse_ ©   (2006-10-19 09:55) [7]

ЗЫ: это чуть чуть расширенный вариант вот этого примера: http://rouse.drkb.ru/files/tcpstat.zip


 
cleverman   (2006-10-19 10:41) [8]

to Ketmar ©
to Rouse_©

Премного благодарен за помощь. :)
Я как раз уже демонтировал по кусочкам выложенный на сайте сниффер (спасибо to Rouse_© за предоставленный код) и преобразовал его в нужный вариант. Не люблю лентяйничать за чужой счет, но все равно спасибо.

З.Ы. в сниффере, кстати идет утечка памяти :) Где, еще не нашел, но визуально утечка налицо


 
Rouse_ ©   (2006-10-19 10:57) [9]

Визуально это не утечка, а просто растет буффер TMemo - туда же текст выводиться :) Очисти TMemo и память вернется к нормальному состоянию :)


 
cleverman   (2006-10-19 11:05) [10]

Я уже сообразил :) Как только добавил последнюю строчку

procedure TSnifferThread.ShowPacket;
begin
 frmMain.memReport.Lines.BeginUpdate;
 frmMain.memReport.Text :=
 frmMain.memReport.Text + sLineBreak + LogData;
 SendMessage(frmMain.memReport.Handle, WM_VSCROLL, SB_BOTTOM, 0);
 frmMain.memReport.Lines.EndUpdate;
 Application.ProcessMessages;
end;



Страницы: 1 вся ветка

Текущий архив: 2007.04.01;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.052 c
15-1173259369
Оззя
2007-03-07 12:22
2007.04.01
DelphiGFX умер?


3-1168614838
Antonyan
2007-01-12 18:13
2007.04.01
Masterkey


2-1173285497
ANTPro
2007-03-07 19:38
2007.04.01
Нарисовать поверх всех


2-1173091442
Магедон
2007-03-05 13:44
2007.04.01
Вопрос о маленьком почновом клиентике.


10-1130305721
Mary
2005-10-26 09:48
2007.04.01
Подключение клиентов к com-серверу