카테고리 보관물: 프로그래밍/소스/팁

NTSTATUS 메시지를 스트링 메시지로..

void DisplayError(DWORD NTStatusMessage)
{
LPVOID lpMessageBuffer;
HMODULE Hand = LoadLibrary(“NTDLL.DLL”);
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_FROM_HMODULE,
Hand,
Err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMessageBuffer,
0,
NULL );

// Now display the string.
// Free the buffer allocated by the system.
LocalFree( lpMessageBuffer );
FreeLibrary(Hand);
}

9x계열에서 프로세스가 실행되는 것을 감지

VXD 드라이버를 만들어서 CREATE_PROCESS 에 대한 control dispatch 펑션을 등록해서 감지를 할 수 있습니다.

Begin_Control_Dispatch XXXX
Control_Dispatch CREATE_PROCESS _OnCreateProcess cCall
Control_Dispatch DESTROY_PROCESS _OnDestroyProcess cCall
End_Control_Dispatch XXX

콜백 함수로 등록된 OnCreate[Destory]Process 함수에는 프로세스가 생성[종료] 시점에 DWORD 형 Process ID 가 넘어오게 됩니다.

물론 드라이버를 만들지 않고도 가능할 것입니다. API Hook 을 한다면… (근데 이 방법은 제가 직접 해보지 않아서..)

vxd에서 로컬 시간 얻기

vxd에서 로컬 시간을 얻는 방법입니다.

DWORD VTD_Get_Date_And_Time(
PDWORD pDate
);

이함수 호출 후에
pDate에는 1980년 1월1일 부터의 현재까지의 날 수를 얻을 수 있습니다.
그리고 리턴값은 현재 날로 부터 경과된 밀리초입니다.

따라서
위 함수를 통해서 시간을 얻기 위해서는

Time = VTD_Get_Date_And_Time(&Day);
MillSeconds = Time % 1000;
Time /= 1000;
Seconds = Time % 60;
Time /= 60;
Minutes = Time % 60;
Hours = Time / 60;

이렇게 얻을 수 있습니다.
그러나 날짜를 얻기위해서는 pDate가 1980년 1월1일 부터의 일 수이므로 윤년계산을 통해서 얻어와야 합니다.
거기까지는 아직 안되어 있는데 직접 구현해 보심이.

매크로 __DATE__, __FILE__, …

__DATE__
__FILE__
__LINE__
__TIME__
__TIMESTAMP__

위 매크로는 Visual C++ 컴파일러에서 지원하는 매크로입니다.

다음은 DbgPrint()함수를 사용해 출력한 결과이다.

DbgPrint(“DATE [%s]\n”, __DATE__);
DbgPrint(“FILE [%s]\n”, __FILE__);
DbgPrint(“LINE [%d]\n”, __LINE__);
DbgPrint(“TIME [%s]\n”, __TIME__);
DbgPrint(“TIMESTAMP [%s]\n”, __TIMESTAMP__);

출력 결과
DATE[Jul 24 2003]
FILE[c:\DebugSample\Debug.c]
LINE[13]
TIME[12:24:56]
TIMESTAMP[Thu Jul 24 12:24:56 2003]

일반적인 윈도우 소멸 순서

일반적으로 윈도우 종료시에는 OnClose() 함수를 Call 하게되고 OnClose() 에서는 DestroyWindows() 를 호출하게 됩니다.
마지막으로 OnNcDestroy() 함수가 호출되게 되고, 이 안에서 PostNcDestroy()함수가 호출되게 됩니다.

OnClose()
– 단지 내부에서 DestoryWindows()를 호출한다.

DestroyWindow()
– CWnd내부에 있는 윈도우를 destroy 한다.
– 윈도우를 해제하고 입력 포커스를 제거하기 위한 적절한 message를 윈도우에게 보낸다.
– 윈도우의 메뉴 제거 –
– 어플리케이션 큐를 비운다.
– timer 제거
– clipboard의 소유주 제거
– Clipboard-viewer chain을 끊는다. ( CWnd가 viewer chain의 맨 위에 있을 경우 )
– WM_DESTROY( OnDestroy )와 WM_NCDESTROY( OnNcDestroy ) 메시지를 위도우에게 보낸다
(아직 CWnd 객체는 Destory 되지 않은 상태임)

OnDestory()
– CWnd에게 현재 CWnd가 소멸되고 있는 중이라고 알려 주기위하여 호출. OnDestroy함수는 CWnd 함수가 화면에서 사라진 다음에 호출됩니다.

OnNcDestroy()
– Client가 아닌 영역이 destroy될 때 불려지는 함수입니다.. 윈도우가 소멸될때 마지막으로 불려지는 함수임. PostNcDestroy 함수를 호출

PostNcDestory()
– 윈도우가 소멸된 후 OnNcDestroy함수에 의하여 불려지는 기본함수.

The End of DLL Hell

MSDN Technical Articles 에 보면 “Teh End Of DLL Hell” 이라는 글이 있네요.

요지는 우리가 dll 을 사용하는데, 아무생각 없이 dll 을 로드해서 사용하게 되면 시스템에 설치된 dll을 우선 사용하게 되어
공격당한(?) dll 을 사용하게 되는것을 막는 방법입니다.
즉.. 무조건 어플리케이션이 있는 디렉토리의 dll을 먼저 로드하게 하는 방법입니다.

예를 들어 실행파일이 Test.exe 이면 같은 디렉토리에 Test.exe.local 이라는 빈 파일을 같이 만들어 두면
무조건 dll을 자기 디렉토리부터 검색하게 됩니다. LoadLibary()에 절대 경로를 넘겨줘도 무조건 현재 디렉토리부터 검색하게 됩니다

GetSystemVersion() 같은 함수를 Driver단에서는?

이런식으로 사용하면 되겠네요.

ULONG MajorVersion;
ULONG MinorVersion;

ULONG GetWinVersion()
{
RTL_OSVERSIONINFOW lpVersionInformation;

lpVersionInformation.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);

if(RtlGetVersion(&lpVersionInformation) != STATUS_SUCCESS)
{
MajorVersion = lpVersionInformation.dwMjaroVersion;
MinorVersion = lpVersionInformation.dwMinorVersion;
}
else
{
PsGetVersion(&MajorVersion, &MinorVersion, NULL, NULL);
}

}

WIN32 – Thread 생성시 어떤 API를 사용해야 할까?

사실상 Windows 운영체제에서 thread를 생성하는 방법은 하나입니다. CreateThread() 를 사용하는 방법 말이죠. 하지만 이렇게 많은 경우의 수가 생긴 이유는 순수한 Windows SDK 만으로 프로그램을 작성하는 경우는 거의 없기 때문입니다.

대부분의 프로그램은 CRT( C 런타임 라이브러리)를 사용하고 있고 좀 크다 싶은 프로그램은 MFC를 사용하는게 사실입니다.

이런 대형 라이브러리들은 훌륭한 체계를 갖추고 있고 그 중에는 thread와 관련된 것도 있으므로 나름대로 thread의 생성과 관련하여 해줘야 될 일들도 많이 있을 겁니다.

그러므로, 우리는 다음과 같은 결론을 얻을 수 있습니다.

순수한 Win32 를 사용해서 작성되는 프로그램이라면 CreateThread()를 사용해야 할 것이며, CRT를 사용하는 경우라면( 대부분의 경우) _beginthread()/_beginthreadex() 를 사용해야 할 것이며, MFC를 사용하는 경우라면 AfxBeginThread()를 사용해야 합니다.

9X 에서 프로세스 ID

영자님이 TDI Hook 에서 프로세스 ID를 얻은다음 app 로 넘겨주고 허용/차단 여부에 따라
드라이버 DB에 해당 프로세스 ID를 허용/차단 해주는 루틴을 테스트 하는 중에…..

9X에서는 프로세스 ID가 재사용 되는 것을 발견하였다.
(2X에서도 그럴 가능성이 없지 않지만)

즉, IEXPLORER 의 프로세스 ID 가 333 이고 이것을 허용 하였을때
IEXPLORER 를 종료한 후에 다른 프로세스(Outlook Express)를 띄우면 프로세스 ID가
333 이고, 자동으로 허용이 되버린다는 사실… ㅋㅋ
(대체 9X는 왜 이렇게 만든거야 쩝)

Win2000에서 137 이상 하드 인식

오늘 Win2000 Server SP4 에 200G 하드를 설치했는데, 디스크 관리자에서 128G로 인식을 하더군요.
찾아봤더니..

…………

일단 전제조건으로 윈2000의경우 서비스팩3 이상,
윈XP는 서비스팩1이 설치되어있어야한다

시작->실행->regedit->
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\atapi\Parameters
항목으로 이동후 우측패널에 REG_DWORD형의 EnableBigLba를 추가-> 데이타 값을 1로 설정한다~~ 그리고 저장후 재부팅하면 137기가 이상의 대용량하드의 인식이 가능해진다~~

(물론 바이오스에서 137G 이상을 인식한다는 전제 조건은 당연한 것이겠지요)