как найти main-функцию

Тема в разделе "WASM.BEGINNERS", создана пользователем milo, 27 июл 2009.

  1. milo

    milo New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2009
    Сообщения:
    43
    Здравствуйте, я в реверсировании начинающий, поэтому такой вопрос. читаю сейчас книгу Касперски "Искусство дизассемблирования", ковыряю примерчик с идентификацией объектов. вроде ничего непонятного нету, пока не начнешь все это делать на практике своими руками. вобщем скомпилировал пример (в аттаче), при открытии его в IDA попадаю, как водится, в Entry Point, где лежат инструкции вида:
    Код (Text):
    1. .text:0040138F                 call    sub_403E34
    2. .text:00401394                 jmp     loc_40123D
    ходил в обоих направлениях. по пути попадались системные вызовы (простите, я линуксоид:)) типа GetComandLineA (ну еще бы, приложение-то консольное). нигде ничего похожего на мою main не было видно. подскажите как найти? хочется вживую поковырять, а не на бумагу смотреть. спасибо.
     
  2. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    попробуй в IDA найти строку "MyClass\n" и перейти по перекрестной ссылке. попадешь в MyClass, а оттуда уже в main
     
  3. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Entry Point – call – jmp? Немаловероятно, что первый call – это вызов __security_init_cookie. Для поиска main надо сразу перейти по jmp и просто смотреть по коду (страницу или две): у main три параметра, достат. кол. системных вызовов необходимо для формирования этих параметров. Ещё помнить, что зачастую библиотечный код (в т.ч. стартовый код до вызова main) размещается линкером _после_ пользовательского.
     
  4. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    milo
    вызви из main MessageBox, потом в иде его легко найти будет. Увидишь, что там откуда вызывается.
     
  5. Microedition

    Microedition Active Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    814
    а можно еще загрузить (если сама не загрузилась) flirt-сингатуру:
    File - Load file - FLIRT signature file.

    там в списке ищете подходящий компилятор.
     
  6. milo

    milo New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2009
    Сообщения:
    43
    у меня есть одна особенность при чтении книг: первые пару сотен страниц я читаю за два дня, остальные (700:)) я растягиваю на ближайшие пару лет:) а к тому времени забываю все, что прочитал ранее. ну так вот, вчера на сон грядущий решил полистать оглавление и... вот она глава - "идентификация стартовой функции". сегодня вечером после работы попробую и отпишусь, если кому интересно.
     
  7. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    нас как минимум двое .D
     
  8. milo

    milo New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2009
    Сообщения:
    43
    вот контекстным поиском нашел свою main-функцию.
    Код (Text):
    1. .text:00401050 probably_main   proc near               ; CODE XREF: .text:00401333p
    2. .text:00401050
    3. .text:00401050 var_8           = dword ptr -8
    4. .text:00401050 var_4           = dword ptr -4
    5. .text:00401050
    6. .text:00401050                 push    ebp
    7. .text:00401051                 mov     ebp, esp        ; çàïîìèíàåì êàäð ñòåêà
    8. .text:00401053                 sub     esp, 8          ; ðåçåðâèðóåì ìåñòî ïîä îáúåêò.
    9. .text:00401053                                         ; ìîé îáúåêò êàê ðàç çàíèìàåò 8 áàéò (áåç ôóíêöèé)
    10. .text:00401056                 push    8               ; íåêèé àðãóìåíò
    11. .text:00401058                 call    inner_func1     ; âðÿä ëè new, ò.ê. íåò ïðîâåðîê âîçâðàùåííîãî ðåçóëüòàòà
    12. .text:0040105D                 add     esp, 4          ; î÷èùàåò ñòåê
    13. .text:00401060                 mov     [ebp+var_8], eax
    14. .text:00401063                 mov     eax, [ebp+var_8]
    15. .text:00401066                 mov     [ebp+var_4], eax
    16. .text:00401069                 mov     ecx, [ebp+var_4] ; ecx - ÿâíî óêàçàòåëü íà this
    17. .text:0040106C                 call    demo            ; ôóíêöèÿ ÷ëåí-êëàññà demo()
    18. .text:00401071                 mov     ecx, [ebp+var_4]
    19. .text:00401074                 mov     dword ptr [ecx], 777h
    20. .text:0040107A                 xor     eax, eax
    21. .text:0040107C                 mov     esp, ebp
    22. .text:0040107E                 pop     ebp
    23. .text:0040107F                 retn
    24. .text:0040107F probably_main   endp
    как видно из первого аттача, в main'е сначала выделяется память и потом вызывается конструктор. Как пишет Крис в "Искусстве дизассемблирования" результат оператора new, как правило, проверяется на 0 (память выделить не удалось) и лишь затем вызывается конструктор класса. очевидно, что inner_func1 возвращает указатель на this. вопрос: где тут оператор new и конструктор, если после вызова inner_func1 сразу идет вызов метода класса? inner_func1 изнутри выглядит так:
    Код (Text):
    1. .text:004011AF inner_func1     proc near               ; CODE XREF: probably_main+8p
    2. .text:004011AF
    3. .text:004011AF var_C           = byte ptr -0Ch
    4. .text:004011AF arg_4           = dword ptr  8
    5. .text:004011AF
    6. .text:004011AF                 mov     edi, edi
    7. .text:004011B1                 push    ebp
    8. .text:004011B2                 mov     ebp, esp
    9. .text:004011B4                 sub     esp, 0Ch        ; ðåçåðâèðóåò 12 áàéò
    10. .text:004011B7                 jmp     short first_jump
    11. .text:004011B9 ; ---------------------------------------------------------------------------
    12. .text:004011B9
    13. .text:004011B9 second_jump:                            ; CODE XREF: inner_func1+22j
    14. .text:004011B9                 push    [ebp+arg_4]     ; = 8
    15. .text:004011BC                 call    sub_402A1C
    16. .text:004011C1                 pop     ecx
    17. .text:004011C2                 test    eax, eax
    18. .text:004011C4                 jz      short loc_4011D5 ; åñëè åùå ðàç 0
    19. .text:004011C6
    20. .text:004011C6 first_jump:                             ; CODE XREF: inner_func1+8j
    21. .text:004011C6                 push    [ebp+arg_4]
    22. .text:004011C9                 call    new_or_constr   ; âåðîÿòíûé îïåðàòîð new
    23. .text:004011CE                 pop     ecx
    24. .text:004011CF                 test    eax, eax
    25. .text:004011D1                 jz      short second_jump ; åñëè âîçâðàùåííûé ðàííåå âûçâàííîé ôóíêöèåé ðåçóëüòàò ðàâåí 0
    26. .text:004011D1                                         ; òî èäåò êóäà-òî îáðàáàòûâàòü
    27. .text:004011D3                 leave
    28. .text:004011D4                 retn
    причем если new_or_constr и есть new, то где, конструктор? или его нету потому что я его не написал руками? хотя, я всегда думал, что конструктор по умолчанию генерируется компилятором (так и есть!), если он явно не задан. вопросов море...
     
  9. Microedition

    Microedition Active Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    814
    а конструктор не обязательно должен вызываться call'ом.
    Он может быть прямо в коде main (inline-функция).

    ну, а данные класса могут в стеке находится. (в стеке main).
     
  10. milo

    milo New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2009
    Сообщения:
    43
    пропарился, извините. inner_func1 и есть оператор new.
     
  11. Microedition

    Microedition Active Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    814
    milo
    в твоем классе определены две переменные.

    а что мы видим в probably_main?
    Код (Text):
    1. .text:00401050 var_8           = dword ptr -8
    2. .text:00401050 var_4           = dword ptr -4
     
  12. milo

    milo New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2009
    Сообщения:
    43
    а в probably_main мы видим, что у нас есть два указателя. значение одного из них находится на 4 байта ниже ebp, другого на 8. ну а какие значения там хранятся можно посмотреть, я думаю, дебаггером. вот только мне непонятно зачем он швыряет эти данные туда обратно вот тут:
    Код (Text):
    1. .text:00401060                 mov     [ebp+var_8], eax
    2. .text:00401063                 mov     eax, [ebp+var_8]
    3. .text:00401066                 mov     [ebp+var_4], eax
    4. .text:00401069                 mov     ecx, [ebp+var_4]
    ну последняя строчка предельно ясна - готовит this указатель. а в первых двух-то зачем туда-сюда швыряться?
     
  13. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Потому что процессор не умеет делать mov [ebp+var_4], [ebp+var_8]
     
  14. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    И оптимизацию включить немешало бы
     
  15. milo

    milo New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2009
    Сообщения:
    43
    с оптимизацией я убьюсь разбираться:)
    TSS, первая строчка: копирует eax в [ebp+var_8], вторая: копирует [ebp+var_8] в eax. тоже самое, но наоборот. зачем?? ну а с третим понятно, потому что не умеет. вопрос в том, зачем первые две швыряет туда сюда?
     
  16. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Судя по дебажной информации, переменной var_8 не существует (последняя строчка вывода):
    Код (Text):
    1. C:\desktop>dia2dump -sym main main3.pdb
    2.                         SymIndex:        0x1
    3.                           SymTag:        0x5
    4.                             Name:        main
    5. ...
    6. Function       : static, [00001080][0001:00000080], len = 00000030, _main
    7.                  Function attribute:
    8.                  Function info: asyncheh
    9. FuncDebugStart :   static, [00001086][0001:00000086]
    10. FuncDebugEnd   :   static, [000010AC][0001:000000AC]
    11. Data           :   ebp Relative, [FFFFFFFC], Local, Type: class MyClass *, zzz
    12.  
    13. C:\desktop>
    По всей видимости, это просто особенность работы компилятора при отключённой оптимизации.

    Вот как выглядит эта функция при включённой оптимизации:
    Код (Text):
    1. C:\desktop>cl /Fm /Zi /Ox main3.cpp
    2. C:\desktop>dumpbin /disasm main3.obj
    3. _main:
    4.   00000040: 56                 push        esi
    5.   00000041: 6A 08              push        8
    6.   00000043: E8 00 00 00 00     call        ??2@YAPAXI@Z
    7.   00000048: 68 00 00 00 00     push        offset $SG3850
    8.   0000004D: 8B F0              mov         esi,eax
    9.   0000004F: E8 00 00 00 00     call        _printf
    10.   00000054: 68 00 00 00 00     push        offset $SG3845
    11.   00000059: E8 00 00 00 00     call        _printf
    12.   0000005E: 83 C4 0C           add         esp,0Ch
    13.   00000061: C7 46 04 66 06 00  mov         dword ptr [esi+4],666h
    14.             00
    15.   00000068: C7 06 77 07 00 00  mov         dword ptr [esi],777h
    16.   0000006E: 33 C0              xor         eax,eax
    17.   00000070: 5E                 pop         esi
    18.   00000071: C3                 ret
    Полезные ключи компилятора для исследований:
    Код (Text):
    1. cl /Fm  – создать map-файл (показано расположение функций и глобальных переменных)
    2. cl /Zi  – включить отладочную информацию (сгенерируется файл с инфой – main3.pdb)
    3. cl /Ox  – включить оптимизацию (там много ключей на самом деле, но этого хватает для подчистки всяких швыряний)
    Для использования отладочной инфы старыми версиями IDA Pro может понадобится плагин к ней – Determina PDB Loader (хотя локальные переменные всё равно не будут отображаться).
     
  17. milo

    milo New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2009
    Сообщения:
    43
    Sol_Ksacap, какая версия IDA у тебя стоит? а то, я смотрю, у тебя библиотечные функции нормально разпознаются (call ??2@YAPAXI@Z) а у меня нет, что начинающему никак не облегчает жизнь.
     
  18. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    потому что без включенной оптимизации компилятор делает все постепенно.
    ему понадобилось записать значение eax в [ebp+var8] и он это сделал, потом (по исходнику) ему понадобилось перекинуть [ebp+var8] в [ebp+var4] и он тоже это сделал. но без оптимизации он даже не подумал о том, что можно просто в обе переменные записать eax, не говоря уже о том, что они просто могут не понадобится и хватит одних регистров.
     
  19. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Это не из IDA Pro листинг – это скопированный из вывода cmd.exe результат выполнения "dumpbin /disasm main3.obj", а main3.obj получен выполнением "cl /Fm /Zi /Ox main3.cpp". Т.е. достаточно указать компилятору "/Zi", и сгенерируется pdb (отладочная инфа) – IDA Pro для полученного таким образом exe-файла выдаст ещё более подробную информацию. То ли с версии 5.4, то ли с 5.3 IDA поддерживает pdb полностью, более ранние её версии – частично.
     
  20. milo

    milo New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2009
    Сообщения:
    43
    Sol_Ksacap отлично, спасибо. вот только, я думаю, не всегда будут исходники исследуемой проги, поэтому надо будет учиться обходиться без отладочной информации:) а насчет map-файлов - у меня старенькая бесплатная IDA, думал пока учиться хватит мне.