Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 17-07-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Jugando con el messenger

Hace unos días hablábamos de la inyección de código y hacer hooks a las APIs. Pues bien me he puesto a jugar un poco, y esto es lo que he conseguido por ahora, una dll que se inyecta en el messenger, hace un hook en las APIs Send, WSASend y WSARecv, y cuando el messenger envía o recibe algo la dll utiliza la función OutputDebugString para mostrarnos lo que se envía o se recibe.

Es solo una prueba de concepto:
Código Delphi [-]
library HookIt;

uses
  Windows,
  Sysutils,
  Messages,
  Psapi,
  ImageHlp,
  winsock;

type
  IMAGE_IMPORT_DESCRIPTOR = record
    Characteristics: DWORD;
    TimeDateStamp: DWORD;
    ForwarderChain: DWORD;
    Name: DWORD;
    FirstThunk: DWORD;
  end;
  PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
  
  u_int = Integer;
  TSocket = u_int;

  TWSABUF = record
    len: u_long;
    buf: PChar;
  end;
  PWSABUF = ^TWSABUF;

  TSendFunc = function (s: TSocket; Buf: Pchar; len, flags: Integer): Integer; stdcall;
  TWSASendFunc = function(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
    lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
    lpCompletionRoutine: Pointer): Integer; stdcall;
  TWSARecvFunc = function(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
    lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
    lpCompletionRoutine: Pointer): Integer; stdcall;

const         
  // Cambiar la ruta del messenger si es necesario
  strTarget = 'C:\Archivos de programa\MSN Messenger\msnmsgr.exe';

var
  Injected: Boolean;
  ModuleHandle: DWORD;
  OldSend: TSendFunc;
  OldWSASend: TWSASendFunc;
  OldWSARecv: TWSARecvFunc;

function newSend(s: TSocket; Buf: PChar; len, flags: Integer): Integer; stdcall;
begin
  OutputDebugString(PChar('Send: ' + String(Buf)));
  if @OldSend <> nil then
    Result:= OldSend(s,Buf,len,flags)
  else
    Result:= -1;
end;

function newWSASend(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
  lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
  lpCompletionRoutine: Pointer): Integer; stdcall;
var
  i: DWORD;
  P: PWSABUF;
begin
  i:= dwBufferCount;
  P:= lpBuffers;
  while i > 0 do
  begin
    OutputDebugString(PChar('Recv: ' + String(P.Buf)));
    dec(i);
    inc(P);
  end;
  if @OldWSASend <> nil then
    Result:= OldWSASend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,
      lpOverlapped,lpCompletionRoutine)
  else
    Result:= -1;
end;

function newWSARecv(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
  lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
  lpCompletionRoutine: Pointer): Integer; stdcall;
var
  i: DWORD;
  P: PWSABUF;
begin
  if @OldWSARecv <> nil then
    Result:= OldWSARecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,
      lpOverlapped,lpCompletionRoutine)
  else
    Result:= -1;
  i:= dwBufferCount;
  P:= lpBuffers;
  while i > 0 do
  begin
    OutputDebugString(PChar('Recv: ' + String(P.Buf)));
    dec(i);
    inc(P);
  end;
end;

// Ajustamos los privilegios
function EnablePrivilege(PrivilegeName: PChar; Enable: Boolean): Boolean;
var
  hToken: THandle;
  Tp: TOKEN_PRIVILEGES;
  Luid: TLargeInteger;
begin
  Result:= FALSE;
  if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or
    TOKEN_QUERY or TOKEN_READ, hToken) then
    if LookupPrivilegeValue(nil,PrivilegeName,Luid) then
    begin
      Tp.PrivilegeCount:= 1;
      Tp.Privileges[0].Luid:= Luid;
      if Enable then
        Tp.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED
      else
        Tp.Privileges[0].Attributes:= 0;
      Result:= AdjustTokenPrivileges(hToken,FALSE,Tp,0,nil,PDWORD(nil)^);
      CloseHandle(hToken);
    end;
end;

function HookFunction(ModName, ProcName: PChar; Nuevo: Pointer): Pointer;
var
  i: Integer;
  hProcess: THandle;
  hModules: array[0..1024] of HMODULE;
  cbNeeded: DWORD;
  hMod: HMODULE;
  ImportDesc: PIMAGE_IMPORT_DESCRIPTOR;
  Size: Cardinal;
  szModName: PChar;
  Thunk: PPointer;
  MBI: MEMORY_BASIC_INFORMATION;
begin
  Result:= nil;
  hMod:= GetModuleHandle(ModName);
  if hMod <> 0 then
  begin
    Result:= GetProcAddress(hMod, ProcName);
    if Result <> nil then
    begin
      hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION  or PROCESS_VM_READ,
        FALSE, GetCurrentProcessId);
      if hProcess <> 0 then
      begin
        if EnumProcessModules(hProcess, @hModules, Sizeof(hModules), cbNeeded) then
          for i:= 0 to (cbNeeded div Sizeof(HMODULE)) - 1 do
          begin
            ImportDesc:= ImageDirectoryEntryToData(Pointer(hModules[i]),
              TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, Size);
            if ImportDesc <> nil then
            begin
              while ImportDesc.Name > 0 do
              begin
                szModName:= PChar(hModules[i] + ImportDesc.Name);
                if StrIComp(szModName,ModName) = 0  then
                begin
                  Thunk:= Pointer(hModules[i] + ImportDesc.FirstThunk);
                  while Thunk^ <> nil do
                  begin 
                    if Thunk^ = Result then
                    begin
                      OutputDebugString('Hookeado');
                      VirtualQuery(Thunk,MBI,Sizeof(MEMORY_BASIC_INFORMATION));
                      VirtualProtect(MBI.BaseAddress,MBI.RegionSize,PAGE_READWRITE,
                        MBI.Protect);
                      Thunk^:=  Nuevo;
                      VirtualProtect(mbi.BaseAddress,mbi.RegionSize,mbi.Protect,
                        MBI.Protect);
                    end;
                    inc(Thunk);
                  end;
                end;
                inc(ImportDesc);
              end;
            end;
          end;
      end;
    end;
  end;
end;

procedure Inject(LibPath: PChar); stdcall;
var
  Procesos: array[1..1024] of DWORD;
  Needed, i: DWORD;
  Process, Thread: THandle;
  ModName, Target: array[0..MAX_PATH] of Char;
  RemLibPath: PChar;
begin
  if ModuleHandle = 0 then
    if EnablePrivilege('SeDebugPrivilege', TRUE) then
    begin
      FillChar(Target,Sizeof(Target),#0);
      //GetSystemDirectory(@Target,Sizeof(Target)-1);
      StrLCat(Target,strTarget,Sizeof(Target)-1);
      if EnumProcesses(@Procesos, SizeOf(Procesos), Needed ) then
      begin
        for i:= 1 to (Needed div Sizeof(DWORD)) do
        begin
          Process := OpenProcess(PROCESS_ALL_ACCESS, FALSE,Procesos[i]);
          if Process <> 0 then
          begin
            if GetModuleFileNameEx(Process,0,ModName,SizeOf(ModName)-1) > 0  then
            begin
              if AnsiStrPos(ModName,Target) <> nil then
              begin
                RemLibPath:= VirtualAllocEx(Process, nil,StrLen(LibPath)+1,
                  MEM_COMMIT, PAGE_READWRITE);
                if RemLibPath <> nil then
                begin
                  if WriteProcessMemory(Process, RemLibPath, LibPath,
                    StrLen(LibPath),PDWORD(nil)^) then
                  begin
                    Thread:= CreateRemoteThread(Process, nil, 0,
                      GetProcAddress(GetModuleHandle('Kernel32'),'LoadLibraryA'),
                      RemLibPath, 0, PDWORD(nil)^);
                    if Thread <> 0 then
                    begin
                      WaitForSingleObject(Thread,INFINITE );
                      GetExitCodeThread(Thread,ModuleHandle);
                      CloseHandle(Thread);
                    end;
                  end;
                  VirtualFreeEx(Process,RemLibPath,StrLen(LibPath)+1,MEM_RELEASE);
                end;
              end;
            end;
            CloseHandle(Process);
          end;
        end;
      end;
      EnablePrivilege('SeDebugPrivilege', FALSE);
    end;
end;

procedure ProcessAttach; stdcall;
var
  Process: THandle;
  ModName: array[0..MAX_PATH] of Char;
  Target: array[0..MAX_PATH] of Char;
begin
  Injected:= FALSE;
  ModuleHandle:= 0;
  Process := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE,
    GetCurrentProcessId);
  if Process <> 0 then
  begin
    if GetModuleFileNameEx(Process, 0, ModName,SizeOf(ModName)-1) > 0  then
    begin
      FillChar(Target,Sizeof(Target),#0);
      //GetSystemDirectory(@Target,Sizeof(Target)-1);
      StrLCat(Target,strTarget,Sizeof(Target)-1);
      if AnsiStrPos(ModName,Target) <> nil then
      begin
        OldSend:= HookFunction('wsock32.dll','send',@newSend);
        OldSend:= HookFunction('Ws2_32.dll','send',@newSend);
        OldWSASend:= HookFunction('Ws2_32.dll','WSASend',@newWSASend);
        OldWSARecv:= HookFunction('Ws2_32.dll','WSARecv',@newWSARecv);
      end;
    end;
    CloseHandle(Process);
  end;
end;

procedure ProcessDetach; stdcall;
begin
//
end;

procedure DLLEntryPoint(Reason: integer);
begin
  case Reason of
    Dll_Process_Detach: ProcessDetach;
    Dll_Process_Attach: ProcessAttach;
  end;
end;

exports
  Inject;

begin
  ProcessAttach;
  DLLProc:= @DLLEntryPoint;
end.

Necesitaremos una aplicación que realice la inyección, una vez inyectada la dll la aplicación se puede cerrar. Por ejemplo:
Código Delphi [-]
program Probador;

{$APPTYPE CONSOLE}

uses Windows, SysUtils;

procedure Inject(LibPath: PChar); stdcall; external 'HookIt.dll';

var
  LibPath: String;
begin
  LibPath:= ExtractFilePath(ParamStr(0)) + 'HookIt.dll';
  Inject(PChar(LibPath));
end.
Por último para ver los mensajes enviados por la función OutputDebugString necesitaremos un programa como DebugView de Sysinternals.

¿Se le ocurre a alguien algo "divertido" que hacer con esto?
Archivos Adjuntos
Tipo de Archivo: zip HookIt.zip (7,2 KB, 69 visitas)
Responder Con Cita
  #2  
Antiguo 17-07-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Esto me huele a capturar lo que se escribe en el messenger, vaya habria muchas utilidades que se podrian crear.

Pero temo que sobrepasa mi precario conocimiento, no sabes como admiro que "juegues" con todo esto.

Pues nada, solo es un poco de envidia (de la buena).

Salud OS.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #3  
Antiguo 18-07-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Cita:
Empezado por egostar
Esto me huele a capturar lo que se escribe en el messenger
Los mensajes comienzan todos por "MSG", y ya no digo mas ...

Y ya que estamos, si cambiamos las siguientes funciones, tendremos una visión un poco mas clara de lo que esta pasando, eliminando los caracteres no imprimibles o extraños:
Código Delphi [-]
function BufToString(Buf: PChar; Len: Integer): String;
var
  i: Integer;
begin
  Result:= EmptyStr;
  for i:= 1 to Len do
  begin
    if (Buf^ in [#32..#126]) then
      Result:= Result + Buf^
    else
      Result:= Result + '.';
    inc(Buf);
  end;
end;

function newSend(s: TSocket; Buf: PChar; len, flags: Integer): Integer; stdcall;
begin
  OutputDebugString(PChar('Send: ' + BufToString(Buf,len)));
  if @OldSend <> nil then
    Result:= OldSend(s,Buf,len,flags)
  else
    Result:= -1;
end;

function newWSASend(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
  lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
  lpCompletionRoutine: Pointer): Integer; stdcall;
var
  i: DWORD;
  P: PWSABUF;
begin
  i:= dwBufferCount;
  P:= lpBuffers;
  while i > 0 do
  begin
    OutputDebugString(PChar('Recv: ' + BufToString(P.Buf,P.len)));
    dec(i);
    inc(P);
  end;
  if @OldWSASend <> nil then
    Result:= OldWSASend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,
      lpOverlapped,lpCompletionRoutine)
  else
    Result:= -1;
end;

function newWSARecv(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
  lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
  lpCompletionRoutine: Pointer): Integer; stdcall;
var
  i: DWORD;
  P: PWSABUF;
begin
  if @OldWSARecv <> nil then
    Result:= OldWSARecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,
      lpOverlapped,lpCompletionRoutine)
  else
    Result:= -1;
  i:= dwBufferCount;
  P:= lpBuffers;
  while i > 0 do
  begin
    OutputDebugString(PChar('Recv: ' + BufToString(P.Buf,P.len)));
    dec(i);
    inc(P);
  end;
end;
Responder Con Cita
  #4  
Antiguo 18-07-2007
Phacko Phacko is offline
Miembro
 
Registrado: jul 2004
Posts: 157
Poder: 20
Phacko Va por buen camino
Grande....

Primero que nada, mi admiración y respeto.
Me da una idea lo que comentas en tu post, pero para ser sincero viendo el codigo que pusiste, no tengo ni idea de lo que hiciste; me pregunto cuanto fue lo que dedicaste en tiempo y esfuerzo para llegar a dominar tal nivel dentro de la programación, mi admiración mas sincera y mi envidia mas sana de la que pueda hacer gala, al igual que a otros de los compañeros del club que no los menciono puesto que podria no nombrar a alguno y no sería correcto pero que muchos sabemos quienes son. Gracias por su apoyo y enseñanza.

Un saludo y abrazo a todos ustedes que hacen posible este gran espacio.
Responder Con Cita
  #5  
Antiguo 18-07-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
¿Nadie se anima a "meter el dedo" en el código?

Bueno, yo sigo dándole un lavado de cara, quitando algunas cosas que sobraban y añadiendo algunas otras.

Ahora el objetivo es el FileZilla, es interesante ver como en una conexión FTP todo, incluso las contraseñas, se envían sin cifrar, mientras que usando FTPS todo se vuelve un revoltijo de bytes sin sentido.

El código de la dll:
Código Delphi [-]
library HookIt;

uses
  Windows,
  Sysutils,
  Messages,
  Psapi,
  ImageHlp,
  winsock;

type
  IMAGE_IMPORT_DESCRIPTOR = record
    Characteristics: DWORD;
    TimeDateStamp: DWORD;
    ForwarderChain: DWORD;
    Name: DWORD;
    FirstThunk: DWORD;
  end;
  PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;

  TWSABUF = record
    len: u_long;
    buf: PChar;
  end;
  PWSABUF = ^TWSABUF;

  TSendFunc = function (s: TSocket; Buf: Pchar; len, flags: Integer): Integer; stdcall;
  TRecvFunc = function (s: TSocket; Buf: Pchar; len, flags: Integer): Integer; stdcall;
  TWSASendFunc = function(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
    lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
    lpCompletionRoutine: Pointer): Integer; stdcall;
  TWSARecvFunc = function(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
    lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
    lpCompletionRoutine: Pointer): Integer; stdcall;

  TBufType = (btSend, btRecv);

const         
  //strTarget = 'C:\Archivos de programa\MSN Messenger\msnmsgr.exe';
  strTarget = 'C:\Archivos de programa\FileZilla\FileZilla.exe';

var
  OldSend: TSendFunc;
  OldRecv: TRecvFunc;
  OldWSASend: TWSASendFunc;
  OldWSARecv: TWSARecvFunc;

function BufToString(Buf: PChar; Len: Integer): String;
var
  i: Integer;
begin
  Result:= EmptyStr;
  for i:= 1 to Len do
  begin
    if (Buf^ in [#32..#126]) then
      Result:= Result + Buf^
    else
      Result:= Result + '.';
    inc(Buf);
  end;
end;

// Todos los hooks apuntan hacia aqui
procedure SaveBuf(S: TSocket; Buf: PChar; Len: Integer; Tipo: TBufType);
var
  Str: String;
begin
  Str:= BufToString(Buf,len);
  if Tipo = btSend then
    Str:= Format('Send(%d): %s',[S,Str])
  else if Tipo = btRecv then
    Str:= Format('Recv(%d): %s',[S,Str]);
  OutputDebugString(PChar(Str));
end;

function NewSend(s: TSocket; Buf: PChar; len, flags: Integer): Integer; stdcall;
begin
  SaveBuf(s,Buf,len,btSend);
  if @OldSend <> nil then
    Result:= OldSend(s,Buf,len,flags)
  else
    Result:= SOCKET_ERROR;
end;

function NewRecv(s: TSocket; Buf: PChar; len, flags: Integer): Integer; stdcall;
begin
  if @OldRecv <> nil then
    Result:= OldRecv(s,Buf,len,flags)
  else
    Result:= SOCKET_ERROR;
  if Result > 0 then
    SaveBuf(s,Buf,Result,btRecv);
end;

function NewWSASend(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
  lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
  lpCompletionRoutine: Pointer): Integer; stdcall;
var
  i: DWORD;
  P: PWSABUF;
begin
  i:= dwBufferCount;
  P:= lpBuffers;
  while i > 0 do
  begin
    SaveBuf(s,P.Buf,P.len,btSend);
    dec(i);
    inc(P);
  end;
  if @OldWSASend <> nil then
    Result:= OldWSASend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,
      lpOverlapped,lpCompletionRoutine)
  else
    Result:= SOCKET_ERROR;
end;

function newWSARecv(s: TSocket; lpBuffers: PWSABUF; dwBufferCount: DWORD;
  lpNumberOfBytesSent: Pointer; dwFlags: DWORD; lpOverlapped: Pointer;
  lpCompletionRoutine: Pointer): Integer; stdcall;
var
  i: DWORD;
  P: PWSABUF;
begin
  if @OldWSARecv <> nil then
    Result:= OldWSARecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,
      lpOverlapped,lpCompletionRoutine)
  else
    Result:= SOCKET_ERROR;
  if Result <> SOCKET_ERROR then
  begin
    i:= dwBufferCount;
    P:= lpBuffers;
    while i > 0 do
    begin
      SaveBuf(s,P.Buf,P.len,btRecv);
      dec(i);
      inc(P);
    end;
  end;
end;

function HookFunction(ModName, ProcName: PChar; Nuevo: Pointer): Pointer;
var
  i: Integer;
  hProcess: THandle;
  hModules: array[0..1024] of HMODULE;
  cbNeeded: DWORD;
  hMod: HMODULE;
  ImportDesc: PIMAGE_IMPORT_DESCRIPTOR;
  Size: Cardinal;
  szModName: PChar;
  Thunk: PPointer;
  MBI: MEMORY_BASIC_INFORMATION;
begin
  Result:= nil;
  hMod:= GetModuleHandle(ModName);
  if hMod <> 0 then
  begin
    Result:= GetProcAddress(hMod, ProcName);
    if Result <> nil then
    begin
      hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION  or PROCESS_VM_READ,
        FALSE, GetCurrentProcessId);
      if hProcess <> 0 then
      begin
        if EnumProcessModules(hProcess, @hModules, Sizeof(hModules), cbNeeded) then
          for i:= 0 to (cbNeeded div Sizeof(HMODULE)) - 1 do
          begin
            ImportDesc:= ImageDirectoryEntryToData(Pointer(hModules[i]),
              TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, Size);
            if ImportDesc <> nil then
            begin
              while ImportDesc.Name > 0 do
              begin
                szModName:= PChar(hModules[i] + ImportDesc.Name);
                if StrIComp(szModName,ModName) = 0  then
                begin
                  Thunk:= Pointer(hModules[i] + ImportDesc.FirstThunk);
                  while Thunk^ <> nil do
                  begin 
                    if Thunk^ = Result then
                    begin
                      OutputDebugString(PChar(String(ProcName) + ': ' + 'Hookeado'));
                      VirtualQuery(Thunk,MBI,Sizeof(MEMORY_BASIC_INFORMATION));
                      VirtualProtect(MBI.BaseAddress,MBI.RegionSize,PAGE_READWRITE,
                        MBI.Protect);
                      Thunk^:=  Nuevo;
                      VirtualProtect(mbi.BaseAddress,mbi.RegionSize,mbi.Protect,
                        MBI.Protect);
                    end;
                    inc(Thunk);
                  end;
                end;
                inc(ImportDesc);
              end;
            end;
          end;
      end;
    end;
  end;
end;

procedure Inject(LibPath: PChar); stdcall;
var
  Procesos: array[1..1024] of DWORD;
  Needed, i: DWORD;
  Process, Thread: THandle;
  ModName, Target: array[0..MAX_PATH] of Char;
  RemLibPath: PChar;
  ExitCode: Cardinal;
begin
  FillChar(Target,Sizeof(Target),#0);
  StrLCopy(Target,strTarget,Sizeof(Target)-1);
  if EnumProcesses(@Procesos, SizeOf(Procesos), Needed ) then
  begin
    for i:= 1 to (Needed div Sizeof(DWORD)) do
    begin
      Process := OpenProcess(PROCESS_ALL_ACCESS, FALSE,Procesos[i]);
      if Process <> 0 then
      begin
        if GetModuleFileNameEx(Process,0,ModName,SizeOf(ModName)-1) > 0  then
        begin
          if AnsiStrPos(ModName,Target) <> nil then
          begin
            RemLibPath:= VirtualAllocEx(Process, nil,StrLen(LibPath)+1,
              MEM_COMMIT, PAGE_READWRITE);
            if RemLibPath <> nil then
            begin
              if WriteProcessMemory(Process, RemLibPath, LibPath,
                StrLen(LibPath),PDWORD(nil)^) then
              begin
                Thread:= CreateRemoteThread(Process, nil, 0,
                  GetProcAddress(GetModuleHandle('Kernel32'),'LoadLibraryA'),
                  RemLibPath, 0, PDWORD(nil)^);
                if Thread <> 0 then
                begin
                  WaitForSingleObject(Thread,INFINITE );
                  GetExitCodeThread(Thread,ExitCode);
                  CloseHandle(Thread);
                end;
              end;
              VirtualFreeEx(Process,RemLibPath,StrLen(LibPath)+1,MEM_RELEASE);
            end;
          end;
        end;
        CloseHandle(Process);
      end;
    end;
  end;
end;

procedure ProcessAttach; stdcall;
var
  Process: THandle;
  ModName: array[0..MAX_PATH] of Char;
  Target: array[0..MAX_PATH] of Char;
begin
  Process := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE,
    GetCurrentProcessId);
  if Process <> 0 then
  begin
    if GetModuleFileNameEx(Process, 0, ModName,SizeOf(ModName)-1) > 0  then
    begin
      FillChar(Target,Sizeof(Target),#0);
      StrLCopy(Target,strTarget,Sizeof(Target)-1);
      if AnsiStrPos(ModName,Target) <> nil then
      begin
        OldSend:= HookFunction('Ws2_32.dll','send',@NewSend);
        OldRecv:= HookFunction('Ws2_32.dll','recv',@newRecv);
        OldWSASend:= HookFunction('Ws2_32.dll','WSASend',@NewWSASend);
        OldWSARecv:= HookFunction('Ws2_32.dll','WSARecv',@NewWSARecv);
      end;
    end;
    CloseHandle(Process);
  end;
end;

procedure ProcessDetach; stdcall;
begin
//
end;

procedure DLLEntryPoint(Reason: integer);
begin
  case Reason of
    Dll_Process_Detach: ProcessDetach;
    Dll_Process_Attach: ProcessAttach;
  end;
end;

exports
  Inject;

begin
  ProcessAttach;
  DLLProc:= @DLLEntryPoint;
end.




Y por si alguien tiene curiosidad sobre lo que comentaba del ftp:

FTP normal:
Código:
00000000	0.00000000	[3420] send: Hookeado	
00000001	0.00014471	[3420] send: Hookeado	
00000002	0.00025730	[3420] recv: Hookeado	
00000003	0.00033300	[3420] recv: Hookeado	
00000004	0.00044000	[3420] WSASend: Hookeado	
00000005	0.00054169	[3420] WSARecv: Hookeado	
00000006	0.01691332	[3420] WSARecv: Hookeado	
00000007	6.09645510	[3420] Recv(472): 220---------- Welcome to Pure-FTPd [TLS] ----------..220-You are user number 10 of 100 allowed...220-Local time is now 11:57. Server port: 21...220-This is a private system - No anonymous login..220 You will be disconnected after 15 minutes of inactivity...	
00000008	6.10500622	[3420] Send(472): USER usuario..	
00000009	6.20800686	[3420] Recv(472): 331 User usuario OK. Password required..	
00000010	6.21136618	[3420] Send(472): PASS password..	
00000011	7.68974400	[3420] Recv(472): 230-User usuario has group access to:  usuario   ..230 OK. Current restricted directory is /..	
00000012	7.69142294	[3420] Send(472): SYST..	
00000013	7.79814720	[3420] Recv(472): 215 UNIX Type: L8..	
00000014	7.79918385	[3420] Send(472): FEAT..	
00000015	7.90416002	[3420] Recv(472): 211-Extensions supported:.. EPRT.. IDLE.. MDTM.. SIZE.. REST STREAM.. MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;.. MLSD.. ESTP.. PASV.. EPSV.. SPSV.. ESTA.. AUTH TLS.. PBSZ.. PROT..211 End...	
00000016	7.92951632	[3420] Send(472): PWD..	
00000017	8.03565025	[3420] Recv(472): 257 "/" is your current location..	
00000018	8.03662586	[3420] Send(472): TYPE A..	
00000019	8.14296532	[3420] Recv(472): 200 TYPE is now ASCII..	
00000020	8.14391899	[3420] Send(472): PASV..	
00000021	8.25138378	[3420] Recv(472): 227 Entering Passive Mode (86,109,99,252,148,1)..	
00000022	8.25234795	[3420] Send(472): LIST..
Y esto es FTPS:
Código:
00000000	0.00000000	[3444] send: Hookeado	
00000001	0.00014499	[3444] send: Hookeado	
00000002	0.00025925	[3444] recv: Hookeado	
00000003	0.00033663	[3444] recv: Hookeado	
00000004	0.00044447	[3444] WSASend: Hookeado	
00000005	0.00057186	[3444] WSARecv: Hookeado	
00000006	0.01196353	[3444] WSARecv: Hookeado	
00000007	8.25035477	[3444] Recv(472): 220 Indy FTP Server ready...	
00000008	8.25047493	[3444] Send(472): AUTH SSL..	
00000009	8.27392101	[3444] Recv(472): 234 AUTH Command OK. Initializing SSL..	
00000010	8.51114845	[3444] Send(472): .j....Q......9..8..5..............3..2../.............................@.....................>^...z....T..).Q	
00000011	8.51255322	[3444] Recv(472): ._....../....0..+0...............j...0...*.H........0E1.0...U....AU1.0...U....Some-State1!0...U....Internet Widgits Pty Ltd0...070709185831Z..100708185831Z0E1.0...U....AU1.0...U....Some-State1!0...U....Internet Widgits Pty Ltd0\0...*.H.........K.0H.A...#...-..tyv.o....w....u.BC......:....&....}.P.":....9.2VI.X.s..........0..0...U......$.*$B...4.P.%..[.pHJ0u..U.#.n0l..$.*$B...4.P.%..[.pHJ.I.G0E1.0...U....AU1.0...U....Some-State1!0...U....Internet Widgits Pty Ltd.......j...0...U....0....0...*.H.........A.........'DQ....2..K..<.h|.*.8QT]..x<.... v.?...5d..0B..m.[.4..................@.......-#..UWB..-..0.E	
00000012	8.51360226	[3444] Send(472): .R.......@...<.#$./d.!..Ji....C......+{}$....`..~.M.....\(.."...u%J..L...Uh.2N.....O.(........g..diz...?nsN.LgOS...9.B...<Z....	
00000013	8.51596642	[3444] Recv(472): .(..R.....B..h+.Cx..(..../....S..V..z#......(.t....l.,....)P.....c.Ky$K.....5.Z.T..K8.

Última edición por seoane fecha: 18-07-2007 a las 20:49:19.
Responder Con Cita
  #6  
Antiguo 18-07-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Pues yo sigo jugando, así que probé a inyectarme en el Opera, Firebird y IExplorer. Los resultados no fueron los que esperaba, solo tuve éxito en el firebird.

Ejemplo de llamada a google desde firebird:
Código:
00000000	0.00000000	[1612] send: Hookeado	
00000001	0.00023970	[1612] send: Hookeado	
00000002	0.00030451	[1612] send: Hookeado	
00000003	0.00040508	[1612] recv: Hookeado	
00000004	0.00055957	[1612] recv: Hookeado	
00000005	0.00061293	[1612] recv: Hookeado	
00000006	0.00079116	[1612] WSARecv: Hookeado	
00000007	0.01721001	[1612] WSARecv: Hookeado	
00000008	3.87779331	[1612] Send(424): 8	
00000009	3.87790227	[1612] Recv(400): 8	
00000010	7.33975983	[1612] Send(424): 8	
00000011	7.36298990	[1612] Recv(400): 8	
00000012	7.36321735	[1612] Send(760): GET /search?q=hola&ie=utf-8&oe=utf-8&aq=t  (... continua ...)
00000013	7.50138474	[1612] Send(424): 8	
00000014	7.50156593	[1612] Recv(760): HTTP/1.1 302 Found..Location: http://www.google.es/search?q=hola  (... continua ...)
00000015	7.50168085	[1612] Send(424): 8	
00000016	7.50173950	[1612] Recv(400): 88	
00000017	7.51233768	[1612] Send(424): 8	
00000018	7.51238394	[1612] Recv(400): 8	
00000019	7.51343203	[1612] Send(424): 8	
00000020	7.51364422	[1612] Send(792): GET /search?q=hola&ie=utf-8&oe=utf-8&aq=t (... continua ...)
00000021	7.51375008	[1612] Recv(400): 8	
00000022	7.66461515	[1612] Send(424): 8	
00000023	7.66482592	[1612] Recv(792): HTTP/1.1 200 OK..Cache-Control: private..Content-Type: text/html;  (... continua ...)
00000024	7.66492271	[1612] Recv(400): 8	
00000025	7.69945812	[1612] Send(424): 8	
00000026	7.69976521	[1612] Recv(400): 8	
00000027	7.74328566	[1612] Send(808): GET /images/nav_logo3.png HTTP/1.1..Host: www.google.es..User-Agent: Mozilla/5.0  (... continua ...)
00000028	7.76948357	[1612] Recv(792): 585...\.R.H......*L.b;..a+.......B`k.jImYXR;-...\.>......V.r.w.&.${NK.._ ..  (... continua ...)
00000030	7.79967022	[1612] Send(424): 8	
00000031	7.85533857	[1612] Send(424): 8	
00000032	7.85574055	[1612] Send(424): 8	
00000033	7.86081028	[1612] Recv(808): HTTP/1.1 200 OK..Content-Type: image/png..Last-Modified:   (... continua ...)
00000036	7.86227322	[1612] Recv(400): 888	
00000037	7.86240196	[1612] Send(424): 8	
00000038	7.86249828	[1612] Send(424): 8	
00000039	7.86318731	[1612] Recv(400): 88	
00000040	7.93753862	[1612] Recv(808): >.0.K..NA......LZ.d......k.Q.e?j0R...X.l...{.C....... ..' (... continua ...)
00000042	7.94816399	[1612] Send(424): 8	
00000043	7.94913769	[1612] Recv(400): 8	
00000044	7.96834993	[1612] Send(424): 8	
00000045	7.96871567	[1612] Recv(400): 8	
00000046	8.02914429	[1612] Send(736): GET / HTTP/1.1..Host: www.hola.com..User-Agent: Mozilla/5.0  (... continua ...)
00000047	8.11064625	[1612] Recv(736): HTTP/1.1 200 OK..Server: Apache..Pragma: no-cache..Last-Modified:  (... continua ...)
00000048	8.11452866	[1612] Send(424): 8	
00000049	8.11458588	[1612] Recv(400): 8	
00000050	18.88658333	[1612] Send(424): 8	
00000051	18.88676453	[1612] Recv(400): 8	
00000052	33.90203857	[1612] Send(424): 8	
00000053	33.90223312	[1612] Recv(400): 8	
00000054	48.91870117	[1612] Send(424): 8	
00000055	48.91886902	[1612] Recv(400): 8	
00000056	64.33921051	[1612] Send(424): 8	
00000057	64.34007263	[1612] Recv(400): 8
*(... continua ...) = El mensaje era mas largo pero lo corte, para postearlo aquí

Lo que me tiene extrañado es por que Opera e IExplorer son inmunes. Ahora estoy interceptando las llamada send, recv, wsasend, wsarecv así que supongo que estos dos no utilizan estas funciones, y me pregunto cuales usaran. O acaso están protegidos contra las inyecciones de código.

Seguiré investigando, es decir jugando
Responder Con Cita
  #7  
Antiguo 19-07-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Lo prometido es deuda:
Código Delphi [-]
// ModName: dll donde se encunetra la funcion
// ProcName: Nombre de la funcion
// Nuevo: Direccion de la nueva funcion
function HookFunction(ModName, ProcName: PChar; Nuevo: Pointer): Pointer;
var
  i: Integer;
  hProcess: THandle;
  hModules: array[0..1024] of HMODULE;
  cbNeeded: DWORD;
  hMod: HMODULE;
  ImportDesc: PIMAGE_IMPORT_DESCRIPTOR;
  Size: Cardinal;
  szModName: PChar;
  Thunk: PPointer;
  MBI: MEMORY_BASIC_INFORMATION;
begin
  Result:= nil;
  // Obtenemos el handle de la dll donde se encuentra la funcion original
  hMod:= GetModuleHandle(ModName);
  if hMod <> 0 then
  begin
    // Obtenemos la direccion de la funcion original
    Result:= GetProcAddress(hMod, ProcName);
    if Result <> nil then
    begin
      // Obtenemos el handle del proceso
      hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION  or PROCESS_VM_READ,
        FALSE, GetCurrentProcessId);
      if hProcess <> 0 then
      begin
        // Enumeramos cada uno de los modulos que tiene cargados el proceso
        if EnumProcessModules(hProcess, @hModules, Sizeof(hModules), cbNeeded) then
          for i:= 0 to (cbNeeded div Sizeof(HMODULE)) - 1 do
          begin
             // Obtenemos la seccion import, que es una array de estructuras
             // del tipo IMAGE_IMPORT_DESCRIPTOR, terminado por una estructura
             // con todos sus campos a cero
            ImportDesc:= ImageDirectoryEntryToData(Pointer(hModules[i]),
              TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, Size);
            if ImportDesc <> nil then
            begin
              // Recorremos el array hasta llegar al elemento con todos
              // los campos a cero.
              while ImportDesc.Name > 0 do
              begin
                // Obtenemos el nombre del modulo importado
                szModName:= PChar(hModules[i] + ImportDesc.Name);
                // Lo comparamos con el que buscamos
                if StrIComp(szModName,ModName) = 0  then
                begin
                  Thunk:= Pointer(hModules[i] + ImportDesc.FirstThunk);
                  // Recorremos cada una de las funciones de ese modulo
                  while Thunk^ <> nil do
                  begin
                    // Si coincide con la que buscamos
                    if Thunk^ = Result then
                    begin
                      OutputDebugString(PChar(String(ProcName) + ': ' + 'Hookeado'));
                      // Obtenemos algunos parametros sobre la memoria
                      VirtualQuery(Thunk,MBI,Sizeof(MEMORY_BASIC_INFORMATION));
                      // Desprotegemos la zona de memoria donde esta
                      // guardada la direccion de la funcion original
                      VirtualProtect(MBI.BaseAddress,MBI.RegionSize,PAGE_READWRITE,
                        MBI.Protect);
                      // Reemplazamos la direccion de memoria de la funcion actual
                      // por la direccion de memoria de nuestra funcion
                      Thunk^:=  Nuevo;
                      // Volvemos a proteger esa zona de memoria
                      VirtualProtect(mbi.BaseAddress,mbi.RegionSize,mbi.Protect,
                        MBI.Protect);
                    end;
                    inc(Thunk);
                  end;
                end;
                inc(ImportDesc);
              end;
            end;
          end;
      end;
    end;
  end;
end;
Espero que se entienda ...
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
delphi y ms messenger `````` alejo000 Internet 9 16-02-2009 19:16:02
Grabar Messenger Avellas Internet 15 29-06-2007 01:14:47
Jugando con los numeros seoane La Taberna 3 14-01-2007 15:34:15
messenger por comandos Cosgaya Varios 0 01-02-2006 12:58:17
Jugando Al Golf Bicho Humor 0 19-01-2006 11:51:52


La franja horaria es GMT +2. Ahora son las 15:34:19.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi