31.12.2014 Views

Скачать - Xakep Online

Скачать - Xakep Online

Скачать - Xakep Online

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

64-áèòíûé ôàéë —<br />

ïåðâûé ïîëåò<br />

òðàäèöèîííîãî: òîëüêî âñå îïåðàíäû è àäðåñà<br />

ïî óìîë÷àíèþ 64-ðàçðÿäíûå, à ïàðàìåòðû APIôóíêöèé<br />

ïåðåäàþòñÿ áîëüøåé ÷àñòüþ ÷åðåç<br />

ðåãèñòðû, à íå ÷åðåç ñòåê. Ïåðâûå ÷åòûðå àðãóìåíòà<br />

âñåõ API-ôóíêöèé ïåðåäàþòñÿ â ðåãèñòðàõ<br />

RCX, RDX, R8 è R9 (ðåãèñòðû ïåðå÷èñëåíû<br />

â ïîðÿäêå ñëåäîâàíèÿ àðãóìåíòîâ, êðàéíèé ëåâûé<br />

àðãóìåíò ïîìåùàåòñÿ â RCX). À óæ îñòàëüíûå ïàðàìåòðû êëàäóòñÿ<br />

â ñòåê. Âñå ýòî íàçûâàåòñÿ x86-64 fast calling conversion (ñîãëàøåíèå î<br />

áûñòðîé ïåðåäà÷å ïàðàìåòðîâ äëÿ x86-64), ïîäðîáíîå îïèñàíèå êîòîðîé<br />

ìîæíî íàéòè â ñòàòüå The history of calling conventions, part 5 amd64<br />

(http://blogs.msdn.com/oldnewthing/archive/2004/01/14/58579.aspx). Òàêæå<br />

ñîâåòóþ çàãëÿíóòü íà ñòðàíè÷êó áåñïëàòíîãî êîìïèëÿòîðà Free PASCAL<br />

è ïîäíÿòü äîêóìåíòàöèþ ïî ñïîñîáàì âûçîâà API: http://www.freepascal.org/<br />

wiki/index.php/Win64/AMD64_API.  ÷àñòíîñòè, âûçîâ ôóíêöèè ñ ïÿòüþ<br />

àðãóìåíòàìè API_func(1,2,3,4,5) âûãëÿäèò òàê:<br />

ðåãèñòðû, äîñòóïíûå â x86-64 ðåæèìå<br />

ðåàêöèÿ 32-áèòíîé Windows íà ïîïûòêó<br />

çàïóñêà 64-áèòíîãî PE-ôàéëà<br />

çàãðóçêà 64-ðàçðÿäíîãî Äåáèàíà<br />

ïîä ýìóëÿòîðîì QEMU<br />

è áåëóþ ìàãèþ) äîòÿíóòüñÿ äî íèõ<br />

íåëüçÿ è ïðåæäå ÷åì ÷òî-òî ñäåëàòü,<br />

íåîáõîäèìî ïåðåâåñòè ïðîöåññîð â<br />

äëèííûé ðåæèì (long mode), êîòîðûé<br />

äåëèòüñÿ íà äâà ïîäðåæèìà: ðåæèì<br />

ñîâìåñòèìîñòè ñ x86 (compatibility<br />

mode) è 64-áèòíûé ðåæèì (64-bit<br />

mode). Ðåæèì ñîâìåñòèìîñòè ïðåäóñìîòðåí<br />

òîëüêî äëÿ òîãî, ÷òîáû 64-ðàçðÿäíàÿ<br />

îïåðàöèîííàÿ ñèñòåìà ìîãëà<br />

âûïîëíÿòü ñòàðûå 32-áèòíûå ïðèëîæåíèÿ.<br />

Íèêàêèå 64-áèòíûå ðåãèñòðû<br />

çäåñü è íå íî÷åâàëè! Ðåàëüíàÿ 64-áèòíîñòü<br />

îáèòàåò òîëüêî â 64-bit long<br />

mode, î êîòîðîì ìû è áóäåì ãîâîðèòü!<br />

[hello world íà x86-64] Ïðîãðàììèðîâàíèå<br />

ïîä 64-áèòíóþ âåðñèþ<br />

Windows ìàëî ÷åì îòëè÷àåòñÿ îò<br />

mov dword ptr [rsp+20h], 5<br />

mov r9d, 4<br />

mov r8d, 3<br />

mov edx, 2<br />

mov ecx, 1<br />

call API_func<br />

; êëàäåì íà ñòåê ïÿòûé ñëåâà àðãóìåíò<br />

; ïåðåäàåì ÷åòâåðòûé ñëåâà àðãóìåíò<br />

; ïåðåäàåì òðåòèé ñëåâà àðãóìåíò<br />

; ïåðåäàåì âòîðîé ñëåâà àðãóìåíò<br />

; ïåðåäàåì ïåðâûé ñëåâà àðãóìåíò<br />

Ñìåùåíèå ïÿòîãî àðãóìåíòà îòíîñèòåëüíî âåðõóøêè ñòåêà òðåáóåò ïîÿñíåíèé.<br />

Ïî÷åìó îíî ðàâíî 20h Âåäü àäðåñ âîçâðàòà çàíèìàåò òîëüêî 8<br />

áàéò. Êàêàÿ ñó… ñóùíîñòü ñúåëà âñå îñòàëüíûå Îêàçûâàåòñÿ, îíè ðåçåðâèðóþòñÿ<br />

äëÿ ïåðâûõ ÷åòûðåõ àðãóìåíòîâ, ïåðåäàííûõ ÷åðåç ðåãèñòðû.<br />

Çàðåçåðâèðîâàííûå ÿ÷åéêè ñîäåðæàò íåèíèöèàëèçèðîâàííûé ìóñîð è ïîáóðæóéñêè<br />

íàçûâàþòñÿ spill, ÷òî ïåðåâîäèòñÿ êàê çàòû÷êà èëè ïîòåðÿ.<br />

Âîò ìèíèìóì çíàíèé, íåîáõîäèìûõ äëÿ âûæèâàíèÿ â ìèðå 64-áèòíîé<br />

Windows ïðè ïðîãðàììèðîâàíèè íà àññåìáëåðå. Îñòàåòñÿ ðàçîáðàòü<br />

ñàìóþ ìàëîñòü: êàê ýòè ñàìûå 64-áèòà çàïîëó÷èòü! Äëÿ ïåðåâîäà<br />

FASM'à â x86-64 ðåæèì äîñòàòî÷íî óêàçàòü äèðåêòèâó use64 è äàëüøå<br />

êîäèòü êàê îáû÷íî.<br />

Íèæå èäåò ïðèìåð ïðîñòåéøåé x86-64 ïðîãðàììû, êîòîðàÿ íå äåëàåò<br />

íè÷åãî, òîëüêî âîçâðàùàåò â ðåãèñòðå RAX çíà÷åíèå 0.<br />

[XÀÊÅÐ 11 [83] 05 > ÊÎÄÈÍÃ 120]<br />

ÏÅÐÅÕÎÄ Â 64-ÐÀÇÐßÄÍÛÉ ÐÅÆÈÌ<br />

Êàê èçâåñòíî, â èñõîäíèêàõ FreeBSD<br />

ìîæíî íàéòè ôàéë amd64_tramp.S,<br />

áûñòðî è ãðÿçíî ïåðåâîäÿùèé<br />

ïðîöåññîð â 64-ðåæèì. Îòêîìïèëèðîâàâ,<br />

åãî ìîæíî çàïèñàòü â bootñåêòîð,<br />

çàãðóæàþùèé íàøó<br />

ñîáñòâåííóþ îïåðàöèîííóþ ñèñòåìó<br />

(òû âåäü ïèøåøü åå, ïðàâäà),<br />

èëè ñëèíêîâàòü com-ôàéë, çàïóñêàåìûé<br />

èç ðåàëüíîãî x86-ðåæèìà (äëÿ<br />

ýòîãî ïîòðåáóåòñÿ ÷èñòàÿ MS-DOS<br />

áåçî âñÿêèõ ýêñòåíäåðîâ). Â îáùåì,<br />

âàðèàíòîâ, êàê ñ ýòèì ñïðàâèòüñÿ,<br />

äîâîëüíî ìíîãî.<br />

[ïåðåâîä ïðîöåññîðà â 64-ðàçðÿäíûé ðåæèì]<br />

//$FreeBSD: /repoman/r/ncvs/src/sys/boot/i386/<br />

libi386/amd64_tramp.S,v 1.4 2004/05/14<br />

/*<br />

* Quick and dirty trampoline to get into 64 bit<br />

(long) mode and running<br />

* with paging enabled so that we enter the kernel<br />

at its linked address.<br />

*/<br />

#define MSR_EFER 0xc0000080<br />

#define EFER_LME 0x00000100<br />

#define CR4_PAE 0x00000020<br />

#define CR4_PSE 0x00000010<br />

#define CR0_PG 0x80000000<br />

/* GRRR. Deal with BTX that links us for a nonzero<br />

location */<br />

#define VPBASE<br />

#define VTOP(x)<br />

.data<br />

.p2align 12,0x40<br />

.globl PT4<br />

PT4:<br />

.space<br />

.globl PT3<br />

PT3:<br />

.space 0x1000<br />

.globl PT2<br />

PT2:<br />

.space<br />

0xa000<br />

((x) + VPBASE)<br />

0x1000<br />

0x1000<br />

gdtdesc:<br />

.word gdtend - gdt<br />

.long VTOP(gdt) # low<br />

.long0<br />

# high<br />

gdt:<br />

.long 0 # null descriptor<br />

.long 0<br />

.long 0x00000000 # %cs<br />

.long 0x00209800<br />

.long 0x00000000 # %ds<br />

.long 0x00008000<br />

gdtend:<br />

.text<br />

.code32<br />

.globl amd64_tramp<br />

amd64_tramp:<br />

/* Be sure that interrupts are disabled */<br />

cli<br />

/* Turn on EFER.LME */<br />

movl $MSR_EFER, %ecx<br />

rdmsr<br />

orl $EFER_LME, %eax<br />

wrmsr<br />

/* Turn on PAE */<br />

movl %cr4, %eax<br />

orl $(CR4_PAE | CR4_PSE), %eax<br />

movl %eax, %cr4<br />

/* Set %cr3 for PT4 */<br />

movl $VTOP(PT4), %eax<br />

movl %eax, %cr3<br />

/* Turn on paging (implicitly sets EFER.LMA) */<br />

movl %cr0, %eax<br />

orl $CR0_PG, %eax<br />

movl %eax, %cr0<br />

movl<br />

movl<br />

movl<br />

lgdt<br />

ljmp<br />

$VTOP(gdtdesc), %eax<br />

VTOP(entry_hi), %esi<br />

VTOP(entry_lo), %edi<br />

(%eax)<br />

$0x8, $VTOP(longmode)<br />

.code64<br />

longmode:<br />

movl %esi, %eax<br />

salq $32, %rax<br />

orq %rdi, %rax<br />

pushq %rax<br />

ret

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!