Форум: "WinAPI";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
ВнизПарадокс при перехвате 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 - тоже самое
Пожалуйста, если кто-то знает причину таких недоразумений, помогите хотя-бы советом, ну а тлучше, конечно-же, рабочим кодом, но я понимаю, что времени у Вас не так уж много.
Заранее большое спасибо,
С ув. Алексей
← →
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]а ты фортрановские функции из бэйсика перехватывать не пробовал? :)
Может, ты забыл внедрить функию перехвата
← →
BiN © (2004-03-15 15:37) [1]а ты фортрановские функции из бэйсика перехватывать не пробовал? :)
Может, ты забыл внедрить функию перехвата
← →
StAL © (2004-03-15 15:48) [2]2BiN
А это идея!! :)
В том-то и дело, что не забыл! Библиотека внедряется во все процессы, и
- если она написана на Delphi, перехватывается только в Delphi-приложениях
- если она написана на VС++, перехватывается только в VC++ приложениях
Запускал примеры Рихтера, Питрека, статей, ...
С ув. Алексей
← →
StAL © (2004-03-15 15:48) [2]2BiN
А это идея!! :)
В том-то и дело, что не забыл! Библиотека внедряется во все процессы, и
- если она написана на Delphi, перехватывается только в Delphi-приложениях
- если она написана на VС++, перехватывается только в VC++ приложениях
Запускал примеры Рихтера, Питрека, статей, ...
С ув. Алексей
← →
BiN © (2004-03-15 15:54) [3]Нет никакого парадокса. Ошибка у тебя где-то
← →
BiN © (2004-03-15 15:54) [3]Нет никакого парадокса. Ошибка у тебя где-то
← →
StAL © (2004-03-15 15:58) [4]2BiN
Я ведь даже не про свой код говорю. У Рихтера, Питрека, да вообще любой пример в интернете по перехвату API методом правки IAT обладает иаким глюком.
С ув. Алексей
← →
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;
← →
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
Спасибо, я проверю. Надеюсь на лучшее конечно, но...
Спасибо,
с ув. Алексей
← →
StAL © (2004-03-15 16:13) [6]2BiN
Спасибо, я проверю. Надеюсь на лучшее конечно, но...
Спасибо,
с ув. Алексей
← →
Digitman © (2004-03-15 17:34) [7]
> StAL © (15.03.04 15:48) [2]
> Библиотека внедряется во все процессы
в GUI-процессы ... и только ... если речь идет о хук-DLL
← →
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:19) [8]2BiN
То же самое и с Вашим кодом
2Digitman
Согласен с Вами, я это и имел в виду, просто неправильно выразился. Спасибо за поправку, но факт остается фактом...
С ув. Алексей
← →
StAL © (2004-03-15 19:28) [9]2BiN
С Вашим кодом то же самое
2Digitman
Именно это я и имел ввиду, просто неправильно выразился. Но факт остается фактом...
← →
StAL © (2004-03-15 19:28) [9]2BiN
С Вашим кодом то же самое
2Digitman
Именно это я и имел ввиду, просто неправильно выразился. Но факт остается фактом...
← →
StAL © (2004-03-15 19:29) [10]Извиняюсь, глюк вышел.
С ув. Алексей
← →
StAL © (2004-03-15 19:29) [10]Извиняюсь, глюк вышел.
С ув. Алексей
← →
Digitman © (2004-03-16 08:14) [11]
> StAL
ну хорошо ... предположим, что MessageBoxA/W есть некая хитрозадая ф-ция, не поддающаяся перехвату) ..
а иные ф-ции ? как у тебя с ними дела обстоят ? к примеру, LoadLibraryA/W ?
← →
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.
← →
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;
← →
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 - одной табакерки черти ...
← →
Digitman © (2004-03-16 18:13) [14]
> Проверял на CreateProcessA/W
ну и как ? каковы результаты-то ?
> MessageBox - это у Рихтера
да хотбь у самого господа бога ! суть-то неизменна) ... что CreateProcess, что MessageBox - одной табакерки черти ...
← →
StAL © (2004-03-19 15:05) [15]2Digitman
Не перехватывается
С ув. Алексей
← →
StAL © (2004-03-19 15:05) [15]2Digitman
Не перехватывается
С ув. Алексей
← →
Digitman © (2004-03-19 17:25) [16]тогда ответ один - см. [3]
← →
Digitman © (2004-03-19 17:25) [16]тогда ответ один - см. [3]
← →
EXE7 (2004-03-20 14:31) [17]может stdcall - вызовы или незапускайте под делфи
← →
EXE7 (2004-03-20 14:31) [17]может stdcall - вызовы или незапускайте под делфи
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.052 c