Разбирался тут с идентификацией функций по книге "Техника хакерских атак" Касперски, и напоролся на такой странный пример... Точнее пример вполне обычный, но код сгенерировался довольно странный: по адресу 401317h, в цикле адрес функции присваевается указателю и через него вызываеться. Странность в том, что вызываеться функция по адресу... 0000000Ch! Естественно дальше дизассемблер отказываеться продолжить выполнение. Ошибки быть не может -- проверил на двух дебаггерах: OllyDbg и Immunity Debugger. Я думаю о том, что в винде этот файл работает без проблем, и выводит обе тестовые строки можно не говорить Исходный код и аттач с файлом прилагается. Код (Text): #include <stdio.h> int func_1(){}; int func_2(){printf("Impossible is possible!");}; int func_3(){}; int main() { printf("Hello World\n"); int x; int a[3]={(int) func_1(),(int) func_2(), (int) func_3()}; int (*f)(); for (x=0;x < 3;x++) { f=(int (*)()) a[x]; //Тот цикл, он по адресу 401317h Сам вызов 40132Ah. f(); } } Как такое может быть? Скомпилено все на Dev-C++ 4.9.9.2
Странно, что-то я аттача не вижу... Ладно сейчас на файлообменник закину. Добавлено: Есть! Прошу любить и жаловать -- оно пришло! Только на http://exfile.ru/198563 !
здесь элементам массива присваиваются не адреса функций, а их возвращаемые значения (соответственно, все три функции вызываются, отсюда и сообщение в консоли). в дизассемблере все прозрачно: Код (Text): .text:004012DA mov [esp+68h+var_68], offset aHelloWorld ; "Hello World\n" .text:004012E1 call printf .text:004012E1 .text:004012E6 call func_1 .text:004012E6 .text:004012EB mov [ebp+a], eax .text:004012EE call func_2 .text:004012EE .text:004012F3 mov [ebp+a+4], eax .text:004012F6 call func_3 .text:004012F6 .text:004012FB mov [ebp+a+8], eax .text:004012FE mov eax, [ebp+a] .text:00401301 mov [ebp+f], eax .text:00401304 mov eax, [ebp+a+4] .text:00401307 mov [ebp+f+4], eax .text:0040130A mov eax, [ebp+a+8] .text:0040130D mov [ebp+f+8], eax .text:00401310 mov [ebp+x], 0 .text:00401310 .text:00401317 .text:00401317 loc_401317: ; CODE XREF: _main+81j .text:00401317 cmp [ebp+x], 2 .text:0040131B jg short loc_401333 .text:0040131B .text:0040131D mov eax, [ebp+x] .text:00401320 mov eax, [ebp+eax*4+f] .text:00401324 mov [ebp+var_3C], eax .text:00401327 mov eax, [ebp+var_3C] .text:0040132A call eax .text:0040132A .text:0040132C lea eax, [ebp+x] .text:0040132F inc dword ptr [eax] .text:00401331 jmp short loc_401317
Ну надо же, блин, и как я не заметил. Буду повнимательней... И все-же оригинальный способ завершения программы -- через исключение. Разработчикам компилятора большой респект
newbye Какой ещё респект? Обычное падение приложения. И валидного завершения работы приложения там нету. А если бы и было, то багрепорт разработчикам писать надо было бы, а не респекты раздавать.
А насчет баг-репорта идея хорошая, отослал. Правда при отправке у меня, отчего-то возникла леденящая душу ассоциация -- с фильмами ужасов -- когда на космическую станцию приходит сообщение, а затем камера отодвигаеться, и показывают покрытые пылью панели управления, треснутый монитор справа, забрызганый чем-то красным, кресло с лежащим в полуразложившихся лохмотьях чьим-то скелетом; все это на фоне фееричекого виде планеты в иллюминаторе, с восходящей за ней звездой... Наверное это от того, что на офсайте дата последнего выхода Dev-C++ то ли 2005, то ли 2006-ой год.
newbye Код (Text): int a[3]={(int) func_1(),(int) func_2(), (int) func_3()}; На Код (Text): int a[3]={(int) func_1,(int) func_2, (int) func_3};
...потом наезд на изображение с камеры отодвигается назад, появляется терминал передающий оное изображение, далее появляется смотрящий в монитор мальчик в красном пионерском галстуке с лицензинной коробкой из под диска с надписью 'дев С++', далее откат изображения продолжается, что обнаруживает мальчика в помещении не одного, а с зелеными, похожими на инопланетян, существами сзади него, которые плачут от данной душевной картины и пытаются похлопать мальчика по плечу. Занавес.
newbye Я ж написал: "Надо было бы" (сослагательное наклонение). В данном случае компилятор делает всё правильно, и никакого багрепорта не нужно.
Неожиданный хэппиэнд! Увы, я пока не умею с ходу определять назначение функций, тем более, что оригинал пришлось править, что бы он скомпилировался. Говоря по правде меня конструкции типа " int a[3]={(int) func_1(),(int) func_2(), (int) func_3()};" и "f=(int (*)()) a[x];" пока еще вводят в ступор. Последнее, я так понял кастинг? В обшем прошу прощения, зеленым человечкам я тоже отписался.
Да, я тоже заметил после регистрации, правда немного другое -- что неправильно имя написал. Хотел исправить, но в профиле, как это часто водиться такой возможности нет