Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 5/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Bilgisayarda internete bağlı olan programların listesi
#1
Bilgisayarımızda internete bağlı olan programları nasıl tespit ederiz?

Aşağıda tümü verilecek olan kod örneği ile bilgisayarımızdan internete çıkış yapan programların listesini form üzerindeki bir TMemo'ya yazdıracağız.

Bunun için yapılması gereken; 
  1. Bilgisayarda mevcut TCP ve UDP bağlantılarını tespit etmek
  2. Bu bağlantılardan hangilerinin başka bir bilgisayara bağlı olduğunu tespit etmek.
  3. Tespit edilen bağlantıların hangi process'lere ait olduğunu bulmak.
  4. Process'lerin isimlerini(Program ismi) tespit etmek

Internet erişimi için genelde TCP kullanıldığı için ben burada sadece TCP için örnek göstereceğim. UDP için de hemen hemen aynı yöntem kullanılabilir. (En basitinden bir web sayfasına erişmenin aslında basit bir TCP bağlantısı olduğunu hatırlatmakta fayda var)

TCP bağlantıları tespit etmek için iphlpapi.dll içindeki Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol APIsini kullanabiliriz.

Bu API sayesinde hangi process'lerin bir TCP bağlantı oluşturdukları bulunabilir. 

APIyi kullanabilmek için bazı tip tanımları yapılmalı:
type
 TCP_TABLE_CLASS = Integer;
 PMibTcpRowOwnerPid = ^TMibTcpRowOwnerPid;
 TMibTcpRowOwnerPid  = packed record
   dwState     : DWORD;
   dwLocalAddr : DWORD;
   dwLocalPort : DWORD;
   dwRemoteAddr: DWORD;
   dwRemotePort: DWORD;
   dwOwningPid : DWORD;
   end;

 PMIB_TCPTABLE_OWNER_PID  = ^MIB_TCPTABLE_OWNER_PID;
 MIB_TCPTABLE_OWNER_PID = packed record
  dwNumEntries: DWord;
  table: array [0..0] OF TMibTcpRowOwnerPid;
 end;

Kodun mümkün olduğunca basit olması için tüm işlemleri bir butonun OnClick olayı içinde yapmaya çalıştım.

procedure TForm1.Button1Click(Sender: TObject);
var
 i: integer;
 dllHandle : THandle;
 GetExtendedTcpTable: function(pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL; lAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: ULONG): DWord; stdcall;
 PID, TableSize: DWORD;
 Snapshot: THandle;
 FCurrentPid: Cardinal;
 FExtendedTcpTable : PMIB_TCPTABLE_OWNER_PID;
 AppName: string;
begin
 dllHandle := LoadLibrary('iphlpapi.dll'); //DLL'i hafızaya yükle
 if dllHandle = 0 then Exit;

 GetExtendedTcpTable := GetProcAddress(dllHandle, 'GetExtendedTcpTable');
 if not Assigned(GetExtendedTcpTable) then Exit; // Kullanmak istediğimiz API bu DLLde yok ise çık

 Memo1.Lines.BeginUpdate;
 Memo1.Lines.Clear;
 try
   FCurrentPid := GetCurrentProcessId();
   TableSize := 0;
   if GetExtendedTcpTable(nil, @TableSize, False, AF_INET, 5, 0) <> ERROR_INSUFFICIENT_BUFFER then //API'yi kullanmak için hafızada ne kadar yere ihtiyaç duyacağız? TableSize bunu bize verecek
     Exit; // Hafızada yeterli yer yok ise çık
   try
     GetMem(FExtendedTcpTable, TableSize); 
     SnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     if GetExtendedTcpTable(FExtendedTcpTable, @TableSize, TRUE, AF_INET, 5, 0) = NO_ERROR then
       for i := 0 to FExtendedTcpTable.dwNumEntries - 1 do
       begin
         PID := FExtendedTcpTable.Table[i].dwOwningPid;
         if (PID<>0) and (PID<>FCurrentPid) and (FExtendedTcpTable.Table[i].dwRemoteAddr<>0) then
         begin
           AppName := GetPidName(SnapShot, PID);
           if Memo1.Lines.IndexOf(AppName) = -1 then
             Memo1.Lines.Add(AppName);
         end;
       end;
   finally
     FreeMem(FExtendedTcpTable);
   end;
 finally
   Memo1.Lines.EndUpdate;
 end;
end;

GetExtendedTcpTable APIsi bize processlerin IDlerini (PID - Process Identifier) verir. Yukarıdaki kod bloğunda PID'den programın ismini tespit etmek için GetPidName adında bir fonksiyon kullandım. Fonksiyon şu şekildedir:
function GetPIDName(hSnapShot: THandle; PID: DWORD): string;
var
 ProcInfo: TProcessEntry32;
begin
 ProcInfo.dwSize := SizeOf(ProcInfo);
 if not Process32First(hSnapShot, ProcInfo) then
    Result := 'Bilinmiyor'
 else
 repeat
   if ProcInfo.th32ProcessID = PID then
      Result := ProcInfo.szExeFile;
 until not Process32Next(hSnapShot, ProcInfo);
end;

Kendi programımızın da internet erişimi olabileceği düşünülerek, tespit edilen PID'lerin bizim programımıza ait olup olmadığının kontrolü için FCurrentPid kullanılmıştır. FCurrentPid, GetCurrentProcessId APIsi sayesinde bizim programımızın PID'sini gösterir.

Memo1 içinde program ismini atarken IndexOf kontrolü yaptık. Çünkü internete bağlı bir program birden fazla TCP/UDP bağlantı kurmuş olabilir. Böyle bir durumda aynı ismi birkaç kez Memo1'e atmamak için IndexOf ile daha önceden listeye eklenip eklenmediğini kontrol etmiş olduk.


Not 1: Yukarıdaki işlemler IPv4 için yapılmıştır. IPv6 için de aynı APIler kullanılabilir.

Not 2: Kullanmak isteyenler için; kod içerisinde bulunan dwRemoteAddr değeri aslında bize bağlantı yapılan IP adresini verir (Yani internete çıkan programın hangi IPye bağlandığı).  4 byte unsigned bu değerden bildiğimiz formattaki IP adresi tespit etmeyi meraklılarına bırakıyorum Smile

Delphi XE ile yazılmış örnek bir program ektedir. 
Ekran görüntüsü:

vZ9vvD.png


Ek Dosyalar
.zip   Source.zip (Dosya Boyutu: 84,13 KB / İndirme Sayısı: 43)
There's no place like 127.0.0.1
WWW
Cevapla
#2
Merhaba,
Bir çok amaçla kullanılabilecek bu yöntem ile özellikle Virus, Malware, Spyware, Trojan gibi bir çok uygulama tespit edilebilir.
Emekleriniz ve değerli paylaşımınız için teşekkür ederim.
While true do; Hayat döngüsü, kısır değildir! Yapılan bir yanlış, o döngünün dışına çıkmanızı sağlayacaktır.
WWW
Cevapla
#3
Elinize sağlık.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#4
Bu çok faydalı paylaşımınız için teşekkürler.
Cevapla
#5
Güzel
Cevapla
#6
teşekkürler bu ara tam internet fazla kullanamı vardı onu tesbit etmeye çalışıyordum.
Cevapla
#7
function IpAddr2Str( IPAddr: DWORD ): string;
var
 i             : integer;
begin
 Result := '';
 for i := 1 to 4 do
 begin
   Result := Result + Format( '%d.', [IPAddr and $FF] );
   IPAddr := IPAddr shr 8;
 end;
 Delete( Result, Length( Result ), 1 );
end;

ip adres işçin yukarıdaki fonksiyon

port dönüşümü için swap() kullanılabilir.
Cevapla

Konuyu Paylaş : facebook gplus twitter



Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  SQL Server : Tablolar için parametrik sıralı alan listesi uparlayan 6 571 16-07-2018, Saat: 18:36
Son Yorum: ssahinoglu



Konuyu Okuyanlar: 1 Ziyaretçi