Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Зачарованные функции main и WinMain

3
21 марта 2008 года
Green
4.8K / / 20.01.2000
Вот столкнулся с волшебством... :)

MSVC 2005, Release

Есть код:
Код:
#pragma comment(linker,"/SECTION:.text,EWR")

__declspec(naked)
void stub()
{
    __asm ret
}

int main()
{
    stub();

    unsigned char* p = (unsigned char*)main;
    for(int i=-8; i<8; i++) {
        p = 0xDD;
    }

    return 0;
}

Функция stub введена лишь для того, чтоб секция кода начиналась не с функции main.

Что по идее должно произойти: должны затереться 8 байт до функции main и 8 байт внутри её.

Проверяю...

Дамп памяти до выполнения цикла:
 
Код:
0x00401008  cc cc cc cc cc cc cc cc e8 eb ff ff ff b9 dd dd

Дамп памяти после:
 
Код:
0x00401008  [color=red]dd dd dd dd dd dd dd dd[/color] e8 [color=red]dd dd dd dd dd dd dd[/color]

Не верю своим глазам, ячейка 0x00401010 (e8) не затерлась. Это первый байт функции main.

Добавляю после цикла сброс кеша:
FlushInstructionCache(GetCurrentProcess(), 0, 0);
Ноль эмоций, дамп тот же.

Делаю другой эксперимент (теперь stub нужен чтоб не затиралась start):
Код:
#pragma comment(linker,"/SECTION:.text,EWR")
#pragma comment(linker,"/ENTRY:start")

int main();

__declspec(naked)
void start()
{
    __asm int 3

    register unsigned char* p;
    p = (unsigned char*)main;
    for(int i=-8; i<8; i++) {
        p = 0xDD;
    }

    __asm ret
}

__declspec(naked)
void stub()
{
    __asm ret
}

int main()
{
    stub();
    stub();
    return 0;
}

Получаю такое же неубиваемое e8 !
Проверяю с FlushInstructionCache, дамп без изменений.

Ставлю еще один эксперимент,- добавляю функцию WinMain. Причем это просто имя, т.к. сигнатура функции иная (нет параметров, тет WINAPI, не подключаю windows.h), и приложение оставляю консольным:
Код:
#pragma comment(linker,"/SECTION:.text,EWR")
#pragma comment(linker,"/ENTRY:start")

int WinMain();
int main();

__declspec(naked)
void start()
{
    __asm int 3

    register unsigned char* p;

    p = (unsigned char*)main;
    for(int i=-8; i<8; i++) {
        p = 0xDD;
    }

    p = (unsigned char*)WinMain;
    for(int i=-8; i<8; i++) {
        p = 0xBB;
    }

    __asm ret
}

__declspec(naked)
void stub()
{
    __asm ret
}

int main()
{
    stub();
    stub();
    stub();
    return 0;
}

int WinMain()
{
    stub();
    stub();
    return 0;
}

Компилятор возмущается
warning C4007: 'WinMain' : must be '__stdcall'
но проект собирается.

Запускаю...

Дамп до:
 
Код:
0x00401048  cc cc cc cc cc cc cc cc e8 eb ff ff ff e8 e6 ff    // main

0x00401068  cc cc cc cc cc cc cc cc e8 cb ff ff ff e8 c6 ff    // WinMain

Дамп после:
 
Код:
0x00401048  [color=red]dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd[/color]    // main

0x00401068  [color=red]bb bb bb bb bb bb bb bb[/color] e8 [color=red]bb bb bb bb bb bb bb[/color]    // WinMain

Аллилуя! main затерлась, но теберь "болезни" подвержена функция WinMain !

Перемещаю WinMain относительно main вперед по коду. Все равно недозатирается WinMain.

Делаю "контрольный в голову" - переименовываю WinMain в WunMoon. Повторяется картина, как во втором эксперименте, т.е. вновь не затирается main.

Так что за странность такая?
Что за волшебные имена main и WinMain?
3
21 марта 2008 года
Green
4.8K / / 20.01.2000
Сегодня первый пример заработал.
Остальные все так же не работают.
Мистика...
5
21 марта 2008 года
hardcase
4.5K / / 09.08.2005
А что, если попробовать затереть первый байт без цикла?
 
Код:
*p = 0xDD
Проверил бы сам, да в студии С++ не установлен...
3
21 марта 2008 года
Green
4.8K / / 20.01.2000
Цитата: hardcase
А что, если попробовать затереть первый байт без цикла?
 
Код:
*p = 0xDD


Неа... ноль эмоций.
За то попробовал во втором эксперименте переименовать main в main2, все прекрасно затирается.

3
21 марта 2008 года
Green
4.8K / / 20.01.2000
До этого пробовал стандартный идущий с MSVS дебаггер.
Сегодня попробовал отлаживаться в IDA, все затирается.
Значит, это только проблема MSVS дебаггера...
Но для чего ему лочить эти несчастные байты?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог