본문 바로가기
Study/리버싱

RegFsNotify (1) 파일 시스템 변화 알림

by 꼬부기가우는소리 2016. 7. 7.
728x90


참고 도서 : [악성코드 분석가의 비법서 Malware Analyst's Cookbook and DVD]

저자 : 마이클 할레 라이, 스티븐 어드에어, 블레이크 할스타인, 매튜 리차드

출판사 : 에이콘


참고 사이트 :

- [위키백과] 콜백

- [Joinc] winapi



알림 기반 도구는 콜백 함수를 틍록해 파일 시스템의 변화를 탐지한다. 콜백 함수는 감시하고 있는 디렉터리에 있는 파일을 임의의 프로세스가 변화시킨 경우 윈도우가 실행하는 개발자 정의 액션 (Programmer-defined action)이다.




  CallBack

프로그래밍에서 콜백(callback)은 다른 코드의 인수로서 넘겨주는 실행 가능한 코드를 말한다. 콜백을 넘겨받는 코드는 이 콜백을 필요에 따라 즉시 실행할 수도 있고, 아니면 나중에 실행할 수도 있다.


일반적으로 콜백수신 코드로 콜백 코드(함수)를 전달할 때는 콜백 함수의 포인터 (핸들), 서브루틴 또는 람다함수의 형태로 넘겨준다. 콜백수신 코드는 실행하는 동안에 넘겨받은 콜백 코드를 필요에 따라 호출하고 다른 작업을 실행하는 경우도 있다. 다른 방식으로는 콜백수신 코드는 넘겨받은 콜백 함수를 '핸들러'로서 등록하고, 콜백수신 함수의 동작 중 어떠한 반응의 일부로서 나중에 호출할 때 사용할 수도 있다 (비동기 콜백). 콜백은 폴리모피즘과 제네릭프로그래밍의 단순화된 대체 수법이며, 콜백 수신 함수의 정확한 동작은 콜백 함수에 의해 바뀐다. 콜백은 코드 재사용을 할 때 유용하다.

 



파일 시스템 변화 알림

변화 알림 등록 하려면 윈도우 API 함수가 필요하다.


(1) FindFirstChangeNotification

(2) FindNextChangeNotification

(3) ReadDirectoryChagnesW




  WINAPI

현대적인 운영체제는 응용 프로그램이 직접 하드웨어에 접근하지 못하도록 한다. 이를 위해서 유저 모드와 커널 모드의 두개의 실행 모드를 가진다. 하드웨어에 대한 직접적인 접근은 커널 모드에서 이루어지는데, 이는 오직 커널만이 진입할 수 있는 영역이다. 응용 프로그램은 유저 모드에서 움직인다. 그러므로 일반적인 방법으로는 하드웨어에 대한 직접적인 접근이 불가능 하다.


대신 커널은 응용 프로그램에서 호출할 수 있는 API를 제공한다. 응용 프로그램은 커널이 제공하는 API로 하드웨어에 대한 접근이 가능하다. 응용 프로그램으로 하여금 "이러이러한 자원을 사용하겠습니다" 라고 커널에게 요청하도록 도와주는 일을 한다.


이러한 API를 리눅스(:12)에서는 시스템콜(:12)이라고 부르고 윈도에서는 win api라고 부른다. 16비트 윈도 운영체제에서 제공하는 API는 win16 api, 32비트 운영체제(:12)에서 제공하는 API는 win32 api라고 부른다.

 



HANDLE WINAPI FindFirstChangeNotification (

__in_ LPCTSTR lpPathName,

__in_ BOOL bWatchSubtree,

  __in_ DWORD dwNotifyFilter

);


함수가 성공적으로 실행되면 핸들을 반환한다.


- lpPathName : 모니터링 할 디렉터리 경로, 감시하려는 디렉터리 이름

- bWatchSubtree : 재귀적인 모니터링 여부, 하위 디렉터리의 변화에 대한 감시 여부를 정의

- dwNotifyFilter : 매개변수 값 목록, 받고자 하는 알림 유형을 나타내는 값


값 

설명 

  FILE_NOTIFY_CHANGE_FILE_NAME 

  파일 이름이 변경되거나, 파일이 생성 또는 삭제된 경우 알림 

  FILE_NOTIFY_CHANGE_DIR_NAME 

  디렉터리가 생성되거나 삭제된 경우 알림 

  FILE_NOTIFY_CHANGE_ATTRIBUTES 

  지정된 디렉터리의 파일 속성이 변경된 경우 알림 

  FILE_NOTIFY_CHANGE_LAST_WRITE 

  지정된 디렉터리에 있는 파일의 마지막 작성 시간이 변경된 경우 알림 

  FILE_NOTIFY_CHANGE_LAST_ACCESS 

  지정된 디렉터리에 있는 파일의 마지막 접근 시간이 변경된 경우 알림 

  FILE_NOTIFY_CHANGE_CREATION 

  지정된 디렉터리에 있는 파일의 생성 시간이 변경된 경우 알림 

  FILE_NOTIFY_CHANGE_SECURITY 

  지정된 디렉터리의 보안 디스크립터 (descriptor)가 변경된 경우 알림 

  FILE_NOTIFY_CHANGE_SIZE 

  지정된 디렉터리에 있는 파일의 크기가 변경된  


다른 필터를 사용해 다수의 디렉터리에 대한 알림을 등록할 수 있다. 이 경우 FindFirstChangeNotification을 두 번 호출한 후 반환된 핸들의 배열을 WaitForMultipleObject로 넘기면 된다. 이런 방식은 프로세스가 두 알림 중 하나가 발생하기 전까지 프로그램이 기다리게 한다. 대기 중인 함수가 반환되면 ReadDirectoryChangesW를 사용해 변화에 대한 상세 정보를 수집할 수 있다.



BOOL WINAPI ReadDirectoryChangesW (

__in HANDLE hDirectory,     // 관할 (감시하고 있는) 디렉터리 핸들 열기

__out LPVOID lpBuffer,       // 결과 버퍼

__in DWORD nBufferLength,  // lpBuffer 길이

__in BOOL bWatchSubtree,    // 재귀적인 모니터링 여부

__in DWORD dwNotifyFilter,  

__out_opt LPDWORD lpBytesReturned,  // lpBuffer에 써진 바이트 크기

__inout_opt LPOVERLAPPED lpOverlapped,  // 덮어쓰기 모드에 필요

__in_opt LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

);


출력되는 결과의 구조는 아래와 같다.


typedef struct _FILE_NOTIFY_INFORMATION {

DWORD NextEntryOffset;     // 다음 구조체의 오프셋

DWORD Action;                 // 액션 (수정, 삭제, 생성 등)

DWORD FileNameLength;     // FileName 배열의 바이트 수

WCHAR FileName[1];           // 파일/디렉터리 이름을 위한 버퍼 크기의 변수

} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;


변화를 보고하려면 구조체 배열을 순환해 Action과 FileName 필드를 출력한다.




728x90

'Study > 리버싱' 카테고리의 다른 글

RegFsNotify (2) 레지스트리 변화 알림  (0) 2016.07.07
Registry  (0) 2016.07.06
PE Structure (3) DLL  (0) 2016.06.29
PE Structure (2) PE 헤더  (1) 2016.06.29
PE Structure (1) PE 포맷  (0) 2016.06.19

댓글