1. 헝가리안 표기법
윈도우는 일반적으로 API 함수 식별자로 헝가리안 표기법(Hungarian Notation)을 사용한다. 이 표기법은 변수 탑입을 식별하기 용이하게 하는 접두사 명명 스키마(prefix naming scheme)를 이용한다. 32비트 unsigned 정수, DWORD를 가진 변수는 dw로 시작한다.
타입과 접두사 | 설명 | |
WORD (w) | 16비트 unsigned 값 | |
DWORD (dw) | 더블 WORD, 32비트 unsigned 값 | |
Handles (H) | 객체 레퍼런스. 핸들에 저장된 정보는 문서화돼 있지 않으며 윈도우 API에 의해서만 조작될 수 있다. 대표적인 예로 HModule, HInstance, HKey를 들 수 있다. | |
Long Pointer (LP) | 다른 유형을 가리키는 포인터. 예를 들어 LPByte는 바이트를 가리키는 포인터고, LPCSTR은 문자열을 가리키는 포인터다. 문자열은 실제 포인터이기 때문에 보통 LP 접두사를 가진다. 32비트 시스템에서 포인터 (P)....로 시작되는 다른 타입을 자주 보게 되는데, 이는 LP와 동일하다. 16비트 시스템에서는 이 차이가 의미를 지닌다. | |
Callback | 윈도우 API가 호출하는 함수를 나타낸다. 예를 들어 InternelSetStatusCallback 함수는 시스템이 인터넷 상태를 업데이트할 때마다 호출하는 함수를 가리키는 포인터를 넘겨준다. |
2. 핸들
핸들(Handle)은 윈도우, 프로세스, 모듈, 메뉴, 파일 등과 같이 운영체제에서 오픈되거나 생성된다. 핸들은 객체나 메모리 위치를 참조한다는 점에서 포인터와 같다. 하지만 일반적인 포인트와 달리 핸들은 산술 연산에 사용하지 않고 항상 객체의 주소를 의미하지는 않는다. 핸들은 같은 객체를 참조하는 함수 호출 이후에만 저장되고 사용할 수 있다.
CreateWindowEx 함수는 간단한 핸들의 예제를 담고 있다. HWND를 반환하는 윈도우 핸들이다. DestoryWindow 호출과 같이 윈도우 관련 작업을 할 때마다 이 핸들을 사용할 필요가 있다.
3. 파일 시스템 함수
파일 행위를 통해 악성코드가 무엇을 하는지 감을 잡을 수 있다. 예를 들어 악성코드가 파일을 생성해 그 파일에 웹 브라우징 내용을 저장한다면 해당 악성코드는 아마 스파이웨어 형태일 것이다.
함수 | 설명 | |
CreateFile | 파일을 생성하고 열 때 사용한다. 기존 파일, 파이프, 스트림, I/O 장치를 열고 새로운 파일을 생성한다. dwCreationDisposition 인자는 CreateFile 함수가 새로운 파일을 생성하는지, 기존 파일을 오픈하는지 여부를 제어한다. | |
ReadFile / WriteFile | 파일을 읽고 쓰는 데 사용한다. 두 함수 모두 파일을 스트림 형태로 운영한다. 우선 ReadFile을 호출하면 파일에서 다음 몇 바이트를 읽고 다음번 호출에 그 다음 몇 바이트를 읽는다. 예를 들어 40바이트 크기로 ReadFile을 호출한다면 다음번 호출 때 41바이트부터 읽기 시작한다. | |
CreateFileMapping MapViewOfFile |
파일 매핑은 파일을 메모리로 로드해 쉽게 조작할 수 있게 해주기 때문에 주로 악성코드 제작자가 이용한다. CreateFileMapping 함수는 파일을 디스크에서 메모리로 로드한다. MapViewOfFile 함수는 매핑된 베이스 주소 포인터를 반환하는데, 메모리 내의 파일에 접근할 수 있다. 이런 함수를 호출하는 프로그램은 파일 내의 어디든 읽고 쓸 수 있는 MapViewOfFile에서 반환된 포인터를 사용할 수 있다. 이 기능은 다른 메모리 주소로 매우 간단히 점프할 수 있기 때문에 파일 포맷을 파싱할 때 아주 용이하다. * 파일 매핑은 윈도우 로더 기능을 복제할 때 주로 사용한다. 파일 맵을 획득한 후 악성코드는 PE 헤더를 파싱해 메모리 내의 파일에 필요한 부분을 변경할 수 있는데, 그렇게 함으로써 마치 OS 로더에 의해 로드된 것처럼 PE 파일을 실행할 수 있다. |
4. 윈도우 레지스트리
윈도우 레지스트리는 운영체제와 설정이나 옵션 같은 프로그램 구성 정보를 저장한다. 파일 시스템과 같이 악성코드 기능에 관한 호스트 기반의 좋은 표식자이며, 유용한 정보를 제공한다.
초기 버전의 윈도우는 구성 정보를 저장하기 위해 ini 파일을 사용했다. 레지스트리는 성능 향상을 목적으로 수직 구조의 정보 데이터베이스를 생성했고, 정보를 저장하는 애플리케이션 입장에서 그 중요성이 더해져 왔다. 네트워킹, 드라이버, 시작, 사용자 계정, 그리고 다른 정보 등 거의 모든 윈도우 구성 정보는 레지스트리에 저장한다.
레지스트리는 다음과 같은 다섯 개의 루트 키로 구성된다.
루트 키 | 설명 | |
HKEY_LOCAL_MACHINE (HKLM) |
시스템 전역 설정을 저장한다. | |
HKEY_CURRENT_USER (HKCU) |
현재 사용자에 특화된 설정을 저장한다. | |
HKEY_CLASSES_ROOT | 정의한 유형 정보를 저장한다. | |
HKEY_CURRENT_CONFIG | 현재 하드웨어 구성 설정, 특히 현재 설정과 표준 설정의 차이를 저장한다. | |
HKEY_USERS | 기본 사용자, 새로운 사용자, 현재 사용자의 설정을 정의한다. |
다음은 가장 빈번히 사용하는 레지스트리 함수다.
- RegOpenKeyEx : 편집과 질의용으로 레지스트리를 오픈한다. 이 함수는 먼저 레지스트리 키를 오픈하지 않고 질의하고 편집할 수 있게 하는데, 대다수 프로그램은 RegOpenKeyEx를 사용한다.
- RegSetValueEX : 레지스트리에 새로운 값을 추가하고 데이터를 설정한다.
- RegGetValue : 레지스트리 내의 값 엔트리용 데이터를 반환한다.
5. 네트워킹 API
악성코드는 일반적으로 악성 행위를 위해 네트워크 기능에 의존하며, 네트워크를 통신에 사용하는 수 많은 윈도우 API가 있다.
* 버클리 호환 소켓
윈도우 네트워크 옵션 중 악성코드는 버클리 호환 소켓(Berkeley Compatible Sockets)을 가장 자주 사용하는데, 윈도우와 유닉스 시스템에서 거의 동일한 기능을 가진다.
함수 | 설명 | |
sockey | 소켓을 생성한다. | |
bind | 호출 전에 소켓을 특정 포트로 할당한다. | |
listen | 소켓이 인바운드 연결을 위해 리스닝하고 있음을 나타낸다. | |
accept | 외부 소켓 연결을 오픈하고 연결을 받아들인다. | |
connect | 연결을 외부 소켓으로 오픈하고 외부 소켓은 연결을 기다린다. | |
recv | 외부 소켓에서 데이터를 받는다. | |
send | 외부 소켓으로 데이터를 보낸다. |
네트워크 라이브러리에 리소스를 할당하기 위해 다른 네트워크 함수가 수행되기 전에 WSAStartup 함수가 할당돼야 한다. 코드 디버깅을 수행하는 동안 네트워크 연결 시작점을 찾을 때 WSAStartup에 브레이크포인트를 설정하면 유용한데, 이는 바로 네트워크 기능이 시작되기 때문이다.
WinINet API
Winsock API 외에 WinINet API라 부르는 좀 더 상위 수준의 API가 있다. WinINet API 함수는 Wininet.dll에 저장돼 있다. 프로그램이 이 DLL에서 함수를 임포트한다면 상위 수준의 네트워크 API를 사용하는 것이다. WinINet API는 애플리케이션 계층에서 HTTP, FTP 같은 프로토콜을 구현한다.
- InternetOpen : 인터넷 연결을 초기화할 때 사용한다.
- InternetOpenUrl : URL에 연결할 때 사용한다(HTTP 페이지나 FTP 리소스에 사용할 수 있음).
- InternetReadFile : ReadFile 함수 같이 프로그램이 인터넷에서 다운로드한 파일에서 데이터를 읽을 수 있게 한다.
6. DLL
DLL(Dynamic Link Library)은 현재 윈도우에서 다양한 애플리케이션끼리 코드를 공유하는 라이브러리를 사용하는 방식이다. DLL은 그 자체로 실행할 수 없는 실헹 파일이지만, 다른 애플리케이션에 의해 사용할 익스포트 함수다.
DLL을 사용하는 주요 이점은 실행 중인 프로세스 간에 DLL이 사용하는 메모리를 공유할 수 있다는 점이다. 또 다른 이점은 실행 파일을 배포할 때 DLL을 재배포할 필요 없이 알려진 윈도우 시스템 호스트에 DLL을 사용할 수 있다는 점이다.
DLL 파일은 .exe 실행 파일과 거의 흡사하다. DLL은 PE 파일 포맷을 이용하며, 플래그 하나로 파일이 .exe가 아닌 DLL이라는 점을 명시한다. 메인 DLL 함수는 DllMain이다. 이름이 없고 DLL 내에 익스포트도 없지만, 파일의 진입점으로서 PE 헤더에 정의돼 있다. 프로세스가 라이브러리를 로드 또는 언로드하거나 새로운 스레드가 생성되거나 기존 스레드가 종료되는 시점을 알려주기 위해 매번 함수를 호출한다. 이 알림을 통해 DLL은 프로세스 단위나 스레드 단위의 리소스를 관리할 수 있다.
'정보보안 > Malware' 카테고리의 다른 글
[Malware] Flare VM을 이용한 악성코드 분석환경 구축 (0) | 2021.07.11 |
---|---|
[Reversing] 컴포넌트 객체 모델(COM) (0) | 2021.06.02 |
[Reversing] 윈도우 커널 모드와 사용자 모드 (0) | 2021.06.01 |
[Reversing] 윈도우 리버싱(프로세스, 스레드, 뮤턴트, 서비스) 개요 (0) | 2021.05.21 |
[Reversing] 어셈블리어 기본 명령어 (0) | 2021.05.13 |