Document Protector 완료 명세서Document Protector 완료 명세서

Posted at 2010.11.01 22:45 | Posted in Project/Document Protector
크리에이티브 커먼즈 라이선스
Creative Commons License

과 제 명

Document Protector

과제분야

System S/W

   

문서보안, 정보유출, DRM, DeviceDriver, WDM

과제기간

2010.05 ~ 2010.08 (4개월)

   

대구

참여인원

3


1. 과제 요약
 1.1 과제 개요
 기업의 기밀 문서 유출 사례에 대한 통계를 보면, 현 또는 전 직원의 매수에 의한 유출 사례가 가장 많은 분포를
차지하고 있다
.
따라서 본 프로젝트에서는 관리자의 모니터링을 통해서 내부 문서의 유통을 감시하여 문서의
유출 사례를 감소시키는 것이
목적이다
.

 1.2 과제 기능(시나리오)
  i. 사용자는 Document Protector Client를 통해 Server에 접속.
  ii. Client를 통해서만 접근 가능한 숨겨진 임시 폴더가 생성.
  iii. 문서 작성에 필요한 Process를 제외하고 모두 차단.
  iv Server와의 통신에 필요한 Port를 제외하고 모두 차단
  v. USB, CD-ROM과 같은 외부 기억장치 Driver를 모두 차단
  vi. 열람할 문서를 서버에서 다운받을 때 그 경로가 처음에 생성된 숨겨진 임시 폴더이기 때문에
      Document Protector Client를 통해서가 아니라면 접근이 불가능.
  vii. 문서는 암호화 되어서 Server에서 Client로 전송.
  viii. 새로운 문서를 작성하여 저장하면, 사용자가 지정한 저장 경로에 관계 없이 숨겨진 임시 폴더로 강제로
      변경되어서
저장.
  ix. Print screen Key를 누르면 이상행동으로 간주하고, 키보드와 마우스 입력이 모두 차단되고 즉시
      관리자에게 통보.

  x. 관리자는 차단된 사용자를 실시간으로 확인하고, 사용자의 요청에 의해 키보드와 마우스 입력 차단 수행.

 1.3 System Architecture


2. 과제 내용
 2.1 업무 분담
  ● 이희준 (PL)
      - Project Management
      - Document Access Restriction
      - Device Connection Sensing & Control
      - I/O Device Control

  ● 배태도
      - Port Control
      - Process Block

  ● 백종승
      - UI Design & Implement
      - Network Module
      - Network 암호화 구현

 2.2 사용 기술
  1) Document Access Restriction

 문서의 무단 유출을 막기 위해서 사용자가 문서에 접근을 하지 못하게 한다.
 그래서 프로그램 실행 시 사용자가 인지 못하게 임의의 폴더가 생성되고, 동시에 숨김 처리가 된다.
 그리고 문서를 서버로부터 다운받거나, 새로운 문서를 작성 후 저장할 때 숨김 처리 되어 있는 폴더로
강제로 경로를 바꾸어서 문서를 저장하게 끔 한다.
 따라서 외부 탐색기를 통해서는 사용자가 폴더 및 문서에 접근을 하지 못하도록 한다.
 단지 Document Protector 프로그램 내의 탐색기를 통해서만 숨김 처리된 폴더에 접근 가능할 수 있는
Minfilter Driver를 구현하였다.

 2) Device Connection Sensing & Control


 프로그램 실행 시 현재 컴퓨터에 연결되어 있는 장치를 감지하여, 키보드와 마우스를 제외한 USB, 외장HDD
등의 장치 연결을
제거한다. 그리고 프로그램 종료 전까지 USB, 외장HDD 등의 장치 연결을 제한 함으로서,
외부 장치를 통한 문서의 유출 시도를
막는 Minifilter Driver를 구현하였다.

 3) I/O Device Control
 키보드에서 기본적으로 Print Screen 키를 막으며, 사용자가 Print Screen 키를 누르게 되면 이상행동이라
간주하고 관리자에게
통보한다. 그리고 이를 통보 받은 관리자에 의해서 사용자는 키보드와 마우스의 사용을
제한 받을 수 있는
Keyboard/Mouse Filter Driver를 구현하였다.

 4) Driver & Application 비동기 이벤트 통신
 사용자가 이상행동을 하였을 때 이를 드라이버 단에서 감지하여 관리자에게 통보를 해주어야 한다.
 따라서 이를 구현하기 위해서는 "Driver → Application" 으로의 통신이 필요하다.
 이는 이벤트 객체를 공유하여서 비동기 통신을 하는 방법으로 가능하도록 하였다.

5) Port control

 Packet Hooking Driver에서 Callback함수로 TCP Packet을 받아 Filter 함수로 전달한다.
 TCP Packet이 가지고 있는 Destination Port가 차단할 Port와 일치하면 차단한다.

6) Process block


 Minifilter driver를 사용하여 Callback함수를 통해 Process의 생성과 종료를 감지한다.
 하지만 Process 파일명 만으로는 신뢰할 수 없다. 그래서 서로 다른 Process 실행 파일은
다른 Link 시간을 가질 것이므로, 이와 실행 파일의 크기를 XOR 한 값을 Process를
판별하는 기준으로 사용하면, 보다 정확한 판별이 가능하다.

7) Crypto Module

 Network를 통해 전송 중인 문서의 보안을 위하여 GPL 라이센스를 따르는 Polar SSL Library를 사용하였다.
 Open Source로 되어 있는 Library로 다양한 암호화 모듈을 제공하고, 암호화 과정에 대해서 자세히
알 수 있어서 유용하다.
 제공 되는 암호화 모듈 중에 AES / RSA / BigNum / SHA2 모듈을 사용하여
암호화를 진행 하였다.


3. 개발환경
[OS] Windows XP SP3
[Tool] Microsoft Visual Studio 2008 SP1, WinDBG, VMWare 7.0
[SDK] WDK & Windows XP DDK
[DB] MY-SQL
[Language] C(WDK), C++(MFC)

4. 참고문헌 및 자료
윈도우 디바이스 드라이버, 이봉석 저, 한빛미디어
윈도우 파일 시스템, 이병오 저
루트킷, 그렉 호글런드 저
WinDbg로 쉽게 배우는 Windows Debugging

http://www.hajesoft.com/ - 하제 소프트 홈페이지
http://www.kosr.org/ - 한국 시스템 프로그래밍 사이트
http://www.osronline.com/ OSR Online 사이트
http://www.devpia.com/ - 데브피아 개발자 포털 사이트
http://www.DriverOnline.com - 드라이버 온라인

5. 향후 발전 방향
 현재는 외부로 문서가 빠져나갈 수 없게 구현되어 있다. 그러나, 경우에 따라서 문서가 외부에서 필요한
경우가 생길 수도 있다.
 따라서 필요에 의해 외부로 반출되었을 경우에도 보안이 유지가 될 수 있게
파일 암호화를 사용하여 추가 기능 구현을 한다면
보다 완성도 높은 프로젝트가 될 수 있을 것이다.

저작자 표시 비영리 변경 금지
신고

'Project > Document Protector' 카테고리의 다른 글

Document Protector 완료 명세서  (0) 2010.11.01
개발 환경  (0) 2010.05.15

Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

SDT 수정을 이용한 Native API HookingSDT 수정을 이용한 Native API Hooking

Posted at 2010.07.28 13:54 | Posted in About Programing/04. Device Driver
크리에이티브 커먼즈 라이선스
Creative Commons License

OS : Windows XP SP3
Tool : Microsoft Visual Studio 2008 SP1 /  Windows Driver Kit (WDK) Version 7.1.0



Native API Hooking은 SDT를 수정하는 방법을 통해서 이루어 집니다.

SDT에 대하여 이야기 하기 전에 User Application Programming을 할때 우리는 WinXX API를 많은 DLL들,
예를들면 KERNEL32,GDI32,USER32같은 것들이 Export해주는 API들을 호출하여 씁니다.

이런 DLL들이 Export해주는 API들을 Disassemble하여 보면,
예를들어서 KERNEL32가 Export해주는 API인 WriteFile()를 Disassemble하여 보면,
내부적으로는 NTDLL.DLL에서 Export해주는 ZwWriteFile()라는 Native API를 사용함을 볼수 있습니다.

또 ZwWriteFile()를 Disassemble하여 보면,

MOV EAX, 0ED 



LEA EDX, DWORD PTR SS:[ESP+4] 



INT 2E 



RETN 24 


위와 같은 부분이 보이게 됩니다.

첫번쨰 줄의 0x0ED는 ZwWriteFile의 ServiceNumber이며,
세번쨰 줄의 INT 2E(System Call)은 UserMode에서 KernelMode로 전환되는 진입점이라고 보면 됩니다.
(아쉽게도 이것은 Windows 2000까지 해당되는 것이며, Windows XP System에서는 INT 2E가 아닌 SYSENTER를 사용합니다.)

이것은 프로세서 차원에서 제공되는 새로운 명령어로서,
기존의 방식보다 커널모드로의 전환이 훨씬 빠르다고 합니다.

위의 Disassemble과정으로 알수 있었던 Call 과정을 도식화 하면,

WinXXAPI - > Native API - > INT2E(Interruptl)

이 Call과정의 중간 단계에 있는 Native API를 Hooking하는 것입니다.

이제 Call과정에 대해서 어느정도 알게 되었으니 SDT에 대하여 알아보면,
SDT란 Service Descriptor Table의 약자로서 SDE를 묶어놓은 구조체입니다.

typedef struct ServiceDescriptorTable {




SDE ServiceDescriptor[4]; 




} SDT;


위와 같이 선언되어 있으며, 위에서 쓰인 SDE라는것은,
ServiceDescriptorEntry의 약자로서 SDT의 구성요소로서,
Native API에 대한 자세한 정보가 담겨진 구조체 입니다.

typedef struct ServiceDescriptorEntry { 




PDWORD ServiceTable; //




PDWORD CounterTableBase;



DWORD ServiceLimit; 



PBYTE ArgumentTable;




} SDE;


실제 Hooking에서는 SDE의 ServiceTable(System Service Dispatch Table)을 우리의 Driver내에 존재하는 함수의 주소로 바꾸어
해당API가 호출될떄 우리의 함수가 실행되도록 한후, 우리의 함수 내부에서 원하는 작업을 처리하고
원래해당 API를 호출해줌으로써, 정상적으로 작동하게 하는 구조입니다.

물런 Hooking을 끝내고자 할때는 Driver를 Unload만 해서는 안되며,
SDE의 해당API의 ServiceTable을 원상태로 돌려놓아야 합니다.

돌려놓지 않았을때는 아름다운 Blue Screen을 만나 보실수 있을겁니다ㅋㅋ



먼저 간단한 Driver의 뼈대를 작성합니다.

Application을 제작할떄 가장 먼저 작성하는 Entry Point가 Console App에서는 main()이고,
Win App에서는 WinMain()이며, 우리가 지금부터 작성하고자 하는 Driver에서는 DriverEntry() 입니다.

밑에와 같이 간단한 DriverEntry()를 작성하여 보았습니다.

NTSTATUS DriverEntry ( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath )
{ 
	NTSTATUS status;
	int i;

	for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
	{ 
		pDriverObject->MajorFunction[i] = DispatchPassThru;
	} 

	SetupSTBHook();

	pDriverObject->DriverUnload = DriverUnload;

	status = STATUS_SUCCESS;

	return status;
}

}

(1)에서는 MajorFunction들을 모두 PassThru루틴으로 채우는것을 볼수 있습니다.

MajorFunction들 예를들면 IRP_MJ_WRITE,IRP_MJ_CREATE 같은 것들을 처리하기 위해 존재하는것인데,
드라이버의 기본 뼈대를 작성하는 단계임으로 PassThru로 모두 채웁니다.

(2)에서는 Unload함수를 채워주는것이 나오는데,
Unload로 채워주는 함수인 DriverUnload()가 하는 역활은 Driver가 Unload될떄 처리 할것이 있다면,
그것들을 처리하는 부분입니다.

NTSTATUS DispatchPassThru( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
	Irp->IoStatus.Status = STATUS_SUCCESS; 
	IoCompleteRequest(Irp,IO_NO_INCREMENT);

	return Irp->IoStatus.Status; 
}


보시다시피 아무것도 수행되지 않는 루틴임을 볼수 있습니다.

DriverUnload()의 코드는 다음과 같습니다.

VOID DriverUnload ( IN PDRIVER_OBJECT pDriverObject )
{ 
	DbgPrint("---My Driver Unloadded---\n");    //언로드시 출력 

	_asm 
	{ 
		CLI 
			MOV    EAX, CR0     
			AND EAX, NOT 10000H 
			MOV    CR0, EAX 
	} 
	(ZWWRITEFILE)
		(SYSTEMSERVICE(ZwWriteFile))   //OldZwWriteFile으로 채운다. 
		= OldZwWriteFile; 
	_asm 
	{ 
		MOV    EAX, CR0         
			OR    EAX, 10000H         
			MOV    CR0, EAX             
			STI     
	}   
}


이제 Hooking기능을 집어넣기 위해 해더파일을 만든후 다음을 집어넣습니다.

#pragma once 
#include 
#include 

#define DWORD unsigned long 
#define WORD unsigned short 
#define BOOL unsigned long 

#pragma pack(1) 
typedef struct ServiceDescriptorEntry { 
	unsigned int *ServiceTableBase; 
	unsigned int *ServiceCounterTableBase; 
	unsigned int NumberOfServices; 
	unsigned char *ParamTableBase; 
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; 
#pragma pack() 

typedef struct _SRVTABLE { 
	PVOID       *ServiceTable; 
	ULONG       LowCall;     
	ULONG       HiCall; 
	PVOID        *ArgTable; 
} SRVTABLE, *PSRVTABLE; 

typedef NTSTATUS (*ZWWRITEFILE)( 
    IN HANDLE hFile, 
    IN HANDLE hEvent OPTIONAL, 
    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, 
    IN PVOID IoApcContext OPTIONAL, 
    OUT PIO_STATUS_BLOCK pIoStatusBlock, 
    IN PVOID WriteBuffer, 
    IN ULONG WriteBufferLength, 
    IN PLARGE_INTEGER FileOffset OPTIONAL, 
    IN PULONG LockOperationKey OPTIONAL 
); 
ZWWRITEFILE    OldZwWriteFile; 

__declspec(dllimport) ULONG NtBuildNumber; 
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; 

#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)] 
#define SYSTEMSERVICEIDX(_index) KeServiceDescriptorTable.ServiceTableBase[_index] 


먼저 NTDDK.H라는 해더 파일을 Include함을 볼수 있습니다.
NTDDK.H는 Driver에서 핵심적인 것들이 선언된 해더파일임으로 반드시 Include해주어야 합니다.

SDE(ServiceDescriptorEntry) 구조체를 선언하는것도 볼수 있습니다.
NtBuildNumber를 통해 현재 운영체제의 빌드넘버를 구해올수 있습니다.

후에 Hooking을 할떄에 Exported by Name이 되지 않은 Native API들이 몇개 존재합니다. ZwDebugActiveProcess(),ZwWriteVirtualMemory()등등의 API입니다.

메크로 함수인 SYSTEMSERVICE와 SYSTEMSERVICEIDX는 얻고자 하는 값이 같지만, 쓰이는 상황이 다릅니다.

SYSTEMSERVICE같은 경우는 Native API의 이름으로 ServiceTableBase를 구해오고자 할떄 쓰이며,
SYSTEMSERVICEIDX같은 경우는 Service Number로서 ServiceTableBase를 얻어오고자 할때 쓰입니다.

위에서 말한 Exported by Name이 되지 않은 몇몇의 Native API들은 SYSTEMSERVICEIDX를 어쩔수 없이 써야 하는데
이때 운영체제의 빌드버젼에 따라서 Service Number가 다를수 있습니다.

그래서 NtBuildNumber로 switch처리를 해주어야 합니다.

지금까지 선언한것들이 Hooking을 하는데 필요한 기본적인 구조체와,메크로함수, 변수들의 선언입니다.
이제 필요한 것들을 선언했으니 Hooking하는 실질적인 Code를 작성하여 보도록 하겠습니다.

Hooking을 하는 방법은 위에서 언급했다싶이 SDE의 ServiceTableBase를 조작하는 것입니다.
이 ServiceTableBase를 조작하는 부분을 처리하는 별도의 루틴을 SetupSTBHook()이라는 이름으로 만들겠습니다.

VOID SetupSTBHook( void )
{
	DbgPrint("---SetupHook---\n");    //STBHook시 출력     
	OldZwWriteFile = 
		(ZWWRITEFILE) 
		(SYSTEMSERVICE(ZwWriteFile));  //(1)기존의 ZwWriteFile의 주소구함 

	DbgPrint("OldZwWriteFile : %Xn", 
		OldZwWriteFile);           //기존 주소 DebugMessage로 출력 

	_asm 
	{ 
		CLI              //인터럽트 일시 중지 
			MOV    EAX, CR0     
			AND EAX, NOT 10000H 
			MOV    CR0, EAX 
	} 

	(ZWWRITEFILE) 
		(SYSTEMSERVICE(ZwWriteFile))   //ServiceTableBase의값을 우리의 
		= NewZwWriteFile;          //루틴에 주소로 교체 

	_asm 
	{ 
		MOV    EAX, CR0      //인터럽트 일시 중지 해제         
			OR    EAX, 10000H         
			MOV    CR0, EAX             
			STI     
	} 
} 


코드가 그렇게 어렵지 않음으로 별도의 설명이 길게 필요하진 않을것입니다.

원래 Native API의 주소를 저장시켜둔후(복구 할떄를 위해서) 우리의 루틴에 주소로 바꿔치기 합니다.
이렇게 함으로써 ZwWriteFile()이 호출될떄 실제적으로 호출되는 함수는 우리 Driver내의 NewZwWriteFile()라는 함수가 되는것입니다.

그렇다면 NewZwWrtieFile()이라는 함수는 어떻게 구성되어 있어야 할까요?

기존의 함수의 처리를 완벽하게 해내야 함으로 전달받는 Parameter가 같아야 할것입니다.
그럼으로 Hooking을 하고자 할떄는 Hooking되는 대상 API의 전달되는 Parameter가 뭔지 미리 알아야 된다는 말이 됩니다.
ZwWrtieFile()의 인자전달 형태를 알아낸 분들께 감사드립니다. :)

NTSYSAPI 
NTSTATUS 
NTAPI 
ZwWriteFile( 
    IN HANDLE hFile, 
    IN HANDLE hEvent OPTIONAL, 
    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, 
    IN PVOID IoApcContext OPTIONAL, 
    OUT PIO_STATUS_BLOCK pIoStatusBlock, 
    IN PVOID WriteBuffer, 
    IN ULONG WriteBufferLength, 
    IN PLARGE_INTEGER FileOffset OPTIONAL, 
    IN PULONG LockOperationKey OPTIONAL 
); 


호출될때 전달되는 인자는 앞에 IN이 붙으며,
API가 처리된후 어떠한 결과를 돌려주는 인자는 OUT이 붙습니다.
NewZwWriteFile()함수 역시 위에와 같은 인자전달 형태를 취하고 있어야 합니다.

NTSTATUS NewZwWriteFile( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
						IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, 
						IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL ) 
{ 
	NTSTATUS rc; 

	DbgPrint("ZwWriteFile is Hookedn"); //훅되고 있음을 알림 
	rc = ((ZWWRITEFILE)(OldZwWriteFile)) ( 
		hFile,               //원래 함수를 호출해서 
		hEvent OPTIONAL,         //정상적으로 처리되게함 
		IoApcRoutine OPTIONAL, 
		IoApcContext OPTIONAL, 
		pIoStatusBlock, 
		WriteBuffer, 
		WriteBufferLength, 
		FileOffset OPTIONAL, 
		LockOperationKey OPTIONAL );

	return rc; 
} 


먼저 DbgPrint()함수를 이용하여 훅되고 있음을 DebugMessage로 출력합니다.
그런후 기존의 ZwWriteFile()주소를 담고 있는 OldZwWriteFile()을 호출 함으로써 기존의 ZwWriteFile() API를 호출합니다.

OldZwWriteFile에 저장해두었던 원래의 값으로 다시 채워넣기만 하면, Hook해제는 끝입니다. 정말 쉽죠? :)



// Hooking.c

#include "Hooking.h"

NTSTATUS DriverEntry ( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath )
{ 
	NTSTATUS status;
	int i;

	for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
	{ 
		pDriverObject->MajorFunction[i] = DispatchPassThru;
	} 

	SetupSTBHook();

	pDriverObject->DriverUnload = DriverUnload;

	status = STATUS_SUCCESS;

	return status;
}

NTSTATUS DispatchPassThru( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
	Irp->IoStatus.Status = STATUS_SUCCESS; 
	IoCompleteRequest(Irp,IO_NO_INCREMENT);

	return Irp->IoStatus.Status; 
}

VOID DriverUnload ( IN PDRIVER_OBJECT pDriverObject )
{ 
	DbgPrint("---My Driver Unloadded---\n");    //언로드시 출력 

	_asm 
	{ 
		CLI 
			MOV    EAX, CR0     
			AND EAX, NOT 10000H 
			MOV    CR0, EAX 
	} 
	(ZWWRITEFILE)
		(SYSTEMSERVICE(ZwWriteFile))   //OldZwWriteFile으로 채운다. 
		= OldZwWriteFile; 
	_asm 
	{ 
		MOV    EAX, CR0         
			OR    EAX, 10000H         
			MOV    CR0, EAX             
			STI     
	}   
}

VOID SetupSTBHook( void )
{
	DbgPrint("---SetupHook---\n");    //STBHook시 출력     
	OldZwWriteFile = 
		(ZWWRITEFILE) 
		(SYSTEMSERVICE(ZwWriteFile));  //(1)기존의 ZwWriteFile의 주소구함 

	DbgPrint("OldZwWriteFile : %Xn", 
		OldZwWriteFile);           //기존 주소 DebugMessage로 출력 

	_asm 
	{ 
		CLI              //인터럽트 일시 중지 
			MOV    EAX, CR0     
			AND EAX, NOT 10000H 
			MOV    CR0, EAX 
	} 

	(ZWWRITEFILE) 
		(SYSTEMSERVICE(ZwWriteFile))   //ServiceTableBase의값을 우리의 
		= NewZwWriteFile;          //루틴에 주소로 교체 

	_asm 
	{ 
		MOV    EAX, CR0      //인터럽트 일시 중지 해제         
			OR    EAX, 10000H         
			MOV    CR0, EAX             
			STI     
	} 
} 

NTSTATUS NewZwWriteFile( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
						IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, 
						IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL ) 
{ 
	NTSTATUS rc; 

	DbgPrint("ZwWriteFile is Hookedn"); //훅되고 있음을 알림 
	rc = ((ZWWRITEFILE)(OldZwWriteFile)) ( 
		hFile,               //원래 함수를 호출해서 
		hEvent OPTIONAL,         //정상적으로 처리되게함 
		IoApcRoutine OPTIONAL, 
		IoApcContext OPTIONAL, 
		pIoStatusBlock, 
		WriteBuffer, 
		WriteBufferLength, 
		FileOffset OPTIONAL, 
		LockOperationKey OPTIONAL );

	return rc; 
} 


// Hooking.h

#ifndef _HOOKING_H
#define _HOOKING_H

#pragma once 
#include 
#include 

#define DWORD unsigned long 
#define WORD unsigned short 
#define BOOL unsigned long 

#pragma pack(1) 
typedef struct ServiceDescriptorEntry { 
	unsigned int *ServiceTableBase; 
	unsigned int *ServiceCounterTableBase; 
	unsigned int NumberOfServices; 
	unsigned char *ParamTableBase; 
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; 
#pragma pack() 

typedef struct _SRVTABLE { 
	PVOID       *ServiceTable; 
	ULONG       LowCall;     
	ULONG       HiCall; 
	PVOID        *ArgTable; 
} SRVTABLE, *PSRVTABLE; 

typedef NTSTATUS (*ZWWRITEFILE)( 
    IN HANDLE hFile, 
    IN HANDLE hEvent OPTIONAL, 
    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, 
    IN PVOID IoApcContext OPTIONAL, 
    OUT PIO_STATUS_BLOCK pIoStatusBlock, 
    IN PVOID WriteBuffer, 
    IN ULONG WriteBufferLength, 
    IN PLARGE_INTEGER FileOffset OPTIONAL, 
    IN PULONG LockOperationKey OPTIONAL 
); 
ZWWRITEFILE    OldZwWriteFile; 

__declspec(dllimport) ULONG NtBuildNumber; 
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; 

#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)] 
#define SYSTEMSERVICEIDX(_index) KeServiceDescriptorTable.ServiceTableBase[_index] 

NTSTATUS DispatchPassThru( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
VOID DriverUnload ( IN PDRIVER_OBJECT pDriverObject );
VOID SetupSTBHook( void );
NTSTATUS NewZwWriteFile( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
						IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, 
						IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL );

#endif // _HOOKING_H


// sources
TARGETNAME=Hooking
TARGETPATH=obj
TARGETTYPE=DRIVER
SOURCES=Hooking.c 

저작자 표시 비영리 변경 금지
신고

'About Programing > 04. Device Driver' 카테고리의 다른 글

ZwCreateFile 함수  (0) 2010.07.29
OBJECT_ATTRIBUTES 구조체  (0) 2010.07.29
SDT 수정을 이용한 Native API Hooking  (0) 2010.07.28
WinDbg 명령어 정리  (0) 2010.06.14
완전 신기!  (0) 2010.05.23
5월 22일 SOURCES 파일  (0) 2010.05.23

Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

5월 22일 SOURCES 파일5월 22일 SOURCES 파일

Posted at 2010.05.23 00:31 | Posted in About Programing/04. Device Driver
크리에이티브 커먼즈 라이선스
Creative Commons License
출처 : 루트킷 - 에이콘 50page

 SOURCES파일은 파일 이름이 항상 대문자로 SOURCES이어야 하고, 파일 확장자가 없다. 다음은 SOURCES파일이 포함해야 하는 내용을 보여주고 있다.

TARGETNAME=MYDRIVER
TARGETPATH=OBJ
TARGETTYPE=DRIVER
SOURCES=mydriver.c
 TARGETNAME 변수에는 드라이버의 이름을 할당한다. TARGETNAME에 설정된 이름은 드라이버 바이너리에 포함되기 때문에 TARGETNAME에 MY_EVIL_ROOTKET_IS_GONNA_GET_YOU와 같은 이름을 할당하는 것은 좋은 생각이 아니다. 드라이버 파일의 이름을 변경하더라도 바이너리 안에 포함된 이름은 변경되지 않는다.

 TARGETPATH 변수는 일반적으로 OBJ로 설정된다. 이것은 파일이 컴파일되어 어디에 저장되는지를 나타낸다. 일반적으로 드라이버 파일은 현재 디렉토리의 objchk_xxx.i386 하위 디렉토리에 위치한다.

 TARGETTYPE 변수는 컴파일 하는 파일의 종류를 나타낸다. 드라이버인 경우에는 DRIVER라고 설정한다.

 SOURCES 항복에는 소스 파일인 .c 파일을 명시한다. 여러 줄을 이용해서 소스 파일들을 명시하고자 한다면 다음과 같이 백슬래시('\')를 이용하면 된다.
SOURCES = myfile1.c \
		myfile2.c \
		myfile3.c
마지막 줄에는 백슬래시가 없다는 것에 주의하라. 선택적으로 INCLUDE 변수를 추가로 이용할 수도 있다. 이를 이용해서 인클루드 파일이 위치하는 디렉토리를 명시할 수 있다. 이 경우에도 백슬래시를 이용하면 여러 줄로 디렉토리들을 명시할 수 있다.
INCLUDE = c:\my_includes\
		..\..\inc\
c:\other_includes
링크해야 할 라이브러리가 있는 경우에는 TARGETLIBS 변수를 이용해야 한다. NDIS라이브러리를 사용하는 경우를 예로 들겠다.
TARGETLIBS = $(BASEDIR) \ lib\w2k\i386\ndis.lib
또는
TARGETLIBS = $(DDK_LIB_PATH)\ndis.lib
$(BASEDIR) 은 DDK가 설치된 경로를 의미하고, $(DDK_LIB_PATH)는 디폴트 라이브러리가 설치된 경로를 의미한다.
저작자 표시 비영리 변경 금지
신고

'About Programing > 04. Device Driver' 카테고리의 다른 글

SDT 수정을 이용한 Native API Hooking  (0) 2010.07.28
WinDbg 명령어 정리  (0) 2010.06.14
완전 신기!  (0) 2010.05.23
5월 22일 SOURCES 파일  (0) 2010.05.23
[TDI_FW] 예제 분석 5월 19일  (0) 2010.05.20
[TDI_FW] 예제 분석 5월 18일  (0) 2010.05.18

Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[TDI_FW] 예제 분석 5월 19일[TDI_FW] 예제 분석 5월 19일

Posted at 2010.05.20 01:49 | Posted in About Programing/04. Device Driver
크리에이티브 커먼즈 라이선스
Creative Commons License
int main (void)
{
	SC_HANDLE schSCManager;
	SC_HANDLE schService;
	SERVICE_STATUS serviceStatus;
	char Path[256];
	HANDLE hDevice;
	schSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);

	if (!schSCManager)
	{
		return 0;
	}

	GetCurrentDirectory (255, Path);
	strcat (Path, "\\FILTER.SYS");

	schService = OpenService (schSCManager, "FILTER", SERVICE_ALL_ACCESS);

	if (schService == NULL)
	{
		schService = CreateService (schSCManager, "FILTER", "FILTER", SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, path, NULL, NULL, NULL, NULL, NULL);

		if (schService == NULL)
		{
			return 0;
		}
	}
}
"FILTER" 이름의 서비스가 있는지 확인한 후 그렇지 않은 경우에만 서비스를 생성한다.
CreateService() 함수에서 사용하는 "PATH" 파라미터는 서비스에 해당하는 드라이버 파일이 존재하는 풀 경로(FULL PATH)다. 이를 통해, 드라이버 파일은 하드디스크에 어디에 존재 하더라도 상관이 없다는 것을 알 수 있다.
 

저작자 표시 비영리 변경 금지
신고

'About Programing > 04. Device Driver' 카테고리의 다른 글

SDT 수정을 이용한 Native API Hooking  (0) 2010.07.28
WinDbg 명령어 정리  (0) 2010.06.14
완전 신기!  (0) 2010.05.23
5월 22일 SOURCES 파일  (0) 2010.05.23
[TDI_FW] 예제 분석 5월 19일  (0) 2010.05.20
[TDI_FW] 예제 분석 5월 18일  (0) 2010.05.18

Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[TDI_FW] 예제 분석 5월 18일[TDI_FW] 예제 분석 5월 18일

Posted at 2010.05.18 20:09 | Posted in About Programing/04. Device Driver
크리에이티브 커먼즈 라이선스
Creative Commons License
참고 자료 : 윈도우 디바이스 드라이버 - 이봉석(한빛미디어) 604쪽

- 서비스를 생성하는 목적으로 사용되는 Win32 API 함수 정리
  • OpenSCManager() : 서비스를 생성하거나 제거, 중지 등의 일을 하기 위해서 사전에 사용하는 서비스 컨트롤 관리자(Service Control Manager) 핸들을 얻는 함수다.
  • OpenService() : 기존에 생성한 서비스 핸들을 얻는 함수다. 디바이스 드라이버 서비스를 생성하기 전에 이 함수를 먼저 사용하여 드라이버를 위한 서비스가 이미 생성되어 있느닞를 알아보는 용도로 사용한다.
  • CreateService() : 서비스를 생성하는 목적으로 사용하는 함수다.
  • StartService() : 서비스를 실행하는 목적으로 사용하는 함수다. NT 구형(Legacy) 드라이버를 위한 서비스는 이와 같은 함수를 응용 프로그램이 직접 호출함으로써 드라이버를 메모리에 적재할 수 있다. 그러나 WDM 드라이버는 디바이스 스택형성 과정을 위해서 메모리에 적재되므로 이 함수를 사용하지 않는다.
  • ControlService() : 동작 중인 서비스에 특정 명령을 전달하는 목적으로 사용하는 함수다.
  • DeleteService() : 생성된 서비스를 제거하는 용도로 사용하는 함수다.
  • CloseServiceHandle() : 사용하던 서비스 핸들, SCM 핸들을 반납하는 용도로 사용하는 함수다.
저작자 표시 비영리 변경 금지
신고

'About Programing > 04. Device Driver' 카테고리의 다른 글

SDT 수정을 이용한 Native API Hooking  (0) 2010.07.28
WinDbg 명령어 정리  (0) 2010.06.14
완전 신기!  (0) 2010.05.23
5월 22일 SOURCES 파일  (0) 2010.05.23
[TDI_FW] 예제 분석 5월 19일  (0) 2010.05.20
[TDI_FW] 예제 분석 5월 18일  (0) 2010.05.18

Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

티스토리 툴바