áúðчðть - Xakep Online
áúðчðть - Xakep Online
áúðчðть - Xakep Online
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