Phase 13: Tools & Protocols

Sözleşmeleri ve Yüklü Çerçeve Çağırma: Sistem V, Windows x64, ve AArch64

Bir parçacık bir fonksiyonun hangi kayıtları okuduğunu gösterir. Sadece ABI bu kayıtların ne anlama geldiğini söyler ve ABI nesne başlığı tarafından seçilir, bu nedenle bu ders başlığı önce okur ve sonra her kayıtları oraya koyan kurallara karşı kontrol eder.

Type: Build

Languages: Python, C, x86-64 and AArch64 assembly

Prerequisites: Phase 13 · 32 (ELF from scratch), Phase 13 · 33 (disassembly and control flow)

Time: ~140 minutes

Öğrenme Hedefleri

  • Nesne başlığından arama konvansiyonunu seçin: ELF x86-64 System V psABI, COFF AMD64 Microsoft x64, ELF AArch64 AAPCS64, Mach-O arm64 Apple'ın variansıdır.
  • Her ABI için bir fonksiyonun byte byte'sinin önbölcüsünü çöz ve kaydedilen her kayıt, geri dönüş adresi ve çerçeve işaretçisini giriş yığın göstergesinden tersine yerleştir.
  • Bir fonksiyonun parametrelerinin kayıtlarını, bunları yazmadan önce okuduğu kayıtlardan ve giriş yığın göstergesi üzerindeki yüklerden yığın argüman boşluklarını yerleştir.
  • Microsoft x64'in konum yuvarlaklarından ve AAPCS64'in NGRN ve NSRN sayıcılarından Sistem V'nin bağımsız kayıt dizilerini söyleyin.
  • Her sonucu kaynağın imzasına, spesifikasyondaki kurallara ve kompilicin kendi çözme verilerine karşı kontrol edin..pdata- Evet ..xdatave.eh_frame- Evet .
  • Ghidra, IDA, Binary Ninja, radar2, rizin ve angr isimlerini karşılaştırın ve aynı gerçekleri geri alın ve çıktısının kaynağa katılmadığı yerleri kaydetin.

Sorun

  • Sen topladın .convention.cLinux için x86-64-O2ve radar2.4.'ın argümanlarını sordu.eight_argsYedi ile cevap verdi:rdi- Evet .rsi- Evet .rdx- Evet .r8- Evet .r9- Evet .rsp+0x8versp+0x10C kaynağı sekiz parametreye sahiptir.%rcxTam bir kez, leaq (%rdx,%rcx), %rax, ve araç değişken kurtarma sadece bir adres içinde görünen bir kayıt sayılmadı.

Sonra aynı dosyanın Windows yapısını rizin 0.9.1'de açtın.amd64ve buldum .r8- Evet .rcx- Evet .rdxBu nesne COFF, bu yüzden konvansiyon Microsoft x64, dördüncü kayıt argümanı r9İki araç aynı kaynağı farklı kayıtlardan kaçıyor.

Bir liste, talimatların bir sırasıdır. Bir çağrı sözleşmesi, listeden dışarıda yaşayan bir sözleşmedir: hangi kayıtlar, çağrıda bulunmuş kişinin koruması gereken argümanları taşıyor, geri dönüş adresi ve yığın argümanları nerede yer almaktadır ve çağrıda bulunmuş kişinin yığın işaretçisinin üstünde ne bırakması gerekir. Burada önemli olan anlaşmaları dört belge tanımlıyor. Sistem V AMD64 psABI (Versiyon 1.0, 12 Mart 2025 tarihli yapı) bölümleri 3.2.1 ile 3.2.3. Microsoft x64 çağrı konvansiyonu, yığın kullanımı ve önbellek ve epilog sayfaları (2018-12-17'den 2025-03-19'e kadar sayfa tarihleri). Arm AAPCS64 2025Q4 (23 Ocak 2026) bölümleri 6.1 ila 6.9'u yayınlıyor. Apple'ın arm64 platform notları. Bu ders bu kuralları okuyor, onları üç şekilde oluşturulan bir C dosyasına uyguluyor ve bir listeyi parametre konumlarının, kaydedilen kayıtların ve çerçeve sıfırlamalarının kontrol edilen bir listesine dönüştüren analizörü oluşturur.

Bir Başlık Kurallar Kitabını Seçir

convention.cOn iki fonksiyonunu vardır: leaf_add- Evet .eight_args- Evet .mixed- Evet .by_value- Evet .big_ret- Evet .sum_varargs- Evet .keeps, ve beş kişi aradı .externBu, aynı şekillerle işlevler oluşturur.long longÇünkü ...longMSVC hedefinde 4 byte ve diğerlerinde 8 byte ve boyut değişikliğini değiştiren bir yapı.-target x86_64-unknown-linux-gnu- Evet .x86_64-pc-windows-msvcveaarch64-unknown-linux-gnu- ...-O0ve -O2vearm64-apple-macos- ...-O2. Linux veya Windows başlıkları yüklenmiyor, bu yüzden dosya ihtiyacı olanları açıklıyor ve sadece clang'ın kendi başlıklarını içerir stdarg.hve stddef.h- Evet .

describe_object()İçeridecode/main.py4 bayt sihirli sayıyı ve bir makine alanını okuyor ve sözleşmeyi isimlendiriyor:

HeaderFieldValueRulebook
7f 45 4c 46 ELFe_machine at offset 0x1262System V AMD64 psABI
64 86 COFFMachine at offset 00x8664Microsoft x64
7f 45 4c 46 ELFe_machine183AAPCS64
cf fa ed fe Mach-O 64cputype at offset 40x0100000cAAPCS64 with Apple differences

Üç sözleşme, aşağıdaki tabloda neredeyse her satırda aynı fikirde değildir. Her değer başlık satırında adı verilen belgeye alıntı yapılır ve her biri sabitlemelere karşı bir testle kontrol edilir.

RuleSystem V psABIMicrosoft x64AAPCS64
Integer arguments%rdi %rsi %rdx %rcx %r8 %r9, next free registerRCX RDX R8 R9, by positionx0 to x7, by NGRN
Floating-point arguments%xmm0 to %xmm7, next free registerXMM0 to XMM3, by positionv0 to v7, by NSRN
Integer result%rax, then %rdxRAXx0, then x1
Floating-point result%xmm0, then %xmm1XMM0v0
Result too large for registersaddress passed in %rdi "as if it were the first argument", returned in %raxpointer in RCX, arguments shifted right, returned in RAXaddress in x8, x0 to x7 untouched
Callee-saved%rbp %rbx %r12 to %r15RBX RBP RDI RSI RSP R12 to R15, XMM6 to XMM15r19 to r29, SP, low 64 bits of v8 to v15
First stack argument on entry8(%rsp)40(%rsp), above a 32-byte shadow store0(sp)
Below the stack pointer128-byte red zone"considered volatile"no red zone (Apple: 128 bytes)
Alignment at the call(%rsp + 8) multiple of 16 on entry16-byte aligned outside prolog and epilogSP mod 16 = 0
Variadic marker%al holds an upper bound on vector registers usedfloats duplicated in the integer registernone in registers; Apple uses 8-byte stack slots

Sistem V: İki bağımsız kayıt sırası ve kırmızı bir bölge

psABI 3.2.3 her argümanın her sekiz baytını INTEGER, SSE veya MEMORY olarak sınıflandırır ve ardından etkileşime girmeyen iki listeden kayıtları tahsis eder. "INTEGER" "%rdi, %rsi, %rdx, %rcx, %r8 ve %r9 dizisinin bir sonraki mevcut kayıtlarını" alır. SSE alır %xmm0- ...%xmm7"Eğer bir argümanın herhangi bir sekizbayt için kayıtlar mevcut değilse, tüm argüman yığın üzerinde geçer", ve bellek argümanları "yığın üzerinde ters (sağdan sola) sırada itilir".

eight_args(a, b, c, d, e, f, g, h)- ...-O227 byte:

text      10: 48 01 fe                     	addq	%rdi, %rsi
      13: 48 8d 04 0a                  	leaq	(%rdx,%rcx), %rax
      17: 48 01 f0                     	addq	%rsi, %rax
      1a: 4c 01 c0                     	addq	%r8, %rax
      1d: 4c 01 c8                     	addq	%r9, %rax
      20: 48 03 44 24 08               	addq	0x8(%rsp), %rax
      25: 48 03 44 24 10               	addq	0x10(%rsp), %rax
      2a: c3                           	retq

Altı kas, sonra iki yük.8(%rsp)ve 16(%rsp). psABI'nin 3.3 şablonunda "memory argument eightbyte 0" yerleştirildi.16(%rbp)Ne zaman ?%rbpçerçeve tabanı, yani 8(%rsp)Herhangi bir itme olmadan giriş.g8'de.h16 yaşında.

mixed(int i, double d, long long l, float f)İki listeyi gösterir.%edive %rsi, ilk ve ikinci INTEGER kayıtları.%xmm0ve %xmm1İlk talimat ise:cvtsi2sd %edi, %xmm2ve%xmm2Bu, işlevin okumadan önce yazdığı bir çizim kaydıdır.cvtsi2sdBir okuyucu üçüncü bir akış noktası argümanı icat etti. Radar2 tam olarak bunu yaptı ve rapor verdi.mixed- Evet .(double arg1, double arg2, double arg3)İçeridexmm0- Evet .xmm1- Evet .xmm2- Evet .

by_value(struct pair p)16 byet bir yapı iki INTEGER 8 byet olarak geçer %rdive %rsi, ve aynı şekilde geri gönderir: leaq 0x1(%rdi), %rax; leaq -0x1(%rsi), %rdx; retq- Evet .big_ret(long long seed)32 byte, yani sınıf YADANlığı gönderir ve psABI "Çalışan, geri dönüş değerine yer sağlar ve bu depolamanın adresini %rdi'de ilk argüman gibi geçer". diyor. seed%rsi, ve işlev ile başlar .movq %rdi, %raxÇünkü "%rax, %rdi'de arayan tarafından gönderilen adresi içerir".

Kırmızı bölge, diğer Sistem V imzası. psABI 3.2.2: "%rsp tarafından gösterilen konumdan öte 128 bayt alanı rezerve sayılır ve sinyal veya kesinti işleyicileri tarafından değiştirilmez. "-O0- Evet .eight_args- Evet .pushq %rbp; movq %rsp, %rbpVe sonra altı mağazaya .-0x8(%rbp)- Evet .-0x30(%rbp)Hayır .subqMağazalar, yığın göstergesi altında 48 byt yer alıyor.-O2yapılandırmasum_varargs88 byteyi ile ayırırsubq $0x58, %rspve sonra kayda kaydetme alanını -0x58(%rsp)Aşağıya kadar-0x80(%rsp): 128 byte daha aşağıda, tüm kırmızı bölge.-mno-red-zoneve leaf_addkazançlar pushq %raxve bir addq $0x8, %rspYerlilerin 8 bytesini yığın işaretçisinin üstünde tutmak için.

Variadic çağrılar bir kayıt ekler. "%al, kullanılan vektör kayıtlarının sayısını belirtmek için gizli bir argüman olarak kullanılır", 0 ila 8 arasında bir üst sınırı. call_varargs- Evet .xorl %eax, %eax- ...-O2ve movb $0x0, %al- ...-O0- Evet .sum_varargsÖnce okuyun: testb %al, %al; jeSekiz atlıyor.movaps %xmmNvektör kayıtları kullanılmadığında kaydedilir.

Microsoft x64: Konumlar, Gölge Mağazası ve Kırmızı Bölge Yok

Microsoft kuralları pozisyonaldır. "Tam argümanlar RCX, RDX, R8 ve R9 kayıtlarında geçer. Dalgıç nokta argümanlar XMM0L, XMM1L, XMM2L ve XMM3L'de geçer. " ve "Önce dört parametredeki herhangi bir dalgıç nokta ve çift hassaslık argümanı konumuna bağlı olarak XMM0 - XMM3'de geçer. " Aynı mixed%ecx- Evet .%xmm1- Evet .%r8- Evet .%xmm3: 0 bir int, yani RCX1 numaralı yuva iki katlı.XMM1; 3. yuva yüzer, bu yüzden XMM3- Evet .XMM0ve XMM2- Boş kal.

Arayan da yer bırakmalıdır. "Arayan her zaman dört kayıt parametresi depolamak için yeterli alan ayırmalıdır, hatta arayan o kadar parametre almazsa bile". Sayfalar ona gölge mağazası veya ev adresleri adını verir ve dört yuva "verilen işlevi tarafından etkin olarak sahiplenir". Giriş sırasında 0(%rsp)dönüş adresi, 8(%rsp)- ...39(%rsp)Dört ev var ve ilk toplu tartışma40(%rsp)- Evet .eight_args- ...-O2okur 0x28(%rsp)- Evet .0x30(%rsp)- Evet .0x38(%rsp)- Evet .0x40(%rsp)40, 48, 56, 64.

Arayıcı tarafı aritmetik gösterir.call8- ...-O2- Evet .subq $0x48, %rspVe sonra da 5, 6, 7, 8'lik dükkanlar.0x20(%rsp)- ...0x38(%rsp)Daha öncemovl $1, %ecx72 byte gölge depo için 32, 32 dört yığın argüman için ve 8 böylece geri dönüş adresi 16 byte bir sınır. call_varargsSadece argümanları kaydetir ve hala dağıtır subq $0x28, %rsp: 32 gölge depo için ve 8 düzeltme için. keepsüç volatile kayıt (24 byte) i itirir ve sonra subq $0x20, %rsp, yani buext32 baytlık gölge depolarını geri dönüş adresinin altında bulur.

Struktlar kendi kurallarını izler. "Eşit bayt içine girmeyen veya 1, 2, 4 veya 8 bayt olmayan herhangi bir argüman referans yoluyla geçmelidir". ve "16 baytlı argümanlar referans yoluyla geçmelidir". by_valueBu nedenle bir kopyayı gösterir.%rdx, gizli bir sonuç göstergesi sonrası %rcx: "Çalışan, geri dönüş değeri için bellek ayırmalı ve ona bir işaretçi göndermelidir.call_pair0x20(%rsp)- Evet .movaps, geçiyor leaq 0x20(%rsp), %rdx, sonuç tamponu ile geçer leaq 0x38(%rsp), %rcxve okuyor ..bGeri dönmek için0x40(%rsp)- Evet .

"RSP'nin mevcut adresinden öte tüm bellek değişken olarak kabul edilir: OS veya bir defugger, bir kullanıcı defug sesyonu veya bir kesinti yöneticisi sırasında bu belleği üst yazıyor olabilir. "-O0 leaf_add8 byte yerel ihtiyaç ve onları alır pushq %raxGiriş ve popq %rcxDaha önceretq, bir yerine iki tek baytlı talimatsubqve bir addq.Stack kullanımı sayfasında bunu yapabilecek bir yaprak tanımlanır: "Bir yaprak işlevi, bir işlev tablosu girişini gerektirmeyen bir işlevi içerir. RSP dahil olmak üzere herhangi bir değişkenlik olmayan kayıtlara değişiklik yapamaz".

Variadic, kayıtlarını evlerine çağırır. "Vararg veya prototipsiz fonksiyonlar için, herhangi bir yüzer nokta değerleri ilgili genel amaçlı kayıtta çoğaltılmalıdır". sum_varargs- ...-O2mağazalar %rdx- Evet .%r8- Evet .%r9- ...0x18(%rsp)- Evet .0x20(%rsp)- Evet .0x28(%rsp)Birinden sonra .pushq %rax, yani giriş oranları 16, 24, 32: ikinci, üçüncü ve dördüncü kayıt parametrelerinin evleri.va_list- Evet .leaq 0x18(%rsp), %rax, evinin%rdx, isimsiz ilk argüman.

AAPCS64, ve Apple'ın Neyi Değiştirdiği

AAPCS64 6.8.2 iki sayıcı ile kuralların bir listesini yürütür. C.9: bir bütün argümanı "x[NGRN]" ve NGRN artışlarına en az önemli bitlere kopyalanır. C.1 aynı şeyi NSRN ile yüzen nokta argümanları için yapar. C.12: en fazla 8 - NGRNC.13 "NGRN'nin 8'e ayarlanması" bir argüman yığınına geçtiğinde, bu nedenle hiçbir şey daha sonra kayıtlara geri dönmez. eight_argskullanımı x0- ...x7Ve asla yığınlara dokunmaz.mixed- Evet .w0- Evet .d0- Evet .x1- Evet .s1- Evet .by_value- Evet .x0ve x1İçeri ve dışarı.

6.9 kayıtlarda geçerli olan bir sonuç "aynı kayıtlarda geri verilir", aksi takdirde "Hoturum blokunun adresi x8 işlevi için ek bir argüman olarak geçer".big_retYazar str x0, [x8]- Evet .stur q0, [x8, #0x8]- Evet .str x9, [x8, #0x18]Ve asla yazmaz.x0- Evet .call_bigtakımlar mov x8, spveseedİçeride kalır.x0, çünkü 6.9 "callee'nin x8'de saklanan değeri korumasına gerek yoktur" ve x8- Tartışma kayıtlarından biri değil.

6.1.1: "Bir alt-düzen çağrısı r19-r29 ve SP kayıtlarının içeriğini korumalıdır". 6.4.5.2: "SP mod 16 = 0" kamu arayüzünde.-O0 leaf_addyayımlarsub sp, sp, #0x10Sistem V'nin kırmızı bölge kullandığı 8 byte yerel halk için.

6.4.6 çerçeve kaydını tanımlar: "dağdaki iki 64 bit değerli çerçeve kaydı... En düşük adresli çift kelime önceki çerçeve kaydını gösterir ve en yüksek adresli çift kelime mevcut fonksiyona girerken LR'de geçen değeri içerir". ve "Bir çerçeve kaydının bir sürü çerçeve içinde bulunduğu yeri belirtilmemiştir". clang bu tek dosyada her iki pozisyonu gösterir. keeps- ...-O2Linux'ta en alt kısmında kayıt var.stp x29, x30, [sp, #-0x30]!; mov x29, spAynı fonksiyon .-O0Üstüne koyar sub sp, sp, #0x20; stp x29, x30, [sp, #0x10]; add x29, sp, #0x10- Evet .

Apple'ın arm64 notları kayıtları ve uyumluluğu korur ve çerçeveyi, kırmızı bölgeyi ve varyadik çağrıları değiştirir. "Frame pointer register (x29) her zaman geçerli bir çerçeve kaydı ile ilgilenmelidir.keepstasarruf eder .x22, x21, x20, x19İlk ve en üstteki rekorları yerleştirir:stp x29, x30, [sp, #0x20]; add x29, sp, #0x20"ARM64 kırmızı bölgesi, yığın işaretçisinin hemen altındaki 128 bayttan oluşur" ve hala yayılan çığlık.sub sp, sp, #0x10- ...-O0Varyadik argümanlar "a uygun sayıda 8 baytlı yığın boşluklarına" ve "va_list tipi char* için bir takmaca" atanır. call_varargsApple mağazalarında 10, 20, 30'dan [sp]- Evet .[sp, #8]- Evet .[sp, #0x10]ve sadece geçer.w0Linux yapılandırması geçerli .w1- Evet .w2- Evet .w3ve ile arkaplan çağrılarıb extva- Elma .sum_varargsokur add x8, sp, #0x10, arayanın yığın göstergesi, onun gibiva_listLinux sum_varargstasarruf eder .x1- ...x7ve q0- ...q7224 baytlı bir çerçeveye girer ve yapı alanlarını initialize eder __gr_offs-56 ve __vr_offs-128'e bir tane ile mov x8, #-0x38; movk x8, #0xff80, lsl #32- Evet .

Mach-O her C sembolünü bir önleme ile belirler._, listede gösterildiği gibi_keepsve ilk işlev özel etiket altında görünür ltmp0Analizör, simge tablosu ile etiketlerin adını değiştirir.

Bir Başlık'ı Elden Üç kez Çıkar

keeps(int n)Çağrılarext(i)Bir döngü içinde ve devam eder.n- Evet .iveaccBu yüzden her ABI kayıtları kaydetmeli.-O2Her hedefe göre inşaat yapın.

Sistem V, 4 byte:

  1. 55- Evet .push r64Aşağı üç bitte kayıtlı: 50 + 5- Evet .%rbp- 8 derinlik.%rbpGiriş geçişinden -8'de kaydedildi.
  2. 41 56- Evet .41REX ile Bbir dizi,56- Evet .50 + 6REX.B 6 ' dan 14 ' e kadar uzanıyor .pushq %r14- 16'da.
  3. 53- Evet .50 + 3- Evet .pushq %rbx-24'te.

3 basmak 24 byte. geri dönüş adresi 8 ekler ve 32 16'ın katı, bu yüzden callq extÇubuk içinde bir olmadan düzeltilmiştirsubq- Yok .movq %rsp, %rbpBu yapıta bir çerçeve işaretçisi yok.%rbpBu da , o çağrıların kaydedilen kayıt .acc(xorl %ebp, %ebp- Evet .addl %eax, %ebpEpilog aynadır .5b 41 5e 5d c3- Evet .

Microsoft x64, 7 bayt:

  1. 56- Evet .pushq %rsi-8'de.57- Evet .pushq %rdi-16'da.53- Evet .pushq %rbx-24'te.RDIve RSISistem V'deki argüman kayıtlarıydı.
  2. 48 83 ec 20: REX.W, opcode 83 /58 bitlik bir modrm ile.ec- Evet .11 101 100- Evet .subq $0x20, %rsp- 56 derinlik.

56 artı geri dönüş adresi 64'dir, 32 byet gölge depo.extEpilog sayfasında sadece "RSP, sabit veya Lea RSP, sabit [FPReg] eklenmesine izin verilir, ardından sıfır veya daha fazla 8 baytlı kayıt popları ve bir geri dönüş veya bir jmp" bir dizi ve baytlar vardır.48 83 c4 20 5b 5f 5e c3- Evet .

AArch64, 16 byte dört kelimeyle, küçük bir endian:

  1. a9bd7bfd- Evet .stp- İndeks öncesi.1064 bitlik kayıtları seçin, 25:23 bit.011Seçili pre-index, bit 22 depo için 0'dur. imm7 bit 21:15'te 1111010Rt2 14:10'da 30'a eşit Rn 9:5'da 31'e eşit (sp), Rt 4:0 29'dur.stp x29, x30, [sp, #-0x30]!: yığın göstergesi 48'e düşüyor.x29-48'e gidiyor ve x30-40'a kadar.
  2. f9000bf5- Evet .strİmza edilmemiş 12 bitlik bir ofset ile 8 ile ölçeklenmiş: imm12 21:10'da 2'dir, Rn spRt 21 ' e eşittir .str x21, [sp, #0x10]Giriş oranı -32'dir.
  3. 910003fd- Evet .addhemen: imm12 0, Rn spRd 29 ' dır .mov x29, sp: çerçeve işaretçisi -48'e kadar kayda atıyor.
  4. a9024ff4- Evet .stpİmza edilen bir ofset ile: imm7 4'e, 32'ye kadar ölçeklendirilmiş. Rt2 19'a, Rt 20'e eşit.stp x20, x19, [sp, #0x20]- Evet .x20-16'da.x19-8'de.

Çerçeve 48 byte: x290'da.x30Saat 8'de.x2116.8 byte, 24.x2032 yaşında.x19Kaydın en düşük kelime önceki kaydı gösterir ve 6.4.6'nın gerektirdiği gibi sonraki kelime LR tutar. cmp w0, #0x1Birinci ve ikinci depo arasında yer alır; programcı onu prologuna taşıyor ve analizci yığın işlemleri arasında bir karşılaştırma veya bir aritmetik talimatı kabul eder.

Yöneticisi Aynı Bilgiyi İki Keşke Yazmış Olsun

Bir öncü analiz bir çıkartmadır. Yükleyici bir ikinci bir çıkartmayı çıkarır ve ikisi de aynı fikirde olmalıdır.

Windows ' da ikinci derivasyon .pdatave .xdata- Yapın .-O2nesne olmadan -fno-asynchronous-unwind-tablesve llvm-objdump -hgösteriler.xdata0x34 byte ve .pdata0x48 bytes. 0x48 72, 6 RUNTIME_FUNCTION12 byte ve üç IMAGE_REL_AMD64_ADDR32NBHer biri yer değiştirdi.sum_varargs- Evet .keeps- Evet .call8- Evet .call_varargs- Evet .call_pairvecall_bigDiğer altı fonksiyonlar yapraklar ve istisna işleme sayfasında "Eğer arama bir fonksiyon tablosu girişini bulamıyorsa, kodun bir yaprak fonksiyonunun bir parçası olduğu varsayılır ve RSP doğrudan geri göstergeyi ele alır".

  • Evet ..xdata için byteskeeps- Evet .01 07 04 00 07 32 03 30 02 70 01 60- Evet .UNWIND_INFO3 bitli Versiyon ve 5 bitli Bayraklar ile başlar: 1. versiyon, bayraklar yok. SizeOfProlog 7, CountOfCodes 4, FrameRegister ve FrameOffset 0. Her biri UNWIND_CODEProlog'daki bir ofset ve bir byte opkod ve bilgi. 07 32: ofset 7'de, op 2'de UWOP_ALLOC_SMALL, info 3 anlamı 3 * 8 + 8 = 32Baytlar.03 30: op 0 UWOP_PUSH_NONVOL, kayıt 3 rbx- Evet .02 70- Evet .rdi- Evet .01 60- Evet .rsi. Kodlar geri yönlü bir şekilde depolanır ve aynı üç baskı ve 32 baytlı tahsis ile aynı baytları adlandırırlar 56 57 53 48 83 ec 20- Ne ?sum_varargsGiriş:01 01 01 00 01 02 00 00: bir kodlu 1 baytlı bir prolog, UWOP_ALLOC_SMALLBu da bir devirci tarafından görülen bir şey.pushq %rax: bir tahsis, çünkü %raxUçurgan ve hiçbir şey kurtarılmıyor.

Linux ' ta ikinci türü .eh_frame, ki bu kısımlar, psABI 4.2.4'te tanımlanmıştır ve DWARF 5 bölüm 6.4'te kodlanmıştır. llvm-dwarfdump --eh-frameYer değiştirilebilir nesne üzerinde fonksiyona bir FDE yazdırır ve R_X86_64_PC32- Bu yüzden alanlar kullanılabilir.keeps- ...

text  DW_CFA_def_cfa_offset: +16
  DW_CFA_def_cfa_offset: +24
  DW_CFA_def_cfa_offset: +32
  DW_CFA_offset: RBX -32
  DW_CFA_offset: R14 -24
  DW_CFA_offset: RBP -16

CFA, çağrıdan önce yığın göstergesidir, giriş yığın göstergesinin üstünde 8'dir, bu nedenle RBP -16Giriş oranı -8'dir.R14 -24-16'ın.RBX -32-24'e, en derin CFA 32'nin de 24 bayt çerçevesini ekleyerek geri dönüş adresi.keepsdiyor kiDW_CFA_def_cfa: W29 +48- Evet .W29 -48- Evet .W30 -40- Evet .W21 -32- Evet .W20 -16- Evet .W19 -8. Orada CFA giriş yığın göstergesi kendisidir, bu nedenle karşılaştırmalar dönüşümsüz çerçeve karşılaştırmalarıdır ve CFA'nın tanımlanması x29Çerçeve kayıtları canlıyken.eh_frame_cross_check()Bu, her iki nesnenin 12 FDE'si için bu karşılaştırmayı yapar.call8Sistem V altında iki çıkış argümanı vücut ortalarına doğru itmektedir. Yani en derin CFA ofset 32'dir. Prolog çerçevesinde ise 8'dir.

Bu aletlerin adı ne ?

Bu alanın her bir aracı, çağrı konvansiyonu için bir veri yapısı ve bir işlevi atanır bir geçiş vardır. İsimler farklıdır ve boşluklar farklıdır. Kapalı araçlar belgeleriyle tanımlanır; açık olanlar armatürlerde çalıştırılır ve çıkışı nesnelerin yanında ele alınır.

Ghidra 12.1.4 (Apache-2.0).Kurallar, kompiliör özellik dosyalarında canlıdır..cspec, SLEIGH dili yanında.x86-64-gcc.cspecbir <default_proto>Adı:__stdcall, "Sistem V Uygulama Binary Interface AMD64 Arsitektur Süperleri Ekisi Nisan 2016" ile <pentry>listeler içinXMM0_Qa- ...XMM7_Qave RDI, RSI, RDX, RCX, R8, R9, 8'te bir yığın giriş, a join_dual_class16 byte'ye kadar türler için kural, çıkışlar XMM0_Qa, XMM1_Qa, RAX, RDXvehidden_returnGerisi için.x86-64-win.cspecAçıklamalar__fastcallDört kişiyle.<group>Çiftleşen elementlerXMM0_Qa- Evet .RCX- Evet .XMM1_Qa- Evet .RDX, ve böylece, konum kuralı, 40'ın karşılaştırılmasındaki bir yığın girişidir.convert_to_ptr3, 5, 6 veya 7 baytlı çizgiler için "Registrasyon için sadece 8,16,32,64 bit büyüklüğündeki çizgiler paketlenebilir" yorumunu kullanın. unaffectedlistelenmeRBX RBP RDI RSI RSP R12- ...R15ve XMM6- ...XMM15, ve bir localrange8 ila 39'daki yığın, gölge mağazası.AARCH64.cspecAçıklamalar__cdeclİlk girişleri x8- Evet .storage="hiddenret"O zaman ...q0- ...q7ve x0- ...x7- Evet .convert_to_ptr17 bayt veya daha fazla olan yapılandırmalar için ve killedbycallİçinde:x8"Yöntemsel sonuç konum kaydı, pentry listesinde yansıtılmamıştır" yorumunu ile. Dekompiler'in son aşaması "Establish Function's Prototype" olarak adlandırılır; analizörler "Call Convention ID" ve "Decompiler Parameter ID"dir; "Prototype Evaluation" program seçeneği varsayılan modeli seçer.

IDA Pro and IDA Free (Hex-Rays, commercial; current release 9.4, build 9.4.260714).Fonksiyon tipi, SetType aracılığıyla belirtilen bir C deklarasyonudır ve "IDA, tip bilgilerini, fonksiyon argümanları hakkında bilgi ile birlikte sökülmeyi yorumlamak için kullanacaktır". Standart bir kuralı oluşturmayan yerler, IDA'nın kendi kuralı yazılmıştır: int __usercall func@<ebx>(int x, int y@<esi>)sonuçları EBXve yİçerideESIve@<^12.4>Düğme konumunun, ölçüm ve oranla adlandırılması. __userpurgeAynı sayfa listesi.__spoilsÇıkartılmış takım için, __hidden- Evet .__return_ptrve__struct_ptrBu ders, içeriksiz argümanlar için el ile geri kazanılır.__usercallIDA Free sadece x86 ve x86-64'i destekler.

Binary Ninja 6.0 "Krypton" (Vector 35, commercial, with a Free edition that decompiles x86, x86_64, ARMv7, and AArch64).A.Platform"biner ortamın yürütme ortamı ile ilgili tüm bilgileri içerir, esas olarak kullanılan arama sözleşmeleri, işletim sistemi ve mimari" ve liste linux-x86_64- Evet .windows-x86_64- Evet .linux-aarch64vemac-aarch64, her biri birdefault_calling_convention- A.CallingConvention- Evet .int_arg_regs- Evet .float_arg_regs- Evet .callee_saved_regs- Evet .caller_saved_regs- Evet .int_return_reg- Evet .high_int_return_reg- Evet .float_return_reg, ve bu dersdeki farklılıkları doğrudan kodlayan iki bayrak:arg_regs_share_index, "Doğru olduğunda, Nth argümanı, türünden bağımsız olarak hem tam sayı hem de akışlı kayıt listelerinin Nth boşluğunu tüketir" ve stack_reserved_for_arg_regs, "Windows x64 çağrı konvansiyonu tarafından kullanılan gölge/ev alanı". eligible_for_heuristics- Evet .required_arg_regsverequired_clobbered_regsPlatform türleri C başlıkları altında types/platform/, platform adı başına bir tane.

radare2 6.2.4 (LGPL-3.0, run here). afclmimarlık eklentisi bildiği konvansiyonları listeler: amd64 amd64syscall dlang golang golang_abi0 ms p9 reg swiftx86-64 ve içinarm64 dlang golang p9 reg swiftAArch64 için.afcmevcut fonksiyonun konvansiyonunu bildirir. afcrParmak izicc.amd64.arg0: rdi- Evet .arg5: r9ve ret0: rax, ve profiller SDB dosyaları olarak adlandırılır cc-ARCH-BITS.sdbRadar seçildi .amd64ELF nesnesi için ve msCOFF nesnesi için doğru bölünme. afvargüman ve değişkenlerin listelerini yapar ve afsLinux'ta bir imza yazdırırır.-O2nesneafvYedi argüman bulmuştum .eight_argsve düştü .rcx; bulduğu Windows nesnesinde rcx, rdx, r8Ve dört yığın yuvası ve düştü .r9İkisi de sadece bir kartın içinde görünmektedir .lea- Evet .mixedrapor etti .double arg1 @ xmm0, arg2 @ xmm1, arg3 @ xmm2Linux'ta ve Windows'ta hiçbir argüman yok.x0- ...x7içineight_argsve içinbig_ret- Listede .x0ve double arg2 @ d1fonksiyonun okuduğu yer x8ve sabit yükler q1Her zaman .afsİmza , void, çünkü geri dönüş türü çıkarılmamıştır.-O0, her argüman çerçeveye kaydedildiği,afvTüm sekiz argümanı buldum .eight_args- Evet .rbp+0x10ve rbp+0x18- Yüklü çift için.

rizin 0.9.1 (LGPL-3.0, run here) and Cutter 2.5.0. afcllisteleramd64 amd64syscall ms reg swift- Evet .afcGeri döndü .amd64COFF nesnesi için, Microsoft profili var ve biçimden seçilmedi. afieight_argsLinux'ta, yine olmadan rcx, ve Windows ' ta r8, rcx, rdxÜç tane yığın boşluğu ile, r9ve boşluk olmadan 0x40- Evet .afvvar değil; listelenme komutası afvlCutter, Rizin'in grafik ön ucudur.

angr 10.0.3 (BSD-2, run here). CFGFastArdından CompleteCallingConventions(recover_variables=True)takımlar function.calling_convention- ...SimCCSystemVAMD64- Evet .SimCCMicrosoftAMD64veyaSimCCAArch64, ikili biçimle ve function.prototypeBu, tüm sekiz argümanı geri aldı.eight_argsÜç hedefin de gizli işaretçisi.big_retx86-64'te.(BOT*, long long) -> BOT*, Windows'un yan referans yapıları by_value- Evet .(BOT*, BOT*) -> BOT*, ve Sistem V varyadı sum_varargs- Evet .(long long, ...)Radar'ın boşlukları radarlardan farklıdır.mixedGeri döndüğümde(long long, long long, double, float)Sistem V ve AArch64'te, doğru kayıtlar yanlış sırada yazılır, çünkü tam sayılar listesi yüzen listeden önce basılır; AArch64 big_retGeri döndüğümde(long long) -> double, yani x8Toplantı kaçırıldı ve bu nedenle vektör depoları okundu; ve AArch64 sum_varargs16 parametreyle geri döndüm, tüm kayıt alanı kurtarıldı.

Others.Hopper 6.6.0 macOS ve Linux için ticari bir parçacık ve parçacık; bu ders için konvansiyon işleme çalıştırılmamış veya belgelemiş değildir.frame infove register readDüzeltme Eksplorörü, üç listeni kaynağın yanında gösterir, bu da bir kuralı baytlar olarak arama yapmadan önce onaylamanın en hızlı yoludur.

ConceptGhidraIDABinary Ninjaradare2 / rizinangrthis lesson
The convention objectprototype in a .cspeccalling convention keyword in the function typeCallingConvention on a Platformafc name, cc-ARCH-BITS.sdbSimCC subclassexpected_locations(abi, name)
Default per target<default_proto> per cspeccompiler settingPlatform.default_calling_conventionafc=, anal.ccby formatdescribe_object()
Argument registers<pentry> list, <group> for positional@<reg> in __usercallint_arg_regs, float_arg_regs, arg_regs_share_indexcc.NAME.argNARG_REGS, FP_ARG_REGSINT_ARG_REGS, FLOAT_ARG_REGS
Shadow storelocalrange stack 8 to 39implicitstack_reserved_for_arg_regscc.ms.argn=stackSTACKARG_SP_DIFFSTACK_ARG_BASE[WIN64] = 40
Hidden result pointerhidden_return, storage="hiddenret"__return_ptr, __hiddenreturn type too large for int_return_regnot modelledBOT* first argumentHIDDEN_RETURN_REG
Callee-saved<unaffected>__spoils lists the oppositecallee_saved_regsprofileCALLEE_CLEANUP and archCALLEE_SAVED
Assigning one to a function"Call Convention ID" analyzer, "Establish Function's Prototype"user or type libraryheuristic detection with required_arg_regsafc, afva, aaftCallingConventionAnalysisread-before-write plus the rulebook

Yapın

Demo çalıştır:

bashcd phases/13-tools-and-protocols/38-calling-conventions-and-stack-frames
python3 code/main.py

Çıktı bir JSON raporu. Yedi nesnenin her biri için format, makine ve ABI adını verir ve on iki işlevin her biri için prolog baytları, giriş karşılığı olan kaydedilen kayıtları, çerçeve boyutu, çerçeve işaretçisi, parametreler kayıtları, yığın argüman karşılığı, dökümler, geri dönüş kayıtları veya gizli işaretçi, arama derinlikleri ve arama yapanların çıkış kayıtları ve depoları verir. Her işlev kontrolleriyle sona erer: kural, imzadan beklenen değer, baytlardan gözlemlenen değer ve uyumlu olup olmadığını. Rapor iki atışlı çapraz kontrol ve araç çekimleriyle sona erer. 84 fonksiyon analizi boyunca 489 kontrol yürütülmüş ve 489'u da aynı fikirdeydi.

Beklenen şekil:

json{
  "objects": {
    "convention-x86_64-windows-O2": {
      "format": "COFF", "machine": "AMD64", "abi": "Microsoft x64", "checks": "73/73 agree",
      "functions": {
        "keeps": {
          "prologue": ["56  pushq %rsi", "57  pushq %rdi", "53  pushq %rbx", "48 83 ec 20  subq $0x20, %rsp"],
          "frameBytes": 56,
          "savedRegisters": [{"register": "rsi", "entryOffset": -8}, {"register": "rdi", "entryOffset": -16}, {"register": "rbx", "entryOffset": -24}],
          "parameterRegisters": ["rcx"],
          "returnRegisters": ["rax"],
          "calls": [{"callee": "ext", "depth": 56}],
          "checks": [{"rule": "Microsoft x64: the caller must always allocate ...", "expected": "at least 32 bytes ...", "observed": [56], "agree": true}, "..."]
        }
      }
    }
  },
  "sehCrossCheck": ["..."],
  "ehFrameCrossCheck": {"...": "..."}
}

Oku code/main.pyBu sırada:

  1. describe_object()ELF, COFF veya Mach-O başlığı ve simge tablosunu okuyor ve ABI ve fonksiyon listesini gönderir.
  2. parse_listing()bölüyor llvm-objdump -d -rmetinleri fonksiyonlara ayırır, her çağrı ve sıçrama için yer değiştirme hedefini tutar ve doğru sözcük anlamının işaretçisi ile yorumları siler: #AT&T için, //ve ;AArch64 için,#Hemen bir önlem verildi.
  3. effect_x86()ve effect_arm()Bir talimatı oku, adres oku, yaz, yükleme, mağaza ve bir yığın işaretçi delta haline getir. AT&T'nin son operandı hedeftir; ilk AArch64 operandı mağazalarda, karşılaştırmalar ve şubeler hariç hedefdir. leaAdres okuyor ve hiçbir şey yüklemiyor.mov- Evet .cvtsi2sd- Evet .setcc, ve sıfır dilini .xor r, rBir çağrı bütün değişken setleri yazıyor.sperişim ve indekslenmeden sonra yük taşıyan bir şey olmadan önce.
  4. analyze_function()Bir kere vücudu ilk kez yürütür.retBu, yığın göstergesinin derinliğini giriş değerinin altında izler.disp(%rsp)Giriş oranı disp - depthve disp(%rbp)- Evet .frame_pointer + disp. Yazılmadan önce okunan argüman sınıfı kayıtlarını kaydeder, ABI'nin ilk yığın argümanının karşılaştırılmasına veya üstündeki yükleri, çerçeveye argüman kayıtlarını saklar, mevcut yığın göstergesi altında erişimi ve her çağrıda derinliği kaydeder.
  5. _return_registers()Bu nedenle, bir veri tabanı olarak okunan bir veri tabanı olarak okunan bir kişiyi öldürür.raxYaşarkenbig_retMicrosoft x64 altında,movq %rcx, %raxSonra da mağazaya kadar gider.(%rax)- Evet .
  6. expected_locations()C imzasına üç kural kitabı uyguluyor: İki Sistem V listesi sekizbayt sınıfları, Microsoft konum boşlukları yan referans yapılarıyla ve AAPCS64 saylayıcıları x816 byt'ten fazla sonuçlar için.
  7. run_checks()Bu iki şeyi karşılaştırır ve çerçeve kurallarını ekler: Kaydetmiş kayıtlar kaydedilmelidir.(rsp + 8) % 16 == 0veya sp % 16 == 0Her çağrıda 32 byte gölge, her Microsoft çağrısında Microsoft ve AAPCS64'te yığın göstergesi altında erişim yok ve en fazla 128 byte Sistem V'de ve yığın göstergesi ile giriş değerinde prologu yansıtan bir epilog.
  8. seh_cross_check()ve eh_frame_cross_check()Yapılan nesnelerin çıkış verilerini okuyun.-fno-asynchronous-unwind-tablesVe onu prolog analizine karşılaştır.

Üç emir daha var.python3 code/main.py analyze convention-x86_64-windows-O2 keepsBir fonksiyon yazdırır. python3 code/main.py object FILEBaşlıkta verdiği kararı yazdırıyor.python3 code/main.py sehÇizilmişleri yazdırırır UNWIND_INFOBir tane olan her fonksiyonun.

Kullan

Bu sırada, yeni bir nesne üzerinde analizörü kullan.

  1. Çık .python3 code/main.py object FILE.oEğer başlık ve yapı komutunuz anlaşmazlıklarda, durun; onlardan biri yanlış.
  2. Yakalamallvm-objdump -d -r FILE.oBir sonraki nesneyi okumak ve analiz çalıştırmak. Başlangıç bytesini ve kaydedilen kayıtları başka bir şeyden önce okuyun ve çerçeve boyutunu basmak ve sub- Evet .
  3. Parametre kayıtlarını ve kaynak imzanıza karşı yığınlıksal sıfırlamaları okuyun. İmzanın açıklamadığı bir kayıt, analizatörün bir argüman olarak yanlış anladığı gizli bir işaretçi, bir varyadik işaretçi veya bir çizim kayıtçısıdır. Son durum, etki tablosundaki bir hata. Bu talimat için genel bir kural ile düzeltin.
  4. Her biri üzerine kurulan kuralın adını verir, yani kontrol etmek için ilk şey kural, sonra baytlar, sonra analizör.
  5. Nesneye veri açıldığında, çapraz kontrolü yapın.
  6. Bir diğer araç kurulduğunda, çıkışını tam komutla yakalayın ve karşılaştırın. Eğer üç türeviniz varsa, eğer farklı ise, belirli bir kayıt ve belirli bir talimatınız var ve bu ders için bir bulgu.

İnteraktif Laboratuvar

Laboratuvar A: Bir talimat, üç etki

  • Evet .codeDizin, açık Python:
bashcd phases/13-tools-and-protocols/38-calling-conventions-and-stack-frames/code
python3 -q

Çık:

pythonfrom main import *
effect(Instruction(0, "48 8d 04 0a", "leaq", "(%rdx,%rcx), %rax"), SYSV)
effect(Instruction(0, "f2 0f 2a d7", "cvtsi2sd", "%edi, %xmm2"), SYSV)
effect(Instruction(0, "a9bd7bfd", "stp", "x29, x30, [sp, #-0x30]!"), AAPCS64)

Her çağrıdan önce beklediğiniz okumaları, adres okumaları, yazıları ve yığın deltalarını yazın.[sp, #-0x30]!- ...[sp], #0x30- Evet .ldpve delta ' nın hareketini izle .sp_delta- ...post_sp_delta- Evet .

Laboratuvar B: Kapı çerçevesini

pythoninfo, listing = load_fixture("convention-aarch64-linux-O2")
keeps = analyze_function("keeps", listing["keeps"], info.abi)
keeps.saved
keeps.frame_pointer
[c.to_dict() for c in frame_cells(keeps)]

Değişiklikleri yukarıdaki el kodlaması ile karşılaştırın.convention-arm64-macos-O2Ve aynı üç satır çalıştırın; kayıt -16'a taşınır ve dört kayıt altındadır.convention-x86_64-linux-O2-fpVe oku .savediçinkeeps: çerçeve işaretçisi geri döndü, ve bir de pushq %raxTek işi yapmak.(rsp + 8)Çağırışta 16'ın katı.

Laboratuvar C: Karışık üzerinde okuma-yazmadan önce

pythoninfo, listing = load_fixture("convention-x86_64-linux-O2")
mixed = analyze_function("mixed", listing["mixed"], info.abi)
mixed.param_registers
mixed.return_registers
expected_locations(SYSV, "mixed")["parameters"]
expected_locations(WIN64, "mixed")["parameters"]

Sistem V listesi rdi, xmm0, rsi, xmm1ve Microsoft listesi rcx, xmm1, r8, xmm3Şimdi Windows nesnesini yükle ve ilk üç satırı tekrar çalıştır.[afv mixed]Üçüncüyi açıklayan talimatı bul.

Laboratuvar D: Windler'in ikinci görüşü

pythonfor row in seh_cross_check():
    print(row["function"], row["sizeOfProlog"], row["unwindPushes"], row["unwindAllocBytes"], row["agree"])
for row in eh_frame_cross_check("convention-x86_64-linux-O2-eh"):
    print(row["function"], row["cfiSaved"], row["cfiMaxOffset"], row["deepestStack"], row["agree"])

Bul .pushq %raxsum_varargsSEH tablosunda, neden bu kodun bir tahsis olarak kaydedildiğini açıklayın.call8- ... ....eh_frame- 32'yi açıkla.

Pratik Laboratuvar

Dördüncü hedefi ve dördüncü kural kitabı ekleyin.

Gereksinimler:

  • Yapıştır convention.c- Evet .-target x86_64-apple-macos -O2- Ve listesini yakalayalım.describe_object()Mak-O'yu okumak için .cputype0x01000007 ve sistem V psABI'ye haritasını yaptırmak, Apple'ın x86-64'te takip ettiği_Simge önlüğü.
  • Her fonksiyonun Sistem V kontrolleriyle uyumlu olduğunu kontrol edin.
  • Bir ekle-fstack-protector-strongLinux x86-64 nesnesini oluşturun.%fs:0x28Ve yerliler altındaki mağazalar bir canaryhücre ve önceki karşılaştırmaretBu, epilog'u koruyan çek gibi.
  • Bir kanarya mağazası dökülen bir tartışmaya sayıldığında başarısız olan bir test ekleyin.
  • Çerçeveyi yaz with_canary- analizörü çalıştırmadan önce kodun şeklini elden yapın ve çizimi testin yanında tutun.

Başarılı olmak demektir .python3 code/main.pyher kontrolün onayıyla yeni nesneyi rapor eder ve korunan fonksiyonun çerçeve hücreleri yerel halk ile kaydedilen kayıtlar arasındaki kanarya gösterir.

Ders Artifakti

Bu ders de içerir .outputs/skill-calling-conventions-and-stack-frames.mdBu, oluşturduğunuz bir nesneyi, listesini ve C imzalarını parametre konumlarına, çerçeve düzenine, geri dönüş kayıtlarına ve kompilire dayanan kurallara ve çözülme verilerine karşı her sonucu kontrol etmek için kullanır.cvtsi2sdveya xor r, rAmacın ne olduğunu ve ilk anlaşmazlıkla sona ermesini.

Kontrol et

Demo ve Deterministik Suite'i çalıştır:

bashcd phases/13-tools-and-protocols/38-calling-conventions-and-stack-frames
python3 code/main.py
python3 -m unittest discover -s code/tests -v

Verifikasyon, şunu kanıtlamalıdır:

  • Yedi nesnenin isimleri System V, Microsoft x64, AAPCS64 ve Apple arm64'in ELF, COFF ve Mach-O başlıkları
  • Her nesnenin simge tablosunda Mach-O ile aynı on iki fonksiyon listelenir._Önbellek ve ltmp0Etiket çözülmüş
  • listesi analiz eden kişi tutar extArama hedefi olarak AArch64'i hemen tutarak,#-0x30sağlam
  • leaq (%rdx,%rcx), %raxİki adres kayıtlarını okuyor ve hiçbir şey yüklemiyor .xorl %eax, %eaxve cvtsi2sdSadece yazılıdır; önceden indekslenmişstpHareketlerspMağazadan önce ve indekslenmeden sonra.ldpyüklenmeden sonra
  • keeps- ...-O2- Evet .55 41 56 53Sistem V'de 24 baytlı bir çerçeve ve çerçeve göstergesi yoktur. 56 57 53 48 83 ec 20Microsoft x64'te 56 baytlı bir çerçeve ile ve a9bd7bfd-48'e kadar rekorla ilk AArch64'de.
  • Apple'ın yapımı kayıtları -16'a 4 kaydedilen kayıtların üstünde yerleştirir.
  • Her fonksiyonun bir çerçeve göstergesi vardır.-O0Linux ' da hiç .-O2ve-fno-omit-frame-pointerBir düzeltme baskı ile geri getirir.
  • -O0yaprak sistem V'de 8 byte kırmızı bölge kullanıyor.pushq %raxMicrosoft x64 altında ve sub sp, sp, #0x10AAPCS64 çerçevesinde; -mno-red-zoneKırmızı bölge kullanımı kaldırılır
  • Her epilog başlıkını yansıtır ve yığın işaretçisi giriş noktasına geri döner.
  • eight_args6 kayıt ve 8 ve 16 yuvarlakı, 4 kayıt ve 40 ila 64 yuvarlakı, veya x0- ...x7, her iki optimizasyon seviyesinde de
  • mixed- Evet .rdi, xmm0, rsi, xmm1Sistem V ve rcx, xmm1, r8, xmm3Microsoft x64 altında, xmm0Sonuç olarak her iki
  • 16 baytlı yapı, sistem V ve AAPCS64 altında iki kayıtta ve Microsoft x64 altında gizli bir işaretçinin arkasında referans olarak seyahat eder.
  • 32 baytlı yapı geçiyor rdi- Evet .rcxveyax8
  • Variadikal bir kalley okuyor .%al, evlerrdx, r8, r916, 24, 32, kurtarır x1- ...x7ve q0- ...q7, veya Apple ' da arayanın işaretçi yığını okuyor
  • Arayanlar beklenen kayıtları ayarlar, 7 ve 8'i 0 ve 8 veya 5 ile 8'e 32 ile 56, sıfırda saklar %alVariad çağrısı için, sonuç tampon adresini rdi- Evet .rcxveyax8
  • 489 kontrol kendi kurallarına uymuştur.
  • Altı .UNWIND_INFOGirişler öncü parse ile eşleşir ve yapraklar hiç
  • 24 FDE'nin kaydedilen kayıtların karşılığı ve en derin yığın göstergesi ile eşleşmesi
  • Araç kayıtlı radarları yakalar.amd64ve ms- Risin'in.amd64COFF nesnesinde, kayıp olan rcx, üç çift ve Angr'ın prototipleri
  • Sit modülüne yerleştirilen rakam verileri analizatörün çıkışına eşit

Üretim Başarısızlık Modları

FailureWhat the weak tool reportsWhat the analysis must prove
COFF object read as System Vrdi and rsi as arguments that the function never readsThe header says 0x8664; the convention is Microsoft x64
Register read only inside a leaSeven arguments for an eight-argument functionBase and index registers are reads
cvtsi2sd destination counted as a readA third double argument in xmm2The first write to xmm2 is a write; mixed has two SSE arguments
Positional slots read as sequencesxmm0 named as the double argument on WindowsSlot 1 is XMM1, slot 3 is XMM3
push rbp taken as a frame pointerA frame pointer in an -O2 function that uses rbp as an accumulatorOnly mov %rsp, %rbp after the push creates one
Red zone measured from the entry stack pointer216 bytes "below the stack pointer"128 bytes below the current stack pointer after an 88-byte sub
Shadow store treated as localsStack arguments at 8 to 32Microsoft stack arguments start at 40
lea treated as a loadA stack argument at 0x60(%rsp) in a variadic calleelea computes overflow_arg_area; it loads nothing
Hidden pointer read as a normal argumentbig_ret(void *, long long)The pointer is stored through and copied to rax, rax, or stays in x8
Deepest CFA compared with the prologue frameA mismatch on a caller that pushes outgoing argumentsCompare with the deepest stack pointer the body reaches
Convention asserted from the ISAamd64 for a COFF objectThe format picks the rulebook, then the ISA picks the registers
Prototype trusted from one toolThree doubles, or sixteen variadic parametersThe source signature or a second derivation must agree

İşlem Kuralı

İlk talimattan önce başlığı okuyun ve kural defterinin adını verin. Kaydettikleri her kayıt ve her argümanı giriş yığın göstergesinden bir sıfırda yerleştirin ve oraya yerleştiren kurallara ve kompilicinin aynı çerçeve için yazdığı çıkartma verilerine karşı kontrol edin.

Daha Fazla Okumak

This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.

Browse the complete course catalog or open this lesson on GitHub.