Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.07.08;
Скачать: [xml.tar.bz2];

Вниз

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

 
romaP   (2007-01-19 09:03) [0]

Начал заниматься перехватом API функций и возник такой вопрос: Возможно ли перехватиль вызов API фунции со всеми переданными ей параметрами (Например перехватить MessageBox с заголовком и текстом). Заранее спасибо!


 
Сергей М. ©   (2007-01-19 09:21) [1]

Возможно.


 
DimaL   (2007-01-20 06:25) [2]

Я знаю как с помощью Хуков перехватить вызов API функции, но как определить какие параметры ей переданы?


 
ors_archangel ©   (2007-01-20 08:43) [3]


> Я знаю как с помощью Хуков перехватить вызов API функции,
>  но как определить какие параметры ей переданы?

Сделай парсер для файла Windows.pas, большинство функций с их параметрами - там. В run-time никакая информация о параметрах (типы, размеры) не передаётся, передаются только их значения.
Наприер, MessageBox - это Win32 API функция, описана в Windows.pas так:
function MessageBox(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
отсюда вполне понятно, сколько и какие параметры функция получает, но при вызове будет происходить что-то вроде

 push 0
 push 0x505055
 push edx
 push ecx
 call   MessageBox

- никаких тебе типов, только четыре машинных слова в стеке и даже нельзя сказтаь, можно, конечно, анализировать код callera, но лучше пропарсить Windows.pas, потом сопоставить имена и адреса и мы уже знаем большинство функция, так говорию, как будто сам делал! :) Многие отладчики асм-кода, например OllyDbg так и делают - у них просто есть база известных функций.


 
DimaL   (2007-01-20 10:23) [4]

push 0
push 0x505055
push edx
push ecx
call   MessageBox


Ты хочешь сказать, что параметры функций можно брать в регистрах процессора или в стеке в момент перехвата?


 
Dmitrij_K   (2007-01-20 11:41) [5]

http://www.madshi.net/
http://help.madshi.net/ApiCodeHooking.htm
демки в комплекте


 
ors_archangel ©   (2007-01-20 11:54) [6]


> Ты хочешь сказать, что параметры функций можно брать в регистрах
> процессора или в стеке в момент перехвата?

Именно так. Вообще есть несколько стандартов передачи параметров: register (eax,edx,ecx, - по порядку, дальше стек справа налево), stdcall (через стек справа налево), pascal (через стек слево направо), cdecl (через стек не помню как, но функция стек не очищает), fastcall (eax,edx (если правильно помню,ecx зарезервирован для this всегда), safecall (ни разу не встречал его использования и не помню как там что даже :)
Если тип вмещается в машинное слово (сейчас будем под этим словом подразумевать машинное слово 32-разрядных процессоров, которое имеет размер 4 байта), например, byte, shortint, word, smallint, cardinal, integer, single, pointer, - то его значение передаётся через один регистр, либо одним словом в стеке: push x, - заметь, даже byte при передаче будет занимать всё машинное слово (4 байта). Если же тип не влезает в 4 байта, что относится в случае с WinAPI и Delhpi практически только к [u]int64, (ну, можно ещё вспомнить double и extended, конечно), то он передаётся как два регистра, либо как два слова. Возвращается значение функции через регистр eax (во всех случаях), либо (в случае 64-битности, например, int64, чего в API, впрочем, я не встречал) через пару регистров edx:eax (ох, когда-то так часто приходилось создавать пары, потому что разрядности не хватало, так этот принцип теперь актуален для Int64). Нужно учитывать не только сами типы, но и модификаторы передачи, такие как const,in,var,out, - в оригинальном WinAPI их нет, т.к. написан он на C, но Delphi вводит их для упрощения использования, так вот, все эти модификаторы делают одно, передают значение по ссылке - т.е. передают значение не переменной, а значение укзаателя на данную переменную, т.е. 4 байта, т.е. одно машинное слово. Сам код вычленения параметров сильно зависит от кода перехватчика, и так сказать что либо работающее невозможно.


 
DimaL   (2007-01-20 14:08) [7]

Вот так я делаю перехват функции massage box

procedure ProcessImports(PImports:PImageImportDescriptor);
   Var
       PImport:PImageImportDescriptor;
       PRVA_Import:LPDWORD;
       ProcAddress:pointer;
       Temp_Cardinal:cardinal;
   begin{1}
     ProcAddress:=GetProcAddress(GetModuleHandle("USER32.DLL"), "MessageBoxA");
     PImport:=PImports;
     while PImport.Name<>0 do
       begin{2}
         PRVA_Import:=LPDWORD(pImport.FirstThunk+ImageBase);
         while PRVA_Import^<>0 do
         begin{3}
           if PPointer(PRVA_Import)^=ProcAddress
              then
                begin{4}
                  VirtualProtect(PPointer(PRVA_Import),4,PAGE_READWRITE,Temp_Cardinal);
                  PPointer(PRVA_Import)^:=@MyHookProcedure; //пишем свою...
                 VirtualProtect(PPointer(PRVA_Import),4,Temp_Cardinal,Temp_Cardinal);
                end;{1}
           Inc(PRVA_Import);
         end;{2}
      Inc(PImport);
  end;{3}
end;{4}


Хочу получить текст сообщения.

Пытался перед вызовом:

VirtualProtect(PPointer(PRVA_Import),4,PAGE_READWRITE,Temp_Cardinal);

Вытаскивать значения из стека. Но там что -то странное. Как лучше сделать?


 
Сергей М. ©   (2007-01-23 08:28) [8]


> Как лучше сделать?


Проще некуда.

type
TMessageBoxA = function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;

var
 OriginalMessageBoxA: TMessageBoxA;

function MyMessageBoxA(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
begin  
 Result := OriginalMessageBoxA(hWnd, PChar("Оригинальный текст сообщения:"#10 + StrPas(lpText)), lpCaption, uType);
end;

...
OriginalMessageBoxA:=GetProcAddress(GetModuleHandle("USER32.DLL"), "MessageBoxA");
...
PPointer(PRVA_Import)^:=@MyMessageBoxA;



Но этого не достаточно.
Кроме IAT нужно модифицировать еще и EAT, потому что оригинальную точку входа в интересующую ф-цию м.б. получен и с пом. GetProcAddress().

Либо (вместо модификации EAT) следует обязательно перехватывать в IAT точку входа в GetProcAddress(), дабы вместо оригинального адреса возвращать  адрес @MyMessageBoxA


 
DimaL   (2007-01-23 09:10) [9]


> Но этого не достаточно.

Если можно по подробнее про модификацию "EAT", и перехват "IAT".


 
DimaL   (2007-01-23 09:10) [10]


> Но этого не достаточно.

Если можно по подробнее про модификацию "EAT", и перехват "IAT".


 
Сергей М. ©   (2007-01-23 09:24) [11]


> DimaL   (23.01.07 09:10) [9]


Приведенный тобой твой код выполняет именно модификацию IAT  - Import Address Table. Эта таблица предназначена для статического импорта, она используется системным загрузчиком на стадии загрузки модуля, работа которого жестко зависит от других модулей.

Кроме статического существует еще динамический импорт, когда адрес точки входа во внешний модуль вычисляется в ран-тайм с пом.вызова ф-ции kernel32.GetProcAddress. Эта ф-ция сканирует EAT - Export Address Table - внешнего модуля и возвращает вирт.адрес, соответствующий указанному имени или ординалу.


 
DimaL   (2007-01-23 09:38) [12]

Я так понимаю, что ты предлагаешь перехватить GetProcAddress()  и вернуть адрес своей процедуры.
Но GetProcAddress() нужно обрабатывать только при запросе адреса нужной нам функции. Как это проверить?


 
Сергей М. ©   (2007-01-23 09:58) [13]


> предлагаешь перехватить GetProcAddress()  и вернуть адрес
> своей процедуры


Если модификация EAT по каким-то соображениям тебя не устраивает, то да, можно и так поступить.


> GetProcAddress() нужно обрабатывать только при запросе адреса
> нужной нам функции. Как это проверить?


Проанализировать параметры вызова этой ф-ции.


 
DimaL   (2007-01-23 10:12) [14]


> Проанализировать параметры вызова этой ф-ции.


Аналогично как и с параметрами MessageBoxA?


 
Сергей М. ©   (2007-01-23 10:13) [15]


> DimaL   (23.01.07 10:12) [14]


Да.


 
DimaL   (2007-01-23 10:28) [16]


> Сергей М. ©

Спасибо за помощь!


 
SmileR   (2007-01-27 14:43) [17]

Ну а в случае если за ранее не известно какие параметры ей передаются и проанализировать нельзя, ну разве что только отладчиком, но это для более продвинутых в асме. Как тогда полчить эти самые параметры?


 
Evgeniy.G   (2007-01-27 14:46) [18]

Во во, если эта функция вообще без описания...


 
Сергей М. ©   (2007-01-29 08:19) [19]


> SmileR   (27.01.07 14:43) [17]


Ты же сам ответил на свой вопрос - с помощью дизассемблера и отладчика ...



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

Форум: "WinAPI";
Текущий архив: 2007.07.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.038 c
2-1181292068
allucard
2007-06-08 12:41
2007.07.08
Событие сворачивания и закрытия окна


5-1155637901
NiGGa
2006-08-15 14:31
2007.07.08
Двойной грид.


9-1156069429
VolanD666
2006-08-20 14:23
2007.07.08
Статичные тени...


15-1180963945
Vendict
2007-06-04 17:32
2007.07.08
Black Box for Win


6-1159720721
_Anwy_
2006-10-01 20:38
2007.07.08
Авторизация на сайте с помощью IdHTTP





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский