Archive for the 'Development' Category

HI DPI Mode지원을 위한 노가다.

지금은 UI 프로그램을 하고 있지는 않지만 Window 7이 나오면서 어쩌면 HI DPI Mode를 많이 쓰게 되지 않을까 하는 생각이 들더군요. 그래서 찾아 보니 MSDN에 Writing Guide가 잘 정리 되어 있었습니다. 물론 엄청난 UI 노가다를 요구하는 내용이지만 말이죠.

Writing High-DPI Win32 Applications
http://msdn.microsoft.com/en-us/library/dd464660(VS.85).aspx

내용을 간단히 말하면 DPI 값과 Screen Resolution 값을 통해서 폰트와 컨트롤들의 크기를 일일이 설정해줘야 한다는 내용입니다.

기존에 잘 쓰고 있더는 사이즈의 프로그램을 HI DPI를 지원하도록 바꿀려면 개발자분들이 정말 많은 노가다를 해야할꺼라 생각이 됩니다. ( 라이브러리화 되지 않은 환경에서 이 작업을 한다는건 거의 퇴사하라는 얘기와 다름 없겠죠 )

Declaring Managed Applications As DPI-Aware
: http://msdn.microsoft.com/en-us/library/ee308410(VS.85).aspx
: http://msdn.microsoft.com/en-us/library/ms633543(VS.85).aspx
: http://msdn.microsoft.com/en-us/library/ms701681(VS.85).aspx

그 아래쪽 내용을 보니 재미 있는것이 있더군요 Manifest를 수정해서 DPI모드를 적용 받지 않도록 하는 방법이더군요. ( 천만 다행이라 생각합니다. )

그래서 간단히 MFC Application에 해당 Manifest를 적용하고 HI DPI 모드에서 실행해 보았습니다.

HI DPI 모드에서 DPI-Aware 가 적용된 Application( Source Code )

HI DPI 모드가 적용되어 있다고 하더라도 원래의 크기 사이즈로 Application이 동작하더군요. !! 하지만 역시 캡션 및 테두리 부분은 그대로 HI DPI 모드가 적용되서 어색해 보이는 군요.

혹시나 HI DPI 모드가 고민이신 분들은 참고하시기 바랍니다.

 

User Mode에서 Hidden Process 탐지

User Mode에서 Hidden Process를 탐지하는 방법을 한가지 소개하도록 하겠습니다. 굉장히 간단하고 나름대로 막강합니다.

원리는 간단합니다. Process를 Hidden 한다고해서 Process Open이 되지 않는것은 아니기 때문에 이러한 원리를 이용해 OpenProcess와 EnumProcess를 이용하면 쉽게 Hidden Process를 탐지 할 수 있습니다.

void FindProcess( DWORD dwType )
{
DWORD dwProcesses[1024], dwNeeded;
DWORD dwProcCount;
DWORD dwPID;
DWORD itCount;

HMODULE hModule;
HANDLE hProcess;
BOOL bHide;

if ( !EnumProcesses( dwProcesses, sizeof(dwProcesses), &dwNeeded ) )
return;

dwProcCount = dwNeeded / sizeof(DWORD);

for ( dwPID = 0x0c ; dwPID < 0xFFFF ; dwPID += 4 )
{
char strName[MAX_PATH] = “”;

bHide = TRUE;
hModule = NULL;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, dwPID );

if ( hProcess == NULL )
continue;

// dwProcesses 안에 존재하지 않으면 Hidden 이 아니고 존재하지 않으며 Hidden Process

for (itCount = 0 ; itCount < dwProcCount ; itCount++ )
{
if ( dwPID == dwProcesses[ itCount ] )
{
bHide = FALSE;
break;
}
}

if( EnumProcessModules( hProcess, &hModule, sizeof(hModule), &dwNeeded))
{
GetModuleFileNameEx( hProcess, hModule, strName, sizeof( strName ) );

if ( ( bHide ) && ( dwType & FIND_HIDDEN ) )
{
printf(”PID : %-5d , Name : %16s %s\n”, dwPID, strName, “–[Hidden]–” );
}
else if ( dwType & FIND_NORMAL )
{
printf(”PID : %-5d , Name : %16s %s\n”, dwPID, strName, “” );
}
}
else if ( dwType & FIND_ZOMBIE )
{
GetProcessImageFileName( hProcess, strName, sizeof( strName ) );
printf(”PID : %-5d , Name : %16s %s\n”, dwPID, strName, “–[Zombie]–”);
}
CloseHandle( hProcess );

}
}

간단하죠 !! ^^

Source code : findhidden

Kernel Stack Overflow를 막는 한가지 방법

일반적으로 Kernel Stack의 사이즈는 굉장히 작기 때문에 UNEXPECTED_KERNEL_MODE_TRAP (7f) 와 같은 BugCheck이 자주 발생하곤 합니다. 이러한 경우에는 로직을 변경하거나 사용하는 Stack의 Size를 조정하여 문제를 해결하곤하죠.
하지만 이러한 방법 말고도 KeExpandKernelStackAndCallout을 이용하여 문제를 해결할 수 있습니다. KeExpandKernelStackAndCallout 함수는 Stack Jump를 통해서 Expand Stack를 사용할 수 있도록 도와 줍니다.

자세한 내용은 MSDN과 Advance Memory Management 문서를 보시면 도움이 되실듯 합니다.
MSDN : http://msdn.microsoft.com/en-us/library/aa906738.aspx
Advance Memory Management : http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/MemMgt.docx

[dev] Fast I/O가 발생하지 않는 3가지 경우..

Fast I/O 가 발생하지 않는 경우는 크게 3가지 정도 있습니다.

  • File Read/Write 여부를 판단하여 IRP를 생성하는 경우
  • 맨 처음 Cache Manager에 Read/Write가 시도 되는 경우
  • APC에 의하여 Read/Write가 시도 되는 경우

이것 이외의 경우도 여러가지 있겠지만 대략 이정도 입니다. 알고 있으면 언젠가 도움이 될꺼 같은 생각이…

최근 Catch Manager에 관한 내용을 개인적으로 정리하고 있지만 실제 Catch Manager의 구조를 보여주는 책자는 많아도  실제 동작을 보여주는 책자( Catch Manager의 동작 Stack 이라던지 ,  Lazy Write 발생하는 System Thread라던지… )의 는 어디에도 없더군요. 슬픈 현실입니다.

Intel Undocument Instruction

EFlag Register 상에 TF  Flag 도 Disable 되어 있고 DR6에 BS Flag도 역시 Disable 되어 있는데 이상하게 Single Step Exception이 발생하는 현상이 있어 관련 부분을 뒤지다 잼있는것을 찾았습니다. 

Intel Manual 상에도 없는 Undocument Instruction이 있더군요.

download : opcodes.zip 

상당히 재미있는 Instruction도 있군요 ㅋ