Допустим есть какой-то стандартный код, который создаёт соединение по TCP/IP с каким-то сервером в Internet'е: Код (Text): invoke WSAStartup,101h,offset wsadata invoke socket,AF_INET,SOCK_STREAM,0h mov s,eax ... mov sin.sin_addr.s_addr,eax mov sin.sin_port,PORT mov sin.sin_family,AF_INET invoke clear,memheap invoke connect,s,addr sin,sizeof(sockaddr_in) .if eax==0h ... ... invoke send,s,memheap,eax,0h Допустим мы скачали TOR http://www.torproject.org! Допустим мы даже знаем как настроить Internet Explorer для работы с TOR, т.е. через Proxy-сервера http://www.torproject.org/docs/tor-doc-web.html.ru! Вопрос: Можно ли каким-нибудь незамысловатым способом сделать так, чтобы наша программуля тоже соединялась с удалённым сервером через Proxy-сервера TOR? Моя догадка: Может быть дело во втором параметре функции connect? invoke connect,s,addr sin,sizeof(sockaddr_in) Т.е. в структуре sockaddr_in? А именно в поле sin_addr? Но туда вроде обычно кладётся адрес сервера, с кем соединяться! Типа так: Код (Text): invoke gethostbyname,eax assume eax:ptr HOSTENT mov eax,[eax].h_addr assume eax:nothing mov eax,[eax] mov eax,[eax] MOV sin.sin_addr.s_addr,eax А как тогда одновременно указать socket'у 2 адреса: адрес proxy-сервера и сервер, с которым надо установить соединение?
1) использовать умные (даже иногда бесплатные) загрузчики-перехватчики, которым указать в кач-ве проксисервера 127.0.0.1 9050 и запускать программу токмо через нее. 2) написать свою ф-цию connect которая сначала будет коннектиться к проксисерверу, обмениваться парой фраз, коннектить проксисервер туда куда надо и возвращаться. Подробнее см. RFC по socks 5.
Код (Text): myconnect proc hWnd,hMemo,hEdit LOCAL s:SOCKET LOCAL memheap:DWORD LOCAL procheap:DWORD LOCAL sin:SOCKADDR_IN invoke GetProcessHeap mov procheap,eax invoke HeapAlloc,eax,HEAP_ZERO_MEMORY,4000h mov memheap,eax invoke WSAStartup,101h,offset wsadata invoke socket,AF_INET,SOCK_STREAM,0h mov s,eax mov eax,memheap invoke SendMessage,hEdit,WM_GETTEXT,50h,eax mov eax,memheap invoke gethostbyname,eax assume eax:ptr HOSTENT mov eax,[eax].h_addr assume eax:nothing mov eax,[eax] mov eax,[eax] mov sin.sin_addr.s_addr,eax mov sin.sin_port,5000h mov sin.sin_family,AF_INET invoke connect,s,addr sin,sizeof(sockaddr_in) .if eax==0h .data CrLf equ 0Dh,0Ah Send_Data db "GET / HTTP/1.1",CrLf db "Accept: */*",CrLf db "Accept-Language: ru",CrLf db "Accept-Encoding: gzip, deflate",CrLf db "If-Modified-Since: Wed, 19 Mar 2008 16:23:38 GMT; length=26538",CrLf db "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)",CrLf db "Host: www.yandex.ru",CrLf db "Connection: Keep-Alive",CrLf db "Cookie: yandexuid=395368511203519150; yabs-frequency=/2/M_4vm2G3v____pF_EG0a0qT8wJa090CdCCen02G3F000//fG8e0mK2WWC0",CrLf,CrLf .code invoke lstrlen,offset Send_Data invoke send,s,offset Send_Data,eax,0h mov eax,memheap invoke recv,s,eax,1000h,0h mov eax,memheap invoke recv,s,eax,1000h,0h mov eax,memheap invoke recv,s,eax,1000h,0h mov eax,memheap invoke recv,s,eax,1000h,0h mov eax,memheap invoke recv,s,eax,1000h,0h invoke shutdown,s,0h invoke closesocket,s invoke WSACleanup .endif invoke HeapFree,procheap,0h,memheap endy: ret myconnect endp Эта функция соединяется по HTTP с каким-то сервером! А сервер посылает в ответ HTML-страничку! Берём из Edit'а имя сервера, потом делаем DNS-запрос и т.д. Код (Text): invoke SendMessage,hEdit,WM_GETTEXT,50h,eax Если вместо, например, www.yandex.ru написать 127.0.0.1 (localhost), то: Код (Text): mov sin.sin_addr.s_addr,eax mov sin.sin_port,5000h mov sin.sin_family,AF_INET invoke connect,s,addr sin,sizeof(sockaddr_in) В eax, который суётся в sin.sin_addr.s_addr находится 0100007Fh, короче, вроде правильно! А функция connect возвращает FFFFFFFFh и ошибку WSAECONNREFUSED (0000274D)! Т.е. даже первый пункт не получается сделать! Т.е. соединиться!!!
Как я понял с сервером, возможно, придётся пообщаться как показано ниже... Но вопрос: Ведь TOR - это программа. Может быть она сама берёт на себя всю эту заботу о Proxy-серверах??? А другая программа (моя разрабатываемая) просто использует TOR! Может быть моей программе и не надо обо всём этом "думать"??? Код (Text): Протокол SOCKS 5 SOCKS 5 расширяет модель SOCKS 4, добавляя к ней поддержку UDP, обеспечение универсальных схем строгой аутентификации и расширяет методы адресации, добавляя поддержку доменных имен и адресов IPv6. Начальное установка связи теперь состоит из следующего: Клиент подключается, и посылает приветствие, которое включает перечень поддерживаемых методов аутентификации Сервер выбирает из них один (или посылает ответ о неудаче запроса, если ни один из предложенных методов не приемлем) В зависимости от выбранного метода, между клиентом и сервером может пройти некоторое количество сообщений Клиент посылает запрос на соединение, аналогично SOCKS 4 Сервер отвечает, аналогично SOCKS 4 Методы аутентификации пронумерованы следующим образом: 0x00 — аутентификация не требуется 0x01 — GSSAPI 0x02 — имя пользователя / пароль 0x03-0x7F — зарезервировано IANA 0x80-0xFE — зарезервировано для методов частного использования Начальное приветствие от клиента: поле 1: номер версии SOCKS (должен быть 0x05 для этой версии) поле 2: количество поддерживаемых методов аутентификации, 1 байт поле 3: номера методы аутентификации, переменная длина, 1 байт для каждого поддерживаемого метода Сервер сообщает о своём выборе: поле 1: Версия SOCKS, 1 байт (0x05 для этой версии) поле 2: выбранный метод аутентификации, 1 байт, или 0xFF, если не было предложено приемлемого метода Последующая идентификация зависит от выбранного метода. Запрос клиента: поле 1: номер версии SOCKS (должен быть 0x05 для этой версии) поле 2: код команды, 1 байт: 0x01 = установка TCP/IP соединения 0x02 = назначение TCP/IP порта (binding) 0x03 = ассоциирование UDP-порта поле 3: зарезервированный байт, должен быть 0x00 поле 4: тип адреса, 1 байт: 0x01 = адрес IPv4 0x03 = имя домена 0x04 = адрес IPv6 поле 5: назначение адреса 4 байта для адреса IPv4 первый байт — длина имени, затем следует имя домена 16 байт для адреса IPv6 поле 6: номер порта, 2 байта Ответ сервера: поле 1: номер версии SOCKS, 1 байт (0x05 для этой версии) поле 2: код ответа, 1 байт: 0x00 = запрос предоставлен 0x01 = ошибка SOCKS-сервера 0x02 = соединение запрещено набором правил 0x03 = сеть недоступна 0x04 = хост недоступен 0x05 = отказ в соединении 0x06 = истечение TTL 0x07 = команда не поддерживается / ошибка протокола 0x08 = тип адреса не поддерживается поле 3: байт зарезервирован, должен быть 0x00 поле 4: тип последующего адреса, 1 байт: 0x01 = адрес IPv4 0x03 = имя домена 0x04 = адрес IPv6 поле 5: назначение адреса 4 байта для адреса IPv4 первый байт — длина имени, затем следует имя домена 16 байт для адреса IPv6 поле 6: номер порта, 2 байта
Эх! Всё! Надо было почитать повнимательнее немного на http://www.torproject.org/docs/tor-doc-web.html.ru! В качестве хоста надо указать localhost, а порт 8118 или 9050! Тогда функция connect вернёт STATUS_SUCCESS и eax==0h! Правда я ещё не понял что дальше-то делать. Я вроде как даже и не с Proxy соединился, а "установил взаимодействие" с TOR, как с программой! Видимо, TOR заботится о том с каким Proxy соединяться!
тор создаёт сок прокси на локальном компутере, привокси цепляется на него и создаёт уже хттп прокси, так что для хттп приложений юзаем 8118 (привокси) для сок 9050 (сам тор)
А ясненько, т.е. если нам нужен только http,то: localhost:8118 А если нам нужен, например, ftp, pop3 или smtp, то: localhost:9050 Как я понял делаем invoke connect с localhost:9050, а затем в полученный SOCKET делаем invoke send и посылаем запрос на соединение в соответствии с SOCKS 5, который описан в RFC 1928! Это я всё себе пока представляю так в теории - на практике, ещё не пробывал...