 |
__cdecl, variable arguments и все что с ними связано - Вопросы и ответы, обсуждения - Ваши вопросы по C/C++ только в данном разделе |
05.03.2013, 11:17
|
#1
|
|
|
|
Сержант
|
 Регистрация: 01.10.2011
 Сообщений: 128
 Популярность: 5723
 Сказал(а) спасибо: 25
Поблагодарили 174 раз(а) в 105 сообщениях
|
__cdecl, variable arguments и все что с ними связано
Знаю, что это последнее место где стоит задавать подобный вопрос, но я наверное конченый оптимист.
Есть функция со следующей сигнатурой
Код:
void __cdecl foo(void*, char*,...)
мне нужно из функции bar с такой же сигнатурой вызвать foo, собственно делаю это так
Код:
void __cdecl bar(void* obj, char* format,...)
{
va_list args;
va_start(args, format);
foo(obj, format, args);
}
с тем же самым printf'ом это срабатывает, но здесь нет
если оригинальная функция имеет вид foo(obj, format, 0x1, 0x2, 0x3) то ее асемблерный вариант выглядит так:
Код:
push 0x3
push 0x2
push 0x1
push format
push obj
call foo
а если вызывать ее из bar то получается
Код:
push args
push format
push obj
call foo
в args помещается указатель на 3 значения в стеке, из за чего функция отказывается корректно работать.
Сразу отмечу, что к исходникам функции foo я доступа не имею.
Вот такая вот хитрая проблема
________________
Talk is cheap. Show me the code
— Linus Torvalds
|
|
|
06.03.2013, 11:53
|
#2
|
|
|
|
Сержант
|
 Регистрация: 20.07.2010
 Сообщений: 138
 Популярность: 26409
 Сказал(а) спасибо: 52
Поблагодарили 567 раз(а) в 198 сообщениях
|
Re: __cdecl, variable arguments и все что с ними связано
я конечно мб не особо вник, но
у тебя же директива __cdecl, значит параметры будут как на чистом сишнике передаваться в обратном порядке, что видно в ее ассемблерном варианте.
Как я понял, в args указатель идет на стек, где все лежит в порядке 0x1 0x2 0x3.
Когда ты вызываешь foo, в стек вызова все складывается в следующем порядке (формально естественно, ибо мы как бы расписываем push args):
push 0x1
push 0x2
push 0x3
push format
push obj
call foo
потому как из стека все забирается по правилу LIFO (Last in, First out)
а должно
push 0x3
push 0x2
push 0x1
push format
push obj
call foo
в этом, видимо, и есть проблема
Последний раз редактировалось Рэйзор; 06.03.2013 в 12:00.
|
|
|
07.03.2013, 10:37
|
#3
|
|
|
|
Сержант
|
 Регистрация: 01.10.2011
 Сообщений: 128
 Популярность: 5723
 Сказал(а) спасибо: 25
Поблагодарили 174 раз(а) в 105 сообщениях
|
Re: __cdecl, variable arguments и все что с ними связано
кстати я таки разобрался, всего то нужно было поправить регистры
Код:
void _cdecl bar(void* obj, char* format, ...)
{
va_list args;
va_start(args, format);
//тут вызывается функция...
//и приходится востанавливать после нее регистры
__asm mov esp,ebp
__asm pop ebp
__asm jmp [foo] //Верхом на шлюхах прямо в рай!
}
________________
Talk is cheap. Show me the code
— Linus Torvalds
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Заявление об ответственности / Список мошенников
Часовой пояс GMT +4, время: 18:26.
|
 |