Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.02.2012, 00:22   #1
Zeneth
Пользователь
 
Регистрация: 16.06.2009
Сообщений: 21
Вопрос Перехват DrawText, проблема с возвратом управления оригиналу.

Всем доброго времени суток.
Собственно вот такая ДЛЛка имеется:
Код:
library dllka;

uses
  Windows,
  ExAPI,
  APIhoking,
  messages,
  SysUtils,

{$R *.res}
const
  MutexName='__API_HOOK';
  CMD_SETEDITTEXT=1;

var
  Hook:HHOOK;
  Sotr:Pchar;

  SystemFunctionBridge:TFunctionRestoreData;

function newDrawTextW(DC: HDC; Str: PChar; Count: Integer; var Rect: TRect; Format:Uint): Integer; stdcall;
var
  info,back_Proc:PSYSTEM_PROCESSES;
  CDS: TCopyDataStruct;
begin

  UnHookCodeHook(@SystemFunctionBridge);
  SetCodeHook(SystemFunctionBridge.Address,@NewDrawTextW,@SystemFunctionBridge);
  CDS.dwData := CMD_SETEDITTEXT;
  CDS.cbData := Length(Str) + 1;
  GetMem(CDS.lpData, CDS.cbData);
    StrPCopy(CDS.lpData, AnsiString(Str));
    SendMessage(FindWindow(nil, 'Catcher'),
                  WM_COPYDATA, 1574634, Integer(@CDS));
    FreeMem(CDS.lpData, CDS.cbData);
   OutputDebugString('Sended');
end;

function MsgProc(code:DWORD;wParam,lparam:DWORD):DWORD; stdcall;
begin
  CallNextHookEx(Hook,code,wParam,lparam);
end;

procedure SetGlobalHook(How:Boolean); stdcall;
var
  Mut:THandle;
begin
  if How then
   begin
    Mut:=CreateMutex(0,false,MutexName);
    if Mut=0 then exit;
    Hook:=SetWindowsHookEx(WH_GETMESSAGE,@MsgProc,HInstance,0);
   end
       else
    UnhookWindowsHookEx(Hook);
end;

procedure DLLEntryPoint(dwReason:DWord);
var S:string;
begin
  case dwReason of
    DLL_PROCESS_ATTACH:
     begin
      SetGlobalHook(true);
      HookProcedure(GetModuleHandle('user32.dll'),'DrawTextW',@NewSystemFunction,@SystemFunctionBridge);
     end;
    DLL_PROCESS_DETACH:
     begin
      SetGlobalHook(false);
      UnHookCode(@SystemFunctionBridge);
     end;
   end;
end;

begin
   DllProc:= @DLLEntryPoint;
   DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Вот так работают
HookCode, UnHookCode и HookProcedure:

Код:

function HookCode(ProcAddress, NewProcAddress: pointer; RestoreDATA:PFunctionRestoreData):boolean;
var
  OldProtect, JMPValue:DWORD;
begin
  Result:=False;
  if not VirtualProtect(ProcAddress,5,PAGE_EXECUTE_READWRITE,OldProtect) then exit;
  JMPValue := DWORD(NewProcAddress) - DWORD(ProcAddress) - 5;
  RestoreDATA^.val1:= Byte(ProcAddress^);
  RestoreDATA^.val2:= DWORD(Pointer(DWORD(ProcAddress)+1)^);
  RestoreDATA^.Address:=ProcAddress;
  byte(ProcAddress^):=$E9;
  DWORD(Pointer(DWORD(ProcAddress)+1)^):=JMPValue;
  Result:=VirtualProtect(ProcAddress,5,OldProtect,OldProtect);
  if result=true then outputdebugstring('Проверка: Атлычно, все пашет.');

end;

function UnHookCode(RestoreDATA:PFunctionRestoreData):Boolean;
var
  ProcAddress:Pointer;
  OldProtect,JMPValue:DWORD;
begin
  Result:=False;
  ProcAddress:=RestoreDATA^.Address;
  if not VirtualProtect(ProcAddress,5,PAGE_EXECUTE_READWRITE,OldProtect) then exit;
  Byte(ProcAddress^):=RestoreDATA^.val1;
  DWORD(Pointer(DWORD(ProcAddress)+1)^):=RestoreDATA^.val2;
  Result:=VirtualProtect(ProcAddress,5,OldProtect,OldProtect);
end;

function HookProcedure(ModuleHandle:HMODULE;ProcedureName:PChar;NewProcedureAddress:Pointer;
   RestoreDATA:PFunctionRestoreData):Boolean;
var
  ProcAddress:Pointer;
begin
  ProcAddress:=GetProcAddress(ModuleHandle,ProcedureName);
  outputdebugstring(Pchar(ProcAddress));
  Result:=SetCodeHook(ProcAddress,NewProcedureAddress,RestoreDATA);
end;
Дллка прекрасно справляется со своей задачей - перехватом нужной мне инфы.
НО!
Почему она не после отработки процедуры хука управление не отдается оригиналу DrawTextW?
Может я чего-то не то с адресами намудрил?
Хотя из анализа кучи статей на тему сплайсинга и перехвата вообще, получается что считаю я все верно.
Практически все статьи, кроме этой:
http://www.wasm.ru/article.php?article=apihook_2
дублируют друг-друга в той или иной степени

В общем нужна помощь
Заранее спасибо.
Zeneth вне форума Ответить с цитированием
Старый 17.02.2012, 01:16   #2
yuran666666
Форумчанин
 
Аватар для yuran666666
 
Регистрация: 23.04.2009
Сообщений: 346
По умолчанию

Выкладывай бинарники exe и dll посмотрим что там не так
Нет, ну правда..
yuran666666 вне форума Ответить с цитированием
Старый 17.02.2012, 14:53   #3
Zeneth
Пользователь
 
Регистрация: 16.06.2009
Сообщений: 21
По умолчанию

Вечером выложу, пока нет возможности.
Код здесь не такой большой, из его анализа все нормально что-ли?

Да, и еще, в перспективе лучше будет ДЛЛку только в один процесс(Или пару ).
Пока не получилось.. но и пробовал не много, правда
Если у кого-то есть примеры, буду признателен.

P.S. Знаю, что примеров много, но пока что-то не вышло
И основа - это все-таки возврат управления перехватываемой функции.
Zeneth вне форума Ответить с цитированием
Старый 17.02.2012, 22:11   #4
yuran666666
Форумчанин
 
Аватар для yuran666666
 
Регистрация: 23.04.2009
Сообщений: 346
По умолчанию

Да там непонятно ничего откуда управление должно возвращаться даже
мне например совсем не очевидно где находится @NewSystemFunction и прочее
ну если принять, что системная функция сплайсится сюда @newDrawTextW
то там какие то вообще непонятные махинации. это насколько я понимаю сплайс снимается и сразу опять ставится зачем то
UnHookCodeHook(@SystemFunctionBridg e);
SetCodeHook(SystemFunctionBridge.Ad dress,@NewDrawTextW,@SystemFunction Bridge);
в конце управление в этой функции перехватчике управление ret'ом, с выталкиванием всех аргументов оригинальной функции передается вызывающему её коду. то есть просто минуя саму оригинальную функцию происходит выход из перехватчика в код, который вызывал DrawTextW. По делу (в многопоточных приложениях так разумеется не делается без остановки потоков или же переписывания первых байт функции затертых переходом на перехватчик) как то так надо:
тут в начале код полезной нагрузки
UnHookCodeHook(@SystemFunctionBridg e); тут снятие сплайсинга с функции
DrawTextW(DC: HDC; Str: PChar; Count: Integer; var Rect: TRect; Format:Uint) тут вызов оригинальной функции с ее параметрами
SetCodeHook(SystemFunctionBridge.Ad dress,@NewDrawTextW,@SystemFunction Bridge); установка сплайсинга обратно
Нет, ну правда..
yuran666666 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Функция DrawText() БалаШагаЛ Win Api 2 13.10.2011 20:06
Проблема с возвратом fstream Farrel Общие вопросы C/C++ 11 09.03.2011 19:03
Проблема с выбором нужного элемента управления. kushnarenkoa Помощь студентам 1 17.12.2010 19:14
проблема использования элементов управления в word sirius_ltd Microsoft Office Word 2 30.09.2010 17:51
TextOut и DrawText Claster Помощь студентам 3 29.03.2010 18:59