Данные в секции кода. Как распознать?

Тема в разделе "WASM.RESEARCH", создана пользователем Temir, 18 фев 2007.

  1. Temir

    Temir New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2005
    Сообщения:
    14
    Приветствую мужички!

    Пишу свой дизассемблер. Возникла проблема. Помогите пожалуйста, чем сможете...
    В секции кода хранятся данные, ида видит это так:

    ...
    CODE:0040158F jnz short loc_401588
    CODE:00401591 call loc_401130
    CODE:00401591 ; END OF FUNCTION CHUNK FOR sub_401056

    CODE:00401596 word_401596 dw 0 ; DATA XREF: start+1Eo
    CODE:00401598 dd 0Ch dup(0)
    ....

    Мой дизассемлер при вызове функции loc_401130 кладет адрес возврата в стек. Потом, когда к нему возвращается, естественно получается белиберда, потому что происходит обработка данных как если бы это был код.
    Как мне обнаружить такие случаи, какие есть способы?

    Я пока вижу только два: перекрестная ссылка (DATA XREF: start+1Eo) указывает на строку: mov edi, offset word_401596. Т.е. в процессе дизассемблирования можно отслеживать такие обращения в инструкциях mov, add и т.д., делая пометки, что там хранятся данных (коли к ним так обращаются). А затем проверять адреса переходов на корректность.
    Или же постоянно отслеживать стек. Т.е. все pop, push и манипуляции с ebp, esp.
    Буду благодарен любым размышлениям.

    Прошу прощения за косноязычное изложение вопроса.
    Спасибо.
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    можно анализировать воздействия кода на память и регистры. если там идет подряд, например, обращение по указателю 0x00001234, потом команда ввода-вывода, потом еще какая-то хрень, это, скорее всего, данные.
     
  3. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Temir
    А на чем твоя программа написана? В зависимости от этого советы могут быть разными. В дельфи, например, можно в подавляющем большинстве случаев найти правильный конец процедуры. В твоем случае вызов call loc_401130 напоминает процедуру завершения и выхода из программы (хотя по такому кусочку можно заниматься только пророчествами).
     
  4. Temir

    Temir New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2005
    Сообщения:
    14
    Анализировать конечно можно, но это будет очень трудоемкий процесс. К тому же практически невозможно учесть все случаи.
    Нужно делать это точно так же, как делает это процессор. Ему-то все равно, он просто подряд исполняет код. Видимо, после call, программа удаляет адрес возврата или изменяет его. То есть получается, что единственный выход, отслеживать все манипуляции со стеком.
    Или все же я не прав?
     
  5. Temir

    Temir New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2005
    Сообщения:
    14
    Crypto
    Программа не моя, на чем написана не знаю. Нужно общее решение.
    Но это не завершение программы. Там дальше по ходу можно выйти на вызов ExitProcess.
     
  6. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Temir
    Если ты сам пишешь код, который надо дизасмить, то после таких калов можно рет ставить. довольно удобно. А если код чужой, то... ида этого сделать до конца не может, а она развивается уже х.з. сколько лет.
     
  7. Temir

    Temir New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2005
    Сообщения:
    14
    asd
    Дизассемблер пишу, чтобы брал любые проги. Конечно я не стремлюсь перегнать иду :)
    В принципе нормальные программы мой дизассм берет отлично в 90% случаев, но когда дело доходит до анализа вирусов, встречаются такие подлянки. Так что получается 50 на 50. Уже давно пытаюсь найти решение, но пока ничего не приходит дельного. Вот и решил спросить.
    А в конце этого колла стоит jmp edi, вот как. Ретом там не пахнет, блин. Что за компилятор это создал?
     
  8. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Temir
    Я тебе толкую о том, что в общем виде проблему решить нельзя, особенно если код и данные сильно перемешаны. Посмотри, что делает из файлов, написанных на Дельфи и Билдере, упомянутая тобой ИДА - черт знает что! А вот если писать дизассемблер, ориентированный на конкретный компилятор...
     
  9. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Ещё может быть такое:
    Код (Text):
    1. push  0
    2. push  0
    3. call  @F
    4.  db 'test',0
    5. @@:
    6. push  0
    7. call [MessageBoxA]
    Кроме этого нужно отслеживать путь исполнения. То есть, если из подпрограммы управление возвращается, то в стеке должен быть код (но если ты не можешь его декодировать (зашифрован), то тут уже варианты - пытаться декодировать начиная с каждого байта вниз или же оставить как есть (с пометкой, что это код)). Если же нет (как в случае call @F), то это - данные.
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    процессор не различает код и данные
     
  11. Temir

    Temir New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2005
    Сообщения:
    14
    Crypto
    в общем виде проблему решить нельзя. Согласен с этим. Да и под конкретный компилятор писать, тоже хрен знает. Не получится отследить все особенности. Частные случаи тоже видимо не учесть. Но все таки:
    если я фиксирую все mov, add (хотя бы их), которые используют данные из секции кода. Создам массив таких адресов и буду сверять с ним. Хотя бы частично это поможет решить проблему?

    IceStudent
    Каким образом "оставить как есть" - какой критерий оставления выбрать?
     
  12. Temir

    Temir New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2005
    Сообщения:
    14
    Great
    Конечно же процессор не различает код и данные. Просто в стеке затирается адрес возврата (если брать вышеназванный случай), я уже говорил. А мой дизассемблер не отслеживает стэк и возвращается по этому адресу. Вот и все.
     
  13. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Temir
    Если вызов заканчивается jmp, то ты можешь
    1. отследить, куда выполнится переход, и если это банальный выход из процедуры, то после вызова должно быть продолжение кода
    2. если невозможно проследить, куда выполнится переход, то ты пытаешься найти ту стартовую точку после вызова, откуда может снова начинаться код. В этом случае полезно ставить флажки по адресам, которые могут принадлежать коду из разных мест, которые ты в данный момент анализируешь.
     
  14. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    проще всего написать небольшой анализатор, который будет проходить по всему коду как бы имитируя его выполнене и строить дерево всех вызовов/переходов, а те куски которые останутся не тронутыми собсно и будут данными
     
  15. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Cr4sh
    тут легко пролететь. если я напишу:

    if(rand() == 1234)
    {
    somecode
    }

    Твой анализатор это посчитает за данные
     
  16. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    >> Твой анализатор это посчитает за данные
    почему? он ведь будет проходить по всем местам, на которые будут указывать инструкции CALL и Jxx
     
  17. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    тогда я не понял твою идею про имитацию выполнения))
     
  18. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    >> тогда я не понял твою идею про имитацию выполнения))
    да про имитацию выполнения это я немного не так выразился)) я имел ввиду что для достижения цели достаточно имитировать только выполнение инструкций CALL, RET и Jxx
    т.е., составить как бы карту кода, по кторой потом будет видно, какие куски выполняются а какие нет
     
  19. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Cr4sh
    Проблема будет к примеру с такими кусками
    call @1
    @2:
    SomeData
    @1:
    pop блабал.

    Такой подход вполне годиться для разбора своего кода, от которого знаешь чего ждать, но чужой...

    Temir
    А для каких целей нужен дизасм. Т.е. кто его использовать будет, и что будет, если дизасм ошибётся?
     
  20. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    Cr4sh
    Составить карту кода очень проблематично, потому что могут быть ведь конструкции типа if(a) { данные } с a заведомо равным false. Такие выражения (так называемые opaque predicates) широко используются при обфускации. То есть определть в общем случае, какие куски будут выполняться, а какие нет, можно только собственно выполнив программу :dntknw: