Introduction to ARM64v8
Uitsonderingsvlakke - EL (ARM64v8)
In die ARMv8-argitektuur definieer uitvoeringsvlakke, bekend as Uitsonderingsvlakke (EL's), die voorregvlak en -vermoëns van die uitvoeringsomgewing. Daar is vier uitsonderingsvlakke, wat strek van EL0 tot EL3, elk met 'n ander doel:
EL0 - Gebruikermodus:
Dit is die minst bevoorregte vlak en word gebruik vir die uitvoering van gewone aansoekkode.
Toepassings wat by EL0 hardloop, is van mekaar en van die stelsel sagteware geïsoleer, wat die veiligheid en stabiliteit verbeter.
EL1 - Bedryfstelsel-kernelmodus:
Die meeste bedryfstelselkerne hardloop op hierdie vlak.
EL1 het meer voorregte as EL0 en kan toegang tot stelselbronne verkry, maar met sekere beperkings om stelselintegriteit te verseker.
EL2 - Hipervisormodus:
Hierdie vlak word vir virtualisering gebruik. 'n Hipervisor wat by EL2 hardloop, kan verskeie bedryfstelsels (elk in sy eie EL1) bestuur wat op dieselfde fisiese hardeware hardloop.
EL2 bied eienskappe vir isolasie en beheer van die gevirtualiseerde omgewings.
EL3 - Sekuriteitsmonitor-modus:
Dit is die mees bevoorregte vlak en word dikwels gebruik vir veilige opstart en vertroude uitvoeringsomgewings.
EL3 kan toegange tussen veilige en nie-veilige toestande bestuur en beheer (soos veilige opstart, vertroude OS, ens.).
Die gebruik van hierdie vlakke maak 'n gestruktureerde en veilige manier moontlik om verskillende aspekte van die stelsel te bestuur, van gebruikersaansoeke tot die mees bevoorregte stelsel sagteware. ARMv8 se benadering tot voorregvlakke help om verskillende stelselkomponente doeltreffend te isoleer, wat die veiligheid en robuustheid van die stelsel verbeter.
Registers (ARM64v8)
ARM64 het 31 algemene doelregisters, gemerk as x0
tot x30
. Elkeen kan 'n 64-bis (8-byte) waarde stoor. Vir operasies wat slegs 32-bis waardes vereis, kan dieselfde registers in 'n 32-bis modus benader word deur die name w0 tot w30 te gebruik.
x0
totx7
- Hierdie word tipies as krapregisters gebruik en vir die deurgawe van parameters aan subroetines.
x0
dra ook die terugvoerdata van 'n funksie.
x8
- In die Linux-kernel wordx8
gebruik as die stelseloproepnommer vir diesvc
-instruksie. In macOS is dit die x16 wat gebruik word!x9
totx15
- Meer tydelike registers, dikwels gebruik vir plaaslike veranderlikes.x16
enx17
- Intra-prosedurele Oproepregisters. Tydelike registers vir onmiddellike waardes. Hulle word ook gebruik vir indirekte funksie-oproepe en PLT (Procedure Linkage Table) stompies.
x16
word as die stelseloproepnommer vir diesvc
-instruksie in macOS gebruik.
x18
- Platformregister. Dit kan as 'n algemene doelregister gebruik word, maar op sommige platforms is hierdie register gereserveer vir platformspefieke gebruike: Wysiger na die huidige draadomgewingsblok in Windows, of om te wys na die tans uitvoerende taakstruktuur in die Linux-kernel.x19
totx28
- Hierdie is callee-bewaarde registers. 'n Funksie moet hierdie registers se waardes vir sy aanroeper bewaar, sodat hulle in die stok gestoor en herstel word voordat teruggekeer word na die aanroeper.x29
- Raamregister om die stokraam dop te hou. Wanneer 'n nuwe stokraam geskep word omdat 'n funksie geroep word, word diex29
-register in die stok gestoor en die nuwe raamadres (sp-adres) word in hierdie register gestoor.
Hierdie register kan ook as 'n algemene doelregister gebruik word, alhoewel dit gewoonlik as verwysing na plaaslike veranderlikes gebruik word.
x30
oflr
- Skakelregister. Dit hou die terugvoeradres wanneer 'nBL
(Branch with Link) ofBLR
(Branch with Link to Register) instruksie uitgevoer word deur diepc
-waarde in hierdie register te stoor.
Dit kan ook soos enige ander register gebruik word.
As die huidige funksie 'n nuwe funksie gaan roep en dus
lr
gaan oorskryf, sal dit dit aan die begin in die stok stoor, dit is die epiloog (stp x29, x30 , [sp, #-48]; mov x29, sp
-> Stoorfp
enlr
, genereer spasie en kry nuwefp
) en dit aan die einde herstel, dit is die proloog (ldp x29, x30, [sp], #48; ret
-> Herstelfp
enlr
en keer terug).
sp
- Stokaanwyser, gebruik om die bopunt van die stok dop te hou.
die
sp
-waarde moet altyd ten minste 'n kwadewoord uitlyn hou, anders kan 'n uitlynuitsondering voorkom.
pc
- Programteller, wat na die volgende instruksie wys. Hierdie register kan slegs deur uitsonderingsgenerasies, uitsonderingsterugkeer en takke opgedateer word. Die enigste gewone instruksies wat hierdie register kan lees, is tak met skakelinstruksies (BL, BLR) om diepc
-adres inlr
(Skakelregister) te stoor.xzr
- Nulregister. Ook genoemwzr
in sy 32-bis registervorm. Dit kan gebruik word om die nulwaarde maklik te kry (gewone operasie) of om vergelykings uit te voer met behulp vansubs
soossubs XZR, Xn, #10
wat die resulterende data nêrens stoor (inxzr
).
Die Wn
-registers is die 32-bis-weergawe van die Xn
-register.
SIMD- en Drijfpuntregisters
Daar is nog 'n ander 32 registers van 128-bis lengte wat gebruik kan word in geoptimeerde enkele instruksie multiple data (SIMD) operasies en vir die uitvoering van drijfpuntberekeninge. Hierdie word die Vn-registers genoem, alhoewel hulle ook in 64-bis, 32-bis, 16-bis en 8-bis kan werk en dan word hulle Qn
, Dn
, Sn
, Hn
en Bn
genoem.
Sisteemregisters
Daar is honderde sisteemregisters, ook genoem spesiale doelregisters (SPRs), wat gebruik word vir monitoring en beheer van verwerkers se gedrag.
Hulle kan slegs gelees of ingestel word met die toegewyde spesiale instruksie mrs
en msr
.
Die spesiale registers TPIDR_EL0
en TPIDDR_EL0
word dikwels gevind tydens omgekeerde ingenieurswese. Die EL0
agtervoegsel dui die minimale uitsondering aan waarvandaan die register toeganklik is (in hierdie geval is EL0 die gewone uitsondering (bevoegdheid) vlak waar gewone programme mee hardloop).
Hulle word dikwels gebruik om die basisadres van die draad-plaaslike stoor-gebied van geheue te stoor. Gewoonlik is die eerste een leesbaar en skryfbaar vir programme wat in EL0 hardloop, maar die tweede kan gelees word van EL0 en geskryf word van EL1 (soos kernel).
mrs x0, TPIDR_EL0 ; Lees TPIDR_EL0 in x0
msr TPIDR_EL0, X0 ; Skryf x0 na TPIDR_EL0
PSTATE
PSTATE bevat verskeie proseskomponente wat geserializeer is in die bedryfstelsel-sigbare SPSR_ELx
spesiale register, waar X die toestemming vlak van die geaktiveerde uitsondering is (dit maak dit moontlik om die prosesstaat te herstel wanneer die uitsondering eindig).
Dit is die toeganklike velde:
Die
N
,Z
,C
enV
toestandsvlagte:N
beteken die operasie het 'n negatiewe resultaat opgelewerZ
beteken die operasie het nul opgelewerC
beteken die operasie is uitgevoerV
beteken die operasie het 'n getekende oorvloei opgelewer:Die som van twee positiewe getalle lewer 'n negatiewe resultaat op.
Die som van twee negatiewe getalle lewer 'n positiewe resultaat op.
By aftrekking, wanneer 'n groot negatiewe getal van 'n kleiner positiewe getal afgetrek word (of andersom), en die resultaat nie binne die reeks van die gegewe bitgrootte verteenwoordig kan word nie.
Duidelik weet die verwerker nie of die operasie geteken is of nie, dus sal dit C en V in die operasies nagaan en aandui of 'n dra gedoen is in die geval dit geteken of ongeteken was.
Nie al die instruksies werk hierdie vlagte by nie. Sommige soos CMP
of TST
doen dit, en ander wat 'n s agtervoegsel het soos ADDS
doen dit ook.
Die huidige registerbreedte (
nRW
) vlag: As die vlag die waarde 0 behou, sal die program in die AArch64-uitvoeringsstaat hardloop sodra hervat.Die huidige Uitsonderingsvlak (
EL
): 'n Gewone program wat in EL0 hardloop, sal die waarde 0 hêDie enkele stap vlag (
SS
): Gebruik deur afsonderlike stappers om deur die SS-vlag na 1 binneSPSR_ELx
'n stap te hardloop en 'n enkele stap uitsondering uit te reik.Die ongeldige uitsonderingstoestandvlag (
IL
): Dit word gebruik om te merk wanneer 'n bevoorregte sagteware 'n ongeldige uitsonderingsvlakoorplasing uitvoer, hierdie vlag word na 1 gesit en die verwerker veroorsaak 'n onwettige toestand-uitsondering.Die
DAIF
vlagte: Hierdie vlagte maak dit vir 'n bevoorregte program moontlik om sekere eksterne uitsonderings selektief te maskeer.As
A
1 is, beteken dit dat asynchrone afbreek geaktiveer sal word. DieI
konfigureer om te reageer op eksterne hardeware Onderbrekingsversoeke (IRQ's). en die F is verwant aan Vinnige Onderbrekingsversoeke (FIR's).Die stapelwyservlagte (
SPS
): Bevoorregte programme wat in EL1 en hoër hardloop, kan tussen hul eie stapelwyservlagregister en die gebruikersmodel een wissel (bv. tussenSP_EL1
enEL0
). Hierdie skakeling word uitgevoer deur te skryf na dieSPSel
spesiale register. Dit kan nie vanaf EL0 gedoen word nie.
Oproepkonvensie (ARM64v8)
Die ARM64 oproepkonvensie spesifiseer dat die eerste agt parameters na 'n funksie oorgedra word in registers x0
tot x7
. Addisionele parameters word op die stapel oorgedra. Die terugkeer-waarde word teruggevoer in register x0
, of in x1
ook as dit 128 bits lank is. Die x19
tot x30
en sp
registers moet oor funksie-oproepe bewaar word.
Wanneer 'n funksie in samestelling lees, soek na die funksieproloog en epiloog. Die proloog behels gewoonlik die berging van die raamwyser (x29
), opstel van 'n nuwe raamwyser, en toewysing van stapelruimte. Die epiloog behels gewoonlik die herstel van die gebergde raamwyser en terugkeer uit die funksie.
Oproepkonvensie in Swift
Swift het sy eie oproepkonvensie wat gevind kan word op https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64
Gewone Instruksies (ARM64v8)
ARM64 instruksies het gewoonlik die formaat opcode dst, src1, src2
, waar opcode
die operasie is wat uitgevoer moet word (soos add
, sub
, mov
, ens.), dst
is die bestemmingsregister waar die resultaat gestoor sal word, en src1
en src2
is die bronregisters. Onmiddellike waardes kan ook gebruik word in plek van bronregisters.
mov
: Skuif 'n waarde van een register na 'n ander.Voorbeeld:
mov x0, x1
— Dit skuif die waarde vanafx1
nax0
.ldr
: Laai 'n waarde vanaf geheue in 'n register.Voorbeeld:
ldr x0, [x1]
— Dit laai 'n waarde vanaf die geheueposisie wat deurx1
aangedui word inx0
.Offsetmodus: 'n Offset wat die oorspronklike wyser affekteer, word aangedui, byvoorbeeld:
ldr x2, [x1, #8]
, dit sal in x2 die waarde vanaf x1 + 8 laaildr x2, [x0, x1, lsl #2]
, dit sal in x2 'n voorwerp laai vanaf die reeks x0, vanaf die posisie x1 (indeks) * 4Vooraf-geïndekse modus: Dit sal berekeninge toepas op die oorsprong, die resultaat kry en ook die nuwe oorsprong in die oorsprong stoor.
ldr x2, [x1, #8]!
, dit salx1 + 8
inx2
laai en in x1 die resultaat vanx1 + 8
stoorstr lr, [sp, #-4]!
, Berg die skakelregister in sp en werk die register sp byNa-indeksmodus: Dit is soos die vorige een, maar die geheue-adres word benader en dan word die offset bereken en gestoor.
ldr x0, [x1], #8
, laaix1
inx0
en werk x1 by metx1 + 8
PC-verwante adressering: In hierdie geval word die adres om te laai relatief tot die PC-register bereken
ldr x1, =_start
, Dit sal die adres waar die_start
simbool begin in x1 laai relatief tot die huidige PC.str
: Stoor 'n waarde vanaf 'n register in geheue.Voorbeeld:
str x0, [x1]
— Dit stoor die waarde inx0
in die geheueposisie wat deurx1
aangedui word.ldp
: Laai Paar van Register. Hierdie instruksie laai twee registers van opeenvolgende geheueposisies. Die geheue-adres word tipies gevorm deur 'n offset by te voeg by die waarde in 'n ander register.Voorbeeld:
ldp x0, x1, [x2]
— Dit laaix0
enx1
vanaf die geheueposisies byx2
enx2 + 8
, onderskeidelik.stp
: Stoor Paar van Register. Hierdie instruksie stoor twee registers na opeenvolgende geheueposisies. Die geheue-adres word tipies gevorm deur 'n offset by te voeg by die waarde in 'n ander register.Voorbeeld:
stp x0, x1, [sp]
— Dit stoorx0
enx1
na die geheueposisies bysp
ensp + 8
, onderskeidelik.stp x0, x1, [sp, #16]!
— Dit stoorx0
enx1
na die geheueposisies bysp+16
ensp + 24
, onderskeidelik, en werksp
by metsp+16
.add
: Tel die waardes van twee registers bymekaar en stoor die resultaat in 'n register.adds
Dit voer 'nadd
uit en werk die vlae bysub
: Aftrek die waardes van twee register en stoor die resultaat in 'n register.Kontroleer
add
sintaksis.Voorbeeld:
sub x0, x1, x2
— Dit trek die waarde inx2
vanx1
af en stoor die resultaat inx0
.subs
Dit is soos sub maar werk die vlag bymul
: Vermenigvuldig die waardes van twee register en stoor die resultaat in 'n register.Voorbeeld:
mul x0, x1, x2
— Dit vermenigvuldig die waardes inx1
enx2
en stoor die resultaat inx0
.div
: Deel die waarde van een register deur 'n ander en stoor die resultaat in 'n register.Voorbeeld:
div x0, x1, x2
— Dit deel die waarde inx1
deurx2
en stoor die resultaat inx0
.lsl
,lsr
,asr
,ror
,rrx
:Logiese skuif links: Voeg 0's by die einde en skuif die ander bits vorentoe (vermenigvuldig met n-keer 2)
Logiese skuif regs: Voeg 1's aan die begin en skuif die ander bits agtertoe (deel deur n-keer 2 in ongeteken)
Aritiese skuif regs: Soos
lsr
, maar in plaas van om 0's by te voeg as die mees beduidende bit 'n 1 is, word **1's bygevoeg (**deel deur n-keer 2 in geteken)Regsdraai: Soos
lsr
maar watookal van die regterkant verwyder word, word by die linkerkant aangehegRegsdraai met Uitbreiding: Soos
ror
, maar met die draagvlag as die "mees beduidende bit". Dus word die draagvlag na bit 31 geskuif en die verwyderde bit na die draagvlag.bfm
: Bitveld Verskuif, hierdie operasies kopieer bits0...n
van 'n waarde en plaas hulle in posisiesm..m+n
. Die#s
spesifiseer die linkerste bit posisie en#r
die regsregs hoeveelheid.Bitveld verskuif:
BFM Xd, Xn, #r
Getekende Bitveld verskuif:
SBFM Xd, Xn, #r, #s
Ongeskrewe Bitveld verskuif:
UBFM Xd, Xn, #r, #s
Bitveld Uithaal en Invoeg: Kopieer 'n bitveld van 'n register en kopieer dit na 'n ander register.
BFI X1, X2, #3, #4
Voeg 4 bits van X2 vanaf die 3de bit van X1 inBFXIL X1, X2, #3, #4
Haal vanaf die 3de bit van X2 vier bits uit en kopieer hulle na X1SBFIZ X1, X2, #3, #4
Teken-uitbrei 4 bits van X2 en voeg hulle in X1 in beginnende by bit posisie 3 deur die regter bits te nulSBFX X1, X2, #3, #4
Haal 4 bits beginnende by bit 3 uit X2, teken dit uit, en plaas die resultaat in X1UBFIZ X1, X2, #3, #4
Nul-uitbrei 4 bits van X2 en voeg hulle in X1 in beginnende by bit posisie 3 deur die regter bits te nulUBFX X1, X2, #3, #4
Haal 4 bits beginnende by bit 3 uit X2 en plaas die nul-uitgebreide resultaat in X1.Teken Uitbrei Na X: Brei die teken uit (of voeg net 0's by in die ongetekende weergawe) van 'n waarde uit om operasies daarmee uit te voer:
SXTB X1, W2
Brei die teken van 'n byte van W2 na X1 (W2
is die helfte vanX2
) om die 64bits te vulSXTH X1, W2
Brei die teken van 'n 16bit nommer van W2 na X1 om die 64bits te vulSXTW X1, W2
Brei die teken van 'n byte van W2 na X1 om die 64bits te vulUXTB X1, W2
Voeg 0's by (ongeskrewe) na 'n byte van W2 na X1 om die 64bits te vulextr
: Haal bits uit 'n gespesifiseerde paar register wat gekonkateniseer is.Voorbeeld:
EXTR W3, W2, W1, #3
Dit sal konkateniseer W1+W2 en kry vanaf bit 3 van W2 tot bit 3 van W1 en stoor dit in W3.cmp
: Vergelyk twee register en stel toestandvlagte in. Dit is 'n alias vansubs
wat die bestemmingsregister na die nulregister stel. Nuttig om te weet ofm == n
.Dit ondersteun dieselfde sintaksis as
subs
Voorbeeld:
cmp x0, x1
— Dit vergelyk die waardes inx0
enx1
en stel die toestandvlagte dienooreenkomstig in.cmn
: Vergelyk negatief operand. In hierdie geval is dit 'n alias vanadds
en ondersteun dieselfde sintaksis. Nuttig om te weet ofm == -n
.ccmp
: Voorwaardelike vergelyking, dit is 'n vergelyking wat slegs uitgevoer sal word as 'n vorige vergelyking waar was en spesifiek nzcv-bits sal stel.cmp x1, x2; ccmp x3, x4, 0, NE; blt _func
-> as x1 != x2 en x3 < x4, spring na funcDit is omdat
ccmp
slegs uitgevoer sal word as die vorigecmp
'nNE
was, as dit nie was nie, sal die bitsnzcv
na 0 gestel word (wat nie aan dieblt
vergelyking sal voldoen nie).Dit kan ook gebruik word as
ccmn
(dieselfde maar negatief, sooscmp
teenoorcmn
).tst
: Dit kontroleer of enige van die waardes van die vergelyking beide 1 is (dit werk soos 'n EN sonder om die resultaat enige plek te stoor). Dit is nuttig om 'n register met 'n waarde te kontroleer en te sien of enige van die bits van die register wat in die waarde aangedui word, 1 is.Voorbeeld:
tst X1, #7
Kontroleer of enige van die laaste 3 bits van X1 1 isteq
: XOR-operasie wat die resultaat verwerpb
: Onvoorwaardelike SprongVoorbeeld:
b myFunction
Let daarop dat dit nie die skakelregister met die terugkeeradres vul nie (nie geskik vir subrutine-oproepe wat moet terugkeer nie)
bl
: Sprong met skakel, gebruik om 'n subrutine te roep. Stoor die terugkeeradres inx30
.Voorbeeld:
bl myFunction
— Dit roep die funksiemyFunction
aan en stoor die terugkeeradres inx30
.Let daarop dat dit nie die skakelregister met die terugkeeradres vul nie (nie geskik vir subrutine-oproepe wat moet terugkeer nie)
blr
: Sprong met Skakel na Register, gebruik om 'n subrutine te roep waar die teiken in 'n register gespesifiseer is. Stoor die terugkeeradres inx30
. (Dit isVoorbeeld:
blr x1
— Dit roep die funksie aan waarvan die adres inx1
ingesluit is en stoor die terugkeeradres inx30
.ret
: Terugkeer van subrutine, tipies deur die adres inx30
te gebruik.Voorbeeld:
ret
— Dit keer terug van die huidige subrutine deur die terugkeeradres inx30
te gebruik.b.<cond>
: Voorwaardelike sprongb.eq
: Sprong indien gelyk, gebaseer op die vorigecmp
instruksie.Voorbeeld:
b.eq label
— As die vorigecmp
instruksie twee gelyke waardes gevind het, spring dit nalabel
.b.ne
: Tak indien nie gelyk nie. Hierdie instruksie kontroleer die toestand vlae (wat deur 'n vorige vergelykingsinstruksie ingestel is), en as die vergelykte waardes nie gelyk was nie, spring dit na 'n etiket of adres.Voorbeeld: Na 'n
cmp x0, x1
instruksie,b.ne label
— As die waardes inx0
enx1
nie gelyk was nie, spring dit nalabel
.cbz
: Vergelyk en spring op Nul. Hierdie instruksie vergelyk 'n register met nul, en as hulle gelyk is, spring dit na 'n etiket of adres.Voorbeeld:
cbz x0, label
— As die waarde inx0
nul is, spring dit nalabel
.cbnz
: Vergelyk en spring op Nie-Nul. Hierdie instruksie vergelyk 'n register met nul, en as hulle nie gelyk is nie, spring dit na 'n etiket of adres.Voorbeeld:
cbnz x0, label
— As die waarde inx0
nie-nul is nie, spring dit nalabel
.tbnz
: Toets bit en spring op nie-nulVoorbeeld:
tbnz x0, #8, label
tbz
: Toets bit en spring op nulVoorbeeld:
tbz x0, #8, label
Kondisionele seleksie-operasies: Dit is operasies waarvan die gedrag varieer afhangende van die kondisionele bits.
csel Xd, Xn, Xm, kond
->csel X0, X1, X2, EQ
-> As waar, X0 = X1, as vals, X0 = X2csinc Xd, Xn, Xm, kond
-> As waar, Xd = Xn, as vals, Xd = Xm + 1cinc Xd, Xn, kond
-> As waar, Xd = Xn + 1, as vals, Xd = Xncsinv Xd, Xn, Xm, kond
-> As waar, Xd = Xn, as vals, Xd = NIE(Xm)cinv Xd, Xn, kond
-> As waar, Xd = NIE(Xn), as vals, Xd = Xncsneg Xd, Xn, Xm, kond
-> As waar, Xd = Xn, as vals, Xd = - Xmcneg Xd, Xn, kond
-> As waar, Xd = - Xn, as vals, Xd = Xncset Xd, Xn, Xm, kond
-> As waar, Xd = 1, as vals, Xd = 0csetm Xd, Xn, Xm, kond
-> As waar, Xd = <alles 1>, as vals, Xd = 0adrp
: Bereken die bladsy-adres van 'n simbool en stoor dit in 'n register.Voorbeeld:
adrp x0, simbool
— Dit bereken die bladsy-adres vansimbool
en stoor dit inx0
.ldrsw
: Laai 'n geteken 32-bis waarde vanaf geheue en teken dit uit tot 64 bits.Voorbeeld:
ldrsw x0, [x1]
— Dit laai 'n geteken 32-bis waarde vanaf die geheuelokasie wat deurx1
aangedui word, teken dit uit tot 64 bits, en stoor dit inx0
.stur
: Stoor 'n registerwaarde na 'n geheuelokasie, met 'n skuif vanaf 'n ander register.Voorbeeld:
stur x0, [x1, #4]
— Dit stoor die waarde inx0
in die geheue-adres wat 4 byte groter is as die adres wat tans inx1
is.svc
: Maak 'n sisteemaanroep. Dit staan vir "Supervisor Call". Wanneer die verwerker hierdie instruksie uitvoer, skakel dit van gebruikersmodus na kernelmodus en spring na 'n spesifieke plek in die geheue waar die kern se sisteemaanroephanterings-kode geleë is.Voorbeeld:
Funksie Proloog
Stoor die skakelregister en raamverwysings na die stok:
Stel die nuwe raam aanduider op:
mov x29, sp
(stel die nuwe raam aanduider op vir die huidige funksie)Ken spasie op die stok toe vir plaaslike veranderlikes (indien nodig):
sub sp, sp, <grootte>
(waar<grootte>
die aantal bytes is wat benodig word)
Funksie Epiloog
Deallokeer plaaslike veranderlikes (indien enige toegewys was):
add sp, sp, <grootte>
Herstel die skakelregister en raam aanduider:
Terugkeer:
ret
(gee beheer terug aan die oproeper deur die adres in die skakelregister)
AARCH32 Uitvoeringsstatus
Armv8-A ondersteun die uitvoering van 32-bietjie programme. AArch32 kan in een van twee instruksiestelle hardloop: A32
en T32
en kan tussen hulle skakel via interworking
.
Bevoorregte 64-bietjie programme kan die uitvoering van 32-bietjie programme skeduleer deur 'n uitsonderingsvlak-oordrag na die laer bevoorregte 32-bietjie uit te voer.
Let daarop dat die oorgang van 64-bietjie na 32-bietjie plaasvind met 'n laer van die uitsonderingsvlak (byvoorbeeld 'n 64-bietjie program in EL1 wat 'n program in EL0 trigger). Dit word gedoen deur die bit 4 van SPSR_ELx
spesiale register op 1 te stel wanneer die AArch32
prosesdraad gereed is om uitgevoer te word en die res van SPSR_ELx
stoor die AArch32
programme se CPSR. Dan roep die bevoorregte proses die ERET
instruksie aan sodat die verwerker oorgaan na AArch32
wat in A32 of T32 binnegaan, afhangende van CPSR**.**
Die interworking
vind plaas deur die gebruik van die J- en T-bits van CPSR. J=0
en T=0
beteken A32
en J=0
en T=1
beteken T32. Dit kom basies daarop neer dat die laagste bit na 1 gestel word om aan te dui dat die instruksiestel T32 is.
Dit word ingestel tydens die interworking takinstruksies, maar kan ook direk met ander instruksies ingestel word wanneer die PC as die bestemmingsregister ingestel word. Voorbeeld:
'n Ander voorbeeld:
Registers
Daar is 16 32-bis registre (r0-r15). Vanaf r0 tot r14 kan hulle gebruik word vir enige operasie, maar sommige van hulle is gewoonlik voorbehou:
r15
: Programteller (altyd). Bevat die adres van die volgende instruksie. In A32 huidige + 8, in T32, huidige + 4.r11
: Raamwyserr12
: Intra-prosedurele oproepregisterr13
: Stewelwyserr14
: Skakelregister
Verder word registre ondersteun in gebankte registre
. Dit is plekke wat die registre se waardes stoor om vinnige konteksverandering in uitsonderingshantering en bevoorregte operasies moontlik te maak om die behoefte om registre elke keer handmatig te stoor en herstel te vermy.
Dit word gedoen deur die prosessorstatus van die CPSR
na die SPSR
van die prosessormodus waarheen die uitsondering geneem word, te stoor. By die terugkeer van die uitsondering word die CPSR
herstel vanaf die SPSR
.
CPSR - Huidige Programstatusregister
In AArch32 werk die CPSR soortgelyk aan PSTATE
in AArch64 en word dit ook gestoor in SPSR_ELx
wanneer 'n uitsondering geneem word om later die uitvoering te herstel:
Die velde is verdeel in sekere groepe:
Aansoekprogramstatusregister (APSR): Wiskundige vlae en toeganklik vanaf EL0
Uitvoeringsstatusregistre: Proseshantering (deur die OS bestuur).
Aansoekprogramstatusregister (APSR)
Die
N
,Z
,C
,V
vlae (net soos in AArch64)Die
Q
vlag: Dit word op 1 gestel wanneer heeltalversadiging plaasvind tydens die uitvoering van 'n gespesialiseerde versadigende wiskundige instruksie. Sodra dit op1
gestel is, sal dit die waarde behou totdat dit handmatig na 0 gestel word. Verder is daar geen instruksie wat sy waarde implisiet kontroleer nie, dit moet handmatig gelees word.GE
(Groter as of gelyk aan) Vlae: Dit word gebruik in SIMD (Enkele Instruksie, Meervoudige Data) operasies, soos "parallelle optel" en "parallelle aftrekking". Hierdie operasies maak dit moontlik om meervoudige datapunte in 'n enkele instruksie te verwerk.
Byvoorbeeld, die UADD8
instruksie tel vier pare van byte op (van twee 32-bis operandos) parallel op en stoor die resultate in 'n 32-bis register. Dit stel dan die GE
vlae in die APSR
in op grond van hierdie resultate. Elke GE-vlag stem ooreen met een van die byte optellings, wat aandui of die optelling vir daardie bytepaar oorvloei.
Die SEL
instruksie gebruik hierdie GE-vlae om voorwaardelike aksies uit te voer.
Uitvoeringsstatusregistre
Die
J
enT
bietjies:J
moet 0 wees en asT
0 is, word die instruksiestel A32 gebruik, en as dit 1 is, word die T32 gebruik.IT Blokstatusregister (
ITSTATE
): Dit is die bietjies vanaf 10-15 en 25-26. Hulle stoor voorwaardes vir instruksies binne 'nIT
voorafgegaan groep.E
bietjie: Dui die eindigheid aan.Modus- en Uitsonderingsmaskerbietjies (0-4): Hulle bepaal die huidige uitvoeringsstatus. Die 5de een dui aan of die program as 32-bis (‘n 1) of 64-bis (‘n 0) loop. Die ander 4 verteenwoordig die uitsonderingsmodus wat tans gebruik word (wanneer 'n uitsondering plaasvind en dit hanteer word). Die nommerstel dui die huidige prioriteit aan in geval 'n ander uitsondering geaktiveer word terwyl dit hanteer word.
AIF
: Sekere uitsonderings kan gedeaktiveer word deur die bietjiesA
,I
,F
. AsA
1 is, beteken dit dat asynchrone afbreek geaktiveer sal word. DieI
konfigureer om te reageer op eksterne hardeware Onderbrekingsversoeke (IRQ's). en die F is verwant aan Vinnige Onderbrekingsversoeke (FIR's).
macOS
BSD-sisteemaanroep
Kyk na syscalls.master. BSD-sisteemaanroepe sal x16 > 0 hê.
Mach-valstrikke
Kyk na in syscall_sw.c die mach_trap_table
en in mach_traps.h die prototipes. Die maksimum aantal Mach-valstrikke is MACH_TRAP_TABLE_COUNT
= 128. Mach-valstrikke sal x16 < 0 hê, dus moet jy die nommers van die vorige lys met 'n min noem: _kernelrpc_mach_vm_allocate_trap
is -10
.
Jy kan ook libsystem_kernel.dylib
in 'n disassembler nagaan om uit te vind hoe om hierdie (en BSD) sisteemaanroepe te doen:
Soms is dit makliker om die gedekompilieerde kode van libsystem_kernel.dylib
te kontroleer as om die bronkode te kontroleer omdat die kode van verskeie syscalls (BSD en Mach) gegenereer word deur skripte (kontroleer kommentaar in die bronkode) terwyl jy in die dylib kan vind wat opgeroep word.
machdep-oproepe
XNU ondersteun 'n ander tipe oproepe genaamd masjienafhanklik. Die hoeveelheid van hierdie oproepe hang af van die argitektuur en nie die oproepe of hoeveelhede is gewaarborg om konstant te bly nie.
komm-pagina
Dit is 'n kernel-eienaar-geheuebladsy wat in die adresruimte van elke gebruikersproses afgebeeld word. Dit is bedoel om die oorgang vanaf gebruikersmodus na kernelruimte vinniger te maak as om syscalls te gebruik vir kernelsdiens wat soveel gebruik word dat hierdie oorgang baie ondoeltreffend sou wees.
Byvoorbeeld, die oproep gettimeofdate
lees die waarde van timeval
direk vanaf die komm-pagina.
objc_msgSend
Dit is baie algemeen om hierdie funksie te vind wat in Objective-C of Swift-programme gebruik word. Hierdie funksie maak dit moontlik om 'n metode van 'n Objective-C-objek aan te roep.
Parameters (meer inligting in die dokumentasie):
x0: self -> Wysiger na die instansie
x1: op -> Kieser van die metode
x2... -> Res van die argumente van die opgeroepde metode
Dus, as jy 'n breekpunt plaas voor die sprong na hierdie funksie, kan jy maklik vind wat in lldb opgeroep word met (in hierdie voorbeeld roep die objek 'n objek vanaf NSConcreteTask
aan wat 'n bevel sal hardloop):
Deur die omgewingsveranderlike NSObjCMessageLoggingEnabled=1
in te stel, is dit moontlik om te log wanneer hierdie funksie in 'n lêer soos /tmp/msgSends-pid
aangeroep word.
Shellkodes
Om te kompileer:
Om die byte te onttrek:
Vir nuwer macOS:
C-kode om die dopkode te toets
Skul
Geneem van hier en verduidelik.
Lees met kat
Die doel is om execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)
uit te voer, dus die tweede argument (x1) is 'n reeks van parameters (wat in die geheue beteken dat dit 'n stapel van die adresse is).
Roep die bevel aan met sh van 'n fork sodat die hoofproses nie afgeskiet word nie
Bind skaal
Bind skaal van https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s in poort 4444
Terugskulp
Van https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s, revshell na 127.0.0.1:4444
Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!
Ander maniere om HackTricks te ondersteun:
As jy jou maatskappy geadverteer wil sien in HackTricks of HackTricks in PDF wil aflaai Kyk na die INSKRYWINGSPLANNE!
Ontdek Die PEASS Familie, ons versameling eksklusiewe NFT's
Sluit aan by die 💬 Discord-groep of die telegram-groep of volg ons op Twitter 🐦 @carlospolopm.
Deel jou haktruuks deur PR's in te dien by die HackTricks en HackTricks Cloud github-opslag.
Last updated