Хак виртуальной машины RarVM внутри WinRAR

Тема в разделе "Новости и статьи IT безопасности", создана пользователем X-Shar, 10 окт 2012.

↑ ↓
  1. X-Shar :)
    X-Shar
    Ответить в чате

    Администрация

    Регистрация:
    03.06.2012
    Сообщения:
    5.800
    Симпатии:
    425
    Пол:
    Мужской
    Репа:
    +957 / 152 / -29
    Jabber:
    Skype:
    ICQ:

    638294628

    Специалист по безопасности Тэвис Орманди (Tavis Ormandy) покопался в коде архиватора WinRAR и разработал инструментарий для встроенной в архиватор виртуальной машины RarVM.
    Мало кто знает, что внутри WinRAR есть примитивная x86-совместимая виртуальная машина. В ней всего около 50 инструкций, а вся виртуальная машина со стандартными фильтрами занимает чуть больше 1000 строк. Она реализована внутри архиватора с одной целью: улучшить сжатие x86-кода. Например, представим программу вроде такой.
    Код:
    mov foo, bar
    cmp bar, baz
    push foo
    call write
    push bar
    call write 
    Повторяющиеся вызовы можно транслировать в абсолютные адреса и более эффективно заархивировать. Поэтому в RAR есть фильтры для десятка стандартных вызовов. Более того, в нём есть возможность создания новых фильтров в процессе архивации! То есть в архив RAR можно включать байткод, который будет исполняться встроенной виртуальной машиной RarVM.
    До сих пор не существовало программ, которые бы использовали эту необычную функциональность, поэтому Тэвис Орманди разработал компоновщик и ассемблер, опубликовал документацию для работы с RarVM, в скором будущем планирует выпустить ещё дизассемблер и, может быть, портировать компилятор на основе llvm.
    Пример программы, которая выводит классическое “Hello, World!” за счёт CRC-компенсации в проверке CRC.

    Код:
        $ cat sample.rs
        #include
        #include
        #include
        #include
        ; vim: syntax=fasm
     
        ; Test RAR assembly file that just demonstrates the syntax.
     
        _start:
        ; Install our message in the output buffer
        mov r3, #0x1000 ; Output buffer.
        mov [r3+#0], #0x41414141 ; Padding for compensation
        mov [r3+#4], #0x0a414141 ; Padding for compensation
        mov [r3+#8], #0x6c6c6548 ; 'lleH'
        mov [r3+#12], #0x57202c6f ; 'W ,o'
        mov [r3+#16], #0x646c726f ; 'dlro'
        mov [r3+#20], #0x00000a21 ; '!\n'
        mov [VMADDR_NEWBLOCKPOS], #0x00001000
        mov [VMADDR_NEWBLOCKSIZE], #22
     
        ; Compensate to required CRC
        push RAR_FILECRC
        push [VMADDR_NEWBLOCKSIZE]
        push [VMADDR_NEWBLOCKPOS]
        call $_compensate_crc
        test r0, r0
        jz $finished
        call $_error
     
        finished:
        call $_success
        $ make sample.rar
        cpp -Istdlib < sample.rs > sample.ri
        ./raras -o sample.ro sample.ri
        ./rarld sample.ro > sample.rar
        rm sample.ri sample.ro
        $ unrar p -idq sample.rar
        AAc��!A
        Hello, World!
    b4bbdbbd79c9.
    Источник
     
    • Мне нравится Мне нравится x 2

Поделиться этой страницей