1. Assembler / Говнокод #5091

    +225

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    ; Program entry point
    00401000:  push 0070F001
    00401005:  call 0040100B
    0040100A:  ret
    0040100B:  ret

    Суровый старт зашифрованного самораспаковывающегося архива. Так хитро передаётся управление на 0070F001 (за сегмент кода).

    Запостил: TarasB, 28 Декабря 2010

    Комментарии (46) RSS

    • Не вызовет ли сочетание пуша и рета тот же эффект, что и в http://govnokod.ru/1520?
      Ответить
      • Должно.
        Ответить
        • Вот и я о том же - что говно говном получается.
          Ответить
      • Почему? Там ведь несколько другое. Там забирается адрес ПОСЛЕ вызова процедуры, а здесь кладётся ДО. Такое впечатление, что командой "call" здесь пытались пофиксить некий системный глюк...
        Можно и так?
        00401000: push 0070F001
        00401005: call 0040100A
        0040100A: ret
        --
        И почему, в обоих случаях, нельзя использовать счётчик команд?.. (вопрос)
        Ответить
        • > Можно и так?
          Хм, похоже, так и нужно. Хотя есть же jmp 0070F001.
          > почему, в обоих случаях, нельзя использовать счётчик команд?
          Дело в хитрожопом 3-битном кодировании регистров:
          _	8 bit	16 bit	32 bit	Segment	Control	Debug
          0 (000)	AL	AX	EAX	ES	CR0	DR0
          1 (001)	CL	CX	ECX	CS		DR1
          2 (010)	DL	DX	EDX	SS	CR2	DR2
          3 (011)	BL	BX	EBX	DS	CR3	DR3
          4 (100)	AH	SP	ESP	FS	CR4	
          5 (101)	CH	BP	EBP	GS		
          6 (110)	DH	SI	ESI			DR6 (DR4)
          7 (111)	BH	DI	EDI			DR7 (DR5)
          Для EIP не нашлось места. Ну и еще, например, команда mov eip, <src> была бы посложнее обычной записи в регистр.
          Ответить
          • Нечто вроде jmp предлагалось в http://govnokod.ru/5091#comment65815 :)

            > Для EIP не нашлось места.
            :) весело.

            Значит с усложнением архитектуры процессоров более лояльнее, использование высокоуровневых языков, либо всеобщая глобальная процессоростандартизация.
            Ответить
            • > глобальная процессоростандартиз ация
              Это вряд ли :)
              Ответить
          • В 8086 была стрёмная инструкция POP CS. Чему равнялось значение IP после записи нового значения в CS?
            К счастью, её вскоре отменили.
            Ответить
          • откуда копипаста?
            Ответить
            • Хороший вопрос. Не помню. Было дело, интересовался немного системой команд, таблички находил...
              Ответить
              • когда-то давно у меня было сборище справочников по опкодам и иже с ними, сейчас от low level отошёл, и справочники протерялись, однако каждый раз когда лезу в интеловские мануалы, появляется желание опять завести себе
                Ответить
                • Как же это манит при всей своей бесполезности...
                  Ответить
                  • рецепт успеха прост: заводите себе интеловские; пробуете скопипастить оттуда что-либо уместное; всё, желание возникло.
                    Ответить
                    • Говорю, это интересно и меня всегда манило, но в наше время редко кормит...
                      Ответить
                      • ну как же без справочника? даже на говнокоде неудобно трепаться :)
                        Ответить
                        • Вы всё ещё пользуетесь книжками? Тогда Интернет идёт к Вам.
                          Ответить
                • Вот тут находил кое-что:
                  http://dospage.by.ru/docs_dos.shtm
                  Еще есть бумажная Assembler: Специальный справочник, В. Юров.
                  Ответить
                  • спасибо, накачал (techhelp и helppc точно были в той коллекции)

                    кстати, у этого чувака нет винрарнейшего справочника Ralf Brown's Interrupt List
                    Ответить
          • >Для EIP не нашлось места.
            Теперь в х64 есть доступ к EIP. :)
            Ответить
        • Инструкция jmp near в машинных кодах на x86 содержит не абсолютный адрес назначения, а относительный, поэтому в коде будет не 0070F001, а разность 0070F001 и текущего адреса, а текущий адрес ВНЕЗАПНО может не оказаться фиксированным. Либо в выбранном ассемблере не оказалось удобного представления для такого прыжка. Потому и push-ret вместо джампа.
          Ответить
          • EA cp
            JMP ptr16:32
            Jump far, absolute, address given in operand
            Ответить
            • Тоже хотел написать, а теперь вот думаю, а не будет ли работа с 48-битным указателем еще медленнее чем рассогласование call/ret...
              Ответить
              • Точно не будет. Рассогласование может начать тормозить всё последующее выполнения программы.
                Ответить
                • Дико извиняюсь, но рассогласование это в http://govnokod.ru/1520 ?
                  Как бы:
                  : call label
                           : ret
                  label: push 0070F001
                           : ret

                  Но здесь же несколько иная ситуация, не?
                  Ответить
                  • В этом говнокоде как раз несоответсвие числа call и ret.
                    Ответить
            • Есть такая штука. Только боюсь, что набирать придётся через директиву db. Ассемблер никаких фиксапов в объектный файл не напихает?
              Ответить
              • когда-то надо было, точно помню label far и потом jmp indirect
                Ответить
    • уж не помню контекста, но я видел как подобные игры использовались для инитиализации начального фрейма в стеке что бы способ запуска не был виден в стеке исполняймой программы. перекладывая на С: между libc и main() нет лишних стек фреймов.
      Ответить
    • А в чём разница между кодом в говнокоде и этим:
      00401000:  push 0070F001
      0040100A:  ret

      ?
      Ответить
      • сколько раз вошли и сколько раз вышли?
        Ответить
      • По идее одно и то же. Выдвину гипотезы:
        1. Что-нибудь сгенерированное языками высокого уровня.
        2. Дурилка для отладчика.
        Ответить
        • Ответить
        • Ну отладчик не задуришь, а вот насчёт 1-го соглашусь.
          Ответить
        • Мой примитивный отладчик за 500 Кб как раз задурился. Он не считает, что адрес 00700000 находится в части кода и не показывает его мне.
          Просто я захотет поковырять самоархиватор, требующий у меня СМС и сразу напоролся на такой прикол.
          Ответить
          • Вы всё ещё используете самодельные отладчики? Тогда OllyDbg идёт к вам!
            Ответить
        • Дурилка однозначно. Это же упаковщик.
          Ответить
    • если это сделано програмно -- то наивно
      если руками -- сам же запутается

      можно еще набить в стек 42 адреса и 8 раз сделать рет
      Ответить
    • Нестеренко поет: "и куда ни пойдешь -- везде наткнешься на ret, и __еще хорошо если в стеке есть адрес возврата__".
      Кажется я понял, о чем он))
      Ответить
    • Чё-то похоже на точку входа аспротекта. Ничего необычного в принципе нет, такие джампы push-ret уже давно юзаются.
      Ответить
    • показать все, что скрытоТарасиха - сучка.
      Ответить
      • Звёздные войны. Эпизод II: Атака клоунов.
        Ответить
    • Солодовняк с его б-гомерзким ASProtect негодуэ!
      Ответить
    • Обычный код, какого в каждой второй защищенной программе как грязи. Не скажется это на быстродействии всей программы. Если уж кому то влом маны курить, то поглядите хотя бы на шитый код форт-программ, творящий со стэком "ужасные" вещи, но остающийся при этом довольно шустрым.
      Ответить

    Добавить комментарий