Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
webprofusa
1 / 1 / 0
Регистрация: 28.10.2011
Сообщений: 7
#1

Получение прототипа функции имея ее адрес - C++

28.10.2011, 12:15. Просмотров 934. Ответов 11
Метки нет (Все метки)

здравствуйте!, писать, и разбираться в программировании на C++ только начал, поэтому если вопрос покажется глупым, не обессудьте)

Итак, у меня есть dll в которой я перехватываю функции WinApi, с перехватом все ок, но возникла необходимость капнуть глубже...
А именно, перехватить вызов функции вызывающей WinApi, затем предыдущую и тд. В общем-то сильно не хватает знаний в организации функций и их параметров в памяти, фактически, как я понимаю, задача сводиться к получению прототипа функции имея лишь ее адрес, адрес возврата перехваченной функции WinApi я получаю(в ее подмененном варианте так):

C++
1
DWORD addr=*((DWORD*)&param1-1);
Где param1 - первый параметр вызванной функции WinApi, собственно два вопроса:
1) действительно ли я получаю правильный адрес функции вызвавшей WinApi?
2) как мне получить список параметров функции по полученному адресу(ведь для перехвата мне нужен точный прототип функции и ее параметров, собственно как их можно, и можно ли в принципе получить из памяти)?

Не могу понять в какую сторону копать, что гуглить и что искать(
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.10.2011, 12:15
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Получение прототипа функции имея ее адрес (C++):

Макрос прототипа функции - C++
Существует ли он? __FILE__ подставляет путь к файлу, в котором находится строка, в которой применён макрос. __LINE__ номер строки, в...

Использование прототипа функции - C++
Привет форумчанам!Помогите пожалуйста! 1.Нужно написать функцию которая вычисляет максимальное и минимальное число массива введенного с...

Объяснить синтаксис прототипа функции - C++
float drob(int k1, char *S1); обьясните строчку пажалуйста зачем задавать флоат потом в скобках инт?

Чем отличается определение функции от прототипа? - C++
чем отличается определение функции от прототипа? и где писать определение?

Объясните синтаксис программы по полочкам с использованием локальных переменных и прототипа функции - C++
Здравствуйте уважаемые форумчане. Вот читаю книгу по C++, не буду писать какую, дабы избежать критики и обсуждений. Хотелось бы что бы вы...

Функция возвращает адрес , как передать этот адрес другой функции ? - C++
const int max = 5; double * fill_array(double, int); void show_array(const double, double *); // как передать этой функции в...

11
Mustik
56 / 56 / 2
Регистрация: 10.07.2011
Сообщений: 229
28.10.2011, 13:48 #2
Цитата Сообщение от webprofusa Посмотреть сообщение
здравствуйте!, писать, и разбираться в программировании на C++ только начал, поэтому если вопрос покажется глупым, не обессудьте)

Итак, у меня есть dll в которой я перехватываю функции WinApi, с перехватом все ок, но возникла необходимость капнуть глубже...
А именно, перехватить вызов функции вызывающей WinApi, затем предыдущую и тд. В общем-то сильно не хватает знаний в организации функций и их параметров в памяти, фактически, как я понимаю, задача сводиться к получению прототипа функции имея лишь ее адрес, адрес возврата перехваченной функции WinApi я получаю(в ее подмененном варианте так):

C++
1
DWORD addr=*((DWORD*)&param1-1);
Где param1 - первый параметр вызванной функции WinApi, собственно два вопроса:
1) действительно ли я получаю правильный адрес функции вызвавшей WinApi?
2) как мне получить список параметров функции по полученному адресу(ведь для перехвата мне нужен точный прототип функции и ее параметров, собственно как их можно, и можно ли в принципе получить из памяти)?

Не могу понять в какую сторону копать, что гуглить и что искать(
В addr будет записано значение по адресу param - 4 адреса (по-байтно), но никак не адрес
А вот, если убрать первую * и оставить
C++
1
((DWORD*)&param1)-1
то получите как-раз предыдущий адрес.
По вопросам ничего рассказать не могу, только догадки и то не на всё.
1
webprofusa
1 / 1 / 0
Регистрация: 28.10.2011
Сообщений: 7
28.10.2011, 14:02  [ТС] #3
спасибо)и как раз предыдущий адрес и есть адрес функции, которая вызвала WinApi? а как мне получить указатель на ее параметры? и, опережая, допустим я получил указатель на парметры.. как мне узнать их тип?(ведь мне нужно их явно указать в прототипе в своей длл-ке)
заранее спасибо!
0
Mustik
56 / 56 / 2
Регистрация: 10.07.2011
Сообщений: 229
28.10.2011, 14:36 #4
Цитата Сообщение от webprofusa Посмотреть сообщение
спасибо)и как раз предыдущий адрес и есть адрес функции, которая вызвала WinApi? а как мне получить указатель на ее параметры? и, опережая, допустим я получил указатель на парметры.. как мне узнать их тип?(ведь мне нужно их явно указать в прототипе в своей длл-ке)
заранее спасибо!
Предыдущий адрес никак не будет адресом предыдущей функции.

Только что смотрел, Win XP 32 бита VS 2008, создал 4 разных функции и адреса функции различались 5 байтами, т.е. 0x004112C1, следующая 0x004112C6, затем 0x004112CB и 0x004112D0.
Короче как-то хитро там все.
0
webprofusa
1 / 1 / 0
Регистрация: 28.10.2011
Сообщений: 7
28.10.2011, 15:19  [ТС] #5
"предыдущая", имеется в виду в стеке вызовов, логика какая-то должна быть иначе как винда понимает куда ей возвращать значение выполненной функции? короче вот так может быть будет наглядней:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int func2(sockaddr param1,char * param2,int param3)
{
    DWORD addr=((DWORD*)&param1)-1; //получим адрес func1
   //теперь тут получим список ее(функции func1) параметров и их тип... .как?????
}
 
int func1(/*тут параметры, тип которых, порядок следования, а также кол-во нам и надо найти*/)
{
   int a=winMainsimle1(); //что-то делаем вообщем не важно что
   int b=winMainsimle1(); //еще какие-то неинтересные нам вызовы
   int c=func2(param1,param2,param3);
}
 
int main()
{
   func1(/*тут параметры, тип которых, порядок следования, а также кол-во нам и надо найти*/);
}
0
Haster
инженер-системотехник
110 / 109 / 2
Регистрация: 10.03.2009
Сообщений: 533
30.10.2011, 00:45 #6
Как я понимаю выражение
C++
1
((DWORD*)&param1)-1
не дает адрес функции, а дает адрес второго параметра...
Т.е. при вызове функции стек выглядит так:
Assembler
1
2
3
4
5
6
Локальные переменные (если имеются)
Адрес возврата из функции
Параметр N
...
Параметр 2
Параметр 1
Соответственно, выражение
C++
1
((DWORD*)&param1)-1
Должно указывать на второй параметр, если он имеется, но на 100% не уверен )
1
webprofusa
1 / 1 / 0
Регистрация: 28.10.2011
Сообщений: 7
30.10.2011, 00:48  [ТС] #7
спасибо, т.е. получается так:
C++
1
((DWORD*)&param1)-N
я получу адрес возврата функции, если N-число параметров? таким образом я смогу поулчить адрес возврата(что собственно и нужно)?
0
Haster
инженер-системотехник
110 / 109 / 2
Регистрация: 10.03.2009
Сообщений: 533
30.10.2011, 00:52 #8
Ну как-то так, только адрес возврата не дает адрес родительской функции, к сожалению...
а только место вызова дочерней функции.
1
webprofusa
1 / 1 / 0
Регистрация: 28.10.2011
Сообщений: 7
30.10.2011, 02:00  [ТС] #9
Haster, спасибо)
тут я затупил неимоверно, это же действительно адрес возврата( это мне ничего не даст.. впрочем я пошел иным путем, я начал изучать в дизассемблере приложение, в котором я хотел все эти операции произвести, нашел нужную мне функцию, но возникли опять трудности(знаний не хватает( ), как этим воспользоваться впрочем топик можно закрывать проблема перекочевала: http://www.cyberforum.ru/cpp-beginners/thread374509.html
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
30.10.2011, 09:52 #10
Цитата Сообщение от Mustik Посмотреть сообщение
((DWORD*)&param1)-1
Учитывая, что компилятор может менять порядок аргументов, их количество и относительное расположение, то это не очень надёжный способ. Т.е. для конкретной версии может сработать, но после апдэйта может вновь потребоваться танцевать с бубном.
0
Haster
инженер-системотехник
110 / 109 / 2
Регистрация: 10.03.2009
Сообщений: 533
30.10.2011, 11:15 #11
Deviaphan, насколько я знаю, в WINAPI используется STDCALL, т.е. параметры всегда передаются в стек одинаковым способом, начиная с первого параметра
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
30.10.2011, 11:24 #12
Цитата Сообщение от Haster Посмотреть сообщение
т.е. параметры всегда передаются в стек одинаковым способом, начиная с первого параметра
Упустил, что речь о WinAPI функциях.)
0
30.10.2011, 11:24
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.10.2011, 11:24
Привет! Вот еще темы с ответами:

Адрес функции - C++
Как узнать адрес функции? Посмотрел дизассемблер IDA. Очень удобная программа, но не могу разобраться, как получить адрес. Там вызов...

Адрес функции - C++
Здравствуйте. Имеется программа с одной функцией. При любом изменении кода и повторной компиляции изменяется адрес этой функции. Можно...

Адрес функции - C++
Доброго времени суток Допустим, хочу узнать адрес функции void fnc(){} int main() { cout<<&fnc<<endl; }

Как объявить функцию без прототипа - C++
Во всех учебниках пишут, что каждая функция должна иметь прототип. ВОт стало интересно, можно ли объявить функцию, которая не имеет...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.