▣ Application Programming Interface(API)
- API는 OS가 App과 통신하기 위해서 제공하는 함수 모음
■ Win32 API
- 로우레벨 프로그래밍 인터페이스 → 향후 하이레벨 인터페이스로 개발됨
- 계층적 구조 : 프로그래머들에게는 프로그래밍하기에 친숙하지만, OS는 모든 호출이 상위계층을 거치므로 다소 성능이 저하됨
- 윈도우에서 핵심적인 Win32 API는 약2,000개
[Win32 인터페이스 DLL과 커널 컴포넌트와의 관계]
● Kernel API
- Based API라고도 불리움
- KERNEL32.DLL 모듈 안에 구현되어 있음
- GUI와 관련되지 않은 서비스들, 즉 파일I/O, 메모리 관리, 객체 관리, 프로세스와 스레드 관리 등
- NTDLL.DLL의 네이티브 API를 호출하여 다양한 서비스를 구현함
● Native API
- Window NT 시스템의 실질적인 인터페이스
- Win32 API는 네이티브 API에 상위 계층일 뿐
- 그래픽 관련 서비스를 포함하지 않음
- 메모리 관리자, I/O 시스템, 객체 관리자, 프로세스와 쓰레드 등에 직접 접근할 수 있는 인터페이스 제공(윈도우 커널에 대한 가장 직접적인 인터페이스)
- App 프로그램은 Win9x와 호환성을 유지하기 위해서 네이티브 API를 직접 호출하면 안됨
- NTDLL.DLL(user mode 호출자를 위한)과 NTOSKRNL.EXE(kernel mode 호출자를 위한)에서 익스포트된 함수들의 집합
- 네이티브 API 이름은 항상 Nt, Zw로 시작됨
∙ Nt 버전 API : 해당 API를 실질적으로 구현하는 함수
∙ Zw 버전 API : 시스템 콜 메커니즘이 수행되는 함수
#시스템 콜 메커님즘을 통해 커널 모드 API를 호출하는 이유?
→API를 커널 모드에서 호출한다는 것을 알려주기 위해서이다.
이런 구분 없이 API를 무작정 호출하면 자신이 유저 모드에서 호출되지는 커널 모드에서 호출되는 알 수 없게 된다. 유저 모드에서 커널 모드 API를 호출하면 유저 모드에서 호출했다고 판단해 유저 모드 주소를 포함하고 있는 모든 파라미터를 조사할 것이다. 이는 유저 모드에서 커널 메모리 주소를 전달함으로써 발생할 수 있는 시스템 충돌을 방지하기 위한 메커니즘이다.
● 시스템 콜 메커니즘
- 시스템 콜은 유저 모드에서 커널 모드 함수를 호출할 필요가 있을 때 발생
- 유저모드에서 커널 함수를 직접 호출하는 것은 불가능함(직접 호출이 가능하다면 보안상 위험이 발생할 수 있음)
프로세스가 특권 모드로 스위칭 → 특별한 CPU 명령(특별한 디스패치 루틴을 호출하게 명령)을 유저모드에서 호출 → 호출된 디스패치 루틴은 유저모드에서 요청한 특정 시스템 함수를 호출
- Window 2000 이후 메커니즘 변경됨
Window 2000 이하 버전 |
인터럽트 2E를 이용해서 커널 호출 |
Ntdll!ZwReadFile: 77f8c552 mov eax,0xa1 //eax 레지스터에 서비스 번호 로드 77f8c557 lea edx,[esp+0x4] //edx 레지스터에 커널모드 함수에 전달되는 첫번째 파라미터 주소 저장 77f8c55b int 2e //인터럽트 디스크립터 테이블(IDT)을 이용해서 해당 인터럽트 핸들러 호출 77f8c55d ret 0x24 |
Window 2003 server Window XP |
인터럽트 사용 안함 SYSENTER 명령어 사용 : 고성능 커널모드 스위칭 명령으로, SYSENTER_EIP_MSR이라는 특별한 MSR 레지스터에 저장된 주소를 호출함 |
Ntdll!ZwReadFile: 77f4302f mov eax,0xbf //eax 레지스터에 서비스 번호 로드 77f43034 mov edx,[0x7ffe0300] //0x7ffe0300 : SharedUserData!SystemCallStub함수 77f43039 call edx 77f4303b ret 0x24 ↓ [디스어셈블 코드] SharedUserData!SystemCallStub: 7ffe0300 mov edx,esp 7ffe0302 sysenter 7ffe0304 ret // 실제 실행되지 않음 |
● 시스템 콜 메커니즘
- 어떤 상태 정보도 저장하지 않음
- SystemCallStub함수를 호출해 OS가 현재의 유저모드 주소 정보를 스택에 저장하게 만듬(이렇게 해야 나중에 되돌아갈 주소를 알 수 있음)
- 커널에서의 작업이 완료되고 다시 유저모드로 되돌아갈 때 단순히 스택에 저장된 주소로 돌아감(따라서, 7ffe0304의 ret명령은 실제 실행되지 않음)
'Security > Reverse Engineering' 카테고리의 다른 글
[Reversing]Input and Output (0) | 2010.05.10 |
---|---|
[Reversing]실행 포멧 (0) | 2010.05.08 |
[Reversing]프로세스 동기화, 초기화 과정 (0) | 2010.05.04 |
[Reversing]프로세스와 쓰레드 (0) | 2010.05.04 |
[Reversing]네임드 객체 (0) | 2010.05.03 |