Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вычисление размера функции, не получается 
:(
    Опции темы
nadge
Дата 3.1.2008, 01:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 12.11.2004

Репутация: нет
Всего: 1



Доброе время суток!

Кусок программы (тестовый пока):

Код

void __declspec(naked) angy_StartOfHappyCode(void)
{
}

void HappyCode()
{    
    MESSAGEBOX pMessageBox=(MESSAGEBOX)0x99999999;

    pMessageBox(0,0,0,0);


}

void __declspec(naked) angy_EndOfHappyCode(void)
{
}


Далее в одной из функций пишу:
Код

DWORD dwCodeSize=((DWORD)&angy_EndOfHappyCode) - ((DWORD)&angy_StartOfHappyCode);


И в dwCodeSize получаю очень большое (явно неверное) значение. Идея взята (практически дословно) из BO2k, там прекрасно работает. Уже час бьюсь, так и не разобрался.

Где ошибка?

З.Ы. Подозреваю, что где-то в опциях компиляции, но никак не могу понять, где именно. Оптимизации вроде все по отключал. Среда: VS 2005.


Это сообщение отредактировал(а) nadge - 3.1.2008, 01:14
PM MAIL   Вверх
MAKCim
Дата 3.1.2008, 01:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



nadge
с чего ты взял, что код функций располагается последовательно?


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
nadge
Дата 3.1.2008, 04:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 12.11.2004

Репутация: нет
Всего: 1



MAKCim, я видел работающий пример, идентичный моему - http://www.bo2k.com/, файл исходника называется process_hop.cpp. (Здесь код не привожу т.к. все полностью как у меня.)


ОК, переформулирую вопрос иначе. Что нужно сделать, чтобы код располагался последовательно?

Это сообщение отредактировал(а) nadge - 3.1.2008, 04:29
PM MAIL   Вверх
pompei
Дата 3.1.2008, 06:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: нет
Всего: 6



Ни чё нельзя!!!

--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
W4FhLF
Дата 3.1.2008, 08:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: нет
Всего: 121



Единственное верное решение: использовать дизассемблер длин машинных инструкций:

Код

#include "LDasm.h"
#include "windows.h"
#include "stdio.h"

void HappyCode()
{    
    MessageBox(0,0,0,0);
}

int main(int argc, char* argv[])
{
    unsigned int dwCodeSize = SizeOfProc(&HappyCode);
    printf("%lu bytes", dwCodeSize);
    return 0;
}



Проект в аттаче.



Присоединённый файл ( Кол-во скачиваний: 10 )
Присоединённый файл  getfunclen.rar 4,79 Kb


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
W4FhLF
Дата 3.1.2008, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: нет
Всего: 121



Цитата(nadge @  3.1.2008,  04:26 Найти цитируемый пост)
Что нужно сделать, чтобы код располагался последовательно?


Это невозможно сделать в рамках стандартных компиляторов. 

Это сообщение отредактировал(а) W4FhLF - 3.1.2008, 08:37


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Damarus
Дата 3.1.2008, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

Репутация: 6
Всего: 29



Цитата(W4FhLF @  3.1.2008,  08:32 Найти цитируемый пост)
Единственное верное решение: использовать дизассемблер длин машинных инструкций:

Относительно верное smile В результате оптимизации в функции может быть несколько инструкций ret.
PM MAIL ICQ Jabber   Вверх
W4FhLF
Дата 3.1.2008, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: нет
Всего: 121



Damarus, верно, поэтому перед использованием всё-таки надо пихнуть программу в дизассемблер smile 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
MAKCim
Дата 3.1.2008, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



не знаю как в PE
но элемент таблицы символов ELF файла может содержать размер символа (функции)
при обычных настройках компилятора/компоновщика эта информация генерируется
в процессе работы программы ее можно получить
кроме того, почему нельзя сделать так



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
W4FhLF
Дата 3.1.2008, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: нет
Всего: 121



Цитата(nadge @  3.1.2008,  04:26 Найти цитируемый пост)
MAKCim, я видел работающий пример, идентичный моему - http://www.bo2k.com/, файл исходника называется process_hop.cpp. (Здесь код не привожу т.к. все полностью как у меня.)


Кстати, ты наверное компилировал в debug? Попробуй в release. 

Ещё можно так:

Код

#include "windows.h"
#include "stdio.h"

void HappyCode()
{    
    MessageBox(0,0,0,0);
    __asm
    {
        nop
        int 3
        nop
        int 3
    }
}

int main(int argc, char* argv[])
{
    
    PCHAR dwCodeEnd = (PCHAR)HappyCode;
    while (*(PULONG)dwCodeEnd != 0xCC90CC90)
        ++dwCodeEnd;

    ULONG dwCodeSize = (ULONG)(dwCodeEnd - (PCHAR)HappyCode);
    // dwCodeSize += 5; (размер ассемблерной вставки и инструкции ret)
    printf("%lu bytes\n", dwCodeSize);
    return 0;
}



--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
MAKCim
Дата 3.1.2008, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



W4FhLF
забыл учесть размер leave (или ручного аналога)


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
W4FhLF
Дата 3.1.2008, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: нет
Всего: 121



MAKCim, в моём случае его небыло.


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
nadge
Дата 3.1.2008, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 12.11.2004

Репутация: нет
Всего: 1



Цитата
Это невозможно сделать в рамках стандартных компиляторов. 

Ну, в вышеприведенном BO2k как-то же сделали?

Цитата
Кстати, ты наверное компилировал в debug? Попробуй в release. 

И так и так, хотя release не особо тщательно проверял. Перепроверю.

Цитата
Ещё можно так:

Кстати, хороший вариант. 

Только в моем случае довольно неудобный, т.к. функций таких будет штук 30, если не больше. 






PM MAIL   Вверх
W4FhLF
Дата 3.1.2008, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: нет
Всего: 121



Цитата(nadge @  3.1.2008,  16:07 Найти цитируемый пост)
Ну, в вышеприведенном BO2k как-то же сделали?


Знаю только, что VS _обычно_ не меняет порядок, но даже если порядок не меняется между процедурами может идти мусор, так что этот способ не рулит. 


Цитата(nadge @  3.1.2008,  16:07 Найти цитируемый пост)
Только в моем случае довольно неудобный, т.к. функций таких будет штук 30, если не больше. 


Но разве удобней пихать туеву кучу пустышек вместо этого? 

Note: Зачем нужна "angy_StartOfHappyCode"? Можно сразу брать &HappyCode.


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
nadge
Дата 3.1.2008, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 12.11.2004

Репутация: нет
Всего: 1



Цитата
Но разве удобней пихать туеву кучу пустышек вместо этого? 

Note: Зачем нужна "angy_StartOfHappyCode"? Можно сразу брать &HappyCode.

Предполагалось написать примерно так:

Код

void __declspec(naked) angy_StartOfHappyCode(void)
{
}

void HappyFunc1()
{    
   // тут какой-то код
}

void HappyFunc2()
{    
   // тут какой-то код
}

void HappyFunc3()
{    
   // тут какой-то код
}

void HappyFunc4()
{    
   // тут какой-то код
}

void HappyFunc5()
{    
   // тут какой-то код
}

void HappyFunc6()
{    
   // тут какой-то код
}

void __declspec(naked) angy_EndOfHappyCode(void)
{

}

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


PM MAIL   Вверх
W4FhLF
Дата 3.1.2008, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: нет
Всего: 121



Какова задача в общем?


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
MAKCim
Дата 3.1.2008, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



Цитата(W4FhLF @  3.1.2008,  11:28 Найти цитируемый пост)
MAKCim, в моём случае его небыло. 

хочешь сказать, что ret был сгенерирован до твоего кода?


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
nadge
Дата 3.1.2008, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 12.11.2004

Репутация: нет
Всего: 1



Цитата
Какова задача в общем?

Создать (относительно большой) базонезависимый код для запуска его в адресном пр-ве другого процесса, куда его сперва нужно будет скопировать.

С деталями написания самого кода более-менее разобрался, а вот такая, как мне казалось, простая функция, как его копирование не получается.


PM MAIL   Вверх
W4FhLF
Дата 3.1.2008, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: нет
Всего: 121



Цитата(MAKCim @  3.1.2008,  18:31 Найти цитируемый пост)
хочешь сказать, что ret был сгенерирован до твоего кода?


может я что-то не так понял?

Код

00401000   .  PUSH    0                                ; /Style = MB_OK|MB_APPLMODAL
00401002   .  PUSH    0                                ; |Title = NULL
00401004   .  PUSH    0                                ; |Text = NULL
00401006   .  PUSH    0                                ; |hOwner = NULL
00401008   .  CALL    DWORD PTR DS:[<&USER32.MessageBo>; \MessageBoxW
0040100E   .  NOP
0040100F   .  INT3
00401010   .  NOP
00401011   .  INT3
00401012   .  RETN



Цитата(nadge @  3.1.2008,  20:12 Найти цитируемый пост)
С деталями написания самого кода более-менее разобрался, а вот такая, как мне казалось, простая функция, как его копирование не получается.


Пользуйся лучше способом с поиском сигнатуры, это самый оптимальный вариант, имхо. 
Вообще, всё зависит от твоей реализации базонезависимого кода, ибо там тонкостей достаточно много. Если ты решил ещё и вызовы процедур делать в нём(своих же), то всё усложняется, тут конечно было бы идеально, если бы ты в том процессе расположил процедуры именно так(относительно друг друга), как они расположены в твоём процессе, ибо иначе придётся тебе править операнды вручную. 



--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
nadge
Дата 3.1.2008, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 12.11.2004

Репутация: нет
Всего: 1



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


Самое интересное другое - ведь получается же такая штука в приведенном мною примере с back orifice 2k. Там тот же VC++ используется. Опции компилятора изучал, переносил в свою программу - не помогло.





Это сообщение отредактировал(а) nadge - 3.1.2008, 22:05
PM MAIL   Вверх
dumb
Дата 3.1.2008, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: нет
Всего: 158



Цитата(nadge @  3.1.2008,  22:02 Найти цитируемый пост)
Базонезависимый код будет большой
развей мои сомнения - приведи небольшой кусок из твоего "базонезависимого кода".
PM MAIL   Вверх
Любитель
Дата 4.1.2008, 00:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 7
Всего: 92



Цитата(Damarus @  3.1.2008,  09:43 Найти цитируемый пост)
Относительно верное  В результате оптимизации в функции может быть несколько инструкций ret.

Не только. А если это не cdecl функция? smile 99% она на retn будет заканчиваться.

Added: точнее, если stdcall, по крайней мере.

Цитата(W4FhLF @  3.1.2008,  21:20 Найти цитируемый пост)
может я что-то не так понял?

Просто у функции нет параметров smile

Добавлено @ 00:40
Цитата(W4FhLF @  3.1.2008,  17:03 Найти цитируемый пост)
Знаю только, что VS _обычно_ не меняет порядок

Угу. Да и большинство компилеров. Но (!) в дебаге будет сгенерена табличка стабов вида jmp <функция> - они и будут вызываться кругом. Нафига это не помню - но где-то когда-то читал разъяснение.

Цитата(nadge @  3.1.2008,  22:02 Найти цитируемый пост)
хорош в первую очередь своей простотой

И плох сомнительностью своей работы smile Впрочем всё-таки отталкиваться ИМХО лучше от него, но учитывать его потенциальную нестабильность smile Так чё насчёт релиза?

Это сообщение отредактировал(а) Любитель - 4.1.2008, 01:15


--------------------
PM MAIL ICQ Skype   Вверх
nadge
Дата 4.1.2008, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 12.11.2004

Репутация: нет
Всего: 1



Цитата
Впрочем всё-таки отталкиваться ИМХО лучше от него, но учитывать его потенциальную нестабильность

Про нестабильность - это точно.

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

Пока не могу сказать, что проблема решена - надо еще потестировать. Но вроде все ОК. 

Цитата
Так чё насчёт релиза?

Всмысле, собрать как релиз? Само по себе это не помогло. Хотя щас все так собираю, для отладки пользуюсь софтайсом.
PM MAIL   Вверх
Любитель
Дата 4.1.2008, 01:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 7
Всего: 92



Цитата(nadge @  4.1.2008,  01:04 Найти цитируемый пост)
Само по себе это не помогло.

И не должно... Просто с дебагом по идее вообще не прокатит, из-за этих стабов для функций.


--------------------
PM MAIL ICQ Skype   Вверх
_n0
Дата 13.2.2008, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 12.2.2008

Репутация: нет
Всего: нет



Актуально сейчас или нет, но изложу ещё один вариант. Он будет несколько корректнее в плане того, чтобы перенести весь необходимый код.
Целевые функции стоит выделить в отдельную секцию (используя #pragma code_seg либо #pragma section).
Чтобы это счатье выдрать -  чуть больше работы нужно будет, чем в уже приводившихся способах, зато надёжней. Просто напросто нужно пробежаться по PE-заголовку образа в памяти и получить адрес и размер секции. Её и копируем в нужный процесс. Относительное расположение в ней элементов можно найти разностью адреса функции в нашем процессе и уже вычисленного адреса секции.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.1388 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.