Ошибка при компиляции дизассемблированного кода

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

  1. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    Получаю следующие две ошибки:
    ; int __cdecl sub_401060(char *Str)
    sub_401060 proc near
    Str = dword ptr 4 ;error A2008:syntax error
    mov eax, [esp+Str] ;error A2008:syntax error : Str

    В секции данных есть определение глобальной Str
    ; char Str[]
    Str db '&/=',0
    но если ее закомментировать, то все равно выпадают эти 2 ошибки
    Где эта зараза Str может быть еще определена.
    И еще:
    при компиляции путает верхний и нижний регистры:
    FILE и File воспринимаются компилятором одинаково. Это можно поправить?
     
  2. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Truhlya
    STR - это инструкция Store Task Registr. Нельзя использовать ее коде для процессоров с 286p и выше.

    > при компиляции путает верхний и нижний регистры ... Это можно поправить?
    Для masm'а смотри ключики
    Код (Text):
    1. /Cp Preserve case of user identifiers
    2. /Cu Map all identifiers to upper case
    3. /Cx Preserve case in publics, externs
    или директиву option casemap : <ALL, NONE, or NOTPUBLIC>
     
  3. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    q_q
    Большое Вам спасибо.
     
  4. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Truhlya
    Я бестолково написал.
    В первом абзаце сообщения #2. читать "Нельзя использовать это имя в коде для процессоров с 286p и выше в качестве отличном от имени команды."
     
  5. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    Все толком: у меня еще есть несколько извилин, чтобы понять, что на самом деле Вы хотели сказать.
    Но вот новый затык:
    ..................................................................
    ..................................................................
    ..................................................................
    .text:00404FBF retn
    .text:00404FBF sub_404F60 endp
    .text:00404FBF
    .text:00404FC0
    .text:00404FC0 ; =============== S U B R O U T I N E =======================
    .text:00404FC0
    .text:00404FC0
    .text:00404FC0 nullsub_1 proc near ; CODE XREF: sub_40DB60+138p
    .text:00404FC0 ; sub_40E370+27Ep
    .text:00404FC0 ; DATA XREF: ...
    .text:00404FC0 retn
    .text:00404FC0 nullsub_1 endp
    .text:00404FC0
    .text:00404FC0 ; ---------------------------------------------------------------------------
    .text:00404FC1 align 10h
    .text:00404FD0 sub esp, 8C4h
    .text:00404FD6 lea eax, [esp+0C4h]
    .text:00404FDD push ebx
    .text:00404FDE push ebp
    .text:00404FDF push esi
    .................................................................
    .................................................................
    .................................................................
    Не врубаюсь:
    за .text:00404FBF идет .text:00404FC0, хотя инструкций никаких нет.
    Далее:
    nullsub_1 места в памяти не занимает - все адреса одинаковы - .text:00404FC0
    И само главное: как искать переход на код, который следует за nullsub_1
     
  6. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    По адресу 00404FBF идет инструкция ret. Занимает один байт, код 0xC3. По адресу 00404FC0 тоже самое. А вызов 00404FD0 может происходить косвенно, например. Можно попробовать поймать место вызова в отладчике, поставив точку останова на начало кода, а когда остановится (если вообще остановится :) ), посмотреть адрес возврата в стеке. Если, конечно, вызов с помощью call происходил. Если не остановилось, то анализировать придется руками. В этом случае есть смысл порыскать вокруг косвенных вызовов/переходов. Хотя все зависит от кода, переход может быть и таким: mov eax, addr_of_func/push eax/ret. Но компиляторы такого не творят обычно.
     
  7. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    retn - инструкция.
    занимает.
     
  8. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    Mika0x65
    До этого места мне еще далеко. Пока не могу разобраться с точкой входаоткомпилированного и слинкованного дизассемблерного файла start proc near
    Функция start, откуда вызывается main, заканчивает свою работу, не доходя до main (вылетает из функции, связанной с C++).
    Псевдокод этой самой start начинается так:
    void __usercall start(int a1<eax>)
    {
    .....................
    }
    Как я понял, система передает через регистр a1 определенную информацию. Кто-нибудь знает, где об этом можно почитать? Заранее приношу свои благодарности за любую информацию.
     
  9. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Truhlya
    > система передает через регистр a1 определенную информацию
    Startup-код как-нибудь ее использует?

    Если речь о windows, то, теоретически (Рихтер), startup-код - это поток, который вызван посредством CreateThread.
     
  10. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    q_q
    Пока решил плясать от места, в котором вылетает программа.
    Начальная функция start обращается к _cinit, которая в свою очередь обращается к _initterm.
    Вот псевдокоды этих функций:
    void __cdecl _cinit()
    {
    if ( off_442A40 )
    off_442A40();
    _initterm((unsigned int)&unk_430008, (unsigned int)&unk_430010);
    _initterm((unsigned int)&unk_430000, (unsigned int)&unk_430004);
    }
    void __cdecl _initterm(unsigned int a1, unsigned int a2)
    {
    unsigned int i; // edi@1
    unsigned int v3; // esi@1

    v3 = a1;
    for ( i = a2; v3 < i; v3 += 4 )
    {
    if ( *(_DWORD *)v3 )
    (*(int (**)(void))v3)();
    }
    }
    На первом же обращении к _initterm программа вылетает. Как следует из псевдокода, начальное значение v3 передается из unk_442008. Из текста программы следует, что это адрес функции ___initstdio. А из псевдокода следует, что значение v3 изменяется в цикле на 4. Бред. Или я впал сам в бредовое состояние.
     
  11. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Это CRT'шный код, зачем его восстанавливать, если его можно посмотреть в сорцах crt ?
     
  12. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    TSS
    Не подскажите, где можно скачать не очень древние сорцы?
     
  13. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Ну в составе MSVC2008 они есть например, или гугл как вариант.
     
  14. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    MSVC2008 у меня стоит, но сырца, например, для __cinit нет. Правда, есть библотека msvcrt.lib, куда она входит. А в гугле нашел только вокруг да около.
     
  15. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    ..\Microsoft Visual Studio 9.0\VC\crt\src <== нет такой папки? Значит либо не установлено, либо не Professional Edition.

    Ф-я _cinit находится в crt0dat.c, залил папку crt сюда: http://slil.ru/27858000
     
  16. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    Да, Вы правы. Я делал поиск по _cinit.c. Спасибо. У меня MSVC2008 SP1 и эта папка присутствует.
     
  17. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    Нет, совсем другая опера.
     
  18. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    Т.к. облом происходит при вызове _cinit, то я решил воспользоваться библиотекой libcmt.lib, где и сидит _cinit: добавил extrn _cinit:dword;, командой ml /coff /I. /c /Cp /Zp1 /Zm /Gz 1.asm получил объектный файл и попробовал получить экзешник командой link /SUBSYSTEM:CONSOLE 1.obj KERNEL32.LIB GDI32.lib Advapi32.lib USER32.lib libcmt.lib, но получил фейсом об тейбл: 1.obj : error LNK2019: libcmt.lib(crt0.obj) : error LNK2019: ссылка на неразрешенный внешний символ _main в функции ___tmainCRTStartup. А причем здесь main?
     
  19. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    С этим я уже разобрался.
    Ранее я имел дело с дизассемблированием фортранного кода и этих заморочек не возникало. Хочу разобраться теперь c С++. Для этого, по крайне мере, надо добраться до main. Но не получаеся пока. Вы не можете подсказать, где можно почитать не очень закрученное про этот предварительный участок (до старта main)?
     
  20. Truhlya

    Truhlya New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    16
    Так как там выскочила ошибка, то и хотел разобраться, что, как и почему.
    Как говорится: заставь дурака Богу молиться, он и лоб расшибёт. Но если бы ошибка в стартовом участке кода не выскочила, то я бы конечно участок до main пропустил. Сейчас воспользовался Вашим советом и уже занимаюсь main.