<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=86903&amp;view=findpost&amp;p=644688</guid>
        <pubDate>Mon, 14 Mar 2005 18:46:04 +0000</pubDate>
        <title>Перехват recv</title>
        <link>https://forum.sources.ru/index.php?showtopic=86903&amp;view=findpost&amp;p=644688</link>
        <description><![CDATA[s-mike: Библиотека:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">////////////////////////////////////////////////////////////////////////////////</div><div class="code_line">//</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">// &nbsp;* Unit Name : Changer</div><div class="code_line">// &nbsp;* Purpose &nbsp; : Библиотека для внедрения в удаленный процесс</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: и перехвата функций</div><div class="code_line">// &nbsp;* Author &nbsp; &nbsp;: Александр (Rouse_) Багель</div><div class="code_line">// &nbsp;* Copyright : © Fangorn Wizards Lab 1998 - 2007 г.</div><div class="code_line">// &nbsp;* Version &nbsp; : 1.02</div><div class="code_line">// &nbsp;* Home Page : http://rouse.drkb.ru</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">//</div><div class="code_line">&nbsp;</div><div class="code_line">library Changer;</div><div class="code_line">&nbsp;</div><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;Windows,</div><div class="code_line">&nbsp;&nbsp;Messages,</div><div class="code_line">&nbsp;&nbsp;SysUtils,</div><div class="code_line">&nbsp;&nbsp;Winsock;</div><div class="code_line">&nbsp;</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;GlobMapID = &#39;{84E5CFE5-30F8-425D-8A2C-98CF9530C0A2}&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">const // Константы нотификаций</div><div class="code_line">&nbsp;&nbsp;NOTIFY_DLL_LOAD = 1;</div><div class="code_line">&nbsp;&nbsp;NOTIFY_API_CALL = 2;</div><div class="code_line">&nbsp;&nbsp;NOTIFY_API_INTERCEPT_SUCCESS = 3;</div><div class="code_line">&nbsp;&nbsp;NOTIFY_API_INTERCEPT_FAILED = 4;</div><div class="code_line">&nbsp;&nbsp;NOTIFY_DLL_UNLOAD = 5;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TReplaceStatus = (rsSuccess, rsFailed, rsNotFound);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;</div><div class="code_line">&nbsp;&nbsp;{$EXTERNALSYM PIMAGE_IMPORT_BY_NAME}</div><div class="code_line">&nbsp;&nbsp;_IMAGE_IMPORT_BY_NAME = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Hint: Word;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: array [0..0] of Char;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;{$EXTERNALSYM _IMAGE_IMPORT_BY_NAME}</div><div class="code_line">&nbsp;&nbsp;IMAGE_IMPORT_BY_NAME = _IMAGE_IMPORT_BY_NAME;</div><div class="code_line">&nbsp;&nbsp;{$EXTERNALSYM IMAGE_IMPORT_BY_NAME}</div><div class="code_line">&nbsp;&nbsp;TImageImportByName = IMAGE_IMPORT_BY_NAME;</div><div class="code_line">&nbsp;&nbsp;PImageImportByName = PIMAGE_IMPORT_BY_NAME;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Структура для нотификации приложения</div><div class="code_line">&nbsp;&nbsp;TLogData = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;AppName: ShortString; // Имя приложения</div><div class="code_line">&nbsp;&nbsp; &nbsp;FuncName: String[30]; &nbsp;// Имя функции</div><div class="code_line">&nbsp;&nbsp; &nbsp;FuncPointer: Integer; // Адрес функции</div><div class="code_line">&nbsp;&nbsp; &nbsp;IP: String[15]; &nbsp; &nbsp; &nbsp; // IP адрес</div><div class="code_line">&nbsp;&nbsp; &nbsp;Port: Cardinal; &nbsp; &nbsp; &nbsp; // Порт</div><div class="code_line">&nbsp;&nbsp; &nbsp;Buff: array [0..$FFFF] of Char; // Содержимое буффера</div><div class="code_line">&nbsp;&nbsp; &nbsp;BuffSize: Word; &nbsp; &nbsp; &nbsp; // Размер буфера</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Структура с рабочей информацией хука</div><div class="code_line">&nbsp;&nbsp;PShareInf = ^TShareInf;</div><div class="code_line">&nbsp;&nbsp;TShareInf = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;AppWndHandle: HWND;</div><div class="code_line">&nbsp;&nbsp; &nbsp;OldHookHandle: HHOOK;</div><div class="code_line">&nbsp;&nbsp; &nbsp;hm: THandle;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Структура в которой описываются все перехватываемые фукнции </div><div class="code_line">&nbsp;&nbsp;TInterceptedAPI = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Lib_Name: String;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FuncName: String;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FuncAddr: Pointer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;OrigAddr: Pointer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Replaced: Boolean;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;TInterceptedAPIs = array of TInterceptedAPI;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Структуры для работы с таблицей импорта</div><div class="code_line">&nbsp;&nbsp;TIIDUnion = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;case Integer of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;0: (Characteristics: DWORD);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;1: (OriginalFirstThunk: DWORD);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PImageImportDescriptor = ^TImageImportDescriptor;</div><div class="code_line">&nbsp;&nbsp;TImageImportDescriptor = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Union: TIIDUnion;</div><div class="code_line">&nbsp;&nbsp; &nbsp;TimeDateStamp: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ForwarderChain: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FirstThunk: DWORD;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PImageThunkData = ^TImageThunkData32;</div><div class="code_line">&nbsp;&nbsp;TImageThunkData32 = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;_function : PDWORD;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PWSAEVENT = ^WSAEVENT;</div><div class="code_line">&nbsp;&nbsp;WSAEVENT = THandle;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;{ WinSock 2 extension -- WSABUF and QOS struct, include qos.h }</div><div class="code_line">&nbsp;&nbsp;{ to pull in FLOWSPEC and related definitions }</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;WSABUF = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;len: U_LONG; &nbsp;{ the length of the buffer }</div><div class="code_line">&nbsp;&nbsp; &nbsp;buf: PChar; { the pointer to the buffer }</div><div class="code_line">&nbsp;&nbsp;end {WSABUF};</div><div class="code_line">&nbsp;&nbsp;PWSABUF = ^WSABUF;</div><div class="code_line">&nbsp;&nbsp;LPWSABUF = PWSABUF;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TServiceType = LongInt;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TFlowSpec = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;TokenRate, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // In Bytes/sec</div><div class="code_line">&nbsp;&nbsp; &nbsp;TokenBucketSize, &nbsp; &nbsp; &nbsp; &nbsp; // In Bytes</div><div class="code_line">&nbsp;&nbsp; &nbsp;PeakBandwidth, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // In Bytes/sec</div><div class="code_line">&nbsp;&nbsp; &nbsp;Latency, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // In microseconds</div><div class="code_line">&nbsp;&nbsp; &nbsp;DelayVariation : LongInt;// In microseconds</div><div class="code_line">&nbsp;&nbsp; &nbsp;ServiceType : TServiceType;</div><div class="code_line">&nbsp;&nbsp; &nbsp;MaxSduSize, MinimumPolicedSize : LongInt;// In Bytes</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;PFlowSpec = ^TFLOWSPEC;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;QOS = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;SendingFlowspec: TFlowSpec; { the flow spec for data sending }</div><div class="code_line">&nbsp;&nbsp; &nbsp;ReceivingFlowspec: TFlowSpec; { the flow spec for data receiving }</div><div class="code_line">&nbsp;&nbsp; &nbsp;ProviderSpecific: WSABUF; { additional provider specific stuff }</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;TQualityOfService = QOS;</div><div class="code_line">&nbsp;&nbsp;PQOS = ^QOS;</div><div class="code_line">&nbsp;&nbsp;LPQOS = PQOS;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;_OVERLAPPED = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Internal: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;InternalHigh: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Offset: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;OffsetHigh: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;hEvent: THandle;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;PWSAOverlapped &nbsp;= ^_OVERLAPPED;</div><div class="code_line">&nbsp;&nbsp;LPWSAOVERLAPPED = PWSAOverlapped;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;LPCONDITIONPROC = function(lpCallerId: LPWSABUF; lpCallerData: LPWSABUF;</div><div class="code_line">&nbsp;&nbsp; &nbsp;lpSQOS, lpGQOS: LPQOS; lpCalleeId, lpCalleeData: LPWSABUF;</div><div class="code_line">&nbsp;&nbsp; &nbsp;g: DWORD; dwCallbackData: DWORD): Integer; stdcall;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;LPWSAOVERLAPPED_COMPLETION_ROUTINE =</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure(const dwError, cbTransferred: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;const lpOverlapped: LPWSAOVERLAPPED;</div><div class="code_line">&nbsp;&nbsp; &nbsp;const dwFlags: DWORD); stdcall;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;function ImageDirectoryEntryToData(Base: Pointer; MappedAsImage: ByteBool;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DirectoryEntry: Word; var Size: ULONG): Pointer; stdcall; external &#39;imagehlp.dll&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;MapHandle: THandle = 0;</div><div class="code_line">&nbsp;&nbsp;ShareInf: PShareInf = nil;</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs: TInterceptedAPIs;</div><div class="code_line">&nbsp;&nbsp;Data: TLogData;</div><div class="code_line">&nbsp;&nbsp;AppTitle: ShortString;</div><div class="code_line">&nbsp;</div><div class="code_line">// &nbsp;Перехват API посредством подмены в таблице импорта</div><div class="code_line">// =============================================================================</div><div class="code_line">function ReplaceIATEntry(const OldProc, NewProc: FARPROC): TReplaceStatus;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;ImportEntry: PImageImportDescriptor;</div><div class="code_line">&nbsp;&nbsp;Thunk: PImageThunkData;</div><div class="code_line">&nbsp;&nbsp;Protect, newProtect: DWORD;</div><div class="code_line">&nbsp;&nbsp;ImageBase: Cardinal;</div><div class="code_line">&nbsp;&nbsp;DOSHeader: PImageDosHeader;</div><div class="code_line">&nbsp;&nbsp;NTHeader: PImageNtHeaders;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result := rsNotFound;</div><div class="code_line">&nbsp;&nbsp;if OldProc = nil then Exit;</div><div class="code_line">&nbsp;&nbsp;if NewProc = nil then Exit;</div><div class="code_line">&nbsp;&nbsp;ImageBase := GetModuleHandle(nil);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Зная структуру PE заголовка - находим начало таблицы импорта</div><div class="code_line">&nbsp;&nbsp;DOSHeader := PImageDosHeader(ImageBase);</div><div class="code_line">&nbsp;&nbsp;if IsBadReadPtr(Pointer(ImageBase), SizeOf(TImageNtHeaders)) then Exit;</div><div class="code_line">&nbsp;&nbsp;if (DOSHeader^.e_magic &#60;&#62; IMAGE_DOS_SIGNATURE) then Exit;</div><div class="code_line">&nbsp;&nbsp;NTHeader := PImageNtHeaders(DWORD(DOSHeader) + DWORD(DOSHeader^._lfanew));</div><div class="code_line">&nbsp;&nbsp;if NTHeader^.Signature &#60;&#62; IMAGE_NT_SIGNATURE then Exit;</div><div class="code_line">&nbsp;&nbsp;ImportEntry := PImageImportDescriptor(DWORD(ImageBase) +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DWORD(NTHeader^.OptionalHeader.DataDirectory[</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));</div><div class="code_line">&nbsp;&nbsp;if DWORD(ImportEntry) = DWORD(NTHeader) then Exit;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;if ImportEntry &#60;&#62; nil then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Бежим по записям таблицы ...</div><div class="code_line">&nbsp;&nbsp; &nbsp;while ImportEntry^.Name &#60;&#62; 0 do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Thunk := PImageThunkData(DWORD(ImageBase) +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DWORD(ImportEntry^.FirstThunk));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// ... пока таблица не кончится ...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;while Thunk^._function &#60;&#62; nil do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// ... или не найдем нужную нам запись.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (Thunk^._function = OldProc) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result := rsFailed;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Производим подмену, сначала так...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if not IsBadWritePtr(@Thunk^._function, sizeof(DWORD)) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Thunk^._function := NewProc;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result := rsSuccess;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin // ... ну а если не получилось - тогда вот так</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if VirtualProtect(@Thunk^._function, SizeOf(DWORD),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PAGE_EXECUTE_READWRITE, Protect) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Thunk^._function := NewProc;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;newProtect := Protect;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;VirtualProtect(@Thunk^._function, SizeOf(DWORD),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;newProtect, Protect);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result := rsSuccess;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Inc(PChar(Thunk), SizeOf(TImageThunkData32));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ImportEntry := Pointer(Integer(ImportEntry) + SizeOf(TImageImportDescriptor));</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// &nbsp;Функция которая будет работать вместо оригинальной Recv ...</div><div class="code_line">// =============================================================================</div><div class="code_line">function InterceptedRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TrecvImage = function(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;CDS: TCopyDataStruct;</div><div class="code_line">&nbsp;&nbsp;SockAddr: TSockAddr;</div><div class="code_line">&nbsp;&nbsp;AddrLen: Integer;</div><div class="code_line">&nbsp;&nbsp;Data: TLogData;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Первоначально вызываем оригинальную функцию, но данные будем писать в свой буффер...</div><div class="code_line">&nbsp;&nbsp;Result := TrecvImage(InterceptedAPIs[0].OrigAddr)(s, Data.Buff[0], len, flags);</div><div class="code_line">&nbsp;&nbsp;// Получаем информацию кто с кем связался</div><div class="code_line">&nbsp;&nbsp;if getpeername(s, SockAddr, AddrLen) &#60;&#62; SOCKET_ERROR then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Data.IP := inet_ntoa(SockAddr.sin_addr);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Data.Port := ntohs(SockAddr.sin_port);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Data.BuffSize := Result;</div><div class="code_line">&nbsp;&nbsp;Data.AppName := AppTitle;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Тут можно встроить проверку (к примеру по какому нибудь порту)</div><div class="code_line">&nbsp;&nbsp;if True then</div><div class="code_line">&nbsp;&nbsp; &nbsp;Move(Data.Buff[0], Buf, Result) // проверка успешна - пишем в буфер полученные данные</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := SOCKET_ERROR; &nbsp; &nbsp; &nbsp; &nbsp; // в противном случае говорим что вызов неуспешен.</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Отправляем полученные данные нашему приложению...</div><div class="code_line">&nbsp;&nbsp;CDS.dwData := NOTIFY_API_CALL;</div><div class="code_line">&nbsp;&nbsp;CDS.cbData := SizeOf(TLogData);</div><div class="code_line">&nbsp;&nbsp;CDS.lpData := @Data;</div><div class="code_line">&nbsp;&nbsp;SendMessage(ShareInf^.AppWndHandle, WM_COPYDATA, 0, Integer(@CDS));</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// &nbsp;Функция которая будет работать вместо оригинальной WSARecv ...</div><div class="code_line">// =============================================================================</div><div class="code_line">function InterceptedWSARecv(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD;</div><div class="code_line">&nbsp;&nbsp;var lpNumberOfBytesRecvd: DWORD; dwFlags: DWORD; lpOverlapped: LPWSAOVERLAPPED;</div><div class="code_line">&nbsp;&nbsp;lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TWSARecvImage = function(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD;</div><div class="code_line">&nbsp;&nbsp; &nbsp;var lpNumberOfBytesRecvd: DWORD; dwFlags: DWORD; lpOverlapped: LPWSAOVERLAPPED;</div><div class="code_line">&nbsp;&nbsp; &nbsp;lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;CDS: TCopyDataStruct;</div><div class="code_line">&nbsp;&nbsp;SockAddr: TSockAddr;</div><div class="code_line">&nbsp;&nbsp;AddrLen, I, Offset: Integer;</div><div class="code_line">&nbsp;&nbsp;Data: TLogData;</div><div class="code_line">&nbsp;&nbsp;TmpBuffers: LPWSABUF;</div><div class="code_line">&nbsp;&nbsp;TmpBuffer: PChar;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Первоначально вызываем оригинальную функцию, но данные будем писать в свой буффер...</div><div class="code_line">&nbsp;&nbsp;Result := TWSARecvImage(InterceptedAPIs[1].OrigAddr)(s, lpBuffers,</div><div class="code_line">&nbsp;&nbsp; &nbsp;dwBufferCount, lpNumberOfBytesRecvd, dwFlags,</div><div class="code_line">&nbsp;&nbsp; &nbsp;lpOverlapped, lpCompletionRoutine);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Получаем информацию кто с кем связался</div><div class="code_line">&nbsp;&nbsp;if getpeername(s, SockAddr, AddrLen) &#60;&#62; SOCKET_ERROR then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Data.IP := inet_ntoa(SockAddr.sin_addr);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Data.Port := ntohs(SockAddr.sin_port);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Data.BuffSize := lpNumberOfBytesRecvd;</div><div class="code_line">&nbsp;&nbsp;Data.AppName := AppTitle;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Тут можно встроить проверку (к примеру по какому нибудь порту)</div><div class="code_line">&nbsp;&nbsp;if True then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Offset := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;TmpBuffers := lpBuffers;</div><div class="code_line">&nbsp;&nbsp; &nbsp;for I := 0 to dwBufferCount - 1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// проверка успешна - пишем в буфер полученные данные</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Move(TmpBuffers^.buf^, Data.Buff[Offset], TmpBuffers^.len);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Inc(TmpBuffers);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Inc(Offset, TmpBuffers^.len);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;end</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := SOCKET_ERROR; &nbsp; &nbsp; &nbsp; &nbsp; // в противном случае говорим что вызов неуспешен.</div><div class="code_line">&nbsp;&nbsp; &nbsp;TmpBuffers := lpBuffers;</div><div class="code_line">&nbsp;&nbsp; &nbsp;for I := 0 to dwBufferCount - 1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TmpBuffer := TmpBuffers^.buf;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for Offset := 0 to TmpBuffers^.len - 1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TmpBuffer^ := #0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Inc(TmpBuffer);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;lpNumberOfBytesRecvd := 0; &nbsp; </div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Отправляем полученные данные нашему приложению...</div><div class="code_line">&nbsp;&nbsp;CDS.dwData := NOTIFY_API_CALL;</div><div class="code_line">&nbsp;&nbsp;CDS.cbData := SizeOf(TLogData);</div><div class="code_line">&nbsp;&nbsp;CDS.lpData := @Data;</div><div class="code_line">&nbsp;&nbsp;SendMessage(ShareInf^.AppWndHandle, WM_COPYDATA, 0, Integer(@CDS));</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// &nbsp;Функция которая будет работать вместо оригинальной WSARecvEx ...</div><div class="code_line">// =============================================================================</div><div class="code_line">function InterceptedWSARecvEx(s: TSocket; var Buf; len: Integer;</div><div class="code_line">&nbsp;&nbsp;var flags: Integer): Integer; stdcall;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TWSARecvExImage = function(s: TSocket; var Buf; len: Integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;var flags: Integer): Integer; stdcall;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;CDS: TCopyDataStruct;</div><div class="code_line">&nbsp;&nbsp;SockAddr: TSockAddr;</div><div class="code_line">&nbsp;&nbsp;AddrLen: Integer;</div><div class="code_line">&nbsp;&nbsp;Data: TLogData;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Первоначально вызываем оригинальную функцию, но данные будем писать в свой буффер...</div><div class="code_line">&nbsp;&nbsp;Result := TWSARecvExImage(InterceptedAPIs[2].OrigAddr)(s, Data.Buff[0], len, flags);</div><div class="code_line">&nbsp;&nbsp;// Получаем информацию кто с кем связался</div><div class="code_line">&nbsp;&nbsp;if getpeername(s, SockAddr, AddrLen) &#60;&#62; SOCKET_ERROR then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Data.IP := inet_ntoa(SockAddr.sin_addr);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Data.Port := ntohs(SockAddr.sin_port);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Data.BuffSize := Result;</div><div class="code_line">&nbsp;&nbsp;Data.AppName := AppTitle;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Тут можно встроить проверку (к примеру по какому нибудь порту)</div><div class="code_line">&nbsp;&nbsp;if True then</div><div class="code_line">&nbsp;&nbsp; &nbsp;Move(Data.Buff[0], Buf, Result) // проверка успешна - пишем в буфер полученные данные</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := SOCKET_ERROR; &nbsp; &nbsp; &nbsp; &nbsp; // в противном случае говорим что вызов неуспешен.</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Отправляем полученные данные нашему приложению...</div><div class="code_line">&nbsp;&nbsp;CDS.dwData := NOTIFY_API_CALL;</div><div class="code_line">&nbsp;&nbsp;CDS.cbData := SizeOf(TLogData);</div><div class="code_line">&nbsp;&nbsp;CDS.lpData := @Data;</div><div class="code_line">&nbsp;&nbsp;SendMessage(ShareInf^.AppWndHandle, WM_COPYDATA, 0, Integer(@CDS));</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// &nbsp;Инициализация данных, вызывается при загрузке библиотеки в новое АП</div><div class="code_line">// =============================================================================</div><div class="code_line">procedure InitData;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;FileName: array [0..MAX_PATH - 1] of Char;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;ZeroMemory(@FileName, SizeOf(FileName));</div><div class="code_line">&nbsp;&nbsp;GetModuleFileName(HInstance, @FileName, SizeOf(FileName));</div><div class="code_line">&nbsp;&nbsp;AppTitle := String(FileName);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;SetLength(InterceptedAPIs, 3);</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs[0].Lib_Name := &#39;wsock32.dll&#39;;</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs[0].FuncName := &#39;recv&#39;;</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs[0].FuncAddr := @InterceptedRecv;</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs[1].Lib_Name := &#39;ws2_32.dll&#39;;</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs[1].FuncName := &#39;WSARecv&#39;;</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs[1].FuncAddr := @InterceptedWSARecv;</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs[2].Lib_Name := &#39;ws2_32.dll&#39;;</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs[2].FuncName := &#39;WSARecvEx&#39;;</div><div class="code_line">&nbsp;&nbsp;InterceptedAPIs[2].FuncAddr := @InterceptedWSARecvEx;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// &nbsp;Начало и завершение работы нашего хука ...</div><div class="code_line">// =============================================================================</div><div class="code_line">procedure DLLEntryPoint(dwReason: DWORD); //stdcall; &nbsp;&#60;- вот это как раз не нужно...</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;CDS: TCopyDataStruct;</div><div class="code_line">&nbsp;&nbsp;ImageBase: Cardinal;</div><div class="code_line">&nbsp;&nbsp;FileName: array [0..MAX_PATH - 1] of Char;</div><div class="code_line">&nbsp;&nbsp;I: Integer;</div><div class="code_line">&nbsp;&nbsp;ReplaceStatus: TReplaceStatus;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;case dwReason Of</div><div class="code_line">&nbsp;&nbsp; &nbsp;DLL_PROCESS_ATTACH:</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DisableThreadLibraryCalls(hInstance);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;InitData;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Все данные во избежании разрыва цепочки хуков</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// храним в отображаемом в память процесса файле,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// только тогда все экземпляры хука будут владеть</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// достоверной информацией</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;MapHandle := CreateFileMapping(INVALID_HANDLE_VALUE, nil,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;PAGE_READWRITE, 0, SizeOf(TShareInf), GlobMapID);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ShareInf := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;0, 0, SizeOf(TShareInf));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Получаем информацию о процессе в который подгружена наша библиотека</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ImageBase := GetModuleHandle(nil);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ZeroMemory(@FileName, SizeOf(FileName));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;GetModuleFileName(ImageBase, @FileName, SizeOf(FileName));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;AppTitle := String(FileName);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Нотифицируем приложение о успешном внедрении библиотеки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// И сообщаем информацию о процессе</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ZeroMemory(@Data, SizeOf(TLogData));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Data.AppName := AppTitle;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;CDS.dwData := NOTIFY_DLL_LOAD;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;CDS.cbData := SizeOf(TLogData);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;CDS.lpData := @Data;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;SendMessage(ShareInf^.AppWndHandle, WM_COPYDATA, 0, Integer(@CDS));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;//if Pos(&#39;IEXPLORE.EXE&#39;, AnsiUpper(@FileName)) &#60;&#62; 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Подменяем адреса вызовов функций своими обработчиками</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for I := 0 to Length(InterceptedAPIs) - 1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;InterceptedAPIs[I].Replaced := False;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;InterceptedAPIs[I].OrigAddr :=</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetProcAddress(GetModuleHandle(PChar(InterceptedAPIs[I].Lib_Name)),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PChar(InterceptedAPIs[I].FuncName));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ReplaceStatus := rsNotFound;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if InterceptedAPIs[I].OrigAddr &#60;&#62; nil then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Смотрим - успешно ли подменилась запись в таблице импорта?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ReplaceStatus := ReplaceIATEntry(InterceptedAPIs[I].OrigAddr,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;InterceptedAPIs[I].FuncAddr);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;case ReplaceStatus of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rsSuccess:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CDS.dwData := NOTIFY_API_INTERCEPT_SUCCESS; // Успешно...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;InterceptedAPIs[I].Replaced := True; &nbsp; &nbsp; &nbsp; &nbsp;// Ставим флаг, что была замена...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rsFailed:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CDS.dwData := NOTIFY_API_INTERCEPT_FAILED; // Не успешно...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rsNotFound:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Continue;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Нотифицируем наше приложение о результате подмены...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Data.FuncName := InterceptedAPIs[I].FuncName;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Data.FuncPointer := Integer(InterceptedAPIs[I].OrigAddr);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;CDS.cbData := SizeOf(TLogData);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;CDS.lpData := @Data;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;SendMessage(ShareInf^.AppWndHandle, WM_COPYDATA, 0, Integer(@CDS));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DLL_PROCESS_DETACH:</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Возвращаем изменения как они и были (если замена была удачна)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for I := 0 to Length(InterceptedAPIs) - 1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if InterceptedAPIs[I].Replaced then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ReplaceIATEntry(InterceptedAPIs[I].FuncAddr,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;InterceptedAPIs[I].OrigAddr);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Нотифицируем приложение о выгрузке библиотеки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;CDS.dwData := NOTIFY_DLL_UNLOAD;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;CDS.cbData := SizeOf(TLogData);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;CDS.lpData := @Data;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;SendMessage(ShareInf^.AppWndHandle, WM_COPYDATA, 0, Integer(@CDS));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;UnMapViewOfFile(ShareInf);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;CloseHandle(MapHandle); &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// &nbsp;Это наш хук, он нужен только для внедрения в удаленный процесс ...</div><div class="code_line">// =============================================================================</div><div class="code_line">function Hook(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// вызываем след. ловушку</div><div class="code_line">&nbsp;&nbsp;Result := CallNextHookEx(ShareInf^.OldHookHandle, Code, WParam, LParam);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// &nbsp;Установка хука ...</div><div class="code_line">// =============================================================================</div><div class="code_line">function SetHook(Wnd: HWND): BOOL; stdcall;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if ShareInf &#60;&#62; nil then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;ShareInf^.AppWndHandle := Wnd;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ShareInf^.OldHookHandle :=</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;SetWindowsHookEx(WH_GETMESSAGE, @Hook, HInstance, 0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := ShareInf^.OldHookHandle &#60;&#62; 0;</div><div class="code_line">&nbsp;&nbsp;end</div><div class="code_line">&nbsp;&nbsp;else </div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := False;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// &nbsp;Снятие хука ...</div><div class="code_line">// =============================================================================</div><div class="code_line">function RemoveHook: BOOL; stdcall;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result := UnhookWindowsHookEx(ShareInf^.OldHookHandle);</div><div class="code_line">&nbsp;&nbsp;CloseHandle(ShareInf^.hm);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">exports</div><div class="code_line">&nbsp;&nbsp;SetHook, RemoveHook;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;DLLProc := @DLLEntryPoint;</div><div class="code_line">&nbsp;&nbsp;DLLEntryPoint(DLL_PROCESS_ATTACH);</div><div class="code_line">end.</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
Приложение:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">////////////////////////////////////////////////////////////////////////////////</div><div class="code_line">//</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">// &nbsp;* Unit Name : Changer</div><div class="code_line">// &nbsp;* Purpose &nbsp; : Пример внедрения в удаленный процесс</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: и перехвата функций</div><div class="code_line">// &nbsp;* Author &nbsp; &nbsp;: Александр (Rouse_) Багель</div><div class="code_line">// &nbsp;* Copyright : © Fangorn Wizards Lab 1998 - 2007 г.</div><div class="code_line">// &nbsp;* Version &nbsp; : 1.02</div><div class="code_line">// &nbsp;* Home Page : http://rouse.drkb.ru</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">//</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">unit uMain;</div><div class="code_line">&nbsp;</div><div class="code_line">interface</div><div class="code_line">&nbsp;</div><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,</div><div class="code_line">&nbsp;&nbsp;Dialogs, StdCtrls;</div><div class="code_line">&nbsp;</div><div class="code_line">const // Константы нотификаций</div><div class="code_line">&nbsp;&nbsp;NOTIFY_DLL_LOAD = 1;</div><div class="code_line">&nbsp;&nbsp;NOTIFY_API_CALL = 2;</div><div class="code_line">&nbsp;&nbsp;NOTIFY_API_INTERCEPT_SUCCESS = 3;</div><div class="code_line">&nbsp;&nbsp;NOTIFY_API_INTERCEPT_FAILED = 4;</div><div class="code_line">&nbsp;&nbsp;NOTIFY_DLL_UNLOAD = 5;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;// Структура для нотификации приложения</div><div class="code_line">&nbsp;&nbsp;PLogData = ^TLogData;</div><div class="code_line">&nbsp;&nbsp;TLogData = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;AppName: ShortString; // Имя приложения</div><div class="code_line">&nbsp;&nbsp; &nbsp;FuncName: String[30]; &nbsp;// Имя функции</div><div class="code_line">&nbsp;&nbsp; &nbsp;FuncPointer: Integer; // Адрес функции</div><div class="code_line">&nbsp;&nbsp; &nbsp;IP: String[15]; &nbsp; &nbsp; &nbsp; // IP адрес</div><div class="code_line">&nbsp;&nbsp; &nbsp;Port: Cardinal; &nbsp; &nbsp; &nbsp; // Порт</div><div class="code_line">&nbsp;&nbsp; &nbsp;Buff: array [0..$FFFF] of Char; // Содержимое буффера</div><div class="code_line">&nbsp;&nbsp; &nbsp;BuffSize: Word; &nbsp; &nbsp; &nbsp; // Размер буфера</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TRecvLoggerMainDialog = class(TForm)</div><div class="code_line">&nbsp;&nbsp; &nbsp;memReport: TMemo;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure FormDestroy(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure FormCreate(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp;private</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure WMCopyData(var Msg: TMessage); message WM_COPYDATA;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;function SetHook(Wnd: HWND): BOOL; stdcall;</div><div class="code_line">&nbsp;&nbsp; &nbsp;external &#39;Changer.dll&#39; name &#39;SetHook&#39;;</div><div class="code_line">&nbsp;&nbsp;function RemoveHook: BOOL; stdcall;</div><div class="code_line">&nbsp;&nbsp; &nbsp;external &#39;Changer.dll&#39; name &#39;RemoveHook&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;RecvLoggerMainDialog: TRecvLoggerMainDialog;</div><div class="code_line">&nbsp;</div><div class="code_line">implementation</div><div class="code_line">&nbsp;</div><div class="code_line">{$R *.dfm}</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TRecvLoggerMainDialog.FormCreate(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if not SetHook(Handle) then</div><div class="code_line">&nbsp;&nbsp; &nbsp;MessageBox(Handle, &#39;Невозможно установить хук.&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;PChar(Application.Title), MB_OK or MB_ICONHAND);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TRecvLoggerMainDialog.FormDestroy(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if not RemoveHook then</div><div class="code_line">&nbsp;&nbsp; &nbsp;MessageBox(Handle, &#39;Невозможно снять хук.&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;PChar(Application.Title), MB_OK or MB_ICONHAND);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function ByteToHexStr(Data: Pointer; Len: Integer): String;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;I, Octets, PartOctets: Integer;</div><div class="code_line">&nbsp;&nbsp;DumpData: String;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if Len = 0 then Exit;</div><div class="code_line">&nbsp;&nbsp;I := 0;</div><div class="code_line">&nbsp;&nbsp;Octets := 0;</div><div class="code_line">&nbsp;&nbsp;PartOctets := 0;</div><div class="code_line">&nbsp;&nbsp;Result := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp;while I &#60; Len do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;case PartOctets of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;0: Result := Result + Format(&#39;%.4d: &#39;, [Octets]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;9:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Inc(Octets, 10);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;PartOctets := -1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := Result + &#39; &nbsp; &nbsp;&#39; + DumpData + sLineBreak;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;DumpData := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := Result + Format(&#39;%s &#39;, [IntToHex(TByteArray(Data^)[I], 2)]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if TByteArray(Data^)[I] in [..$FF] then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DumpData := DumpData + Chr(TByteArray(Data^)[I])</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DumpData := DumpData + &#39;.&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Inc(I);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Inc(PartOctets);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;if PartOctets &#60;&#62; 0 then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;PartOctets := (8 - Length(DumpData)) * 3;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Inc(PartOctets, 4);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := Result + StringOfChar(&#39; &#39;, PartOctets) +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DumpData</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TRecvLoggerMainDialog.WMCopyData(var Msg: TMessage);</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;ReportLoad = &#39;Библиотека внедрена в приложение &quot;%s&quot;&#39;;</div><div class="code_line">&nbsp;&nbsp;ReportIntercept = &#39;Приложение: &quot;%s&quot; IP %s:%d размер данных = %d &#39;#13#10&#39;%s&#39;;</div><div class="code_line">&nbsp;&nbsp;ReportSucceeded = &#39;Перехват функции &quot;%s&quot; в модуле &quot;%s&quot; успешен.&#39;;</div><div class="code_line">&nbsp;&nbsp;ReportFailed = &#39;Перехват функции &quot;%s&quot; в модуле &quot;%s&quot; неуспешен!!!&#39;;</div><div class="code_line">&nbsp;&nbsp;ReportUnload = &#39;Библиотека выгружена из приложения &quot;%s&quot;&#39;;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Data: TLogData;</div><div class="code_line">&nbsp;&nbsp;Buffer: String;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Data := PLogData(PCopyDataStruct(Msg.LParam)^.lpData)^;</div><div class="code_line">&nbsp;&nbsp;// Типы нотификаций</div><div class="code_line">&nbsp;&nbsp;case PCopyDataStruct(Msg.LParam)^.dwData of</div><div class="code_line">&nbsp;&nbsp; &nbsp;NOTIFY_DLL_LOAD: // Пришло уведомление о внедрении библиотеки в удаленный процесс</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;with Data do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memReport.Lines.Add(Format(ReportLoad, [AppName]));</div><div class="code_line">&nbsp;&nbsp; &nbsp;NOTIFY_API_CALL: // Уведомление о вызове функции</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;SetLength(Buffer, Data.BuffSize);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Move(Data.Buff, Buffer[1], Data.BuffSize);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;with Data do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memReport.Lines.Add(Format(ReportIntercept,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[AppName, IP, Port, BuffSize, ByteToHexStr(@Buffer[1], BuffSize)]));</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;NOTIFY_API_INTERCEPT_SUCCESS: // Уведомление о удачной подмене таблицы импорта</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;with Data do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memReport.Lines.Add(Format(ReportSucceeded, [FuncName, AppName]));</div><div class="code_line">&nbsp;&nbsp; &nbsp;NOTIFY_API_INTERCEPT_FAILED: // Уведомление о неудачной подмене таблицы импорта</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;with Data do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memReport.Lines.Add(Format(ReportFailed, [FuncName, AppName]));</div><div class="code_line">&nbsp;&nbsp; &nbsp;NOTIFY_DLL_UNLOAD: // Пришло уведомление о выгрузке библиотеки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;with Data do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memReport.Lines.Add(Format(ReportUnload, [AppName]));</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>Автор:</strong> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=19443' target='_blank'>Rouse_</a>]]></description>
        <author>s-mike</author>
        <category>Системные функции, WinAPI, работа с железом</category>
      </item>
	
      </channel>
      </rss>
	