2017. 5. 12. 23:56 악성코드 분석

API Sets



1. 개요

  윈도우 7부터는 MinWin 즉 Minimal Windows kernel라는 개념을 통해 커널에 변화가 생겼다. 과거부터 발전되어 감에 따라 그리고 동시에 하위호환을 만족시켜야 함에 따라 kernel32.dll이나 advapi32.dll 같은 DLL은 수 많은 API들을 포함함으로써 크기나 성능, 구조적으로 경제적이지 않게 되었다. 이에 따라 이러한 DLL들을 기능 및 목적에 따라 재구성할 필요가 생긴 것이다.





2. Virtual DLL과 Logical DLL

  예를들어 최신 VC++로 개발한 애플리케이션을 분석해보면 과거와 달리 api-ms-win-crt-heap-l1-1-0.dll 같은 api-ms-win으로 시작하는 DLL들이 보인다. 이러한 DLL들을 Virtual DLL이라고 하며 실제 kernel32.dll이나 advapi32.dll 같은 DLL들을 Logical DLL이라고 한다. 이런식으로 함수들이 기능 및 목적에 따라 각각의 Virtual DLL들로 재구성되어 있다. 실질적으로 Virtual DLL은 실제 함수 루틴이 존재하는 Logical DLL에 대한 스텁 DLL이라고 할 수 있다. api-ms-win-crt로 시작하는 것들은 CRT 라이브러리들의 Virtual DLL이고 또 다른 종류로는 api-ms-win-core로 시작하는 것들이 있는데 이것은 뒤에서 보겠지만 kernelbase.dll 등으로 매핑된다. 


  이렇게 Virtual DLL만 만들어진 것이 아니라 Logical DLL 즉, 실제 시스템 DLL들에 대해서도 변화가 생겼다. 첫 번째는 kernelbase.dll과 sechost.dll인데 kernelbase.dll은 kernel32.dll과 advapi32.dll의 api들 중에서 필요한 부분을 가져온 것이다. 정확히 말하자면 kernelbase.dll은 MinWin을 위한 핵심 서비스를 제공하는 함수들이 포함된 라이브러리이다. 즉 kernel32.dll과 advapi32.dll 같은 무겁고 큰 라이브러리 대신 필요한 핵심 함수들만 제공하는 이 kernelbase.dll만으로 MinWin을 지원할 수 있는 것이다. 참고로 이렇게 가져온 함수들은 kernel32.dll이나 advapi32.dll에서도 여전히 호출할 수 있다. 실제 구현은 kernelbase.dll에 존재하지만 똑같은 이름의 함수가 존재하며 내부적으로 간단한 처리를 거쳐서 kernelbase.dll에 존재하는 함수를 호출하기 때문이다. 이에 따라 레거시 애플리케이션은 계속 kernel32.dll 등의 함수를 호출할 수 있고 최근 VC++로 만들어진 애플리케이션은 직접 kernelbase.dll의 함수를 호출할 것이다. 물론 더 자세히 해보자면 애플리케이션은 api-ms-win-core 같은 Virtual DLL을 임포트할 것이고 앞의 과정을 통해 결국 kernelbase.dll 내부의 함수를 호출할 것이다. 참고로 sechost.dll에는 advapi32.dll 중에서 kernelbase.dll로 이동한 함수들을 제외한 다른 함수들이 이동되어 있다.


  다른 하나는 CRT 라이브러리이다. msvcrt.dll 같은 CRT 라이브러리는 두 개로 나뉘어 졌다. 하나는 vcruntime140.dll로써 프로세스 스타트업이나 예외 핸들링 같은 컴파일러 지원에 요구되는 기능들(함수들)이 존재한다. 다른 하나는 ucrtbase.dll로써 이것은 범용 CRT 즉 순수한 CRT 라이브러리이다. 예를들면 api-ms-win-crt-stdio나 api-ms-win-crt-math 같은 Virtual DLL들이 이것과 매핑된 것이다. 일반적으로 PEview로 보면 vcruntime140.dll은 그대로 보이지만 ucrtbase.dll은 보이지 않고 api-ms-win-crt를 접두사로 갖는 Virtual DLL들만 보일 것이다. 물론 내부적으로 이런 Virtual DLL들은 ucrtbase.dll의 함수를 호출하게 된다.


  정리해 보자면 특정 DLL들의 구조가 Virtual DLL과 Logical DLL로 나뉘게 되었다. Logical DLL은 실제 함수 루틴이 존재하는, 과거부터 있어왔던 DLL들이지만 변화가 생겼는데 kernelbase.dll이 만들어 졌으며 이것은 kernel32.dll과 advapi32.dll의 함수들 중에서 필요한 부분을 가져와서 만들었다. 이 외에도 sechostd.dll도 만들어 졌다. 물론 레거시 애플리케이션을 위해 이 두 DLL에서도 kernelbase.dll로 이동한 함수들을 호출할 수 있는데 같은 이름의 스텁 함수가 존재해서 내부적으로 실제 함수 루틴이 존재하는 kernelbase.dll의 함수를 호출해 주기 때문이다. 이 외에도 CRT 라이브러리에도 변화가 생겼다. vcruntime140.dll과 ucrtbase.dll로 나뉜 것이다. 


  올리디버거로 api들을 분석해 보면 어느 DLL에서 함수 루틴이 진행되는지를 직접 확인할 수 있다. Virtual DLL은 PEview 같은 도구를 통해 임포트 테이블을 확인하면 차이점을 발견할 수 있을 것이다. 확인해 보면 애플리케이션이 익숙치 않은 api-ms-win으로 시작하는 DLL들의 함수들을 임포트하는 것을 볼 수 있다. 이 Virtual DLL들은 실제로는 Logical DLL을 호출한다. 예를들면 api-ms-win-crt-runtime-l1-1-0.dll의 _initterm_e 함수를 호출할 경우 실제로는 ucrtbase.dll의 _iinitterm_e를 호출하게 된다.





3. 원리

  여기서는 Virtual DLL과 Logical DLL이 어떻게 매핑되는지를 알아본다. 부팅 과정 중에 ApiSetSchema.dll이 로드되며 이 DLL의 .apiset 섹션 내의 데이터가 메모리에 로드된다. 이후 이 DLL은 언로드되고 데이터는 PEB의 ApiSetMap에 매핑된다. 이제 DLL을 로드하게 된다면 LoadLibrary() 내부에서 PEB에 저장된 ApiSetMap 구조체를 참조해서 Virtual DLL의 이름을 Logical DLL의 이름으로 리다이렉트 시킨다.





4. 분류

  참고로 아래에서 kernel32.dll 및 advapi32.dll로 설명한 것은 kernelbase.dll도 포함하며 advapi32.dll로 설명한 것은 sechost.dll도 포함할 수 있다. 자주 볼 수 있는 것들 위주로 정리한 것이며 이 외에도 다수 존재한다.


- API-MS-Win-Core : 대부분 kernel32.dll의 함수들이며 advapi32.dll도 약간 존재한다.

- API-MS-Win-Security : kernel32.dll, advapi32.dll, sechost.dll의 함수들.

- API-MS-Win-Service : advapi32.dll 및 sechost.dll의 함수들

- API-MS-Win-CRT : ucrtbase.dll



'악성코드 분석' 카테고리의 다른 글

VC++ 옵션 정리  (0) 2017.06.03
다형성 바이러스  (4) 2017.05.16
윈도우의 예외 처리  (0) 2017.05.09
링크 및 책 정리  (0) 2017.04.23
윈도우의 드라이버 개발과 루트킷 그리고 AV  (0) 2017.04.23
Posted by SanseoLab

블로그 이미지
Malware Analyst
SanseoLab

태그목록

공지사항

Yesterday
Today
Total

달력

 « |  » 2024.3
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

최근에 올라온 글

최근에 달린 댓글

글 보관함