일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- initial-exec
- LLVM 난독화
- v8 tracing
- 난독화
- pthread
- tracerpid
- Obfuscator
- Linux packer
- Linux custom packer
- android inject
- on-stack replacement
- v8 optimizing
- on stack replacement
- pinpoint
- anti debugging
- custom packer
- 안티디버깅
- uftrace
- OSR
- thread local storage
- LLVM Obfuscator
- LLVM
- so inject
- tracing
- linux debugging
- TLS
- apm
- linux thread
- Injection
- Android
Archives
- Today
- Total
Why should I know this?
SystemCall 직접 박아넣기 본문
여러가지 이유(?)로 SystemCall를 직접 하는 경우가 존재합니다.
해서 이번 글에서는 간단히 SystemCall을 직접하는 방법을 알아볼까 합니다.
/*
* Generic syscall call.
* Upon entry:
* %rax: system call number
* %rdi: arg0 to system call
* %rsi: arg1
* %rdx: arg2
* %rcx: arg3 - syscall expects it at %r10
* %r8: arg4
* %r9: arg5
*/
#include "arch/bionic_asm.h"
ENTRY_PRIVATE(syscall)
# All arguments are passed via registers.
# (Not all will be valid, depending on the syscall.)
mov %edi, %eax
mov %rsi, %rdi
mov %rdx, %rsi
mov %rcx, %rdx
mov %r8, %r10
mov %r9, %r8
mov 8(%rsp), %r9
# Make the system call.
syscall
cmpq $-MAX_ERRNO, %rax
jb 1f
negl %eax
movl %eax, %edi
call __set_errno_internal
1:
ret
END(syscall)
SystemCall 에 관련된 코드는 모두 Android에서 퍼왔습니다.
#define K_openat 257
int k_open(const char *__path, int __flags, ...) {
va_list arg;
int fd, root;
root = open("/", O_RDONLY);
if (__path[1] == '\x00' && __path[0] == '/')
return root;
if (__flags & O_CREAT) {
va_start(arg, __flags);
mode_t mode = va_arg(arg, mode_t);
fd = syscall(K_openat, root, __path, __flags, mode);
if (fd < 0) {
LOGVVV("syscall failed %s %x %o", __path, __flags, mode);
fd = open(__path, __flags, mode);
}
} else {
fd = syscall(K_openat, root, __path, __flags);
if (fd < 0) {
LOGVVV("syscall failed %s %x", __path, __flags);
fd = open(__path, __flags);
}
}
return fd;
}
SystemCall Table의 순서는 아키텍쳐마다 다릅니다.
위 함수는 시스템 콜을 직접하는 open의 구현입니다.
openat을 사용한 이유는 open에 syscall을 직접하는걸 제한하는 아키텍쳐가 존재하기 때문입니다 (...)
위를 구현한 코드로 frida 로 hooking 테스트를 해봤습니다.
원래는 위에 libc.open 메시지도 안떠야겠지만 왜 계속 뜨냐면, syscall이 실패하면 -1을 리턴하는데 openat 도 open과 마찬가지로 -1을 리턴하기 때문입니다. 그래서 open이 실패한건지 syscall이 실패한건지 모르겠어서 안전성을 위해 실패한 경우 open을 한번더 호출하게 코드가 짜여져있죠. 그래서 위처럼 libc open 관련 메시지가 뜨는 겁니다.
이렇게 Syscall을 직접하게 되면 native 영역의 hooking에서 어느정도 자유로울 수 있다는 장점이 있습니다.
native 영역의 hooking은 검색하면 잔뜩 나오므로 따로 다루지는 않겠습니다.
- 끗 -
'Knowledge > Android' 카테고리의 다른 글
AOSP build 후 Linux에서 dex 실행 해보기 (0) | 2022.12.28 |
---|---|
Android Hooking - Java layer 편 #1 (3) | 2022.12.07 |
Dexopt, Dex2oat 실행 옵션 (0) | 2020.03.15 |
ARMv7 에서 Cacheflush를 사용할 때 주의점 (0) | 2020.02.22 |
Android 보안솔루션의 기법 깨기 (8) | 2019.02.22 |
Comments