Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #83, НОЯБРЬ 2005 г.

64-битный привет

Крис Касперски ака мыщъх

Хакер, номер #083, стр. 083-118-7


section '.idata' import data readable writeable

dd 0,0,0,RVA kernel_name,RVA kernel_table

dd 0,0,0,RVA user_name,RVA user_table

dd 0,0,0,0,0 ; завершаем список двумя 64-разряными нулеми!!!

kernel_table:

ExitProcess dq RVA _ExitProcess

dq 0 ; завершаем список 64-разряным нулем!!!

user_table:

MessageBox dq RVA _MessageBoxA

dq 0

kernel_name db 'KERNEL32.DLL',0

user_name db 'USER32.DLL',0

_ExitProcess dw 0

db 'ExitProcess',0

_MessageBoxA dw 0

db 'MessageBoxA',0

Ассемблируем файл (fasm PE64DEMO.ASM) и запустим образовавшийся EXE на выполнение. Под 32-разрядной Windows он, естественно, не запустится.

Вдоволь наигравшись нашем первым x86-64 файлом, загрузим его в дизассемблер (например, в IDA Pro 4.7. Она хоть и материться, предлагая использовать специальную 64-битную версию, но при нажатии на yes все корректно дизассемблирует, во всяком случае до тех пор, пока не столкнется с подлинным 64-битным адресом или операндом, с которым произойдет обрезание, в частности, mov r9,1234567890h дизассемблируется, как mov r9, 34567890h, так что переход на 64-битную версию IDA все же очень желателен, тем более, что начиная с IDA 4.9 она входит в базовую поставку). Посмотрим, что у нашей программы внутри?

[дизассемблерный листинг 64-битного приложения hello, world!]

.code:0000000000401000 41 B9 00 00 00 00 mov r9d, 0

.code:0000000000401006 4C 8D 05 F3 0F 00 00 lea r8, aPENUMBRA

.code:000000000040100D 48 8D 15 03 10 00 00 lea rdx, aHelloWorld ; "Hello World!"

.code:0000000000401014 48 C7 C1 00 00 00 00 mov rcx, 0

.code:000000000040101B FF 15 2B 20 00 00 call cs:MessageBoxA

.code:0000000000401021 89 C1 mov ecx, eax

.code:0000000000401023 FF 15 13 20 00 00 call cs:ExitProcess

Что ж, довольно громоздко, объемно и концептуально. Для сравнения, дизассемблированный листинг аналогичного 32-разрядного файла приведен ниже. Старый x86 код в 1,6 раз короче! А ведь это только демонстрационная программа из нескольких строк! На полновесных приложениях разрыв будет только нарастать! Так что не стоит злоупотреблять 64-разрядным кодом без необходимости. Его следует использовать только там, где 64-битная арифметика и 8 дополнительных регистров действительно дают ощутимый выигрыш. Например, в математических задачах или программах для вскрытия паролей.

[дизассемблерный листинг 32-битного приложения hello, world!]

code:00401000 6A 00 push 0

code:00401002 68 00 20 40 00 push offset aPENUMBRA

code:00401007 68 17 20 40 00 push offset aHelloWorld

code:0040100C 6A 00 push 0

code:0040100E FF 15 44 30 40 00 call ds:MessageBoxA

code:00401014 6A 00 push 0

code:00401016 FF 15 3C 30 40 00 call ds:ExitProcess

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

[64-битное приложение hello, world под Windows на MASM'е]

; объявляем внешние API-функции, которые мы будем вызывать

extrn MessageBoxA: PROC

extrn ExitProcess: PROC

; секция данных с атрибутами по умолчанию (чтение и запись)

Назад на стр. 083-118-6  Содержание  Вперед на стр. 083-118-8