Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Посылка Raw IP-пакетов

01.01.2007

Автор: Erwin Molendijk

Используя данный исходник можно конструировать собственные пакеты содержащие внутри всё, что угодно. Можно самостоятельно указывать в пакете IP-адрес получателя и отправителя, порт назначения и т.д. Если Вы не знаете, что это такое, то лучше не эксперементировать. Единственный недостаток, то, что скорее всего данный пример будет работать только в Windows 2000. Так же исходник позволяет произвести SYN flood и IP spoofing.

Необходимо зайти в систему под Администратором.

Совместимость: Delphi 5.x (или выше)

{ 
Raw Packet Sender 
using: Delphi + Winsock 2 
 
Copyright (c) 2000 by E.J.Molendijk (xes@dds.nl) 
 
---------------------------------------------------------------------- 
Перед использованием измените значения SrcIP+SrcPort+ 
DestIP+DestPort на нужные! 
---------------------------------------------------------------------- 
 
} 
unit main; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  StdCtrls, OleCtrls, Registry; 
 
Const 
  SrcIP       = '123.123.123.1'; 
  SrcPort     = 1234; 
  DestIP      = '123.123.123.2'; 
  DestPort    = 4321; 
 
  Max_Message = 4068; 
  Max_Packet  = 4096; 
 
type 
 
  TPacketBuffer = Array[0..Max_Packet-1] of byte; 
 
  TForm1 = class(TForm) 
    Button1: TButton; 
    Memo1: TMemo; 
    procedure Button1Click(Sender: TObject); 
  private 
    { Private declarations } 
  public 
    { Public declarations } 
    procedure SendIt; 
  end; 
 
// Заголовок IP пакета
type 
  T_IP_Header = record 
    ip_verlen       : Byte; 
    ip_tos          : Byte; 
    ip_totallength  : Word; 
    ip_id            : Word; 
    ip_offset       : Word; 
    ip_ttl          : Byte; 
    ip_protocol     : Byte; 
    ip_checksum     : Word; 
    ip_srcaddr      : LongWord; 
    ip_destaddr     : LongWord; 
  end; 
 
// Заголовок UDP пакета 
Type 
  T_UDP_Header = record 
    src_portno    : Word; 
    dst_portno    : Word; 
    udp_length    : Word; 
    udp_checksum  : Word; 
  end; 
 
// Некоторые объявления типов для Winsock 2 
  u_char  = Char; 
  u_short = Word; 
  u_int   = Integer; 
  u_long  = Longint; 
 
  SunB = packed record 
    s_b1, s_b2, s_b3, s_b4: u_char; 
  end; 
  SunW = packed record 
    s_w1, s_w2: u_short; 
  end; 
  in_addr = record 
    case integer of 
      0: (S_un_b: SunB); 
      1: (S_un_w: SunW); 
      2: (S_addr: u_long); 
  end; 
  TInAddr = in_addr; 
  Sockaddr_in = record 
    case Integer of 
      0: (sin_family: u_short; 
          sin_port: u_short; 
          sin_addr: TInAddr; 
          sin_zero: array[0..7] of Char); 
      1: (sa_family: u_short; 
          sa_data: array[0..13] of Char) 
  end; 
  TSockAddr = Sockaddr_in; 
  TSocket = u_int; 
 
const 
  WSADESCRIPTION_LEN     =   256; 
  WSASYS_STATUS_LEN      =   128; 
 
type 
  PWSAData = ^TWSAData; 
  WSAData = record // !!! also WSDATA 
    wVersion: Word; 
    wHighVersion: Word; 
    szDescription: array[0..WSADESCRIPTION_LEN] of Char; 
    szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char; 
    iMaxSockets: Word; 
    iMaxUdpDg: Word; 
    lpVendorInfo: PChar; 
  end; 
  TWSAData = WSAData; 
 
// Определяем необходимые функции winsock 2 
function closesocket(s: TSocket): Integer; stdcall; 
function socket(af, Struct, protocol: Integer): TSocket; stdcall; 
function sendto(s: TSocket; var Buf; len, flags: Integer; var addrto: TSockAddr; 
  tolen: Integer): Integer; stdcall;{} 
function setsockopt(s: TSocket; level, optname: Integer; optval: PChar; 
  optlen: Integer): Integer; stdcall; 
function inet_addr(cp: PChar): u_long; stdcall; {PInAddr;}  { TInAddr } 
function htons(hostshort: u_short): u_short; stdcall; 
function WSAGetLastError: Integer; stdcall; 
function WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer; stdcall; 
function WSACleanup: Integer; stdcall; 
 
const 
  AF_INET         = 2;                // internetwork: UDP, TCP, etc. 
 
  IP_HDRINCL      = 2;                // включаем заголовок IP пакета 
 
  SOCK_RAW        = 3;                // интерфейс raw-протокола 
 
  IPPROTO_IP      = 0;                // dummy for IP 
  IPPROTO_TCP     = 6;                // tcp 
  IPPROTO_UDP     = 17;              // user datagram protocol 
  IPPROTO_RAW     = 255;              // raw IP пакет 
 
  INVALID_SOCKET = TSocket(NOT(0)); 
  SOCKET_ERROR                  = -1; 
 
var 
  Form1: TForm1; 
 
implementation 
 
// Импортируем функции Winsock 2 
const WinSocket = 'WS2_32.DLL'; 
 
function closesocket;        external    winsocket name 'closesocket'; 
function socket;            external    winsocket name 'socket'; 
function sendto;            external    winsocket name 'sendto'; 
function setsockopt;        external    winsocket name 'setsockopt'; 
function inet_addr;          external    winsocket name 'inet_addr'; 
function htons;              external    winsocket name 'htons'; 
function WSAGetLastError;   external    winsocket name 'WSAGetLastError'; 
function WSAStartup;        external    winsocket name 'WSAStartup'; 
function WSACleanup;        external    winsocket name 'WSACleanup'; 
 
 
{$R *.DFM} 
 
// 
// Function: checksum 
// 
// Description: 
//    This function calculates the 16-bit one's complement sum 
//    for the supplied buffer 
// 
function CheckSum(Var Buffer; Size : integer) : Word; 
type 
  TWordArray = Array[0..1] of Word; 
var 
  ChkSum : LongWord; 
  i      : Integer; 
begin 
  ChkSum := 0; 
  i := 0; 
  While Size > 1 do begin 
    ChkSum := ChkSum + TWordArray(Buffer)[i]; 
    inc(i); 
    Size := Size - SizeOf(Word); 
  end; 
 
  if Size=1 then ChkSum := ChkSum + Byte(TWordArray(Buffer)[i]); 
 
  ChkSum := (ChkSum shr 16) + (ChkSum and $FFFF); 
  ChkSum := ChkSum + (Chksum shr 16); 
 
  Result := Word(ChkSum); 
end; 
 
 
procedure BuildHeaders( 
  FromIP      : String; 
  iFromPort   : Word; 
  ToIP        : String; 
  iToPort     : Word; 
  StrMessage  : String; 
  Var Buf         : TPacketBuffer; 
  Var remote      : TSockAddr; 
  Var iTotalSize  : Word 
); 
Var 
  dwFromIP    : LongWord; 
  dwToIP      : LongWord; 
 
  iIPVersion  : Word; 
  iIPSize     : Word; 
  ipHdr       : T_IP_Header; 
  udpHdr      : T_UDP_Header; 
 
  iUdpSize    : Word; 
  iUdpChecksumSize : Word; 
  cksum       : Word; 
 
  Ptr         : ^Byte; 
 
  procedure IncPtr(Value : Integer); 
  begin 
    ptr := pointer(integer(ptr) + Value); 
  end; 
 
begin 
   // преобразуем ip адреса 
 
   dwFromIP    := inet_Addr(PChar(FromIP)); 
   dwToIP      := inet_Addr(PChar(ToIP)); 
 
    // Инициализируем заголовок IP пакета 
    // 
    iTotalSize := sizeof(ipHdr) + sizeof(udpHdr) + length(strMessage); 
 
    iIPVersion := 4; 
    iIPSize := sizeof(ipHdr) div sizeof(LongWord); 
    // 
    // IP version goes in the high order 4 bits of ip_verlen. The 
    // IP header length (in 32-bit words) goes in the lower 4 bits. 
    // 
    ipHdr.ip_verlen := (iIPVersion shl 4) or iIPSize; 
    ipHdr.ip_tos := 0;                          // IP type of service 
    ipHdr.ip_totallength := htons(iTotalSize); // Total packet len 
    ipHdr.ip_id := 0;                  // Unique identifier: set to 0 
    ipHdr.ip_offset := 0;              // Fragment offset field 
    ipHdr.ip_ttl := 128;              // время жизни пакета 
    ipHdr.ip_protocol := $11;          // Protocol(UDP) 
    ipHdr.ip_checksum := 0 ;          // IP checksum 
    ipHdr.ip_srcaddr := dwFromIP;     // Source address 
    ipHdr.ip_destaddr := dwToIP;      // Destination address 
    // 
    // Инициализируем заголовок UDP пакета 
    // 
    iUdpSize := sizeof(udpHdr) + length(strMessage); 
 
    udpHdr.src_portno := htons(iFromPort) ; 
    udpHdr.dst_portno := htons(iToPort) ; 
    udpHdr.udp_length := htons(iUdpSize) ; 
    udpHdr.udp_checksum := 0 ; 
    // 
    // Build the UDP pseudo-header for calculating the UDP checksum. 
    // The pseudo-header consists of the 32-bit source IP address, 
    // the 32-bit destination IP address, a zero byte, the 8-bit 
    // IP protocol field, the 16-bit UDP length, and the UDP 
    // header itself along with its data (padded with a 0 if 
    // the data is odd length). 
    // 
    iUdpChecksumSize := 0; 
 
    ptr := @buf[0]; 
    FillChar(Buf, SizeOf(Buf), 0); 
 
    Move(ipHdr.ip_srcaddr, ptr^, SizeOf(ipHdr.ip_srcaddr)); 
    IncPtr(SizeOf(ipHdr.ip_srcaddr)); 
 
    iUdpChecksumSize := iUdpChecksumSize + sizeof(ipHdr.ip_srcaddr); 
 
    Move(ipHdr.ip_destaddr, ptr^, SizeOf(ipHdr.ip_destaddr)); 
    IncPtr(SizeOf(ipHdr.ip_destaddr)); 
 
    iUdpChecksumSize := iUdpChecksumSize + sizeof(ipHdr.ip_destaddr); 
 
    IncPtr(1); 
 
    Inc(iUdpChecksumSize); 
 
    Move(ipHdr.ip_protocol, ptr^, sizeof(ipHdr.ip_protocol)); 
    IncPtr(sizeof(ipHdr.ip_protocol)); 
    iUdpChecksumSize := iUdpChecksumSize + sizeof(ipHdr.ip_protocol); 
 
    Move(udpHdr.udp_length, ptr^, sizeof(udpHdr.udp_length)); 
    IncPtr(sizeof(udpHdr.udp_length)); 
    iUdpChecksumSize := iUdpChecksumSize + sizeof(udpHdr.udp_length); 
 
    move(udpHdr, ptr^, sizeof(udpHdr)); 
    IncPtr(sizeof(udpHdr)); 
    iUdpChecksumSize := iUdpCheckSumSize + sizeof(udpHdr); 
 
    Move(StrMessage[1], ptr^, Length(strMessage)); 
    IncPtr(Length(StrMessage)); 
 
    iUdpChecksumSize := iUdpChecksumSize + length(strMessage); 
 
    cksum := checksum(buf, iUdpChecksumSize); 
    udpHdr.udp_checksum := cksum; 
 
    // 
    // Now assemble the IP and UDP headers along with the data 
    //  so we can send it 
    // 
    FillChar(Buf, SizeOf(Buf), 0); 
    Ptr := @Buf[0]; 
 
    Move(ipHdr, ptr^, SizeOf(ipHdr));      IncPtr(SizeOf(ipHdr)); 
    Move(udpHdr, ptr^, SizeOf(udpHdr));    IncPtr(SizeOf(udpHdr)); 
    Move(StrMessage[1], ptr^, length(StrMessage)); 
 
    // Apparently, this SOCKADDR_IN structure makes no difference. 
    // Whatever we put as the destination IP addr in the IP header 
    // is what goes. Specifying a different destination in remote 
    // will be ignored. 
    // 
    remote.sin_family := AF_INET; 
    remote.sin_port := htons(iToPort); 
    remote.sin_addr.s_addr := dwToIP; 
end; 
 
procedure TForm1.SendIt; 
Var 
  sh          : TSocket; 
  bOpt        : Integer; 
  ret         : Integer; 
  Buf         : TPacketBuffer; 
  Remote      : TSockAddr; 
  Local       : TSockAddr; 
  iTotalSize  : Word; 
  wsdata      : TWSAdata; 
 
begin 
  // Startup Winsock 2 
  ret := WSAStartup($0002, wsdata); 
  if ret<>0 then begin 
    memo1.lines.add('WSA Startup failed.'); 
    exit; 
  end; 
  with memo1.lines do begin 
    add('WSA Startup:'); 
    add('Desc.:  '+wsData.szDescription); 
    add('Status: '+wsData.szSystemStatus); 
  end; 
 
  try 
    // Создаём сокет 
    sh := Socket(AF_INET, SOCK_RAW, IPPROTO_UDP); 
    if (sh = INVALID_SOCKET) then begin 
      memo1.lines.add('Socket() failed: '+IntToStr(WSAGetLastError)); 
      exit; 
    end; 
    Memo1.lines.add('Socket Handle = '+IntToStr(sh)); 
 
    // Option: Header Include 
    bOpt := 1; 
    ret := SetSockOpt(sh, IPPROTO_IP, IP_HDRINCL, @bOpt, SizeOf(bOpt)); 
    if ret = SOCKET_ERROR then begin 
      Memo1.lines.add('setsockopt(IP_HDRINCL) failed: '+IntToStr(WSAGetLastError)); 
      exit; 
    end; 
 
    // строим пакет 
    BuildHeaders( SrcIP,  SrcPort, 
                  DestIP, DestPort, 
                  'THIS IS A TEST PACKET', 
                  Buf, Remote, iTotalSize ); 
 
    // Отправляем пакет 
    ret := SendTo(sh, buf, iTotalSize, 0, Remote, SizeOf(Remote)); 
    if ret = SOCKET_ERROR then 
      Memo1.Lines.Add('sendto() failed: '+IntToStr(WSAGetLastError)) 
     else 
      Memo1.Lines.Add('send '+IntToStr(ret)+' bytes.'); 
 
    // Закрываем сокет 
    CloseSocket(sh); 
  finally 
    // Закрываем Winsock 2 
    WSACleanup; 
  end; 
end; 
 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  SendIt; 
end; 
 
end.

Взято из https://forum.sources.ru