Introduction to ARM64v8
İstisna Seviyeleri - EL (ARM64v8)
ARMv8 mimarisinde, İstisna Seviyeleri (EL'ler) olarak bilinen yürütme seviyeleri, yürütme ortamının ayrıcalık seviyesini ve yeteneklerini tanımlar. EL0'dan EL3'e kadar dört istisna seviyesi bulunmaktadır ve her biri farklı bir amaca hizmet etmektedir:
EL0 - Kullanıcı Modu:
Bu en az ayrıcalıklı seviyedir ve düzenli uygulama kodlarını yürütmek için kullanılır.
EL0'da çalışan uygulamalar birbirinden ve sistem yazılımından izole edilir, bu da güvenliği ve kararlılığı artırır.
EL1 - İşletim Sistemi Çekirdek Modu:
Çoğu işletim sistemi çekirdekleri bu seviyede çalışır.
EL1, EL0'dan daha fazla ayrıcalığa sahiptir ve sistem kaynaklarına erişebilir, ancak sistem bütünlüğünü sağlamak için bazı kısıtlamalar vardır.
EL2 - Hipervizör Modu:
Bu seviye sanallaştırma için kullanılır. EL2'de çalışan bir hipervizör, aynı fiziksel donanım üzerinde çalışan birden fazla işletim sistemini (her biri kendi EL1'inde) yönetebilir.
EL2, sanallaştırılmış ortamların izolasyonu ve kontrolü için özellikler sağlar.
EL3 - Güvenli Monitör Modu:
Bu en ayrıcalıklı seviyedir ve genellikle güvenli önyükleme ve güvenilir yürütme ortamları için kullanılır.
EL3, güvenli ve güvensiz durumlar arasındaki erişimleri yönetebilir ve kontrol edebilir (güvenli önyükleme, güvenilir işletim sistemi vb.).
Bu seviyelerin kullanımı, kullanıcı uygulamalarından en ayrıcalıklı sistem yazılımlarına kadar farklı sistem bileşenlerini yapılandırılmış ve güvenli bir şekilde yönetme olanağı sağlar. ARMv8'in ayrıcalık seviyelerine yaklaşımı, farklı sistem bileşenlerini etkili bir şekilde izole etmeye yardımcı olarak sistemin güvenliğini ve sağlamlığını artırır.
Kayıtlar (ARM64v8)
ARM64'ün 31 genel amaçlı kaydı bulunmaktadır, x0
ile x30
arasında etiketlenmiştir. Her biri 64 bit (8 byte) bir değer saklayabilir. Yalnızca 32 bit değerler gerektiren işlemler için aynı kayıtlara w0
ile w30
adları kullanılarak 32 bit modunda erişilebilir.
x0
ilex7
- Bu genellikle geçici kayıtlar olarak ve alt programlara parametre iletmek için kullanılır.
x0
ayrıca bir fonksiyonun dönüş verisini taşır.
x8
- Linux çekirdeğinde,x8
svc
komutu için sistem çağrısı numarası olarak kullanılır. macOS'ta ise x16 kullanılır!x9
ilex15
- Daha fazla geçici kayıt, genellikle yerel değişkenler için kullanılır.x16
vex17
- İçsel-prosedürel Çağrı Kayıtları. Hemen değerler için geçici kayıtlar. Ayrıca dolaylı fonksiyon çağrıları ve PLT (Procedure Linkage Table) sapmaları için de kullanılır.
x16
, macOS'tasvc
komutu için sistem çağrısı numarası olarak kullanılır.
x18
- Platform kaydı. Genel amaçlı bir kayıt olarak kullanılabilir, ancak bazı platformlarda bu kayıt platforma özgü kullanımlar için ayrılmıştır: Windows'ta mevcut iş parçacığı ortam bloğuna işaretçi veya linux çekirdeğinde şu anda çalışan görev yapısına işaret etmek için.x19
ilex28
- Bunlar çağrılan kaydedilen kayıtlardır. Bir işlev, bu kayıtların değerlerini çağrıcısı için korumalıdır, bu nedenle bunlar yığında saklanır ve çağrıcıya geri dönmeden önce kurtarılır.x29
- Yığın çerçevesini takip etmek için çerçeve işaretçisi. Bir işlev çağrıldığında yeni bir yığın çerçevesi oluşturulduğunda,x29
kaydı yığında saklanır ve yeni çerçeve işaretçi adresi (sp
adresi) bu kayıtta saklanır.
Bu kayıt genel amaçlı bir kayıt olarak da kullanılabilir, ancak genellikle yerel değişkenlere referans olarak kullanılır.
x30
veyalr
- Bağlantı kaydı. BirBL
(Bağlantılı Dal) veyaBLR
(Kayıtlı Bağlantılı Dal) komutu yürütüldüğündepc
değerini bu kayıtta saklayarak dönüş adresini tutar.
Diğer kayıtlar gibi kullanılabilir.
Eğer mevcut işlev yeni bir işlevi çağıracak ve dolayısıyla
lr
'yi üzerine yazacaksa, başlangıçta bunu yığında saklar, bu epilog (stp x29, x30 , [sp, #-48]; mov x29, sp
->fp
velr
'yi sakla, alan oluştur ve yenifp
al) ve sonunda kurtarır, bu prolog (ldp x29, x30, [sp], #48; ret
->fp
velr
'yi kurtar ve geri dön).
sp
- Yığın işaretçisi, yığının en üstünü takip etmek için kullanılır.
sp
değeri her zaman en az bir quadword hizalamasında tutulmalıdır aksi takdirde bir hizalama istisnası oluşabilir.
pc
- Program sayacı, bir sonraki komutu işaret eder. Bu kayıt yalnızca istisna oluşturma, istisna dönüşü ve dallanmalar aracılığıyla güncellenebilir. Bu kaydı okuyabilen tek sıradan komutlar,pc
adresinilr
'ye (Bağlantı Kaydı) saklamak için dallanma ile bağlantılı komutlardır (BL, BLR).xzr
- Sıfır kaydı. 32 bit kayıt formundawzr
olarak da adlandırılır. Sıfır değerini kolayca almak için kullanılabilir (yaygın işlem) veyasubs
kullanarak karşılaştırmalar yapmak için kullanılabilir, örneğinsubs XZR, Xn, #10
sonuç verisini hiçbir yere saklamadan (xzr
içinde) saklar.
Wn
kayıtları, Xn
kaydının 32 bit sürümüdür.
SIMD ve Kayan Nokta Kayıtları
Ayrıca, optimize edilmiş tek bir komutla çoklu veri (SIMD) işlemleri ve kayan nokta aritmetiği yapmak için kullanılabilen 32 adet 128 bit uzunluğunda kayıt bulunmaktadır. Bunlar Vn kayıtları olarak adlandırılır, ancak aynı zamanda 64-bit, 32-bit, 16-bit ve 8-bit olarak da çalışabilir ve o zaman Qn
, Dn
, Sn
, Hn
ve Bn
olarak adlandırılırlar.
Sistem Kayıtları
Yüzlerce sistem kaydı, ayrıca özel amaçlı kayıtlar (SPR'ler) olarak adlandırılan, işlemcilerin davranışını izleme ve kontrol etme amacıyla kullanılır.
Bu kayıtlar yalnızca özel mrs
ve msr
komutlarını kullanarak okunabilir veya ayarlanabilir.
Özel kayıtlar TPIDR_EL0
ve TPIDDR_EL0
genellikle tersine mühendislik yapılırken bulunur. EL0
eki, kaydın hangi istisnai durumdan erişilebileceğini belirtir (bu durumda EL0, normal programların çalıştığı ayrıcalık seviyesidir).
Genellikle bunlar bellek bölgesinin iş parçacığı yerel depolama alanının taban adresini saklamak için kullanılır. Genellikle birinci EL0'da çalışan programlar için okunabilir ve yazılabilir, ancak ikincisi EL0'dan okunabilir ve EL1'den yazılabilir (çekirdek gibi).
mrs x0, TPIDR_EL0 ; TPIDR_EL0'i x0'a oku
msr TPIDR_EL0, X0 ; x0'u TPIDR_EL0'e yaz
PSTATE
PSTATE, işlemcinin işletim sistemi tarafından görülebilen SPSR_ELx
özel kaydına seri hale getirilmiş birkaç işlem bileşenini içerir, X tetiklenen istisna izin seviyesi olur (bu, istisna sona erdiğinde işlem durumunu kurtarmayı sağlar).
Bu erişilebilir alanlar şunlardır:
N
,Z
,C
veV
durum bayrakları:N
, işlemin negatif bir sonuç verdiğini belirtirZ
, işlemin sıfır verdiğini belirtirC
, işlemin taşıdığını belirtirV
, işlemin işaretli bir taşma verdiğini belirtir:İki pozitif sayının toplamı negatif bir sonuç verir.
İki negatif sayının toplamı pozitif bir sonuç verir.
Çıkarma işleminde, büyük bir negatif sayıdan daha küçük bir pozitif sayı çıkarıldığında (veya tersi durumda) ve sonuç verilen bit boyutu aralığında temsil edilemiyorsa.
Açıkçası işlemcinin işlemin işaretli olup olmadığını bilmediği için, işlemlerde C ve V'yi kontrol edecek ve taşıma işareti olup olmadığını belirtecektir.
Tüm komutlar bu bayrakları güncellemez. CMP
veya TST
gibi bazıları yapar, ve ADDS
gibi s eki olan diğerleri de yapar.
Mevcut kayıt genişliği (
nRW
) bayrağı: Bayrağın değeri 0 ise, program devam edildiğinde AArch64 yürütme durumunda çalışacaktır.Mevcut İstisna Seviyesi (
EL
): EL0'da çalışan normal bir programın değeri 0 olacaktırTek adımlama bayrağı (
SS
): Hata ayıklama araçları tarafından tek adımlamak için kullanılır, SS bayrağınıSPSR_ELx
içinde 1 olarak ayarlayarak bir istisna yoluyla adım adım çalıştırır. Program bir adım atar ve tek adım istisnası oluşturur.Yasadışı istisna durumu bayrağı (
IL
): Ayrıcalıklı bir yazılımın geçersiz bir istisna seviyesi transferi gerçekleştirdiğinde işaretlenir, bu bayrak 1 olarak ayarlanır ve işlemci yasadışı bir durum istisnası oluşturur.DAIF
bayrakları: Bu bayraklar ayrıcalıklı bir programın belirli harici istisnaları seçici olarak maskelemesine izin verir.A
1 ise asenkron hataların tetikleneceği anlamına gelir.I
harici donanım Kesme İsteklerine (IRQ'ler) yanıt vermek için yapılandırılır ve F Hızlı Kesme İstekleriyle (FIR'ler) ilgilidir.Yığın işaretçisi seçim bayrakları (
SPS
): EL1 ve üstünde çalışan ayrıcalıklı programlar, kendi yığın işaretçi kayıtlarını ve kullanıcı modelini (örneğinSP_EL1
veEL0
arasında) değiş tokuş yapabilir. Bu değişim,SPSel
özel kaydına yazılarak gerçekleştirilir. Bu EL0'dan yapılamaz.
Çağrı Sözleşmesi (ARM64v8)
ARM64 çağrı sözleşmesi, bir işlevin ilk sekiz parametresinin x0
ile x7
kayıtlarında geçirildiğini belirtir. Ek parametreler yığın üzerinde geçirilir. Dönüş değeri, x0
kaydına geri döndürülür, veya 128 bit uzunluğunda ise ayrıca x1
'e de. x19
ile x30
ve sp
kayıtları işlev çağrıları arasında korunmalıdır.
Bir işlevi montajda okurken, işlev giriş ve çıkışını arayın. Giriş genellikle çerçeve işaretçisini (x29
) kaydetmeyi, yeni bir çerçeve işaretçisi kurmayı ve bir yığın alanı tahsis etmeyi içerir. Çıkış genellikle kaydedilen çerçeve işaretçisini geri yüklemeyi ve işlevden dönmeyi içerir.
Swift'te Çağrı Sözleşmesi
Swift'in kendi çağrı sözleşmesi burada bulunabilir.
Ortak Komutlar (ARM64v8)
ARM64 komutları genellikle opcode hedef, kaynak1, kaynak2
biçimindedir, burada opcode
yapılacak işlemi belirtir (add
, sub
, mov
, vb.), hedef
sonucun depolanacağı hedef kaydı belirtir ve kaynak1
ve kaynak2
kaynak kayıtlarıdır. Hemen kaynak kayıtlarının yerine anlık değerler de kullanılabilir.
mov
: Bir değeri bir kaynaktan başka bir kayda taşı.Örnek:
mov x0, x1
— Bu,x1
'denx0
'a değeri taşır.ldr
: Bir değeri bellekten bir kayda yükle.Örnek:
ldr x0, [x1]
— Bu,x1
tarafından işaret edilen bellek konumundanx0
'a bir değer yükler.Ofset modu: Orin işaretçisini etkileyen bir ofset belirtilir, örneğin:
ldr x2, [x1, #8]
, bu x1 + 8'den x2'ye değeri yüklerldr x2, [x0, x1, lsl #2]
, bu x0 dizisinden x1 (indeks) * 4 pozisyondaki nesneyi x2'ye yüklerÖn-indeks modu: Bu, hesaplamaları orijine uygular, sonucu alır ve yeni orijini orijine kaydeder.
ldr x2, [x1, #8]!
, bux1 + 8
'ix2
'ye yükler vex1 + 8
'in sonucunux1
'e kaydederstr lr, [sp, #-4]!
, bağlantı kaydını sp'ye kaydeder ve sp kaydını güncellerSonrası-indeks modu: Bu bir öncekine benzer ancak bellek adresine erişilir ve ardından ofset hesaplanır ve kaydedilir.
ldr x0, [x1], #8
,x1
'ix0
'a yükler vex1
'ix1 + 8
ile güncellerPC'ye göre adresleme: Bu durumda yüklenecek adres, mevcut PC kaydına göre hesaplanır
ldr x1, =_start
, Bu,_start
sembolünün başladığı adresi x1'e yükler.str
: Bir değeri bir kaynaktan belleğe kaydet.Örnek:
str x0, [x1]
— Bu,x0
'daki değerix1
tarafından işaret edilen bellek konumuna kaydeder.ldp
: Çift Kayıt Yükle. Bu komut ardışık bellek konumlarından iki kaydı yükler. Bellek adresi genellikle başka bir kayırdaki değere bir ofset ekleyerek oluşturulur.Örnek:
ldp x0, x1, [x2]
— Bu, sırasıylax2
vex2 + 8
konumlarındaki bellektenx0
vex1
'i yükler.stp
: Çift Kayıt Sakla. Bu komut iki kaydı ardışık bellek konumlarına saklar. Bellek adresi genellikle başka bir kayırdaki değere bir ofset ekleyerek oluşturulur.Örnek:
stp x0, x1, [sp]
— Bu, sırasıylasp
vesp + 8
konumlarındaki belleğex0
vex1
'i saklar.stp x0, x1, [sp, #16]!
— Bu, sırasıylasp+16
vesp + 24
konumlarındaki belleğex0
vex1
'i saklar vesp
'yisp+16
ile günceller.add
: İki kaydın değerlerini ekler ve sonucu bir kayda kaydeder.Sözdizimi: add(s) Xn1, Xn2, Xn3 | #imm, [shift #N | RRX]
Xn1 -> Hedef
Xn2 -> Operand 1
Xn3 | #imm -> Operand 2 (register veya anlık)
[shift #N | RRX] -> Bir kaydırma yap veya RRX'i çağır
Örnek:
add x0, x1, x2
— Bu,x1
vex2
değerlerini toplar ve sonucux0
'a kaydeder.add x5, x5, #1, lsl #12
— Bu, 4096'ya eşittir (1'i 12 kez kaydırma) -> 1 0000 0000 0000 0000adds
Bu, biradd
işlemi gerçekleştirir ve bayrakları güncellersub
: İki kaydırıcının değerlerini çıkarır ve sonucu bir kaydırıcıda saklar.add
sözdizimini kontrol et.Örnek:
sub x0, x1, x2
— Bu,x1
'deki değerdenx2
'yi çıkarır ve sonucux0
'a kaydeder.subs
Bu, sub işlemini yapar ancak bayrakları güncellermul
: İki kaydırıcının değerlerini çarpar ve sonucu bir kaydırıcıda saklar.Örnek:
mul x0, x1, x2
— Bu,x1
vex2
değerlerini çarpar ve sonucux0
'a kaydeder.div
: Bir kaydırıcının değerini başka bir kaydırıcıya böler ve sonucu bir kaydırıcıda saklar.Örnek:
div x0, x1, x2
— Bu,x1
'deki değerix2
'ye böler ve sonucux0
'a kaydeder.lsl
,lsr
,asr
,ror
,rrx
:Mantıksal sola kaydırma: Diğer bitleri ileriye taşıyarak sona 0'lar ekler (n kez 2 ile çarpar)
Mantıksal sağa kaydırma: Diğer bitleri geriye taşıyarak başa 1'ler ekler (işaretsiz bölmede n kez 2'ye bölme)
Aritmetik sağa kaydırma:
lsr
gibi, ancak en anlamlı bit 1 ise, 1'ler eklenir (işaretli bölmede n kez 2'ye bölme)Sağa döndürme:
lsr
gibi, ancak sağdan kaldırılan her şey sola eklenirUzantılı Sağa Döndürme:
ror
gibi, ancak taşıma bayrağı "en anlamlı bit" olarak kabul edilir. Bu nedenle, taşıma bayrağı 31. bit'e ve kaldırılan bit taşıma bayrağına taşınır.bfm
: Bit Alanı Taşıma, bu işlemler bir değerden bitleri kopyalar ve bunları belirli konumlara yerleştirir.#s
en sol bit konumunu belirtir ve#r
sağa döndürme miktarını belirtir.Bit alanı taşıma:
BFM Xd, Xn, #r
İşaretli Bit alanı taşıma:
SBFM Xd, Xn, #r, #s
İşaretsiz Bit alanı taşıma:
UBFM Xd, Xn, #r, #s
Bit Alanı Çıkarma ve Ekleme: Bir kaydırıcıdan bir bit alanını kopyalar ve başka bir kaydırıcıya kopyalar.
BFI X1, X2, #3, #4
X2'den X1'in 3. bitine 4 bit eklerBFXIL X1, X2, #3, #4
X2'nin 3. bitinden başlayarak dört biti çıkarır ve bunları X1'e kopyalarSBFIZ X1, X2, #3, #4
X2'den 4 bit işareti genişletir ve bunları 3. bit pozisyonundan başlayarak X1'e ekler, sağdaki bitleri sıfırlarSBFX X1, X2, #3, #4
X2'den 3. bit başlayarak 4 bit çıkarır, işareti genişletir ve sonucu X1'e yerleştirirUBFIZ X1, X2, #3, #4
X2'den 4 bit sıfır genişletir ve bunları 3. bit pozisyonundan başlayarak X1'e ekler, sağdaki bitleri sıfırlarUBFX X1, X2, #3, #4
X2'den 3. bit başlayarak 4 bit çıkarır ve sıfır genişletilmiş sonucu X1'e yerleştirir.İşareti Genişlet X'e: Bir değerin işaretini genişletir (veya işaretsiz sürümde sadece 0'ları ekler) ve işlemler yapabilmek için:
SXTB X1, W2
Bir baytın işaretini genişletir W2'den X1'e (W2
,X2
'nin yarısıdır) 64 biti doldurmak içinSXTH X1, W2
16 bitlik bir sayının işaretini genişletir W2'den X1'e 64 biti doldurmak içinSXTW X1, W2
Bir baytın işaretini genişletir W2'den X1'e 64 biti doldurmak içinUXTB X1, W2
Bir bayta 0'lar ekler (işaretsiz) W2'den X1'e 64 biti doldurmak içinextr
: Belirtilen çift kaydırıcıdan bitleri çıkarır ve birleştirir.Örnek:
EXTR W3, W2, W1, #3
Bu, W1+W2'yi birleştirir ve **W2'nin 3. bitinden W1'in 3. bitine kadar olan kısmı alır ve W3'e kaydeder.cmp
: İki kaydırıcıyı karşılaştırır ve koşul bayraklarını ayarlar.subs
'nin bir takma adıdır ve hedef kaydırıcıyı sıfır kaydırıcıya ayarlar.m == n
'yi bilmek için kullanışlıdır.Aynı sözdizimini destekler
Örnek:
cmp x0, x1
— Bu,x0
vex1
değerlerini karşılaştırır ve koşul bayraklarını buna göre ayarlar.cmn
: Negatif karşılaştırma işlemi. Bu durumda, biradds
takma adıdır ve aynı sözdizimini destekler.m == -n
'yi bilmek için kullanışlıdır.ccmp
: Koşullu karşılaştırma, önceki bir karşılaştırmanın doğru olması durumunda gerçekleştirilen ve özellikle nzcv bitlerini belirleyen bir karşılaştırmadır.cmp x1, x2; ccmp x3, x4, 0, NE; blt _func
-> eğer x1 != x2 ve x3 < x4 ise, _func'a atlaBu, çünkü
ccmp
yalnızca öncekicmp
birNE
ise gerçekleştirilecek, eğer öyle değilse bitlernzcv
0 olarak ayarlanacaktır (blt
karşılaştırmasını karşılamayacaktır).Bu aynı zamanda
ccmn
olarak da kullanılabilir (aynı ancak negatif,cmp
vscmn
gibi).tst
: Karşılaştırmanın değerlerinden herhangi ikisinin de 1 olup olmadığını kontrol eder (sonucu herhangi bir yere kaydetmeden ANDS gibi çalışır). Bir kaydırıcıyı bir değerle kontrol etmek ve belirtilen değerde gösterilen kaydırıcının herhangi bir bitinin 1 olup olmadığını kontrol etmek için kullanışlıdır.Örnek:
tst X1, #7
X1'in son 3 bitinden herhangi birinin 1 olup olmadığını kontrol edinteq
: Sonucu atlayarak XOR işlemib
: Koşulsuz atlamaÖrnek:
b myFunction
Bu, dönüş adresiyle bağlantı kaydırıcısını doldurmayacaktır (geri dönmesi gereken alt program çağrıları için uygun değildir)
bl
: Bağlantı ile atla, bir alt programı çağırmak için kullanılır. Dönüş adresinix30
'da saklar.Örnek:
bl myFunction
— Bu,myFunction
fonksiyonunu çağırır ve dönüş adresinix30
'da saklar.Bu, dönüş adresiyle bağlantı kaydırıcısını doldurmayacaktır (geri dönmesi gereken alt program çağrıları için uygun değildir)
blr
: Kayıtlı bir hedefte belirtilen bir alt programı çağırmak için kullanılan Bağlantı ile Kaydır, dönüş adresinix30
'da saklar. (BuÖrnek:
blr x1
— Bu, adresix1
içeren fonksiyonu çağırır ve dönüş adresinix30
'da saklar.ret
: Alt programdan dön, genelliklex30
adresini kullanarak.Örnek:
ret
— Bu, mevcut alt programdanx30
adresindeki dönüş adresini kullanarak döner.b.<cond>
: Koşullu atlamalarb.eq
: Eşitse atla, öncekicmp
talimatına dayanarak.Örnek:
b.eq label
— Eğer öncekicmp
talimatı iki eşit değer bulursa, bulabel
'a atlar.b.ne
: Eşit Değilse Dal. Bu komut, koşul bayraklarını kontrol eder (daha önceki bir karşılaştırma komutu tarafından ayarlanmıştır) ve karşılaştırılan değerler eşit değilse, bir etikete veya adrese dalış yapar.Örnek:
cmp x0, x1
komutundan sonra,b.ne label
— Eğerx0
vex1
içindeki değerler eşit değilse, bulabel
'e atlar.cbz
: Sıfıra Karşılaştır ve Dal. Bu komut bir kaydı sıfır ile karşılaştırır ve eğer eşitlerse, bir etikete veya adrese dalış yapar.Örnek:
cbz x0, label
— Eğerx0
içindeki değer sıfırsa, bulabel
'e atlar.cbnz
: Sıfır Olmayanı Karşılaştır ve Dal. Bu komut bir kaydı sıfır ile karşılaştırır ve eğer eşit değillerse, bir etikete veya adrese dalış yapar.Örnek:
cbnz x0, label
— Eğerx0
içindeki değer sıfır olmayan bir değerse, bulabel
'e atlar.tbnz
: Biti test et ve sıfır olmayan durumda dalÖrnek:
tbnz x0, #8, label
tbz
: Biti test et ve sıfır durumunda dalÖrnek:
tbz x0, #8, label
Koşullu seçim işlemleri: Bu işlemler, davranışı koşullu bitlere bağlı olarak değişen işlemlerdir.
csel Xd, Xn, Xm, cond
->csel X0, X1, X2, EQ
-> Doğruysa, X0 = X1, yanlışsa, X0 = X2csinc Xd, Xn, Xm, cond
-> Doğruysa, Xd = Xn, yanlışsa, Xd = Xm + 1cinc Xd, Xn, cond
-> Doğruysa, Xd = Xn + 1, yanlışsa, Xd = Xncsinv Xd, Xn, Xm, cond
-> Doğruysa, Xd = Xn, yanlışsa, Xd = DEĞİL(Xm)cinv Xd, Xn, cond
-> Doğruysa, Xd = DEĞİL(Xn), yanlışsa, Xd = Xncsneg Xd, Xn, Xm, cond
-> Doğruysa, Xd = Xn, yanlışsa, Xd = - Xmcneg Xd, Xn, cond
-> Doğruysa, Xd = - Xn, yanlışsa, Xd = Xncset Xd, Xn, Xm, cond
-> Doğruysa, Xd = 1, yanlışsa, Xd = 0csetm Xd, Xn, Xm, cond
-> Doğruysa, Xd = <tüm 1'ler>, yanlışsa, Xd = 0adrp
: Bir sembolün sayfa adresini hesapla ve bir kayıtta sakla.Örnek:
adrp x0, symbol
— Bu,symbol
'ün sayfa adresini hesaplar vex0
'a saklar.ldrsw
: Bellekten işaretle 32 bitlik bir değeri 64 bitlere genişleterek yükle.Örnek:
ldrsw x0, [x1]
— Bu,x1
tarafından işaret edilen bellek konumundan işaretle 32 bitlik bir değeri yükler, 64 bitlere genişletir vex0
'a saklar.stur
: Bir kayıt değerini başka bir kayıttan ofset kullanarak bir bellek konumuna kaydet.Örnek:
stur x0, [x1, #4]
— Bu,x1
içindeki adresin 4 byte daha büyük olan bellek adresinex0
içindeki değeri kaydeder.svc
: Bir sistem çağrısı yap. "Supervisor Call" kısaltmasıdır. İşlemci bu komutu çalıştırdığında, kullanıcı modundan çekirdek moduna geçer ve belleğin belirli bir konumuna atlar, burada çekirdeğin sistem çağrısı işleme kodu bulunur.Örnek:
Fonksiyon Prologu
Bağlantı kaydedici ve çerçeve işaretçisini yığına kaydet:
Yeni çerçeve işaretçisini ayarlayın:
mov x29, sp
(geçerli işlev için yeni çerçeve işaretçisini ayarlar)Yerel değişkenler için yığın üzerinde yer ayırın (gerekiyorsa):
sub sp, sp, <boyut>
(burada<boyut>
, ihtiyaç duyulan bayt sayısıdır)
İşlev Sonu
Yerel değişkenleri serbest bırakın (eğer ayrılmışsa):
add sp, sp, <boyut>
Bağlantı kaydedicisini ve çerçeve işaretçisini geri yükleyin:
Dönüş:
ret
(kontrolü çağırana link kaydedicideki adrese döndürür)
AARCH32 Yürütme Durumu
Armv8-A, 32 bitlik programların yürütülmesini destekler. AArch32, iki komut setinden birinde çalışabilir: A32
ve T32
ve aralarında geçiş
yapabilir.
Ayrıcalıklı 64 bitlik programlar, daha düşük ayrıcalıklı 32 bitlik programa bir istisna seviye transferi gerçekleştirerek 32 bitlik programların yürütülmesini planlayabilir.
64 bitlikten 32 bitliğe geçişin, istisna seviyesinin düşürülmesiyle gerçekleştiğini unutmayın (örneğin, EL1'de 64 bitlik bir program EL0'da bir programı tetikler). Bu, AArch32
işlem ipliğinin yürütülmeye hazır olduğunda SPSR_ELx
özel kaydedicisinin 4. bitini 1 olarak ayarlayarak yapılır ve SPSR_ELx
'in geri kalanı AArch32
programlarının CPSR'ini saklar. Ardından, ayrıcalıklı işlem ERET
komutunu çağırarak işlemcinin AArch32
'ye geçiş yapmasını sağlar ve CPSR'ye bağlı olarak A32 veya T32'ye girer.
Geçiş
, CPSR'nin J ve T bitleri kullanılarak gerçekleşir. J=0
ve T=0
A32
anlamına gelir ve J=0
ve T=1
T32 anlamına gelir. Bu temelde, komut setinin T32 olduğunu belirtmek için en düşük bitin 1 olarak ayarlanması anlamına gelir.
Bu, geçiş dalı komutları sırasında ayarlanır, ancak PC hedef kaydedici olarak ayarlandığında diğer komutlarla da doğrudan ayarlanabilir. Örnek:
Başka bir örnek:
Kayıtlar
16 adet 32-bit kayıt bulunmaktadır (r0-r15). r0'dan r14'e kadar olanlar herhangi bir işlem için kullanılabilir, ancak bazıları genellikle ayrılmıştır:
r15
: Program sayacı (her zaman). Bir sonraki komutun adresini içerir. A32'de mevcut + 8, T32'de ise mevcut + 4.r11
: Çerçeve İşaretçisir12
: İçsel işlem çağrı kaydedicir13
: Yığın İşaretçisir14
: Bağlantı Kaydedici
Ayrıca, kayıtlar banked registries
içinde yedeklenir. Bu, istisna işleme ve ayrıcalıklı işlemlerde hızlı bağlam değiştirme yapabilmek için kayıt değerlerini depolayan yerlerdir ve her seferinde kayıtları manuel olarak kaydetme ve geri yükleme ihtiyacını ortadan kaldırır.
Bu, işlemcinin durumunu CPSR
'den işlemcinin alındığı işlemci modunun SPSR
'ine kaydederek yapılır. İstisna dönüşlerinde, CPSR
SPSR
'den geri yüklenir.
CPSR - Geçerli Program Durumu Kaydedici
AArch32'de CPSR, AArch64'teki PSTATE
ile benzer şekilde çalışır ve bir istisna alındığında ileride geri yüklemek üzere SPSR_ELx
içinde depolanır:
Alanlar bazı gruplara ayrılmıştır:
Uygulama Program Durumu Kaydedici (APSR): Aritmetik bayraklar ve EL0'dan erişilebilir.
İşlem Durumu Kaydedicileri: İşlem davranışı (işletim sistemi tarafından yönetilir).
Uygulama Program Durumu Kaydedici (APSR)
N
,Z
,C
,V
bayrakları (AArch64'te olduğu gibi)Q
bayrağı: Özel doyurucu aritmetik komutun yürütülmesi sırasında tamsayı doygunluğu oluştuğunda 1 olarak ayarlanır. Bir kez1
olarak ayarlandığında, elle 0 olarak ayarlanana kadar değeri korur. Ayrıca, değerini örtük olarak kontrol eden herhangi bir komut yoktur, değeri manuel olarak okunarak kontrol edilmelidir.GE
(Büyük veya eşit) Bayraklar: SIMD (Tek Komutla, Çoklu Veri) işlemlerinde kullanılır, örneğin "paralel toplama" ve "paralel çıkarma". Bu işlemler tek bir komutta birden fazla veri noktasını işlemeyi sağlar.
Örneğin, UADD8
komutu, paralel olarak dört çift baytı (iki 32-bit işlemden) ekler ve sonuçları bir 32-bit kaydediciye depolar. Ardından, bu sonuçlara dayanarak APSR
içindeki GE
bayraklarını ayarlar. Her GE bayrağı, bayt eklemelerinden birine karşılık gelir ve o bayt çifti için eklemenin taştığını gösterir.
SEL
komutu, bu GE bayraklarını koşullu işlemler yapmak için kullanır.
İşlem Durumu Kaydedicileri
J
veT
bitleri:J
0 olmalıdır veT
0 ise A32 komut seti kullanılır, 1 ise T32 kullanılır.IT Blok Durum Kaydedici (
ITSTATE
): Bunlar 10-15 ve 25-26'dan gelen bitlerdir. BirIT
ön ekli grup içindeki komutlar için koşulları depolarlar.E
biti: endianness'ı belirtir.Mod ve İstisna Maske Bitleri (0-4): Mevcut yürütme durumunu belirler. 5. si programın 32 bit (1) veya 64 bit (0) olarak çalıştığını belirtir. Diğer 4'ü, kullanılan mevcut istisna modunu belirtir (bir istisna oluştuğunda ve işlendiğinde). Sayı seti, bunun işlenirken başka bir istisna tetiklenirse mevcut önceliği belirtir.
AIF
: Belirli istisnalar,A
,I
,F
bitleri kullanılarak devre dışı bırakılabilir.A
1 ise asenkron hatalar tetikleneceği anlamına gelir.I
, harici donanım Kesme İstekleri'ne (IRQ'lar) yanıt vermek için yapılandırılır ve F, Hızlı Kesme İstekleri'ne (FIR'lar) ilişkilidir.
macOS
BSD sistem çağrıları
syscalls.master dosyasına göz atın. BSD sistem çağrıları x16 > 0 olacaktır.
Mach Tuzakları
mach_trap_table ve mach_traps.h dosyalarına bakın. Mach tuzaklarının sayısı MACH_TRAP_TABLE_COUNT
= 128'dir. Mach tuzakları x16 < 0 olacaktır, bu nedenle önceki listedeki numaraları bir eksi ile çağırmalısınız: _kernelrpc_mach_vm_allocate_trap
-10
'dur.
Bu (ve BSD) sistem çağrılarını nasıl çağıracağınızı bulmak için bir ayraçta libsystem_kernel.dylib
'i kontrol edebilirsiniz:
Bazen libsystem_kernel.dylib
dosyasından derlenmiş kodu kontrol etmek kaynak kodunu kontrol etmekten daha kolay olabilir çünkü birkaç sistem çağrısının (BSD ve Mach) kodu betikler aracılığıyla oluşturulur (kaynak kodundaki yorumlara bakın) iken dylib dosyasında neyin çağrıldığını bulabilirsiniz.
machdep çağrıları
XNU, makine bağımlı olarak adlandırılan başka bir çağrı türünü destekler. Bu çağrıların sayısı mimariye bağlıdır ve ne çağrılar ne de numaraların sabit kalması garanti edilmez.
comm sayfası
Bu, her kullanıcı işleminin adres alanına eşlenmiş olan bir çekirdek sahibi bellek sayfasıdır. Bu, kullanıcı modundan çekirdek alanına geçişi, bu geçişin çok verimsiz olacağı çekirdek hizmetleri için sistem çağrılarını kullanmaktan daha hızlı yapmayı amaçlar.
Örneğin, gettimeofdate
çağrısı, timeval
değerini doğrudan comm sayfasından okur.
objc_msgSend
Bu fonksiyonun Objective-C veya Swift programlarında sıkça kullanıldığını görmek çok yaygındır. Bu fonksiyon, bir Objective-C nesnesinin bir yöntemini çağırmayı sağlar.
Parametreler (daha fazla bilgi için dokümantasyona bakın):
x0: self -> Örneğin işaretçi
x1: op -> Yöntemin seçicisi
x2... -> Çağrılan yöntemin diğer argümanları
Bu nedenle, bu fonksiyona yapılan dal öncesinde kesme noktası koyarsanız, lldb'de neyin çağrıldığını kolayca bulabilirsiniz (bu örnekte nesne, bir komut çalıştıracak olan NSConcreteTask
nesnesinden bir nesneyi çağırır).
NSObjCMessageLoggingEnabled=1
çevresel değişkeni ayarlanarak bu işlevin /tmp/msgSends-pid
gibi bir dosyada çağrıldığında kaydedilmesi mümkündür.
Ayrıca, OBJC_HELP=1
ayarlanarak herhangi bir ikili dosyayı çağırarak belirli Objc-C eylemleri gerçekleştiğinde kaydetmek için kullanabileceğiniz diğer çevresel değişkenleri görebilirsiniz.
Bu işlev çağrıldığında, belirtilen örneğin çağrılan yöntemini bulmak gereklidir, bunun için farklı aramalar yapılır:
İyimser önbellek araması yap:
Başarılıysa, tamam
runtimeLock al (okuma)
(gerçekleştir && !cls->realized) ise sınıfı gerçekleştir
(initialize && !cls->initialized) ise sınıfı başlat
Sınıfın kendi önbelleğini dene:
Başarılıysa, tamam
Sınıf yöntem listesini dene:
Bulunduysa, önbelleği doldur ve tamam
Üst sınıf önbelleğini dene:
Başarılıysa, tamam
Üst sınıf yöntem listesini dene:
Bulunduysa, önbelleği doldur ve tamam
(çözücü) yöntem çözücüyü dene ve sınıf aramasından tekrarla
Hala buradaysa (= her şey başarısız oldu) yönlendiriciyi dene
Kabuk Kodları
Derlemek için:
Bytes'ı çıkarmak için:
Yeni macOS sürümleri için:
<özet>Shellcode'u test etmek için C kodu</özet>
Kabuk
buradan alınmış ve açıklanmıştır.
Cat ile oku
Amacımız execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)
komutunu çalıştırmak, bu nedenle ikinci argüman (x1) parametrelerin bir dizisi olmalıdır (bellekte bu adreslerin bir yığını anlamına gelir).