Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> LSP 
:(
    Опции темы
ButtonOFF
Дата 21.11.2009, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


улетевший
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 16.11.2009

Репутация: нет
Всего: нет



Нужно создать LSP модуль. Полазив по японско-китайским сайтам и http://www.microsoft.com/msj/0599/LayeredS...redService.aspx ... пишут что бы установить Layer (провайдер имеющий ChainLen = 0) нужно создать также Chain с ссылкой на наш Layer и дальше на базовый протокол, а сам Chain разместить поверх базового протокола. Вот накатал инсталялку, создает в каталоге обе записи о Layer'е и Chain'е. Chain для задуманной функциональности необходимо поставить поверх ТСП/ИП программой SpOrder.Exe.

Вот сам код
Код

procedure TForm1.Button1Click(Sender: TObject);
const
  Layer = '==LAYER==';
  Chain = '==CHAIN==';
var
  EnumProto, LayerBuf, ChainBuf : LPWSAPROTOCOL_INFOW;
  WSAData: TWSADATA;
  LayerID, BaseID, Count, Error, i : Integer;
  len, oldprotect: dword;
  s : string;
begin
  WSAStartup($202, WSAData);
  Len := $ffff;
  GetMem(EnumProto, Len);
  Count := WSCEnumProtocols(nil, EnumProto, Len, Error);
  for i:=0 to Count-1 do begin
    // Ищем MSAFD Tcpip [TCP/IP] (или любой другой протокол)
    if String(EnumProto.szProtocol) = 'MSAFD Tcpip [TCP/IP]'  then begin
      LayerBuf := VirtualAlloc(0, SizeOf(TWSAPROTOCOL_INFOW), MEM_COMMIT, PAGE_READWRITE);
      // Копируем TWSAPROTOCOL_INFOW MSAFD Tcpip [TCP/IP], чтоб меньше движений делать
      Move(EnumProto, LayerBuf, SizeOf(TWSAPROTOCOL_INFOW));
      Break;
    end;
    EnumProto := Pointer(dword(EnumProto)+SizeOf(TWSAPROTOCOL_INFOW));
  end;
  LayerBuf.dwProviderFlags := PFL_HIDDEN ; // флаг для Layer
  LayerBuf.ProviderId := LayerGUID;
  LayerBuf.ProtocolChain.ChainLen := 0; // Указывает что это LSP
  FillChar(LayerBuf.szProtocol, 256, 0);
  Move(WideString(Layer),LayerBuf.szProtocol, length(Layer)*2);
  if WSCInstallProvider(LayerGUID, PWideChar(WideString('C:\Temp\LSP.dll')), LayerBuf, 1, Error) = 0 then
    MessageBox(0, PChar('Layer installed'),PChar('Install'), MB_ICONINFORMATION)
  else begin
    case Error of
      WSAEFAULT: s := 'WSAEFAULT: One or more of the arguments is not in a valid part of the user address space.';
      WSAEINVAL: s := 'WSAEINVAL: One or more of the arguments are invalid.';
      WSAENOBUFS: s := 'WSAENOBUFS: Memory cannot be allocated for buffers.';
      WSANO_RECOVERY: s := 'WSANO_RECOVERY: The provider is already installed.';
      WSASYSCALLFAILURE: s := 'WSASYSCALLFAILURE: A system call that should never fail has failed.';
      WSA_NOT_ENOUGH_MEMORY: s := 'WSA_NOT_ENOUGH_MEMORY: Insufficient memory was available.';
    end;
      MessageBox(0, PChar(s), PChar('Install'), MB_ICONERROR);
  end;
  GetMem(EnumProto, Len);
  Count := WSCEnumProtocols(nil, EnumProto, Len, Error);
  for i:=0 to Count-1 do begin
    // Ищем MSAFD Tcpip [TCP/IP]
    if String(EnumProto.szProtocol) = 'MSAFD Tcpip [TCP/IP]'  then begin
      BaseID := EnumProto.dwCatalogEntryId;  // Запоминаем его EntryId, он нужен для цепочки
      ChainBuf := VirtualAlloc(0, SizeOf(TWSAPROTOCOL_INFOW), MEM_COMMIT, PAGE_READWRITE);
      // Копируем прокол инфо чтоб меньше движений делать
      Move(EnumProto, ChainBuf, SizeOf(TWSAPROTOCOL_INFOW));
      Break;
    end;
    EnumProto := Pointer(dword(EnumProto)+SizeOf(TWSAPROTOCOL_INFOW));
  end;
  GetMem(EnumProto, Len);
  Count := WSCEnumProtocols(nil, EnumProto, Len, Error);
  // Нужно найти EntryId нашего Layer'a чтоб вставить в цепочку
  for i:=0 to Count-1 do begin
    if String(EnumProto.szProtocol) = Layer then begin
      LayerID := EnumProto.dwCatalogEntryId;
      Break;
    end;
    EnumProto := Pointer(dword(EnumProto)+SizeOf(TWSAPROTOCOL_INFOW));
  end;
// делаем цепочку
  ChainBuf.ProtocolChain.ChainLen := 2; 
  ChainBuf.ProtocolChain.ChainEntries[0] := LayerID;
  ChainBuf.ProtocolChain.ChainEntries[1] := BaseID;
  CHainBuf.ProviderId := ChainGUID;
  FillChar(ChainBuf.szProtocol, 256, 0);
  Move(WideString(Chain),ChainBuf.szProtocol, length(Chain)*2);
  if WSCInstallProvider(ChainGUID, PWideChar(WideString('C:\Temp\LSP.dll')), ChainBuf, 1, Error) = 0 then
    MessageBox(0, PChar('Layer installed'),PChar('Install'), MB_ICONINFORMATION)
  else begin
    case Error of
      WSAEFAULT: s := 'WSAEFAULT: One or more of the arguments is not in a valid part of the user address space.';
      WSAEINVAL: s := 'WSAEINVAL: One or more of the arguments are invalid.';
      WSAENOBUFS: s := 'WSAENOBUFS: Memory cannot be allocated for buffers.';
      WSANO_RECOVERY: s := 'WSANO_RECOVERY: The provider is already installed.';
      WSASYSCALLFAILURE: s := 'WSASYSCALLFAILURE: A system call that should never fail has failed.';
      WSA_NOT_ENOUGH_MEMORY: s := 'WSA_NOT_ENOUGH_MEMORY: Insufficient memory was available.';
    end;
      MessageBox(0, PChar(s), PChar('Install'), MB_ICONERROR);
  end;
end;

Сам lsp модуль
Код

library LSP;

uses
  Windows, SysUtils, Classes, WinSock2, WS2spi, SyncObjs, Messages,
  LSPStructures in 'LSPStructures.pas',
  Overlapped in 'Overlapped.pas';

const
  Layer = '==LAYER==';
{$R *.res}

var
  NextProcTable: LPWSPPROC_TABLE;
  glCS:TCriticalSection;
  cOverlapped: TOverlapped;

function WSPRecv(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD;
    var lpNumberOfBytesRecvd, lpFlags: DWORD; lpOverlapped: LPWSAOVERLAPPED;
    lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE; lpThreadId: LPWSATHREADID;
    var lpErrno: Integer): Integer; stdcall;
begin
result := NextProcTable.lpWSPRecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,
                                lpFlags,lpOverlapped,lpCompletionRoutine,lpThreadId,
                                lpErrno);
end;

function WSPStartup(wVersionRequested: WORD; lpWSPData: LPWSPDATA;
  lpProtocolInfo: LPWSAPROTOCOL_INFOW; UpcallTable: WSPUPCALLTABLE;
  lpProcTable: LPWSPPROC_TABLE): Integer; stdcall;
var
  Count, Error, i, iLen: integer;
  EnumBuf: LPWSAPROTOCOL_INFOW;
  Len, LayerID, NextLayerID, hDLL: dword;
  wDllPath, DllPath: PWideChar;
  WSPStartupFunc: LPWSPSTARTUP;
begin
  Len := $ffff;
  GetMem(EnumBuf, Len);
  Count := WSCEnumProtocols(nil, EnumBuf, Len, Error);
  // Ищем свой номерок в каталоге
  for i:=0 to count-1 do begin
    if string(EnumBuf.szProtocol) = Layer then begin
      LayerID := EnumBuf.dwCatalogEntryId;
      break;
    end;
    EnumBuf := Pointer(Dword(EnumBuf)+SizeOf(TWSAPROTOCOL_INFOW));
  end;
  // Ищем следующего провайдера относительно нас
  for i:=0 to lpProtocolInfo.ProtocolChain.ChainLen-1 do begin
    if lpProtocolInfo.ProtocolChain.ChainEntries[i] = LayerID then begin
      NextLayerID := lpProtocolInfo.ProtocolChain.ChainEntries[i+1];
      break;
    end;
  end;
  GetMem(EnumBuf, Len);
  Count := WSCEnumProtocols(nil, EnumBuf, Len, Error);
  for i:=0 to count-1 do begin
    if EnumBuf.dwCatalogEntryId = NextLayerID then begin
      iLen := 256;
      GetMem(DllPath, iLen);
      WSCGetProviderPath(EnumBuf.ProviderId, DllPath, iLen, Error);
      GetMem(wDllPath, iLen);
      ExpandEnvironmentStringsW(DllPath, wDllPath, iLen);
      Break;
    end;
    EnumBuf := Pointer(Dword(EnumBuf)+SizeOf(TWSAPROTOCOL_INFOW));
  end;
  hDLL := LoadLibraryW(wDllPath);
  WSPStartupFunc := LPWSPSTARTUP(GetProcAddress(hDLL,Pchar('WSPStartup')));
  result := WSPStartupFunc(wVersionRequested, lpWSPData, lpProtocolInfo, UpcallTable, lpProcTable);
  NextProcTable := lpProcTable;
  lpProcTable.lpWSPRecv := WSPRecv;
end;

procedure DllMain(dwReason : DWORD);
begin
  case dwReason of
    DLL_PROCESS_ATTACH :
      begin
        cOverlapped := TOverlapped.create;
        glCS := TCriticalSection.Create;
      end;
    DLL_PROCESS_DETACH :
      begin
      end;
    DLL_THREAD_ATTACH :
      begin
      end;
    DLL_THREAD_DETACH :
      begin
      end;
  end;
end;

exports
  WSPStartup;

begin
  DLLProc := @DLLMain;
  DLLMain(DLL_PROCESS_ATTACH);
end.

Такой код отрубает винсок )) для восстановления нужно в командной строке написать netsh winsock reset, либо удалить провайдер функцией WSCDeinstallProvider, либюо использовать утилиту LSPFix.exe или другую, коих множество, на край можно самому написать.
Так вот проблема я думаю в длл, нужно ее как-то по другому сделать, и вообще принцип построения LSD-DLL непонятен. Нужно передать параметры кому откуда, непонятно, запарка в WSPStartUp. 

Кажется разобрался, при вызове функции socket, винсок по заданным параметрам ищет удовлетворяющего запрос, этот провайдер смотрит нет ли в его цепочки lsp, и если есть вызывает Wspstartup следущего провайдера и т.д. "Пустая" Dll-lsp работает нормально, т.е установленая поверх базового провайдера, вызывается и передает управление следующему, если я указываю ссылку на мою функцию например WSPRecv, для этого нужно задать адрес нашей функции в lpProcTable, происходит перехват, вызов моей функции, но при этом связь с инетом прерывается, помогите найти ошибку.



Это сообщение отредактировал(а) ButtonOFF - 22.11.2009, 14:16
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0428 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.