1. PID를 알고 있을 때 작업관리자에서 프로세스 종료시 종료되지 않는 드라이버.

//3. SDT Hooking

#include <ntddk.h>

// 함수 이름(주소)를 가지고 SDT 서비스 번호를 얻어내는 매크로
#define SERIVCE_ID( f )        *(ULONG*)( (char*)f + 1 )

// SDT Table의 각항목을 구성하는 구조체
#pragma pack(1)    // 1 Byte 단위로 align(정렬)하라는 지시어
typedef struct ServiceDescriptorEntry
{
    unsigned int*   ServiceTableBase; // 함수 주소
    unsigned int*   ServiceCounterTableBase;
    unsigned int    NumberOfServices;
    unsigned char*  ParamTableBase;
} ServiceDescriptorTableEntry_t;
#pragma pack()

// ntoskrnl.exe 에서는 SDT Table을 export 하고 있다.
__declspec(dllimport) ServiceDescriptorTableEntry_t
                                            KeServiceDescriptorTable;

// ntoskrnl.exe 가 가진 ZwTerminateProcess를 import 한다.
// Hooking 에 대상이 되는 함수를 import
__declspec(dllimport)
        NTSTATUS __stdcall ZwTerminateProcess( HANDLE handle, NTSTATUS ExitCode);

// 원래 함수의 주소를 보관하고 있어야 한다.
typedef NTSTATUS (__stdcall *FUNC)(HANDLE, NTSTATUS );
FUNC old; // 원래 함수의 주소를 담아둘 변수.

// 새로운 함수
NTSTATUS __stdcall foo( HANDLE handle, NTSTATUS ExitCode )
{
    DbgPrint("TerminateProcess is Called : %x", handle );

    if ( handle != (HANDLE)0 && handle != (HANDLE)-1 )    // 자기 스스로 죽는 ExitProcess 일 경우 제외
    {
        PVOID pEprocess = 0;    // 계산기의 EPROcESS의 주소를 담을 변수
        OBJECT_HANDLE_INFORMATION obj_handle;    // 핸들의 관한 정보(상속여부등)를 얻어 올 변수

        // User Level 에서 사용하던 핸들을 가지고 커널메모리에 있는 구조체의 주소를 직접 얻는다.
        // 이때 참조 개수가 증가한다.
        NTSTATUS status = ObReferenceObjectByHandle(
            handle,
            GENERIC_ALL,
            NULL,
            KernelMode,
            &pEprocess,
            &obj_handle );

        if( pEprocess != 0 )
        {
            // ObjectTable에 등록된 주소(물리주소)의 0x84에(xp,2003) PID값이 저장되어 있다.
            int id = *((int*)((char*)pEprocess + 0x84));

            if( id == 2648 ) // PID 값을 조사
            {
                DbgPrint("no kill");
                return STATUS_SUCCESS;
            }
            // 구조체를 다 사용했으므로 참조개수를 줄인다.
            ObDereferenceObject( pEprocess );
        }
    }
    // 기존의 함수로 다시 보낸다.
    return old( handle, ExitCode );
}

// 실제 SDT 훅을 하는 함수.
void InstallSDTHook()
{
    // 함수의 서비스 번호를 구한다.
    int id = SERIVCE_ID(ZwTerminateProcess);
   
    DbgPrint("ZwTerminateProcess service ID : %d", id );

    // 원래 함수의 주소를 보관해 둔다.
    old = (FUNC)KeServiceDescriptorTable.ServiceTableBase[ id ];

    __asm { CLI }   // interrupt 중지 - 다른 스레드가 실행흐름을 중지시키지 못하게 한다.(커널모드만 가능)

    // SDT Table을 수정(Hooking) 한다.
    KeServiceDescriptorTable.ServiceTableBase[ id ] = (unsigned int)foo;

    __asm { STI }    // interrupt 다시 시작 - 다른 스레드로의 전환(Context Switch) 를 가능하게 한다.
}

void UninstallSDTHook()
{
    int id = SERIVCE_ID(ZwTerminateProcess);
   
    __asm { CLI }   // interrup 중지

    // SDT 를 다시 원래대로 변경해 놓는다.
    KeServiceDescriptorTable.ServiceTableBase[ id ] = (unsigned int)old;

    __asm { STI }
}

VOID DriverUnload( PDRIVER_OBJECT pDrvObj )
{
    UninstallSDTHook();
    DbgPrint( "Driver Unload" );
}

NTSTATUS DriverEntry( PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath )
{
    DbgPrint("DriverEntry");

    pDrvObj->DriverUnload = DriverUnload;
    InstallSDTHook();
    return STATUS_SUCCESS;
}
Tag |

WDM 실습 - 작업관리자 흉내내기

from Study/WDM 2007/11/28 20:14 view 32109

1. 작업관리자 흉내내기. ( 서비스의 시작과 스톱을 신중히 하지 않는다면 블루스크린 )

// 프로세스의 생성/파괴를 감시하는 드라이버

#include <ntddk.h>

VOID foo( HANDLE ParentID, HANDLE ProcessID, BOOLEAN Create )
{
    if( Create == TRUE )
    {
        DbgPrint( "Process Created : %d, %d", ProcessID, ParentID );
    }
    else
    {
        DbgPrint( "Process Terminated : %d, %d", ProcessID, ParentID );
    }
}

VOID DriverUnload( PDRIVER_OBJECT pDrvObj )
{
    DbgPrint( "Driver Unload" );

    // 반드시 Callback 함수를 제거하고 unload 되어야 한다.
    PsSetCreateProcessNotifyRoutine( foo, TRUE );
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj            // DRIVER_OBJECT 객체의 주소
                     , PUNICODE_STRING pRegPath )    // 설치된 레지스트리 경로
{
    DbgPrint( "DriverEntry : %p", pDrvObj );

    // 드라이버가 unload 될때 호출될 함수를 등록한다.
    pDrvObj->DriverUnload = DriverUnload;

    // 프로세스 감시 함수를 등록한다.
    PsSetCreateProcessNotifyRoutine( foo, FALSE );

    return STATUS_SUCCESS;
}

WDM 기본 - 빌드

from Study/WDM 2007/11/28 20:10 view 57159
1. 기본 동작방식
 1) 소스제작 -> 빌드 -> 설치 -> 시동 -> 중지 -> 제거

  - 소스제작
//1. 가장 가단한 드라이버
#include <ntddk.h>

VOID DriverUnload( PDRIVER_OBJECT pDrvObj )
{
    DbgPrint( "Driver Unload" );    // 이 메세지는 커널 디버거에게 전달된다.
                                              // 이 메세지를 보려면 winDbg 또는 softice 또는 DebugView 가 필요
}

// 드라이버의 EntryPoint - 반드시 C 맹글링 규칙을 따라야 한다.
NTSTATUS DriverEntry( PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath )
{
    DbgPrint( "DriverEntry" );

    pDrvObj->DriverUnload = DriverUnload;    // 드라이버가 unload 될 때 호출 될 함수 등록

    return STATUS_SUCCESS;
}

 - 빌드
1. 설치된 DDK의 Windows XP Checked Build Environment 프롬프트를 사용하여 빌드한다.
2. MakeFile 과 Sources 파일이 필요하며 Sources만 편집하여 빌드 'build' 하면 된다.
3. 주의 해야 할점은 소스는 .c 로 되어야 하며 한글경로가 포함 되어 있으면 build가 되지 않는다.

- 설치, 시동, 중지, 제거
1. 레지스토리 편집기(regedit)에서 HKEY_LOCAL_MACHINE\SYSTEM 경로에 레지스토리를 등록한다.
  1) 직접 수정해서 등록한다.
  2) 서비스 API 함수를 사용하는 프로그램을 제작하여 등록한다.(Software 드라이버)
  3) inf 파일을 제작하여 등록한다.(Hardware 드라이버)
  4) Setup API를 사용한다.
2. 서비스의 설치 시작 정지 삭제는 나중에 알아보고 일단 EnumService.exe를 사용한다.

Tag |

DDK 설치

from Study/WDM 2007/11/28 19:38 view 37544

1. DDK

1) 다운 - http://www.microsoft.com/whdc/devtools/ddk/default.mspx
2) VC++ 디렉토리 경로
  - 포함파일에서(include)  DDK 설치폴더의 inc\wxp 와 inc\ddk\wxp 추가

3) 그외 필요한 파일.
 - DbgView.exe : 디버그 출력 DbgPrint 를 보기위한 파일 .
 - EnumService.exe : 빌드한 *.sys 를 서비스등록 시작을 간편하게 하기 위한 파일.

 - Makefile : 빌드시 필요한 파일
 - Sources : 빌드시 수정해야 하는 파일 파일의 명과 파일 경로를 알려준다.!



2. Detours ( MS 연구소가 만든 API HOOKING 라이브러리. )

1) 다운   -  http://research.microsoft.com/sn/detours/
2) Detours 설치 디렉토리에서 nmake  하면 빌드 됩니다.( cmd 말고 VC++ 명령 프롬프트 )
3) bin  폴더에 가면 detour 관련 실행파일및..dll 있습니다.

4) test 하는 법.
 - VC++ 명령 프롬프트 창을 2개 실행
 - 1번 프롬프트에서 bin으로 오세요 한후..  'syelogd > trace.txt'
 - 2번 프롬프트에서 'withdll -d:traceapi.dll  응용프로그램이름'

Tag |

MSDN Network 관련 함수들

from Study/Network 2007/11/27 22:34 view 35867

1.1 Transformation Functions

htonl
htons
inet_addr
inet_ntoa
ntohl
ntohs

1.2 DataBase Functions

gethostbyaddr
gethostbyname
gethostname
getprotobyname
getprotobynumber
getservbyname
getservbyport

1.3 Socket Functions

accept
bind
closesocket
connect
getpeername
getsockname
getsockopt
ioctlsocket
listen
recv
recvfrom
select
send
sendto
setsockopt
shutdown
socket


2. Windows  Socket  Extension  APIs

2.1 Transformation Functions

WSAHtonl
WSANtohl
WSAHtons
WSANtohs

2.2 DataBase Functions

WSAAsyncGetHostByAddr
WSAAsyncGetHostByName
WSAAsyncGetProtoByName
WSAAsyncGetProtoByNumber
WSAAsyncGetServByName
WSAAsyncGetServByPort
WSAEnumProtocols

2.3 Socket Functions

WSAAsyncSelect
WSACancelAsyncRequest
WSACancelBlockingCall
WSACleanup
WSAGetLastError
WSAIsBlocking
WSASetBlockingHook
WSASetLastError
WSAStartup
WSAUnhookBlockingHook
WSAEventSelect
WSAAccept
WSASend
WSASendTo
WSARecv
WSARecvFrom
WSAConnect
WSAloctl
WSAJoinLeaf
WSARecvEx
WSASocket
WSAWaitForMultipleEvents
WSAEnumNetworkEvents
WSACreateEvent
WSAGetOverlappedResult
WSASetEvent
WSAResetEvent


3. Socket  Structures

SOCKADDR
SOCKADDR_IN
IN_ADDR
HOSTENT
PROTOENT
SERVENT
LINGER
FD_SET
TIMEVAL
WSADATA
WSABUF
WSAOVERLAPPED
WSAPROTOCOL_INFO
WSANETWORKEVENTS

Tag |

익스플로러의 힘은 막강하다.

무려 보기->인코딩 에서 선택되는 방식에 따라서 시스템 전역으로 영향을 끼친다. 어설프게 설정했다가는

한글의 깨진 글씨만을 보게 된다. 아 윈도우~ -_-...

이 문제를 전에 어느 블로그에서 VS 2005에서 한글로된 프로젝트를 실행하지 못하는 문제를 해결하는 법을 보지

않았다면 개고생, 뻘짓을 할 뻔 했다.. 기억은 안나지만 그분에게 고마울 따름이다.

한글이 깨지거나 열리지 않거나 등등이 상황이 발생되면 무조건~ 익스플로러의 보기->인코딩 먼저 보자..ㅠ_ㅠ...

Tag |
1. msdn 참고
http://msdn2.microsoft.com/en-us/library/eeah46xd(VS.80).aspx


2. MFC의 Message Reflection 을 활용해서만든다.
In MFC 4.0, the old mechanism still works ? parent windows can handle notification messages. In addition, however, MFC 4.0 facilitates reuse by providing a feature called "message reflection" that allows these notification messages to be handled in either the child control window or the parent window, or in both.

3. 서브클리싱, 가상함수의 개념만 있다면 쉽게 이해 할 수 있다. 자식이 부모가 요청한 작업을 한다.
Windows controls frequently send notification messages to their parent windows. For instance, many controls send a control color notification message (WM_CTLCOLOR or one of its variants) to their parent to allow the parent to supply a brush for painting the background of the control.


예제 1. CEdit 클래스로 부터 상속받은 클래스로 에디트 박스의 배경색과 글자색을 정한다.

more..


예제 2. CListBox 로 상속받아은 클래스로 아이콘을 포함하는 리스트박스를 구현.

more..


예제 3. CStatusBar 에 안에 다른 Control을 포함시키기. Control in Control

more..



Tag |

hash 기본 구현.

from Study/자료구조 2007/11/27 19:19 view 31442
해쉬 구조를 알기 위해선 아래 문서를 읽어 보고...c로 해쉬를 구성해보자.
http://lxr.linux.no/source/include/linux/hash.h


1. 해쉬 함수는 여러가지 알고리즘이 있으나 커널에서는 간단하면서도 우수한 folding exclusive 방식을 사용.

#define PIDHASH_SZ  16
#define
pid_hashfn(x)   ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))

pid_hashfn(777)

( ( 777 >> 8 ) ^ 777 ) & ( 16 - 1 )

777                                           => 1100001001
777 >> 8                                   => 0000000011
( 777 >> 8 ) ^ 777                      => 1100001010
16 - 1                                       => 0000001111
( ( 777 >> 8 ) ^ 777 ) & ( 16 - 1 )  => 0000001010

2. 해쉬는 탐색을 위한 자료구조라고도 할 수 있다. 자료를 효율적으로 분산하여 저장할 수 있게 된다.
사용자 삽입 이미지
사용자 삽입 이미지


전체 소스~

more..

List를 C로만 구성하기 위해서 공개된 list 를 참고해 본다.
일단  http://lxr.linux.no/source/include/linux/list.h 를 참조.

1. 보통 리스트를 구현할 때 리스트와 자료형을 같이 사용하지만 이런 구현은 매번 리스트를 따로 구현해야하는 아픔이 있다.
사용자 삽입 이미지


2. 그래서 리스트의 구조를 구조체를 만들때 그 밑에 구현 해 놓는 방식을 사용하도록 한다.
3. 이렇게 되면 리스트를 포함 시켜놓으면 헤더 파일을 중심으로 리스트를 가질수 있다.

사용자 삽입 이미지

4. 리스트의 추가는 앞뒤의 객체에게 알려주면 된다.
void __list_add(struct list_head *new=0x3004,

            struct list_head *prev=0x1000,

            struct list_head *next=0x2004)

{

  next->prev = new;

  new->next = next;

  new->prev = prev;

  prev->next = new;

}


5. 구조체의 내용을 읽기 위해선 시작위치를 0으로 시작한다는 개념을 잡아야 한다. 

#define  list_entry( temp, type, list ) \

((type *)((char*)temp (unsigned long)(&((type *)0)->list)))

TASK *p = list_entry( temp, TASK, list );

p->pid;


전체 소스 ~

more..


조절과 조정의 의미

from Study/한글 2007/11/15 16:49 view 44790
조절 [調節]
[명사]
1 균형이 맞게 바로잡음. 또는 적당하게 맞추어 나감.
2 <의학>눈의 망막과 수정체의 거리를 알맞게 맞추거나 수정체의 모양을 바꾸어 외계(外界)의 상(像)을 망막 위에 맺도록 하는 작용. ≒조절 작용.
조절 [阻絶]
[명사]막히고 끊어짐. 또는 막히고 끊어지게 함.
조절 [操切]
[명사]=조속(操束).
조절하다
[동사]『…을』 ⇒조절.
조절하다
[동사]『…을』
1 ⇒조절.
2 <의학>⇒조절.

조정 [調整]
[명사]
1 어떤 기준이나 실정에 맞게 정돈함.
2 <고적>≒다듬기.
조정 [調停]
[명사]
1 분쟁을 중간에서 화해하게 하거나 서로 타협점을 찾아 합의하도록 함. =조제(調劑).
2 <법률>분쟁을 해결하기 위하여 법원이 당사자 사이에 끼어들어 쌍방의 양보를 통한 합의를 이끌어 냄으로써 화해시키는 일.
3 <사회>노동 쟁의가 해결되지 않았을 때에 노동 위원회에서 선출한 조정 위원이 노사 쌍방의 의견을 듣고 조정안을 작성·제시하여 쟁의가 해결되도록 노력하는 일.
조정 [朝廷]
[명사]임금이 나라의 정치를 신하들과 의논하거나 집행하는 곳. 또는 그런 기구. ≒궁부·정하·조가(朝家)·조단(朝端)·조당(朝堂)·조저(朝著).
조정 [漕艇]
[명사]<운동·오락>
1 정해진 거리에서 보트를 저어 스피드를 겨루는 경기. 혼자서 젓는 싱글 스컬에서 8명이 젓는 에이트까지 9종목이 있는데, 올림픽에서 남자는 2,000미터, 여자는 1,000미터 코스에서 실시한다. ≒경정(競艇)·경조(競漕)·경주(競舟).
2 배의 어느 한 부분에도 고정되지 않은 노를 앞에서 뒤로 저으면서 몰아가는 경기용 배. 선수는 배가 나가는 쪽을 마주 향하여 자리 잡고 배를 몬다.
조정 [?征]
[명사]가서 정벌함.
Tag |