Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.11;
Скачать: CL | DM;

Вниз

Парадокс при перехвате API   Найти похожие ветки 

 
StAL ©   (2004-03-15 15:30) [0]

Здравствуйте, ув. Мастера!

  При перехвате API методом правки таблицы импорта происходит следующее.

Если приложение-перехватчик скомпилирован на VC++, ф-ции НЕ перехватываются в Delphi-приложениях, и наоборот - приложение-перехватчик, написанное на Delphi не перехватывает вызовы функций на VC++ приложениях.

Примеры:

Дж. Рихтер. Windows для профессионалов - LastMsgBoxInfo. НЕ перехватывается вызов MessageBoxA/W из Delphi приложений. (Переписывал на Delphi - наоборот)
Мэтт Питрек Win95 System Programming Secrets - тоже самое
Статьи с RSDN.ru - тоже самое

Пожалуйста, если кто-то знает причину таких недоразумений, помогите хотя-бы советом, ну а тлучше, конечно-же, рабочим кодом, но я понимаю, что времени у Вас не так уж много.

Заранее большое спасибо,

С ув. Алексей


 
BiN ©   (2004-03-15 15:37) [1]

а ты фортрановские функции из бэйсика перехватывать не пробовал? :)
Может, ты забыл внедрить функию перехвата


 
StAL ©   (2004-03-15 15:48) [2]

2BiN
 А это идея!! :)
В том-то и дело, что не забыл! Библиотека внедряется во все процессы, и
- если она написана на Delphi, перехватывается только в Delphi-приложениях
- если она написана на VС++, перехватывается только в VC++ приложениях

Запускал примеры Рихтера, Питрека, статей, ...

С ув. Алексей


 
BiN ©   (2004-03-15 15:54) [3]

Нет никакого парадокса. Ошибка у тебя где-то


 
StAL ©   (2004-03-15 15:58) [4]

2BiN

Я ведь даже не про свой код говорю. У Рихтера, Питрека, да вообще любой пример в интернете по перехвату API методом правки IAT обладает иаким глюком.

С ув. Алексей


 
BiN ©   (2004-03-15 16:08) [5]

...помогите хотя-бы советом, ну а тлучше, конечно-же, рабочим кодом


function MakePtr(base:Dword;Offset:DWORD):Pointer;
begin
 Result:=Pointer(Base+Offset);
end;

function ReplaceIATEntry(hLocalHinst:HINST;
                        ProcAddr,
                        NewProcAddr:Pointer):pointer; overload;
var
 pDosHeader:PImageDosHeader;
 pNtHeader:PImageNtHeaders;
 PImportDesc:PImageImportDescriptor;
 dwProtect:DWORD;
 dwNewProtect:DWORD;
 dwAddressToInterCept:DWORD;
 pThunk:PImageThunkData;
begin
 Result:=nil;
 if ProcAddr=nil then exit;
 pDosHeader:=PImageDosHeader(hLocalHinst);
 dwAddressToIntercept:=Dword(ProcAddr);

 if IsBadReadPtr(Pointer(hLocalHinst),sizeof(PImageNtHeaders)) then Exit;
 if pDosHeader.e_magic<>IMAGE_DOS_SIGNATURE then exit;

 pNtHeader:=PImageNtHeaders(MakePtr(DWord(pDOSHeader),DWord(pDOSHeader._lfanew)));
 if pNTHeader.signature<>IMAGE_NT_SIGNATURE then exit;
 pImportDesc:=PImageImportDescriptor(

 MakePtr(hLocalHinst,
 pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
 if (PImportDesc=PImageImportDescriptor(pNtHeader))  then exit;
 while(pImportDesc.Name>0)do
 begin
   pThunk:=PImageThunkData(MakePtr(DWord(hLocalHinst),
   Dword(pImportDesc.FirstThunk)));
   while(pThunk.u1.Functionn<>nil) do
   begin
     if DWord(pThunk.u1.Functionn)=dwAddressToIntercept then
     begin
       if not IsBadWritePtr(Pointer(@pThunk.u1.Functionn),sizeof(DWORD)) then
       begin
         Result:=Pointer(pThunk.u1.Functionn);
         pThunk.u1.Functionn:=NewProcAddr;
       end
       else
       begin
         if VirtualProtect(Pointer(@pThunk.u1.Functionn),sizeof(DWORD),
                           PAGE_EXECUTE_READWRITE,@dwProtect) then
         begin
           Result:=Pointer(pThunk.u1.Functionn);
           pThunk.u1.Functionn:=PDWORD(NewProcAddr);
           dwNewProtect:=dwProtect;
           VirtualProtect(Pointer(@pThunk.u1.Functionn),
           sizeof(DWORD),dwNewProtect,@dwProtect);
         end;
       end;
     end;
     Inc(PThunk);
   end;
   Inc(pImportDEsc);
 end;
end;

function ReplaceIATEntry(
       hLocalHinst:HINST;
       lpLibName:Pchar;
       lpProcName:PChar;
       NewProcAddr:Pointer):Pointer; overload;
begin
 Result:=ReplaceIATEntry(hLocalHinst,
         GetProcAddress(GetModuleHandle(lpLibName),lpProcName), NewProcAddr);
end;


 
StAL ©   (2004-03-15 16:13) [6]

2BiN

Спасибо, я проверю. Надеюсь на лучшее конечно, но...

Спасибо,
с ув. Алексей


 
Digitman ©   (2004-03-15 17:34) [7]


> StAL ©   (15.03.04 15:48) [2]


> Библиотека внедряется во все процессы


в GUI-процессы ... и только ... если речь идет о хук-DLL


 
StAL ©   (2004-03-15 19:19) [8]

2BiN
 То же самое и с Вашим кодом
2Digitman
 Согласен с Вами, я это и имел в виду, просто неправильно выразился. Спасибо за поправку, но факт остается фактом...

С ув. Алексей


 
StAL ©   (2004-03-15 19:28) [9]

2BiN
 С Вашим кодом то же самое
2Digitman
 Именно это я и имел ввиду, просто неправильно выразился. Но факт остается фактом...


 
StAL ©   (2004-03-15 19:29) [10]

Извиняюсь, глюк вышел.

С ув. Алексей


 
Digitman ©   (2004-03-16 08:14) [11]


> StAL


ну хорошо ... предположим, что MessageBoxA/W есть некая хитрозадая ф-ция, не поддающаяся перехвату) ..

а иные ф-ции ? как у тебя с ними дела обстоят ? к примеру, LoadLibraryA/W ?


 
BiN ©   (2004-03-16 09:26) [12]

  StAL ©   (15.03.04 19:19) [8]
То же самое и с Вашим кодом


Вот мой код. Не поленился и только что накатал тест. При внедрении этой библиотеки в notepad всепрекрасно перехватывается.
Сдается мне, что в Дельфи ты везде используешь MessageBoxA и пытаешься ее перехватывать, а MS использует  unicode layer, т.е. функции MessageBoxW


library msgbx;

uses
 Windows, IAT;//<<<< В IAT содержится функция ReplaceIATEntry

var
 OlDMsgBox:function (hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;

function MyMsgBox(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
begin
 Result:=OlDMsgBox(hWnd, lpText, lpCaption, MB_ICONWARNING);//<=== Меняем UType на MB_ICONWARNING
end;

begin
 @OlDMsgBox:=ReplaceIATEntry(GetModuleHandle(nil), user32, "MessageBoxW", @MyMsgBox);
end.



 
StAL ©   (2004-03-16 17:08) [13]

2Digitman
 Проверял на CreateProcessA/W, а MessageBox - это у Рихтера.

2BiN
 Проверю еще раз, но может все дело в ImageImportDescriptor
Как Вы перевели?

type
PImageThunkData = ^TImageThunkData;
TImageThunkData = packed record
  case Byte of
    0: (ForwarderString: PByte);
    1: (Func:   PLongWord);
    2: (Ordinal: LongWord);
    3: (AddressOfData: PLongWord);
  end;

PImageImportDescriptor = ^TImageImportDescriptor;
TImageImportDescriptor = packed record
  RVAImportLookupTable: LongWord;
  TimeDateStamp: LongWord;
  FowarderChain: LongWord;
  RVAImportModuleName: LongWord;
  RVAImportAddressTable: LongWord;
end;

Я использовал такой перевод, или такой

type
 PImageImportByName = ^TImageImportByName;
 TImageImportByName = packed record
   Hint: Word;
   Name: packed array [0..0] of char;
 end;

 PImageThunkData = ^TImageThunkData;
 TImageThunkData = packed record
   case Byte of
     0: (ForwarderString : PByte);
     1: (Func            : PLongWord);
     2: (Ordinal         : LongWord);
     3: (AddressOfData   : PImageImportByName);
   end;

 PImportLookupTable = ^TImportLookupTable;
 TImportLookupTable = packed array
                      [0..IMAGE_MAX_IMPORT_MODULE_ENTRIES - 1]
                      of TImageThunkData;

 PImportAddressTable = ^TImportAddressTable;
 TImportAddressTable = packed array
                       [0..IMAGE_MAX_IMPORT_MODULE_ENTRIES - 1]
                       of TImageThunkData;

 PImageImportDescriptor = ^TImageImportDescriptor;
 TImageImportDescriptor = packed record
   RVAImportLookupTable: PImportLookupTable;
   TimeDateStamp: LongWord;
   FowarderChain: LongWord;
   RVAImportModuleName: LongWord;
   RVAImportAddressTable: PImportAddressTable;
 end;


 
Digitman ©   (2004-03-16 18:13) [14]


> Проверял на CreateProcessA/W


ну и как ?  каковы результаты-то ?


> MessageBox - это у Рихтера


да хотбь у самого господа бога ! суть-то неизменна) ... что CreateProcess, что MessageBox - одной табакерки черти ...


 
StAL ©   (2004-03-19 15:05) [15]

2Digitman
 Не перехватывается
С ув. Алексей


 
Digitman ©   (2004-03-19 17:25) [16]

тогда ответ один - см. [3]


 
EXE7   (2004-03-20 14:31) [17]

может stdcall - вызовы или незапускайте под делфи



Страницы: 1 вся ветка

Текущий архив: 2004.04.11;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.03 c
4-1076098453
димка
2004-02-06 23:14
2004.04.11
Как определить, что какое-то приложение создало файл


1-1082570828
ЯЯЯ
2004-04-21 22:07
2004.04.11
Как узнать выбранную ячейку в StringGrid.


3-1079325995
Janbolat
2004-03-15 07:46
2004.04.11
данные вычисляемых полей не сохраняются


9-1065468251
Spose
2003-10-06 23:24
2004.04.11
У DirectX 8 пытаюсь применить процедуру Lock к BackBuffer


1-1082621579
Stas
2004-04-22 12:12
2004.04.11
Работа с памятью