사용자는 당신들이 프로그램을 아무리 멋지게(cool) 만들어도 신경 쓰지 않는다.
프로그램에 멋진 것을 넣어 놓고, 이봐라 멋지지? 이렇게 생각하지 마라.
사용자는 당신들에게 아무 관심이 없다. 당신들이 누구인지조차도 모른다.
사용자가 원하는 것은 당신의 프로그램을 더 이상 보지 않는 것이다.
사용자들은 빨리 당신의 프로그램을 쓰는 것을 마치고 밖에 나가서 인생을 즐기고 싶어 할 뿐이다.
static unsigned char _bNoMansLandFill = 0xFD; /* 메모리 상태 채크를 위해 쓰이는 값*/ static unsigned char _bDeadLandFill = 0xDD; /* 삭제된 메모리에 쓰이는 값 */ static unsigned char _bCleanLandFill = 0xCD; /* 새로 할당된 메모리에 쓰이는 값 */ static unsigned char _bAlignLandFill = 0xBD; /* fill no-man's land for aligned routines */
힙에 메모리 할당시 디버그 모드에서는 _CrtMemBlockHeader 구조체 + _bNoMansLandFill(2바이트) + 실제 메모리( _bCleanLandFill 로 채워짐 ) + _bNoMansLandFill(2바이트) 로 구성되며 릴리즈모드에서는 널영역(2바이트) + _CrtMemBlockHeader 의 일부분 + 실제 메모리 (쓰레기 값) + 널영역(2바이트) 로 구성되며 _bNoMansLandFill 는 포함되지 않는다
디버그 모드에서 메모리 삭제시 _bNoMansLandFill 의 메모리 영역을 검사하게 되는데 여기 다른 메모리가 침범해 있을때 발생하는 에러가 바로 힙 커럽션이다 문제는 이 에러의 원인이되는 메모리침범이 당시에는 나오지 않고 delete 할때 나온다는거다
델파이에서 VC 8.0(VS 2005)에서 작성한 DLL을 사용하는데 개발환경이 셋업되어있지않은 곳에서 사용하는데 문제가 있어서 몇일간 삽질한 내용을 정리하고자한다.
테스트 환경 우선 Visual C++ Ver 8.0에서 DLL을 만들었다. 그리고 그것을 Delphi 2005에서 만든 실행 파일에서 불러서 쓰려했다.
실행파일을 실행한 OS는 Windows XP Professional SP2로 개발환경이 전혀 깔려있지않은 상태였다.
■ 첫번째 삽질 델파이라 만든 실행파일을 실행하면 아래의 메세지가 떴다. "응용 프로그램을 제대로 초기화하지 못했습니다(0xc0150002)."
→ 문제는 Visual C++ Ver 8.0에서 DLL을 만들 때 Debug 모드로 빌드를 해서 Debug용 DLL로 테스트를 했었다. Release 모드로 바꾸어서 빌드 해봤지만 에러는 뜨지 않았지만 dll이 제대로 동작하지 않았다.
■ 두번째 삽질 VC 8.0(VS 2005)으로 DLL을 만들면 DLL만 카피한다고 DLL이 제대로 동작하지 않는다. 자세한 내용은 옆의 링크 참조 배포(C++) 여하튼 가장 편한 방법은 아래의 패키지를 설치하는 것이 가장 편한 것같다. Microsoft Visual C++ 2005 재배포 가능 패키지(x86) (무엇이 좋아졌는지는 잘 모르겠지만 왜 더 불편하게 만들어졌는지가 잘 이해가 안간다.)
■ 세번째 삽질 호출 규칙이란 것을 모르고 DLL을 작성하였다. (아직도 제대로 이해하지 못하고 있지만...) Visual C++ 2005의 호출규칙(컴파일 옵션) 에는 아래와 같은 것들이 있다. __cdecl __fastcall __stdcall
위와 같은 방법으로 pClass에 해당 드라이버 오브젝트를 얻어 올 수 있다. SearchObject 함수 내의 ObOpenObjectByName() 를 사용하기 위해서는 헤더 파일에 다음과 같은 구문을 넣어줘야 한다:
extern "C"{ #include <ntddk.h>
NTSTATUS ObOpenObjectByName( IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN OUT PVOID ParseContext OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN ACCESS_MASK DesiredAccess, IN PACCESS_STATE PassedAccessState, OUT PHANDLE Handle); }
Visual Studio 2008 Prefessional Windows Driver Kit 6001.18001 Build Windows XP SP2
우선, 다음의 작업을 수행합니다.
1. VS2008 실행 2. 도구->옵션->프로젝트 및 솔루션->VC++ 디렉터리 3. 오른쪽 위의 "다음 파일의 디렉터리 표시(S):"에서 "포함 파일" 선택 4. {WDK Installation Path}\{Build Number}\inc 을 추가합니다. 5. {WDK Installation Path}\{Build Number}\lib 을 추가합니다.
이제 VC++에서 드라이버 개발에 관련된 인텔리전스 기능을 사용할 수 있게 되었습니다.
하지만 드라이버 제작을 위해서는 makefile sources 2가지의 파일이 더 필요합니다.
makefile은 다음과 같이 만들면 됩니다. Windows 98이상의 환경이라면 모두 같은 형태의 makefile을 써야합니다.
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source # file to this component. This file merely indirect to the real make file # that is shared by all the driver components of the Windows NT DDK !INCLUDE $(NTMAKEENV)\makefile.def
sources 파일은 일반적으로 드라이버를 제작할 때와 마찬가지로 만들면 됩니다. sources의 기본 형태는 다음과 같습니다.
INCLUDES=..\inc // include 디렉터리 설정 LIBS=..\lib // lib 디렉터리 설정
SOURCES=main.c send.c recv.c ...
위의 sources 파일은, 드라이버의 목적명이 Wdm1.sys 라는 것, Wdm1.sys가 WDM드라이버 라는 것, OBJ 서브디렉터리에 구성할 것, 소스 브라우저 정보를 생성할 것등의 정보를 가지고 있습니다. 그리고 INCLUDES, LIBS는 각각의 디렉터리를 설정하면 됩니다. SOURCES=에는 컴파일 할 파일 목록을 지정합니다. 그리고 sources 매크로와 등호(=)사이에 공간이 들어가면 안됩니다.
그 외에 DDKBuild를 이용한 연동이나 더 많은 정보를 원하면 다음의 링크를 참조하세요 보러가기
WINDOWS 내부 안내 전문번역서. 이 책은 마이크로소프트 WINDOWS 제품 개발팀과 공동으로 개발한 안내서로 64비트 확장을 포함하여 WINDOWS Server 2003, WINDOWS XP, 그리고 WINDOWS 2000의 운영체제 아키텍처와 내부를 설명한다. 또한 WINDOWS를 구성하고 제어하는 핵심 메커니즘 이해액세스, WINDOWS 보안 모델 탐구커널 디버거와 알고리즘검사Windo ws 가상 메모리와 물리 메모리 관리 방법NTFS의 동작 및 포맷의 이해와 파일
윈도우 커널 조작의 미학! '에이콘 해킹ㆍ보안' 시리즈, 제15권 『루트킷』. 해커들이 공격하고자 하는 시스템에 지속적이면서도 탐색되지 않은 채로 교묘히 접근할 수 있는 최고의 백도어인 '루트킷(ROOTKITS)'에 대한 전문서다. 이 책은 '루트킷'에 대해 세세하게 설명하면서, 그것을 제작하는 방법, 작동하는 방법 등에 대해 가르쳐준다. '루트킷'에 관한 최고의 전문가라고 할 수 있는 두 저자가 현재까지 쌓아온 기술을
윈도우를 위한 차세대 통합 드라이버 개발 모델! 윈도우를 위한 차세대 통합 드라이버 개발 모델인 윈도우 드라이버 파운데이션(WDF) 안내서. WDF를 개발자들이 직접 저술한 것이다. 짧은 시간 안에 고품질의 드라이버를 개발할 수 있도록 도와준다. 이 책은 WDF를 사용한 커널 모드나 유저 모드 드라이버를 개발할 수 있도록 구성되어 있다. 최소의 코드로 플러그 앤 플레이 등이 가능한 드라이버를 만들고, I/O 핸들링 코드
지우고 또 지우려해도 만져질 듯한 너의 따뜻한 미소 이제는 잊어야지 그래야만 하지 모두 끝났으니까 내가 떠났으니까 난 시간이 흐르고 흘러 지금쯤이면 괜찮을거라 생각했어 아무리 사랑했어도 다시는 울지 않기로 다짐해왔었는데 아픈만큼 슬픈만큼 널 위해 흘린 눈물만큼 해주고 싶은 말 너무나도 많은데 이렇게 잊지 못한 채 하루하루 널 생각해 지울수 없는 나의 마지막 이별의 기억
지금은 어떻게 지내고 있니 모두 잊고서 다른 사람 만나고 있니 아니면 너도 나처럼 지우지 못해서 매일 울고 또 울어 지쳤니 아직도 그때 우리 함께 했던 행복한 순간 내게 너무나 소중해 기억하나봐 아픈만큼 널 위해 흘린 눈물만큼 나 사랑하는데 기다려왔었는데 잘지내란 말 한마디 행복하란 말 한마디 하지 못한 채 너를 떠나야만했던 나~ 단 한번만 딱 한번만 널 만날수만 있다면 해주고 싶은 말 너무나도 많은데 아직도 잊지 못한 채 하루하루 널~ 생각해 지울수 없는 나의 마지막 이별의 기억~@
IAT(Import Address Table) Hooking: IAT 에 적혀있는 API 의 주소를 자신의 함수주소로 바꾸고 자신의 함수 끝에 다시 원래 API 주소로 돌려주는 방식. 가장 일반적으로 바이러스에서 사용하는 기법.
Inline Function Hooking (Detour Hooking): 사용할 API 의 첫 5바이트를 자신의 함수주소로 Jmp 하는 코드로 바꾸고 자신의 코드에서 다시 원래 API 의 바뀐 코드를 수정해주고 API 시작위치로 돌려주는 방식. IAT 후킹보다 지능적이여서 찾아내기가 쉽지 않다. 요새 많이 등장한다.
Kernel-Mode Hooking (루트킷)
SSDT(System Service Descriptor Table Modification): SSDT 가 가리키는 주소를 후킹 함수의 주소로 바꾸고 그 함수 호출후 다시 원래 커널 API 의 주소로 돌려주는 기법. 50% 이상의 루트킷이 사용하는 기법. 이런 기법은 프로세스, 파일의 은폐에 많이 사용됨.
DKOM(Direct Kernel Object Modification): 커널 Object 를 직접 조작해서 실행되는 프로세스, 스레드, 서비스, 포트, 드라이버 및 핸들의 Entry 를 실행리스트(PsActiveProcessHead, PsActiveModuleHead....)에서 감추는 기법.
SYSENTER: 유저모드에서 시스템 호출로 넘어갈때 INT 2E(for Windows 2000)/ SYSENTER 를 사용하게 되는데 호출후 시스템 서비스의 핸들러는 IA32_SYSENTER_EIP 라는 레지스터리에 저장된다. 커널 드라이버를 설치하여 해당 값을 수정하여 루트킷을 호출하고 다시 원래 값으로 돌려주는 기법.
Filter Device Drivers: 시큐리티 제품의 하단에 filter device driver 로 등록하는 기법이다. 부트 타임에 로드됨으로써 다른 어떤 안티바이러스 제품보다 먼저 실행된다.
Runtime Detour Patching: 커널 메모리를 직접 조작함으로써 그 메모리의 포인터가 루트킷을 가르키게 함으로써 커널 함수들을 후킹하는 기법. 예를 들면 Exception 을 일으키고 Exception Handle 을 컨트롤하는 IDT 레지스터를 자신을 가리키는 주소로 써줌으로써 후킹목적을 달성한다.
IRP table Modification: 디바이스 드라이버가 네트웍 패킷을 처리하거나 파일을 쓸때 사용하는 I/O Request Packets 을 제어하는 Dispatch Routine 은 DEVICE_OBJECT 구조체에 저장된다. 바이러스에서 사용하는 루트킷은 IoGetDeviceObjectPointer 란 API를 사용하여 DEVICE_OBJECT 구조체에서 DRIVER_OBJECT 의 위치를 선정해줄수 있다. 즉 다른 Original Driver Call 이 일어나기 전에 자신의 루트킷을 먼저 실행하여 Call 결과를 조작한다.
서쪽하늘로 노을은 지고 이젠 슬픔이 되버린 그대를 다시 부를수 없을 것 같아 또 한번 불러보네 소리쳐 불러도 늘 허공에 부서져 돌아오는 너의 이름 이젠 더 견딜 힘조차 없게 날 버려두고 가지 사랑하는 날 떠나가는 날 하늘도 슬퍼서 울어준날 빗속에 떠날 나였음을 넌 알고 있는듯이
*
비가오는 날엔 난 항상 널 그리워해 언젠간 널 다시 만나는 그날을 기다리며 비내린 하늘은 왜 그리 날 슬프게해 흩어진 내 눈물로 널 잊고 싶은데