Смотря для каких целей тебе нужны сырые сокеты. Потому что от различный назначений будет выбран метод написания. 1) Просто побалываться - WinPCap подойдет. 2) Если вредоносный софт - тот первый пункт отпадает. 3) Если чтото серьезное, то лучше в ядре. Если требуется просто послать пакет без подмены адреса, то реализуется везде очень просто и не требует никаких дополнительных фишек. Да и без подмены адреса отправителя довольно хорошо идет всё наобчном уровне Если юзать из драйвера, то лучше забей. Гемор еще тот. Потому что если будешь использовать через NDIS(как это делает вроде WinPCap) то слишком много что учесть нужно, начиная от определения адаптера и заканчивая поиском адаптера через который осуществляется маршрутизация. Хотя большинство исходников есть в открытом доступе. Если юзать TDI с его RawIp - то тут тоже не всё гладко. Создать сырой сокет легко. По аналогии с UDP сокетом. Но вот проблема - перевести его в режим позволяющий отправлять данные вместе с IP заголовком. Это вообще недокументровано. Исходников на эту тему нет ни в ReacOS ни Win2k. Короче гемор. Также как вариант поищи в инете - есть проект драйвера который слал сырой пакет через NDIS в обход все[ запретов. Проект идет с исходником драйвера и юзермодной прогой. Всё довольно компактно и понятно. И не требует какойлибо мошной установки. Один из аналогов такого проекта http://www.codeproject.com/KB/IP/sendrawpacket.aspx?display=Print
Скажу прямо, мне нужно зафдудить udp сервер (при чем со спуфингом адреса так как на сервере предусмотрена некоторая защита), скорость моего инета оставляет желать лучшего поэтому хочется поднять сеть ботов (вариант со скрытой установкой WinPCap на чужой машине оч. стремный ) , если чесно гемор еще тот, на си или асме не писал ничего серьезнее чем "привет мир" (пара готовых проектов которые несколько модифицировал не в счет). учиться это делать боюсь что будет долго (задача требует скорейшей развязки) но проблема дала толчок к изучению Си. посмотрел проект что предложил slesh, в принципе ясно что ничего не ясно щас сижу и втыкаю в статью http://www.wasm.ru/article.php?article=apihook_3 но никак не соображу что к чему. завтра попытаюсь как нить собрать все что понял и напишу резалт, думаю без помощи снова не обойдусь
... поднять сеть ботов ... если будешь ставить задачу так то никто не откликнется, ведь будут думать что для убийства комара ... ты надумал выплавить пушку!
пемогите перевести на делфи с C# Code: using System; using System.Runtime.InteropServices; using System.Text; namespace RawEthernet { class RawEthernet { [STAThread] static void Main(string[] args) { RawEthernet rawether = new RawEthernet(); if (rawether.m_bDriverOpen) { Console.WriteLine("Handle to NDIS Driver: " + rawether.Handle.ToString()); } else { Console.WriteLine("ERROR: NDIS Driver could not be opened\n"); Console.WriteLine("Press enter to exit..."); Console.ReadLine(); return; } AdaptersInfo[] aiAdapters = rawether.EnumerateAdapters(); Console.WriteLine("\nThe following adapters can be used to send packets:"); foreach (AdaptersInfo ai in aiAdapters) { Console.WriteLine("\t" + ai.ToString()); } Console.Write("\nChoose the adapter number that you want to send from: "); int adIndex = Convert.ToInt32(Console.ReadLine()); if (!rawether.BindAdapter(aiAdapters[adIndex].AdapterID)) { Console.WriteLine("ERROR: Could not bind to the adapter.\n"); Console.WriteLine("Press enter to exit..."); Console.ReadLine(); return; } else { Console.WriteLine("\nAdapter " + aiAdapters[adIndex].AdapterID + " is ready for writing...\n"); } // ok, now we are ready to write a raw packet on the adapter // create a generic raw packet (must be at least 16 bytes long) byte[] packet = new byte[] {0xff,0xff,0xff,0xff,0xff,0xff, //destination mac 0x00,0x02,0x3e,0x4c,0x49,0xaa, //source mac 0x08,0x00, //protocol 0x01,0x02,0x03,0x04,0x05,0x06}; //generic data rawether.DoWrite(packet); rawether.DoWrite(packet); rawether.DoWrite(packet); Console.WriteLine("\nPress enter to exit..."); Console.ReadLine(); rawether.CloseDriver(); rawether = null; } #region ATTRIBUTES private string m_sNdisProtDriver = "\\\\.\\\\NdisProt"; private IntPtr m_iHandle = IntPtr.Zero; private bool m_bDriverOpen = false; private bool m_bAdapterBound = false; #endregion ATTIBUTES #region PROPERTIES public IntPtr Handle { get { return this.m_iHandle; } } public bool IsDriverOpen { get { return this.m_bDriverOpen; } } public bool IsAdapterBound { get { return this.m_bAdapterBound; } } #endregion PROPERTIES #region CONSTRUCTOR public RawEthernet() { // Open a handle to the NDIS Device driver this.m_bDriverOpen = this.OpenDriver(); } #endregion CONSTRUCTOR #region METHODS private bool OpenDriver() { this.m_iHandle = CreateFile(this.m_sNdisProtDriver, GENERIC_WRITE|GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if ((int)this.m_iHandle <= 0) { this.m_iHandle = IntPtr.Zero; return false; } return true; } private AdaptersInfo[] EnumerateAdapters() { int adapterIndex = 0; bool validAdapter = true; AdaptersInfo[] aiTemp = new AdaptersInfo[10]; do { byte[] buf = new byte[1024]; uint iBytesRead = 0; NDISPROT_QUERY_BINDING ndisprot = new NDISPROT_QUERY_BINDING(); ndisprot.BindingIndex = (ulong)adapterIndex; uint bufsize = (uint)Marshal.SizeOf(ndisprot); unsafe { fixed (void* vpBuf = buf) { // use the DeviceIoControl API to query the adapters validAdapter = DeviceIoControl(this.m_iHandle, IOCTL_NDISPROT_QUERY_BINDING, (void*)&ndisprot, bufsize, vpBuf, (uint)buf.Length, &iBytesRead, 0); } } if (!validAdapter) break; string tmpinfo = Encoding.Unicode.GetString(buf).Trim((char)0x00); tmpinfo = tmpinfo.Substring(tmpinfo.IndexOf("\\")); aiTemp[adapterIndex].Index = adapterIndex; aiTemp[adapterIndex].AdapterID = tmpinfo.Substring(0, tmpinfo.IndexOf("}")+1); aiTemp[adapterIndex].AdapterName = tmpinfo.Substring( tmpinfo.IndexOf("}")+1).Trim((char)0x00); adapterIndex++; }while (validAdapter || adapterIndex < 10); AdaptersInfo[] aiReturn = new AdaptersInfo[adapterIndex]; for (int i=0;i<aiReturn.Length;i++) aiReturn[i] = aiTemp[i]; return aiReturn; } private bool BindAdapter(string adapterID) { char[] ndisAdapter = new char[256]; int iNameLength = 0, i = 0; for (i=0;i<adapterID.Length;i++) { ndisAdapter[i] = adapterID[i]; iNameLength++; } ndisAdapter[i] = '\0'; uint uiBytesReturned; unsafe { fixed (void* vpNdisAdapter = &ndisAdapter[0]) { // Call the DeviceIoControl API to bind the adapter to the handle return DeviceIoControl(this.m_iHandle, IOCTL_NDISPROT_OPEN_DEVICE, vpNdisAdapter, (uint)(iNameLength*sizeof(char)), null, 0, &uiBytesReturned, 0); } } } private bool CloseDriver() { return CloseHandle(this.m_iHandle); } private bool DoWrite(byte[] packet) { uint uiSentCount = 0; bool packetSent = false; unsafe { fixed (void* pvPacket = packet) { packetSent = WriteFile(this.m_iHandle, pvPacket, (uint)packet.Length, &uiSentCount, 0); } } if (!packetSent) { Console.WriteLine("ERROR: Packet not sent: 0 bytes written"); return false; } Console.WriteLine("Packet sent: " + uiSentCount.ToString() + "bytes written"); return true; } #endregion METHODS #region CONSTANTS private const uint GENERIC_READ = 0x80000000; private const uint GENERIC_WRITE = 0x40000000; private const uint OPEN_EXISTING = 0x00000003; private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; private const int INVALID_HANDLE_VALUE = -1; private const uint IOCTL_NDISPROT_QUERY_BINDING = 0x12C80C; private const uint IOCTL_NDISPROT_OPEN_DEVICE = 0x12C800; #endregion CONSTANTS #region IMPORTS [DllImport("kernel32", SetLastError=true)] private static extern IntPtr CreateFile( string _lpFileName, uint _dwDesiredAccess, uint _dwShareMode, uint _lpSecurityAttributes, uint _dwCreationDisposition, uint _dwFlagsAndAttributes, uint _hTemplateFile); [DllImport("kernel32", SetLastError=true)] private static extern unsafe bool WriteFile( IntPtr _hFile, void* _lpBuffer, uint _nNumberOfBytesToWrite, uint* _lpNumberOfBytesWritten, uint _lpOverlapped); [DllImport("kernel32", SetLastError=true)] private static extern bool CloseHandle( IntPtr _hObject); [DllImport("kernel32", SetLastError=true)] private static extern unsafe bool DeviceIoControl( IntPtr _hDevice, uint _dwIoControlCode, void* _lpInBuffer, uint _nInBufferSize, void* lpOutBuffer, uint _nOutBufferSize, uint* _lpBytesReturned, uint _lpOverlapped); #endregion IMPORTS #region STRUCTS [StructLayout(LayoutKind.Sequential)] private struct NDISPROT_QUERY_BINDING { public ulong BindingIndex; public ulong DeviceNameOffset; public ulong DeviceNameLength; public ulong DeviceDescrOffset; public ulong DeviceDescrLength; } #endregion STRUCTS } public struct AdaptersInfo { #region ATTRIBUTES private int m_iIndex; private string m_sAdapterID; private string m_sAdapterName; #endregion ATTRIBUTES #region PROPERTIES public int Index {get{return m_iIndex;}set{m_iIndex = value;}} public string AdapterID {get{return m_sAdapterID;}set{m_sAdapterID = value;}} public string AdapterName {get{return m_sAdapterName;}set{m_sAdapterName = value;}} #endregion PROPERTIES #region CONSTRUCTOR public AdaptersInfo(int index, string adapterID, string adapterName) { // set the attributes according to the passed args this.m_iIndex = index; this.m_sAdapterID = adapterID; this.m_sAdapterName = adapterName; } #endregion CONSTRUCTOR #region METHODS public override string ToString() { return this.m_iIndex + ". " + this.m_sAdapterID + " - " + this.m_sAdapterName; } #endregion METHODS } }
опыта особого не имею в программировании классов. перевел приблизительно (урезал не нужное) и очень сомневаюсь в верности функции Code: function TRawEthernet.EnumAdapters:TAdapters; TAdapters в особый класс не хочу переводить, достаточно record; надо все по минимуму, заранее спасибо за помощь Code: unit Unit1; interface uses Windows; type NDISPROT_QUERY_BINDING = record BindingIndex : DWORD; // 0-based binding number DeviceNameOffset : DWORD; // from start of this struct DeviceNameLength : DWORD; // in bytes DeviceDescrOffset : DWORD; // from start of this struct DeviceDescrLength : DWORD; // in bytes end; TAdaptor = record Index : Byte; ID : String; Name : String; end; TAdapters = record Adapter : array [0..10] of TAdaptor; Count : Byte; end; TRawEthernet = class private FHandle : DWORD; FDriverOpen : Boolean; FAdapterBound : Boolean; public property Handle:DWORD read FHandle; property IsDriverOpen : Boolean read FDriverOpen; property IsAdapterBound : Boolean read FAdapterBound; procedure DriverInit(const adapterID:String); function SendData(const Data:PChar):Boolean; function CloseDriver:Boolean; function EnumAdapters:TAdapters; end; implementation procedure TRawEthernet.DriverInit(const adapterID:String); const IOCTL_NDISPROT_OPEN_DEVICE = $12C800; var lpBytesReturned : DWORD; begin FHandle := CreateFile('\\.\\NdisProt', GENERIC_WRITE or GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (FHandle=INVALID_HANDLE_VALUE)or(FHandle=0) then FDriverOpen := false else FDriverOpen := true; FAdapterBound := DeviceIoControl( FHandle, IOCTL_NDISPROT_OPEN_DEVICE, @adapterID, Length(adapterID), nil, 0, lpBytesReturned, nil); end; function TRawEthernet.SendData(const Data:PChar):Boolean; var Buf : PChar; lpNumberOfBytesWritten: DWORD; begin lstrcpy(Buf,Data); Result := WriteFile(FHandle, Buf, lstrlen(Buf), lpNumberOfBytesWritten, nil); end; function TRawEthernet.CloseDriver:Boolean; begin Result := CloseHandle(FHandle); end; function TRawEthernet.EnumAdapters:TAdapters; const IOCTL_NDISPROT_QUERY_BINDING = $12C80C; var validAdapter: Boolean; tmpPos : Word; iBytesRead : DWORD; adapterIndex: Integer; ndisprot : NDISPROT_QUERY_BINDING; Buf : PChar; tmpInfo : String; begin adapterIndex := 0; validAdapter := true; repeat iBytesRead := 0; ndisprot.BindingIndex := adapterIndex; try validAdapter := DeviceIoControl(FHandle, IOCTL_NDISPROT_QUERY_BINDING, @ndisprot, SizeOf(bufsize),//что тут надо поставить? @Buf, 1024, iBytesRead, nil); except; end;//после этого вообще бред какой то на мой взгляд if ( not validAdapter) then break; move(Buf,tmpinfo,iBytesRead); Result.Adapter[adapterIndex].Index := adapterIndex; tmpPos := Pos('}',tmpInfo)+1; Result.Adapter[adapterIndex].Name := copy(tmpinfo,1,tmpPos); delete(tmpinfo,1,tmpPos); Result.Adapter[adapterIndex].Name := tmpinfo; Inc(adapterIndex); until (not validAdapter) or (adapterIndex = 10); end; end.