- library ServerHook; 
-   
- uses 
-   SysUtils, 
-   Windows, 
-   winsock, 
-   APIHook, 
-   SharedMemory; 
-   
- type 
-   TIPData = record 
-     IP: DWORD; 
-     Time: TDateTime; 
-   end; 
-   PWhiteList = ^TWhiteList; 
-   TWhiteList = array [0..1023] of TIPData; 
-   
- const 
-  SizeMemory: DWORD = sizeof(TWhiteList); 
-  TimeBlock: WORD = 30; //segundos sin conexión -> Bloqueo 
-   
- type 
-   
- Precv = function(S: TSOCKET; var buf: CHAR; len, flags: integer): integer; stdcall; 
- Precvfrom = function(s: TSOCKET; var buf: CHAR; len, flags: integer; var from: Tsockaddr; fromlen: integer): integer; stdcall; 
- PWSARECV = function (s: TSOCKET; lpBuffers: Pointer; dwBufferCount: DWORD;  lpNumberOfBytesRecvd: LPDWORD; lpFlags: LPDWORD; lpOverlapped: Pointer; lpCompletionRoutine: Pointer): integer; stdcall; 
- PWSARECVFROM = function(s: TSOCKET; lpBuffers: Pointer; dwBufferCount: DWORD;  lpNumberOfBytesRecvd: LPDWORD; lpFlags: LPDWORD; lpfrom: Psockaddr; lpFromlen: PINT; lpOverlapped, lpCompletionRoutine: Pointer): integer; stdcall; 
- PWSARECVEX = function(s: TSOCKET; buf: PCHAR; len: integer; flags: Pinteger): integer; PASCAL; 
-   
- var 
-   Oldrecv: Precv = nil; 
-   Oldrecvfrom : Precvfrom  = nil; 
-   OldWSARecv: PWSARECV = nil; 
-   OldWSARecvEx: PWSARECVEX = nil; 
-   OldWSARecvFrom: PWSARECVFROM = nil; 
-   
-   WinHook: HHOOK = 0; 
-   Memory: TSharedMemory; 
-   WhiteList: PWhiteList; 
-   
- //---------------------------------------------------------------------------- 
- // Obtener la IP desde el Socket 
- function GetIPFromSoket(Sock: TSOCKET): DWORD; 
- var 
-   addr: WinSock.sockaddr_in; 
-   addr_size: integer; 
- begin 
-   addr_size:= sizeof(sockaddr_in); 
-   getpeername(Sock, addr, addr_size); 
-   Result:= addr.sin_addr.S_addr; 
- end; 
-   
- // Busca un IP con más de un tiempo determinado sin conexión 
- function BlockIP(IP: DWORD): BOOL; 
- var 
-   n: integer; 
-   IPCount: integer; 
- begin 
-   Result:= TRUE; 
-   WhiteList:= Memory.Buffer; 
-   IPCount:= sizeof(TWhiteList) div sizeof(TIPData); 
-   for n:= 0 to IPCount-1 do 
-   begin 
-     if WhiteList[n].IP = 0 then break; 
-     if WhiteList[n].IP = IP then 
-       // Si hace más de 30 segundos que no se conecta lo bloqueo 
-       if Now - WhiteList[0].Time < TimeBlock/(24*3600) then 
-       begin 
-         Result:= FALSE; 
-         Exit; 
-       end; 
-   end; 
- end; 
-   
- //---------------------------------------------------------------------------- 
- // La APIs Hookeadas 
- function NewWSARecv(s: TSOCKET; lpBuffers: Pointer; dwBufferCount: DWORD; lpNumberOfBytesRecvd: LPDWORD; lpFlags: LPDWORD; lpOverlapped: Pointer; lpCompletionRoutine: Pointer): integer; stdcall; 
- begin 
-   if BlockIP(GetIPFromSoket(S)) then 
-   begin 
-     Result:= WSAETIMEDOUT; 
-     WSASetLastError(WSAETIMEDOUT); 
-     lpNumberOfBytesRecvd^:= DWORD(-1); 
-   end 
-   else 
-     Result:= OldWSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine); 
- end; 
-   
- function NewWSARecvEx(S: TSOCKET; buf: PCHAR; len: integer; flags: Pinteger): integer; PASCAL; 
- begin 
-   Result:= SOCKET_ERROR; 
-   if BlockIP(GetIPFromSoket(S)) then 
-     WSASetLastError(WSAETIMEDOUT) 
-   else 
-     Result:= OldWSARecvEx(S, buf, len, flags); 
- end; 
-   
- function NewWSARecvFrom(s: TSOCKET; lpBuffers: Pointer; dwBufferCount: DWORD;  lpNumberOfBytesRecvd: LPDWORD; lpFlags: LPDWORD; lpfrom: Psockaddr; lpFromlen: PINT; lpOverlapped, lpCompletionRoutine: Pointer): integer; stdcall; 
- begin 
-   if (lpfrom.sin_addr.S_addr <> 0) and BlockIP(lpfrom.sin_addr.S_addr) then 
-   begin 
-     Result:= WSAETIMEDOUT; 
-     WSASetLastError(WSAETIMEDOUT); 
-     lpNumberOfBytesRecvd^:= DWORD(-1); 
-   end 
-   else 
-     Result:= OldWSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpfrom, lpFromlen, lpOverlapped, lpCompletionRoutine); 
- end; 
-   
- function NewRecv(S: TSOCKET; var buf: CHAR; len, flags: integer): integer; stdcall; 
- begin 
-   Result:= SOCKET_ERROR; 
-   if BlockIP(GetIPFromSoket(S), ) then 
-     WSASetLastError(WSAETIMEDOUT) 
-   else 
-     Result:= OldRecv(S, buf, len, flags); 
- end; 
-   
- function NewRecvfrom(s: TSOCKET; var buf: CHAR; len, flags: integer; var from: Tsockaddr; fromlen: integer): integer; stdcall; 
- begin 
-   Result:= SOCKET_ERROR; 
-   if BlockIP(from.sin_addr.S_addr) then 
-     WSASetLastError(WSAETIMEDOUT) 
-   else 
-     Result:= OldRecvfrom(s, buf, len, flags, from, fromlen); 
- end; 
-   
-   
- //---------------------------------------------------------------------------- 
- // Instalando los Hooks a las API 
- procedure InstallHooks; 
- begin 
-   InstallHook(@NewRecv, @OldRecv, 'Ws2_32.dll', 'recv', true); 
-   InstallHook(@NewRecvfrom, @OldRecvfrom, 'Ws2_32.dll', 'recvfrom', true); 
-   InstallHook(@NewWSARecv, @OldWSARecv, 'Ws2_32.dll', 'WSARecv', true); 
-   InstallHook(@NewWSARecvEx, @OldWSARecvEx, 'Mswsock.dll', 'WSARecvEx', true); 
-   InstallHook(@NewWSARecvFrom, @OldWSARecvFrom, 'Ws2_32.dll', 'WSARecvFrom', true); 
- end; 
-   
- //---------------------------------------------------------------------------- 
- // Desinstalando todos los Hooks 
- procedure UnInstallHooks; 
- begin 
-   UnInstallHook(@OldRecv, 'Ws2_32.dll', 'recv'); 
-   UnInstallHook(@OldRecvfrom, 'Ws2_32.dll', 'recvfrom'); 
-   UnInstallHook(@OldWSARecv, 'Ws2_32.dll', 'WSARecv'); 
-   UnInstallHook(@OldWSARecvEx, 'Mswsock.dll', 'WSARecvEx'); 
-   UnInstallHook(@OldWSARecvFrom, 'Ws2_32.dll', 'WSARecvFrom'); 
- end; 
-   
- procedure DllMain(reason: integer); 
- begin 
-    case reason of 
-      DLL_PROCESS_ATTACH: 
-      begin 
-        Memory:= TSharedMemory.Create('_WhiteList_', sizeof(TWhiteList)); 
-        InstallHooks; 
-      end; 
-      DLL_PROCESS_DETACH: 
-      begin 
-        UnInstallHooks; 
-        Memory.Free; 
-      end; 
-    end; 
- end; 
-   
- begin 
-  DllProc := @DllMain; 
-  DllProc(DLL_PROCESS_ATTACH); 
- end.