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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Большая проблема с CopyMemory, Выдает ошибку 
:(
    Опции темы
Teran
  Дата 4.5.2006, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

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



Есть два исходника :
первый это длл в которой является хуком на Api функцию 
send(s: TSocket; var Buf; len, flags: Integer): Integer;

в ней я получаю указатель на содержимое пакета:
  //DLL
Код

Function sendCallback(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;   
Var
  DataBuffer: pchar;
  BufPointer:Pointer;
Tmp:string;
Begin
BufPointer:=@Buf;
GetMem(DataBuffer, len);
try
   CopyMemory(DataBuffer, BufPointer, len);
   Sendcmd(IntToStr(integer(BufPointer))+'|'+IntToStr(len)); //передаю указатель и длинну в главную программу
//   CopyMemory(BufPointer, DataBuffer, len);
   Tmp:=StrPas(DataBuffer);
   MessageBox(0,Pchar(Tmp),Pchar(Inttostr(integer(BufPointer))),MB_OK);

finally FreeMem(DataBuffer);end;   
 
  result:=sendNext(s, Buf, len, flags);
End;

ВОТ ЗДЕСЬ функиция CopyMemory отрабатывается отлично
но я еще передаю указатель в главную программу и когда там пытаюсь сделать CopyMemory выдает ошибку
   //Программа
Код

function TForm1.Query(ttttt: Pchar): byte;
var
  BufPointer:Pointer;
  len:integer;
begin
........
len:=StrToInt(lenStr);                                        //получил размер
BufPointer:=Pointer(StrToInt(BufPointerStr));   //получил указатель (размер и указатель полностью совпадают и исходными в DLL)

GetMem(DataBuffer,len);
try
  CopyMemory(DataBuffer, BufPointer, len);      //ВОТ ТУТ ВЫБРАСЫВАЕТ ОШИБКУ
  Memo1.Text:=StrPas(DataBuffer);
  //  CopyMemory(BufPointer, DataBuffer, len);
finally FreeMem(DataBuffer);end;

end;


Такое ощущенье что система открывает этот кусок памяти только для Iexplorer-а , а когда пытаюсь обратится к нему с другой проги - ругается
Не подскажите Как можно это обойти?  smile  smile  smile  


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
RaIDeR
Дата 4.5.2006, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А ты не подумал о том что возможно на момент вызова ф-ции CopyMemory указатель уже является не действительным ? 
PM MAIL   Вверх
Rouse_
Дата 4.5.2006, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Приведи полный код TForm1.Query...  


--------------------
 Vae Victis
(Горе побежденным (лат.))
Демо с открытым кодом: http://rouse.drkb.ru 
PM MAIL WWW ICQ   Вверх
Teran
Дата 5.5.2006, 08:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

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



Цитата(RaIDeR @  4.5.2006,  20:17 Найти цитируемый пост)
А ты не подумал о том что возможно на момент вызова ф-ции CopyMemory указатель уже является не действительным ?

думаю что нет так как я пробовал в начале сделать CopyMemory в главной форме(это выдало ошибку) а затем в DLL (здесь прошло все Ok)




Цитата(Rouse_ @  4.5.2006,  21:59 Найти цитируемый пост)
Приведи полный код TForm1.Query...   



Код

function TForm1.QueryChek(ttttt: Pchar): byte;
var
 Tmp,BufPointerStr,lenStr: string;
  DataBuffer: pchar;
  BufPointer:Pointer;
  len:integer;
begin
result:=0;
Tmp:=ttttt;    //Здесь приходит строка типа (1938463||273)
BufPointerStr:=Tmp;
delete(BufPointerStr,Pos('||',BufPointerStr),Length(localport));
delete(Tmp,1,Pos('||',Tmp)+1);
lenStr:=Tmp;

len:=StrToInt(lenStr);
BufPointer:=Pointer(StrToInt(BufPointerStr));

GetMem(DataBuffer,len);
try
  CopyMemory(DataBuffer, BufPointer, len);
  Memo1.Text:=StrPas(DataBuffer);

  //  CopyMemory(BufPointer, DataBuffer, len);
except Memo1.Text:='Error';end;
FreeMem(DataBuffer);



end;



  

Это сообщение отредактировал(а) Girder - 5.5.2006, 16:26


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
Rouse_
Дата 5.5.2006, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А, все понятно. Библиотека это хук? Верно?
Тогда смотри что происходит - ты находясь в чужом адресном пространстве выделяешь в нем память ложишь в нее данные потом нотифицируешь свое приложение куда передаешь адрес, а приложение пытается прочитать по этому адресу но уже в своем адресном пространстве, где естественно ничего не лежит. Вот тебе и вылет.
тут тебе проще использовать WM_COPYDATA, ну а если хочешь всеже по своему принципу - тогда нужно делать ReadProcessMemory

Добавлено @ 11:05 
Вот смотри писал примерчик комуто перехвата вызова RECV в удаленном приложении:

DLL:

Код

////////////////////////////////////////////////////////////////////////////////
//
//  ****************************************************************************
//  * Unit Name : HookDLL
//  * Purpose   : Демонстрационный пример хука и подмены API в приложениях...
//  * Author    : Александр (Rouse_) Багель
//  * Version   : 1.00
//  ****************************************************************************
//

library HookDLL;

uses
  Windows,
  Messages,
  Winsock;

const
  GlobMapID = 'Global Hook for API Interception {2E662583-74C4-45DB-B6DF-FE318C94258D}';

const // Константы нотификаций
  NOTIFY_DLL_INJECT = 1;
  NOTIFY_API_CALL = 2;
  NOTIFY_API_INTERCEPT_SUCCESS = 3;
  NOTIFY_API_INTERCEPT_FAILED = 4;

type
  // Структура для нотификации приложения
  TLogData = record
    AppName: ShortString; // Имя приложения
    FuncName: String[8];  // Имя функции
    FuncPointer: Integer; // Адрес функции
    IP: String[15];       // IP адрес
    Port: Cardinal;       // Порт
    Buff: array [0..$FFFF] of Char; // Содержимое буффера
    BuffSize: Word;       // Размер буфера
  end;

  // Структура с рабочей информацией хука
  PShareInf = ^TShareInf;
  TShareInf = record
    AppWndHandle: HWND;
    OldHookHandle: HHOOK;
    hm:THandle;
  end;

  // Структуры для работы с таблицей импорта
  TIIDUnion = record
    case Integer of
      0: (Characteristics: DWORD);
      1: (OriginalFirstThunk: DWORD);
    end;

  PImageImportDescriptor = ^TImageImportDescriptor;
  TImageImportDescriptor = record
    Union: TIIDUnion;
    TimeDateStamp: DWORD;
    ForwarderChain: DWORD;
    Name: DWORD;
    FirstThunk: DWORD;
  end;

  PImageThunkData = ^TImageThunkData32;
  TImageThunkData32 = packed record
    _function : PDWORD;
  end;

  function ImageDirectoryEntryToData(Base: Pointer; MappedAsImage: ByteBool;
    DirectoryEntry: Word; var Size: ULONG): Pointer; stdcall; external 'imagehlp.dll';

var
  MapHandle: THandle = 0;
  ShareInf: PShareInf = nil;
  OldRecv: FARPROC = nil;
  Replaced: Boolean;
  AppTitle: ShortString;

//  Перехват API посредством подмены в таблице импорта
// =============================================================================
function ReplaceIATEntryInOneMod(const OldProc,
  NewProc: FARPROC): Boolean;
var
  ImportEntry: PImageImportDescriptor;
  Thunk: PImageThunkData;
  Protect, newProtect: DWORD;
  ImageBase: Cardinal;
  DOSHeader: PImageDosHeader;
  NTHeader: PImageNtHeaders;
begin
  Result := False;
  if OldProc = nil then Exit;
  if NewProc = nil then Exit;
  ImageBase := GetModuleHandle(nil);

  // Зная структуру PE заголовка - находим начало таблицы импорта
  DOSHeader := PImageDosHeader(ImageBase);
  if IsBadReadPtr(Pointer(ImageBase), SizeOf(TImageNtHeaders)) then Exit;
  if (DOSHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then Exit;
  NTHeader := PImageNtHeaders(DWORD(DOSHeader) + DWORD(DOSHeader^._lfanew));
  if NTHeader^.Signature <> IMAGE_NT_SIGNATURE then Exit;
  ImportEntry := PImageImportDescriptor(DWORD(ImageBase) +
      DWORD(NTHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
  if DWORD(ImportEntry) = DWORD(NTHeader) then Exit;

  if ImportEntry <> nil then
  begin
    // Бежим по записям таблицы ...
    while ImportEntry^.Name <> 0 do
    begin
        Thunk := PImageThunkData(DWORD(ImageBase) +
          DWORD(ImportEntry^.FirstThunk));
        // ... пока таблица не кончится ...
        while Thunk^._function <> nil do
        begin
          // ... или не найдем нужную нам запись.
          if (Thunk^._function = OldProc) then
          begin
            // Производим подмену, сначала так...
            if not IsBadWritePtr(@Thunk^._function, sizeof(DWORD)) then
            begin
              Thunk^._function := NewProc;
              Result := True;
            end
            else
            begin // ... ну а если не получилось - тогда вот так
              if VirtualProtect(@Thunk^._function, SizeOf(DWORD),
                PAGE_EXECUTE_READWRITE, Protect) then
              begin
                Thunk^._function := NewProc;
                newProtect := Protect;
                VirtualProtect(@Thunk^._function, SizeOf(DWORD),
                  newProtect, Protect);
                Result := True;
              end;
            end;
          end
          else
            Inc(PChar(Thunk), SizeOf(TImageThunkData32));
        end;
      ImportEntry := Pointer(Integer(ImportEntry) + SizeOf(TImageImportDescriptor));
    end;
  end;
end;

//  Наша функция которая будет работать вместо оригинальной ...
// =============================================================================
function InterceptedRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
type
  TrecvImage = function(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
  CDS: TCopyDataStruct;
  SockAddr: TSockAddr;
  AddrLen: Integer;
  Data: TLogData;
begin
  // Первоначально вызываем оригинальную функцию, но данные будем писать в свой буффер...
  Result := TrecvImage(OldRecv)(s, Data.Buff[0], len, flags);
  // Получаем информацию кто с кем связался
  if getpeername(s, SockAddr, AddrLen) = SOCKET_ERROR then Exit;
  Data.IP := inet_ntoa(SockAddr.sin_addr);
  Data.Port := ntohs(SockAddr.sin_port);
  Data.BuffSize := Result;
  Data.AppName := AppTitle;

  // Тут можно встроить проверку (к примеру по какому нибудь порту)
  if True then
    Move(Data.Buff[0], Buf, Result) // проверка успешна - пишем в буфер полученные данные
  else
    Result := SOCKET_ERROR;         // в противном случае говорим что вызов неуспешен.

  // Отправляем полученные данные нашему приложению...
  CDS.dwData := NOTIFY_API_CALL;
  CDS.cbData := SizeOf(TLogData);
  CDS.lpData := @Data;
  SendMessage(ShareInf^.AppWndHandle, WM_COPYDATA, 0, Integer(@CDS));
end;

//  Начало и завершение работы нашего хука ...
// =============================================================================
procedure DLLEntryPoint(dwReason: DWORD); //stdcall;  <- вот это как раз не нужно...
var
  CDS: TCopyDataStruct;
  Data: TLogData;
  ImageBase: Cardinal;
  FileName: array [0..MAX_PATH - 1] of Char;
begin
  case dwReason Of
    DLL_PROCESS_ATTACH:
    begin
      // Все данные во избежании разрыва цепочки хуков храним в отображаемом в память процесса файле,
      // только тогда все экземпляры хука будут владеть достоверной информацией
      MapHandle := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TShareInf), GlobMapID);
      ShareInf := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TShareInf));

      // Получаем информацию о процессе в который подгружена наша библиотека
      Replaced := False;
      OldRecv := GetProcAddress(GetModuleHandle('wsock32.dll'), 'recv');
      DisableThreadLibraryCalls(hInstance);
      ImageBase := GetModuleHandle(nil);
      ZeroMemory(@FileName, SizeOf(FileName));
      GetModuleFileName(ImageBase, @FileName, SizeOf(FileName));
      AppTitle := String(FileName);

      // Нотифицируем приложение о успешном внедрении библиотеки
      // И сообщаем информацию о процессе
      ZeroMemory(@Data, SizeOf(TLogData));
      Data.AppName := AppTitle;
      Data.FuncName := 'recv';
      Data.FuncPointer := Integer(OldRecv);

      CDS.dwData := NOTIFY_DLL_INJECT;
      CDS.cbData := SizeOf(TLogData);
      CDS.lpData := @Data;
      SendMessage(ShareInf^.AppWndHandle, WM_COPYDATA, 0, Integer(@CDS));

      // Подменяем процедуры своими (если это нужное нам приложение)
      if Pos('NETCHAT.EXE', AnsiUpper(@FileName)) <>0 then
      begin
        if OldRecv <> nil then
          // Смотрим - успешно ли подменилась запись в таблице импорта?
          if ReplaceIATEntryInOneMod(OldRecv, @InterceptedRecv) then
          begin
            CDS.dwData := NOTIFY_API_INTERCEPT_SUCCESS; // Успешно...
            Replaced := True;                           // Ставим флаг, что была замена...
          end
          else
            CDS.dwData := NOTIFY_API_INTERCEPT_FAILED;  // Не успешно...

        // Нотифицируем наше приложение о результате подмены...
        CDS.cbData := SizeOf(TLogData);
        CDS.lpData := @Data;
        SendMessage(ShareInf^.AppWndHandle, WM_COPYDATA, 0, Integer(@CDS));
      end;
    end;
    DLL_PROCESS_DETACH:
    begin
      UnMapViewOfFile(ShareInf);
      CloseHandle(MapHandle);
      // Возвращаем изменения как они и были (если замена была удачна)
      if Replaced then
        ReplaceIATEntryInOneMod(@InterceptedRecv, OldRecv);
    end;
  end;
end;

//  Это наш хук, он нужен только для внедрения в удаленный процесс ...
// =============================================================================
function Hook(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
begin
  Result := CallNextHookEx(ShareInf^.OldHookHandle, Code, WParam, LParam); // вызываем след. ловушку
end;

//  Установка хука ...
// =============================================================================
function SetHook(Wnd: HWND): BOOL; stdcall;
begin
  if ShareInf <> nil then
  begin
    ShareInf^.AppWndHandle := Wnd;
    ShareInf^.OldHookHandle := SetWindowsHookEx(WH_GETMESSAGE, @Hook, HInstance, 0); // <- Обратите внимание, не допускаем главной ошибки
    Result := ShareInf^.OldHookHandle <> 0;
  end
  else 
    Result:=False;
end;

//  Снятие хука ...
// =============================================================================
function RemoveHook: BOOL; stdcall;
begin
  Result := UnhookWindowsHookEx(ShareInf^.OldHookHandle);
  CloseHandle(ShareInf^.hm);
end;

exports
  SetHook, RemoveHook;

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


Приложение:

Код

////////////////////////////////////////////////////////////////////////////////
//
//  ****************************************************************************
//  * Unit Name : uMain
//  * Purpose   : Демонстрационный пример хука и подмены API в приложениях...
//  * Author    : Александр (Rouse_) Багель
//  * Version   : 1.00
//  ****************************************************************************
//

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ActiveX;

const // Константы нотификаций
  NOTIFY_DLL_INJECT = 1;
  NOTIFY_API_CALL = 2;
  NOTIFY_API_INTERCEPT_SUCCESS = 3;
  NOTIFY_API_INTERCEPT_FAILED = 4;

type
  TLogData = record
    AppName: ShortString; // Имя приложения
    FuncName: String[8];  // Имя функции
    FuncPointer: Integer; // Адрес функции
    IP: String[15];       // IP адрес
    Port: Cardinal;       // Порт
    Buff: array [0..$FFFF] of Char; // Содержимое буффера
    BuffSize: Word;       // Размер буфера
  end;
  PLogData = ^TLogData;

  THADemo = class(TForm)
    memReport: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    procedure WMCopyData(var Msg: TMessage); message WM_COPYDATA;
  end;

  function SetHook(Wnd: HWND): BOOL; stdcall;
    external 'HookDLL.dll' name 'SetHook';
  function RemoveHook: BOOL; stdcall;
    external 'HookDLL.dll' name 'RemoveHook';     

var
  HADemo: THADemo;

implementation

{$R *.dfm}

{ TForm1 }

procedure THADemo.FormCreate(Sender: TObject);
begin
  if not SetHook(Handle) Then
    MessageBox(Handle, 'Невозможно установить хук.', PChar(Application.Title), MB_OK OR MB_ICONHAND);
end;

procedure THADemo.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if not RemoveHook Then
    MessageBox(Handle, 'Невозможно снять хук.', PChar(Application.Title), MB_OK OR MB_ICONHAND);
end;

procedure THADemo.WMCopyData(var Msg: TMessage);
const
  ReportInject = 'Библиотека внедрена в приложение "%s", функция "%s" имеет адрес: $%s';
  ReportIntercept = 'Приложение: "%s" IP %s:%d размер данных = %d буфер = "%s"';
  ReportSucceeded = 'Перехват функции "%s" в модуле "%s" успешен.';
  ReportFailed = 'Перехват функции "%s" в модуле "%s" неуспешен!!!';
var
  Data: TLogData;
  Buffer: String;
begin
  Data := PLogData(PCopyDataStruct(Msg.LParam)^.lpData)^;
  // Типы нотификаций
  case PCopyDataStruct(Msg.LParam)^.dwData of
    NOTIFY_DLL_INJECT: // Пришло уведомление о внедрении библиотеки в удаленный процесс
      with Data do
        memReport.Lines.Add(Format(ReportInject, [AppName, FuncName,
          IntToHex(Data.FuncPointer, 8)]));
    NOTIFY_API_CALL: // Уведомление о вызове функции
    begin
      SetLength(Buffer, Data.BuffSize);
      Move(Data.Buff[0], Buffer[1], Data.BuffSize);
      with Data do
        memReport.Lines.Add(Format(ReportIntercept, [AppName, IP, Port, BuffSize, Buffer]));
    end;
    NOTIFY_API_INTERCEPT_SUCCESS: // Уведомление о удачной подмене таблицы импорта
      with Data do
        memReport.Lines.Add(Format(ReportSucceeded, [FuncName, AppName]));
    NOTIFY_API_INTERCEPT_FAILED: // Уведомление о неудачной подмене таблицы импорта
      with Data do
        memReport.Lines.Add(Format(ReportFailed, [FuncName, AppName]));
  end;
end;

end.


Но правильней всего внедрять не хуком а через CreateRemoteThread

Примерно вот так:

Код

////////////////////////////////////////////////////////////////////////////////
//
//  ****************************************************************************
//  * Project   : Inject/Eject Library Demo
//  * Unit Name : main
//  * Purpose   : Демонстрационный пример внедрения библиотеки через CreateRemoteThread
//  * Author    : Александр (Rouse_) Багель
//  * Version   : 1.00
//  ****************************************************************************
//

unit main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

resourcestring
  BTN_INJECT = 'Inject';
  BTN_EJECT  = 'Eject';
  
const
  DLLName = 'hooklib.dll';

type
  TfrmMain = class(TForm)
    btnInjectEject: TButton;
    GroupBox: TGroupBox;
    lbStatus: TListBox;
    procedure btnInjectEjectClick(Sender: TObject);
  private
    function InjectLib(const ProcessID: DWORD): Boolean;
    function EjectLib(const ProcessID: DWORD): Boolean;
  end;

  // Декларация функций при помощи которых будет происходить выгрузка билиотеки
  TGetModuleHandle = function (lpModuleName: PChar): HMODULE; stdcall;
  TFreeLibrary = function (hLibModule: HMODULE): BOOL; stdcall;

  // Структура передаваемая потоковой функции при выгрузке библиотеки
  PEjectLibStruct = ^TEjectLibStruct;
  TEjectLibStruct = record
    hGetModuleHandle: TGetModuleHandle;
    hFreeLibrary: TFreeLibrary;
    lpModuleName: PChar;
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

{ TfrmMain }

//  Обработчик кнопки на внедрение/выгрузку библиотеки
// =============================================================================
procedure TfrmMain.btnInjectEjectClick(Sender: TObject);
begin
  TComponent(Sender).Tag := TComponent(Sender).Tag + 1;
  if (TComponent(Sender).Tag mod 2) = 1 then
  begin
    btnInjectEject.Caption := BTN_EJECT;
    if InjectLib(GetCurrentProcessID) then
      lbStatus.Items.Add('Library injected succes.')
    else
      lbStatus.Items.Add('Library injected fail.');
  end
  else
  begin
    btnInjectEject.Caption := BTN_INJECT;
    if EjectLib(GetCurrentProcessID) then
      lbStatus.Items.Add('Library ejected succes.')
    else
      lbStatus.Items.Add('Library ejected fail.');
  end;
end;

//  Пока наш процесс не получит отлабочные привилегии,
//  весь этот код работать не будет
// =============================================================================
function SetDebugPriv: Boolean;
var
  Token: THandle;
  tkp: TTokenPrivileges;
  ReturnLength: DWORD;
begin
  Result := false;
  // Получаем токен текущего процесса
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then
  begin
    // Получаем Luid привилегии
    if LookupPrivilegeValue(nil, PChar('SeDebugPrivilege'), tkp.Privileges[0].Luid) then
    begin
      // Заполняем необходимые параметры
      tkp.PrivilegeCount := 1;
      tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
      // Включаем привилегию
      Result := AdjustTokenPrivileges(Token, false, tkp, 0, nil, ReturnLength);
    end;
  end;
end;     

//  Функция внедряет библиотеку в удаленный процесс с PID равным ProcessID
//  Для успешного внедрения нужно передать адрес функции LoadLibraryA
//  и путь к загружаемой библиотеке.
//  Строку с путем необходимо разместить в алресном пространстве удаленного процесса
// =============================================================================
function TfrmMain.InjectLib(const ProcessID: DWORD): Boolean;
var
  Process: HWND;
  ThreadRtn: FARPROC;
  DllPath: String;
  RemoteDll: Pointer;
  BytesWriten: DWORD;
  Thread: DWORD;
  ThreadId: DWORD;
  ExitCode: DWORD;
begin
  // Устанавливаем отладочные привилегии для нашего процесса
  Result := SetDebugPriv;
  if not Result then Exit;
  Process := 0;
  Thread := 0;
  try
    // Открываем процесс
    Process := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or
      PROCESS_VM_WRITE, True, ProcessID);
    if Process = 0 then Exit;
    // Выделяем в нем память под строку
    DllPath := ExtractFilePath(ParamStr(0)) + DLLName;
    RemoteDll := VirtualAllocEx(Process, nil, Length(DllPath),
      MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
    if RemoteDll = nil then Exit;
    // Пишем путь к длл в его адресное пространство
    if not WriteProcessMemory(Process, RemoteDll, PChar(DllPath),
      Length(DllPath), BytesWriten) then Exit;
    if BytesWriten <> DWORD(Length(DllPath)) then Exit;
    // Получаем адрес функции из Kernel32.dll
    ThreadRtn := GetProcAddress(GetModuleHandle('Kernel32.dll'), 'LoadLibraryA');
    if ThreadRtn = nil then Exit;
    // Запускаем удаленный поток
    Thread := CreateRemoteThread(Process, nil, 0, ThreadRtn, RemoteDll, 0, ThreadId);
    if Thread = 0 then Exit;
    // Ждем пока удаленный поток отработает...
    if (WaitForSingleObject(Thread, INFINITE) = WAIT_OBJECT_0) then
      if GetExitCodeThread(Thread, ExitCode) then
        Result := ExitCode = 0;
  finally
    // Удаленный поток свою задачу выполнил и загрузил нашу библиотеку,
    // можно освобождать занятую память...
    if RemoteDll <> nil then
      VirtualFreeEx(Process, @RemoteDll, 0, MEM_RELEASE);
    if Thread <> 0 then CloseHandle(Thread);
    if Process <> 0 then CloseHandle(Process);  
  end;
end;

//  Для того чтобы выгрузить библиотеку, необходимо найти ее адрес в удаленном
//  процессе и вызвать там же FreeLibrary
//  Этим у нас будет заниматься вот такая функция
//  Для успешной ее работы необходимо передать 3 параметра.
//  1: Адреса функций GetModuleHandle и FreeLibrary;
//  2: Имя модуля, выгрузку которого мы будем производить
// =============================================================================
function RemoteFreeLibrary(lpParameter: Pointer): DWORD; stdcall;
var
  hLibModule: HMODULE;
begin
  Result := 0;
  if lpParameter = nil then Exit;
  // Получаем описатель нашей библиотеки (используем переданные параметры)
  hLibModule := TGetModuleHandle(PEjectLibStruct(lpParameter)^.hGetModuleHandle)
    (PEjectLibStruct(lpParameter)^.lpModuleName);
  if hLibModule <> 0 then
    // Выгружаем библиотеку
    Result := DWORD(TFreeLibrary(PEjectLibStruct(lpParameter)^.hFreeLibrary)(hLibModule));
end;

//  Данная функция запускает в удаленном процессе поток
//  с потоковой функцией RemoteFreeLibrary
//  и подготавливает для ее работы необходимые данные
// =============================================================================
function TfrmMain.EjectLib(const ProcessID: DWORD): Boolean;
var
  Process: HWND;
  BytesWriten: DWORD;
  Thread: DWORD;
  ThreadId: DWORD;
  ExitCode: DWORD;
  EjectLibStruct: TEjectLibStruct;
  EjectLibStructAddr: Pointer;
begin
  Result := False;
  Process := 0;
  Thread := 0;
  try
    // Открываем процесс
    Process := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or
      PROCESS_VM_WRITE, True, ProcessID);
    if Process = 0 then Exit;
    // Выделяем в нем память под имя модуля
    EjectLibStruct.lpModuleName := VirtualAllocEx(Process, nil, Length(DLLName),
      MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
    if EjectLibStruct.lpModuleName = nil then Exit;
    // Пишем имя модуля в его адресное пространство
    if not WriteProcessMemory(Process, EjectLibStruct.lpModuleName, PChar(DLLName),
      Length(DLLName), BytesWriten) then Exit;
    if BytesWriten <> DWORD(Length(DLLName)) then Exit;
    // Получаем адрес функции FreeLibrary из Kernel32.dll
    EjectLibStruct.hFreeLibrary :=
      GetProcAddress(GetModuleHandle('Kernel32.dll'), 'FreeLibrary');
    if not Assigned(EjectLibStruct.hFreeLibrary) then Exit;
    // Получаем адрес функции GetModuleHandle из Kernel32.dll
    EjectLibStruct.hGetModuleHandle :=
      GetProcAddress(GetModuleHandle('Kernel32.dll'), 'GetModuleHandleA');
    if not Assigned(EjectLibStruct.hGetModuleHandle) then Exit;
    // Выделяем память под структуру, которая передается нашей функции
    EjectLibStructAddr := VirtualAllocEx(Process, nil, SizeOf(TEjectLibStruct),
      MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
    if EjectLibStructAddr = nil then Exit;
    // Пишем саму структуру
    if not WriteProcessMemory(Process, EjectLibStructAddr, @EjectLibStruct,
      SizeOf(TEjectLibStruct), BytesWriten) then Exit;
    if BytesWriten <> DWORD(SizeOf(TEjectLibStruct)) then Exit;

    // Запускаем удаленный поток
    Thread := CreateRemoteThread(Process, nil, 0, @RemoteFreeLibrary,
      EjectLibStructAddr, 0, ThreadId);
    if Thread = 0 then Exit;
    // Ждем пока удаленный поток отработает...
    if (WaitForSingleObject(Thread, INFINITE) = WAIT_OBJECT_0) then
      if GetExitCodeThread(Thread, ExitCode) then
        Result := BOOL(ExitCode);
  finally
    // Удаленный поток свою задачу выполнил и выгрузил нашу библиотеку,
    // можно освобождать занятую память...
    VirtualFreeEx(Process, @EjectLibStruct.lpModuleName, 0, MEM_RELEASE);
    VirtualFreeEx(Process, @EjectLibStructAddr, 0, MEM_RELEASE);
    if Thread <> 0 then CloseHandle(Thread);
    if Process <> 0 then CloseHandle(Process);
  end;
end;

end.
 


--------------------
 Vae Victis
(Горе побежденным (лат.))
Демо с открытым кодом: http://rouse.drkb.ru 
PM MAIL WWW ICQ   Вверх
Teran
Дата 5.5.2006, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

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



хочу сделать свой хук чтобы при обнаружении определенного URL автоматически перенаправлял на другой URL

Вот добился:
при открытии www.ya.ru получаю Http запрос такой:
Код

GET http://www.ya.ru/ HTTP/1.0
Accept: */*
Accept-Language: en-us
Proxy-Connection: Keep-Alive
If-Modified-Since: Fri, 13 Jan 2006 11:32:57 GMT; length=2003
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: www.ya.ru


при открытии ya.ru этот 
Код

GET http://gmail.com/ HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-icq, application/x-shockwave-flash, */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: gmail.com
Proxy-Connection: Keep-Alive


но вот перенаправить не получается 
в хуке сделал StringReplace(...., 'gmail.com', 'ya.ru', [rfReplaceAll, rfIgnoreCase])
и даже пакет отправляется такой 
Код

GET http://ya.ru/ HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-icq, application/x-shockwave-flash, */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: ya.ru
Proxy-Connection: Keep-Alive


НО страница в эксплорере тормозит и не хочет грузится
не подскажеш из-за чего это может быть? smile  smile  smile  
PM MAIL ICQ   Вверх
Teran
Дата 5.5.2006, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

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



Похоже что с перенаправлением URL у меня ничего не выйдет.

даже если для функции 
Код

Send(s: TSocket; var Buf; len, flags: Integer)

http запрос(Buf) - можно изменить, то соединение по сокету остаётся тоже самое 


Никто не сталкивался с такой проблемой? smile  smile  smile  


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

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

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

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


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

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


 




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


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

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