PDA

Просмотр полной версии : проблема со спуфингом


t04
23.11.2008, 04:29
собрал довольно таки известный в сети код:
unit Spoof;

interface

const
Max_Packet_Size = 4096;

type
TPacketBuffer = Array[0..Max_Packet_Size-1] of byte;

// Заголовок IP пакета
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 пакета
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;

procedure SendPack( const SrcIP,
DestIP : String;
const SrcPort,
DestPort:WORD);

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';

function IntToStr(I: Int64): String;
var
S: String;
begin
Str(I, S);
Result := S;
end;

// 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( const FromIP : String;
const iFromPort : Word;
const ToIP : String;
const iToPort : Word;
const 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 SendPack( const SrcIP,
DestIP : String;
const SrcPort,
DestPort:WORD);
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
WriteLn('WSA Startup failed.');
exit;
end;
WriteLn('WSA Startup:',#13#10,
'Desc.: ',wsData.szDescription,#13#10,
'Status: ',wsData.szSystemStatus);
try
// Создаём сокет
sh := Socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
if (sh = INVALID_SOCKET) then
begin
WriteLn('Socket() failed: '+IntToStr(WSAGetLastError));
exit;
end;
WriteLn('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
WriteLn('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
WriteLn('sendto() failed: '+IntToStr(WSAGetLastError))
else
WriteLn('send '+IntToStr(ret)+' bytes.');
// Закрываем сокет
CloseSocket(sh);
finally
// Закрываем Winsock 2
WSACleanup;
end;
end;

end.
вызываю
SendPack('1.2.3.4','127.0.0.1',7,7);
и получаю ошибку
WSA Startup:
Desc.: WinSock 2.0
Status: Running
Socket Handle = 1960
sendto() failed: 10004

в описании кода ошибки говорится
Системный вызов прерван. Это может произойти, если выполняется вызов сокета, а сокет закрыт
но мне это ничего не говорит %( . как избежать этой ошибки?

criz
23.11.2008, 13:17
Вот тут обсуждали эту ошибку:
http://www.rsdn.ru/Forum/message/2430767.flat.aspx#2430767

t04
24.11.2008, 19:23
по ссылке идет другая ссылка
__http://www.codeproject.com/KB/IP/rawsocket.aspx?df=100&forumid=372728&exp=0&select=1904971#xx1904971xx
как я понял в статье написанно что на XP+SP2 поддержка UDP спуфинга есть. проблема остается открытой

Jes
24.11.2008, 19:52
https://forum.antichat.ru/thread43666.html

Delimiter
24.11.2008, 20:04
Сервис пак 2 на Хрюше закрыл доступ к rawsocket!

_nic
24.11.2008, 20:45
как я понял в статье написанно что на XP+SP2 поддержка UDP спуфинга есть. проблема остается открытой
Я где то давно читал что для этого ещё надо и в реестре покулапатся.

criz
24.11.2008, 21:27
Я где то давно читал что для этого ещё надо и в реестре покулапатся.
Не везде/не всем помогает. Из 10ти сообщений в рунете, видел только одно положительное

t04
25.11.2008, 17:41
ммм, а как можно это реализовать на уровне ядра? то есть как я понимаю надо написать драйвер, вообще как можно представить такую систему? существует ли уже готовая реализация?

bons
25.11.2008, 17:58
юзай WinPCAP.

t04
25.11.2008, 18:18
Быть может существуют уже готовые патчи? кто нить слышал об этом?

0verbreaK
25.11.2008, 19:21
xpsp2tcpipfix.exe - патч поможет с сырыми сокетами

Суть ограничения:
http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/7c815a9d-d8af-4e57-b64a-371002e8487f/

Также хорошим решением является пакет WinPCAP, которые с открытым исходным кодом, документацией, к тому же Delimiter писал на ачате про использование его (правда про ARP так и не закончил)

t04
25.11.2008, 21:44
ммм, а как именно юзать WinPCap?
Где об этом можно почитать?

criz
25.11.2008, 22:14
Тут (http://www.winpcap.org/)
А еще мне в свое время помогли вот эти ссылки:
http://security.h12.ru/docs/windows/arhitektura_zahvata_paketov_dlya_windows_winpcap_( chast_1).htm
http://security.h12.ru/docs/windows/arhitektura_zahvata_paketov_dlya_windows_winpcap_( chast_2).htm
http://security.h12.ru/docs/windows/arhitektura_zahvata_paketov_dlya_windows_winpcap_( chast_3).htm

Примерно с этой темы (http://forum.antichat.ru/threadnav40894-107-10.html) начинаются мои "мучения" с winpcap'ом :)
А потом появилось: RST киллер или все через "призму" WinPCap (http://forum.antichat.ru/showpost.php?p=681701&postcount=5) Спасибо Delimiter'у :)

t04
27.11.2008, 21:25
ссылочки то битые :(
есть зеркала? или може сохранял их?

bons
27.11.2008, 21:55
убери пробелы, которые форум вставил в ссылки и все будет ок

t04
27.11.2008, 22:52
а те что в статье делиметра (там сырцы на слил ру)

вообще опыта нету на Си работы, скачал себе Дев-С++ сижу мозги разминаю.

0verbreaK
27.11.2008, 23:39
Дев-С++ отложи в сторонку лучше поставь себе Microsoft Visual Studio C++ или Borland Builder C++, при всем уважении к GCC

t04
28.11.2008, 00:03
качаю Visual.Studio.2005.Express (вроде там ток с++ если верно понял)
но нашел вроде какуюто библиотеку для делфи
вот линк http://www.misalpina.net/ghost3k/mypcap.zip
не пойму как заюзать. помогите plz

bons
28.11.2008, 01:16
может это тебе поможет
вот исходник генератора пакетов, написал давно и иногда пользуюсь. В файле, имя которого надо передавать в аргументах, должен быть пакет канального уровня - с ethernet заголовком. Также надо указать номер адаптера


//Утилита передает содержимое файла
//напрямую сетевому адаптеру([к]анальный уровень)

program Generator;
{$APPTYPE CONSOLE}
uses windows;
//Описания структур
type packet = packed record
OVERLAPPED: OverLapped;
Buffer: pointer;
Length: cardinal;
Next: pointer;
ulBytesReceived: cardinal;
bIoComplete: boolean;
end;
ADAPTER = packed record
hFile:cardinal;
SymbolicLink: PAnsiChar;
end;

//описания констант
const SIMULTANEOU_READS = 10;
MAX_ETHERNET_FRAME_SIZE = 1513;
Max_Num_Adapter=5;
NDIS_PACKET_TYPE_PROMISCUOUS = $0020;
NumberOfPacket:cardinal=1; //How mutch send Packets

//импортируемые функции
function PacketGetAdapterNames(pStr:pointer; BufferSize:pointer):longint;stdcall;
external 'packet.dll';
function PacketOpenAdapter(AdapterName:pointer):pointer; stdcall;
external 'packet.dll';
function PacketAllocatePacket:pointer; stdcall;
external 'packet.dll';
function PacketSetHwFilter(AdapterObject:pointer; Filter:cardinal):boolean; stdcall;
external 'packet.dll';
procedure PacketInitPacket(lpPacket:pointer; Buffer:pointer; Length:cardinal); stdcall;
external 'packet.dll';
function PacketSetNumWrites(AdapterObject:pointer; nwrites:integer):boolean; stdcall;
external 'packet.dll';
function PacketSendPacket(AdapterObject:pointer; lpPacket:pointer; Sync:boolean):boolean; stdcall;
external 'packet.dll';
procedure PacketFreePacket(lpPacket:pointer); stdcall;
external 'packet.dll';
procedure PacketCloseAdapter(lpAdapter:pointer); stdcall;
external 'packet.dll';

//Описания переменных
var //Список идентификаторов сетевых адаптеров
AdapterList: array[0..Max_Num_Adapter-1, 0..255] of char;
//Список имён сетевых адаптреров
AdapterNameList: array[0..Max_Num_Adapter-1, 0..255]of char;
//Хэндл проекции файла
hMap:cardinal;
//Указатель на область памяти с отображенным файлом
pBuf:pointer;
//Номер используемого адаптера
NAdapter:integer;
//Указательн на структуру сетевого пакета
lppacket:^Packet;
//Указатель на структуру открытого адаптера
lpadapter:^ADAPTER;
//Хэндл файла
hFile:cardinal;
//Буфер для списка адаптеров и их названий
AdapterBuffer:array [0..4095] of char;
dwFileSize:word;
AdapterBufferLength: cardinal;
i,j,n:integer;

begin
//Формирование списка адаптеров
AdapterBufferLength := sizeof(AdapterBuffer);
PacketGetAdapterNames(@AdapterBuffer, @AdapterBufferLength);

n:=0; j:=0;
while AdapterBuffer[j]<>#0 do begin
lstrcpy(@AdapterList[n], @AdapterBuffer[j]);
j:=j+lstrlen(@AdapterBuffer[j])+1;
inc(n);
end;
while AdapterBuffer[j] = #0 do j:=j+1;
for i:=0 to n-1 do begin
lstrcpy(@AdapterNameList[i], @AdapterBuffer[j]);
j:=j+lstrlen(@AdapterBuffer[j]) + 1;
end;

writeln('# Packet Generator on packet.dll');
writeln('# ',n,' adapters detected');
for j:=0 to n-1 do writeln(j+1,'. ', pChar(@AdapterNameList[j]),
' - ', pChar(@AdapterList[j]));
writeln;

if ParamCount<2 then begin
writeln('Usage: generator N_adapter packet_file');
exit;
end;

//Выбор используемого адаптера
if n=1 then NAdapter:=0
else begin

val(ParamStr(1), NAdapter, i);
if (NAdapter>n) or (NAdapter=0) then begin
writeln ('Invalid number');
exit;
end;
NAdapter := NAdapter-1;
end;
writeln('# Selected adapter - ',pChar(@AdapterNameList[NAdapter]));

//Адаптер нужно открыть
lpAdapter := PacketOpenAdapter(@AdapterList[NAdapter]);
if lpadapter.hFile=INVALID_HANDLE_VALUE then begin
writeln('Error open adapter');
exit;
end;

//Перевод адаптера в режим принятия всех пакетов
if not PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_PROMISCUOUS) then begin
writeln('! Could not set promiscuous type');
//PacketCloseAdapter(lpAdapter);
exit;
end;
writeln('# promiscuous type success');

//Выделяется память для пакета
lpPacket:= PacketAllocatePacket;
if lpPacket=nil then begin
writeln('! Could not allocate packet');
//PacketCloseAdapter(lpAdapter);
exit;
end;
writeln('# packet allocated success');

//Открывается файл с пакетом
hFile:=CreateFile(pChar(ParamStr(2)), GENERIC_READ, FILE_SHARE_READ,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if hFile = INVALID_HANDLE_VALUE then begin
writeln('Could not open file');
//PacketFreePacket(lpPacket);
//PacketCloseAdapter(lpAdapter);
exit;
end;
dwFileSize:=GetFileSize(hFile, nil);
hMap:=CreateFileMapping(hFile, nil, PAGE_WRITECOPY, 0, 0, nil);
pBuf:=MapViewOfFile(hMap, FILE_MAP_COPY, 0, 0, 0);
writeln;

writeln('# File open success');
writeln('# File size - ', dwFileSize);

//Инициализация структуры пакета
PacketInitPacket (lppacket, pBuf, dwFileSize);

//Установка количества посылаемых пакетов
PacketSetNumWrites (lpAdapter, NumberOfPacket);
writeln('# Start sending');

PacketSendPacket (lpAdapter, lpPacket,false);
writeln('# All done.');

//Проекция файла уничтожается
UnmapViewOfFile(pBuf);
CloseHandle(hMap);
CloseHandle(hFile);
end.

t04
28.11.2008, 02:53
то есть как я понял надо в [pBuf : pointer;] запихать UDP пакет? или я ошибся (что скорее всего).

bons
28.11.2008, 14:28
да, pBuf по сути есть указатель на буфер с пакетом, в данном случае он заполнен содержимым файла.

slesh
28.11.2008, 15:33
Смотря для каких целей тебе нужны сырые сокеты. Потому что от различный назначений будет выбран метод написания.
1) Просто побалываться - WinPCap подойдет.
2) Если вредоносный софт - тот первый пункт отпадает.
3) Если чтото серьезное, то лучше в ядре.

Если требуется просто послать пакет без подмены адреса, то реализуется везде очень просто и не требует никаких дополнительных фишек.
Да и без подмены адреса отправителя довольно хорошо идет всё наобчном уровне

Если юзать из драйвера, то лучше забей. Гемор еще тот. Потому что если будешь использовать через NDIS(как это делает вроде WinPCap) то слишком много что учесть нужно, начиная от определения адаптера и заканчивая поиском адаптера через который осуществляется маршрутизация. Хотя большинство исходников есть в открытом доступе.
Если юзать TDI с его RawIp - то тут тоже не всё гладко. Создать сырой сокет легко. По аналогии с UDP сокетом. Но вот проблема - перевести его в режим позволяющий отправлять данные вместе с IP заголовком. Это вообще недокументровано. Исходников на эту тему нет ни в ReacOS ни Win2k. Короче гемор.

Также как вариант поищи в инете - есть проект драйвера который слал сырой пакет через NDIS в обход все[ запретов. Проект идет с исходником драйвера и юзермодной прогой. Всё довольно компактно и понятно. И не требует какойлибо мошной установки. Один из аналогов такого проекта
http://www.codeproject.com/KB/IP/sendrawpacket.aspx?display=Print

t04
28.11.2008, 21:35
Программа написанна на Си шарп, висуал студио 2005 экспресс откомпилирует её?

Delimiter
28.11.2008, 23:34
Новые магазины открою и допишу статью про ArpSpoof на WinPCap!

... свои обещания помню 8))

t04
29.11.2008, 01:45
Скажу прямо, мне нужно зафдудить udp сервер (при чем со спуфингом адреса так как на сервере предусмотрена некоторая защита), скорость моего инета оставляет желать лучшего поэтому хочется поднять сеть ботов (вариант со скрытой установкой WinPCap на чужой машине оч. стремный :D ) , если чесно гемор еще тот, на си или асме не писал ничего серьезнее чем "привет мир" (пара готовых проектов которые несколько модифицировал не в счет).

учиться это делать боюсь что будет долго (задача требует скорейшей развязки) но проблема дала толчок к изучению Си.

посмотрел проект что предложил slesh, в принципе ясно что ничего не ясно :(

щас сижу и втыкаю в статью http://www.wasm.ru/article.php?article=apihook_3

но никак не соображу что к чему. завтра попытаюсь как нить собрать все что понял и напишу резалт, думаю без помощи снова не обойдусь :(

Delimiter
29.11.2008, 02:03
... поднять сеть ботов ... если будешь ставить задачу так то никто не откликнется, ведь будут думать что для убийства комара ... ты надумал выплавить пушку!

t04
29.11.2008, 14:02
пемогите перевести на делфи с C#


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
}
}

t04
30.11.2008, 03:44
опыта особого не имею в программировании классов. перевел приблизительно (урезал не нужное) и очень сомневаюсь в верности функции
function TRawEthernet.EnumAdapters:TAdapters;
TAdapters в особый класс не хочу переводить, достаточно record;
надо все по минимуму, заранее спасибо за помощь

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.