1. EXE의 종류
- Console App : 콘솔창을 생성한다. main, 콘솔(/SUBSYSTEM:CONSOLE)
- GUI App : 윈도우창을 생성. WinMain,Windows (/SUBSYSTEM:WINDOWS)
- Net App : CLR을 동작한다.
- Linker 옵션의 Subsytem차이 일 뿐이다.
- #pragma comment( linker, "[옵션]" )
- WhatExe ( EXE의 종류를 파악한다. )
- Console App : 콘솔창을 생성한다. main, 콘솔(/SUBSYSTEM:CONSOLE)
- GUI App : 윈도우창을 생성. WinMain,Windows (/SUBSYSTEM:WINDOWS)
- Net App : CLR을 동작한다.
- Linker 옵션의 Subsytem차이 일 뿐이다.
- #pragma comment( linker, "[옵션]" )
- WhatExe ( EXE의 종류를 파악한다. )
[ more.. | less.. ]
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD_PTR)(ptr) + (DWORD_PTR)(addValue))
int main(int argc, char* argv[])
{
char *filename = NULL;
HANDLE hFile;
HANDLE hFileMapping;
PIMAGE_DOS_HEADER dosHeader;
PBYTE g_pMappedFileBase = 0;
if(argc != 2)
{
cout << "WhatEXE.exe [대상파일명]" << endl;
exit(0);
}
filename = argv[1];
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if ( hFile == INVALID_HANDLE_VALUE )
{
cout << "CreateFile() fail" << endl;
return 0;
}
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if ( hFileMapping == 0 )
{
CloseHandle(hFile);
cout << "CreateFileMapping() fail " << endl;
return 0;
}
g_pMappedFileBase = (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);
if ( g_pMappedFileBase == 0 )
{
CloseHandle(hFileMapping);
CloseHandle(hFile);
cout << "MapViewOfFile() fail" << endl;
return 0;
}
dosHeader = (PIMAGE_DOS_HEADER)g_pMappedFileBase;
PIMAGE_FILE_HEADER pImgFileHdr = (PIMAGE_FILE_HEADER)g_pMappedFileBase;
if ( dosHeader->e_magic == IMAGE_DOS_SIGNATURE )
{
PIMAGE_NT_HEADERS pNTHeader;
PBYTE pImageBase = (PBYTE)dosHeader;
// Make pointers to 32 and 64 bit versions of the header.
pNTHeader = MakePtr( PIMAGE_NT_HEADERS, dosHeader, dosHeader->e_lfanew );
// First, verify that the e_lfanew field gave us a reasonable
// pointer, then verify the PE signature.
if ( IsBadReadPtr( pNTHeader, sizeof(pNTHeader->Signature) ) )
{
cout << "Not EXE" << endl;
return 0;
}
if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE )
{
cout << "Not EXE" << endl;
return 0;
}
char *s;
UINT width = 30;
switch( pNTHeader->OptionalHeader.Subsystem )
{
case IMAGE_SUBSYSTEM_UNKNOWN: s = "UNKNOWN (0)"; break;
case IMAGE_SUBSYSTEM_NATIVE: s = "Native"; break;
case IMAGE_SUBSYSTEM_WINDOWS_GUI: s = "Windows GUI"; break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI: s = "Windows character"; break;
case IMAGE_SUBSYSTEM_OS2_CUI: s = "OS/2 character"; break;
case IMAGE_SUBSYSTEM_POSIX_CUI: s = "Posix character"; break;
case IMAGE_SUBSYSTEM_NATIVE_WINDOWS: s = "Native Windows (Win9X driver)"; break;
case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: s = "Windows CE GUI"; break;
case IMAGE_SUBSYSTEM_EFI_APPLICATION: s = "EFI_APPLICATION"; break;
case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: s = "EFI_BOOT_SERVICE_DRIVER"; break;
case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: s = "EFI_RUNTIME_DRIVER"; break;
case IMAGE_SUBSYSTEM_EFI_ROM: s = "EFI_ROM";
case IMAGE_SUBSYSTEM_XBOX: s = "XBOX";
default: s = "unknown";
}
cout << filename << " " << "Subsystem" << " " <<
pNTHeader->OptionalHeader.Subsystem << " " << s;
}
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD_PTR)(ptr) + (DWORD_PTR)(addValue))
int main(int argc, char* argv[])
{
char *filename = NULL;
HANDLE hFile;
HANDLE hFileMapping;
PIMAGE_DOS_HEADER dosHeader;
PBYTE g_pMappedFileBase = 0;
if(argc != 2)
{
cout << "WhatEXE.exe [대상파일명]" << endl;
exit(0);
}
filename = argv[1];
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if ( hFile == INVALID_HANDLE_VALUE )
{
cout << "CreateFile() fail" << endl;
return 0;
}
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if ( hFileMapping == 0 )
{
CloseHandle(hFile);
cout << "CreateFileMapping() fail " << endl;
return 0;
}
g_pMappedFileBase = (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);
if ( g_pMappedFileBase == 0 )
{
CloseHandle(hFileMapping);
CloseHandle(hFile);
cout << "MapViewOfFile() fail" << endl;
return 0;
}
dosHeader = (PIMAGE_DOS_HEADER)g_pMappedFileBase;
PIMAGE_FILE_HEADER pImgFileHdr = (PIMAGE_FILE_HEADER)g_pMappedFileBase;
if ( dosHeader->e_magic == IMAGE_DOS_SIGNATURE )
{
PIMAGE_NT_HEADERS pNTHeader;
PBYTE pImageBase = (PBYTE)dosHeader;
// Make pointers to 32 and 64 bit versions of the header.
pNTHeader = MakePtr( PIMAGE_NT_HEADERS, dosHeader, dosHeader->e_lfanew );
// First, verify that the e_lfanew field gave us a reasonable
// pointer, then verify the PE signature.
if ( IsBadReadPtr( pNTHeader, sizeof(pNTHeader->Signature) ) )
{
cout << "Not EXE" << endl;
return 0;
}
if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE )
{
cout << "Not EXE" << endl;
return 0;
}
char *s;
UINT width = 30;
switch( pNTHeader->OptionalHeader.Subsystem )
{
case IMAGE_SUBSYSTEM_UNKNOWN: s = "UNKNOWN (0)"; break;
case IMAGE_SUBSYSTEM_NATIVE: s = "Native"; break;
case IMAGE_SUBSYSTEM_WINDOWS_GUI: s = "Windows GUI"; break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI: s = "Windows character"; break;
case IMAGE_SUBSYSTEM_OS2_CUI: s = "OS/2 character"; break;
case IMAGE_SUBSYSTEM_POSIX_CUI: s = "Posix character"; break;
case IMAGE_SUBSYSTEM_NATIVE_WINDOWS: s = "Native Windows (Win9X driver)"; break;
case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: s = "Windows CE GUI"; break;
case IMAGE_SUBSYSTEM_EFI_APPLICATION: s = "EFI_APPLICATION"; break;
case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: s = "EFI_BOOT_SERVICE_DRIVER"; break;
case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: s = "EFI_RUNTIME_DRIVER"; break;
case IMAGE_SUBSYSTEM_EFI_ROM: s = "EFI_ROM";
case IMAGE_SUBSYSTEM_XBOX: s = "XBOX";
default: s = "unknown";
}
cout << filename << " " << "Subsystem" << " " <<
pNTHeader->OptionalHeader.Subsystem << " " << s;
}
2. Data Type
P
Pointer를 나타낸다. ( ex : PPOINT -> POINT* )
LP
32비트 Code에서는 P와 완전히 같다. WIN32에서 PSTR과 LPSTR은 같은 코드.
T,_t
T는 DBCS와 UNICODE Type을 동시에 지원하기 위한 매크로이다.(TCHAR->char,wchar_t)
W
UNICODE Type이다.
C
const를 의미한다.
STR
문자열을 나타낸다.( ex : PSTR->char*)
H
H로 시작하는 대부분의 Type은 핸들형 Type을 나타낸다.( ex : HWND, HPEN, HBRUSH )
- 윈도우 구조체의 크기를 얻는 이유( Window Version이 많아서-_-.. )
- 구조체의 크기는 조건에 따라 달라지므로 구조체에서 크기를 저장하는 변수를 가지고 있다.
3. HANDLE 개념 : 객체를 가리키는 번호, 32bit 정수(long), 고유의 번호를 가진다.
- OS는 HANDLE 번호를 만들어서 리턴해준다.
- HWND : 윈도우 번호
- HPEN : 펜 번호
- HBRUSH : 브러시 번호
4. 윈도우 만들기 GUI 윈도우 생성!!
- 모든 윈도우는 윈도우 클래스로 부터 만들어진다.
- 배경색, 아이콘, 이름, 윈도우틀(클래스).. 이 필요하다.
- 윈도우 클래스를 시스템에 등록한다.
- 등록된 클래스로 윈도우를 생성한다.
- 윈도우를 보여준다.
- 미리 가져다 쓸수 있는 등록된 클래스가 40~50개가 있다.(button, edit...)
- OS는 윈도우클래스모음 List를 가지고 이를 관리한다. 65536개를 관리 가능하다.
- OS는 HANDLE 번호를 만들어서 리턴해준다.
- HWND : 윈도우 번호
- HPEN : 펜 번호
- HBRUSH : 브러시 번호
4. 윈도우 만들기 GUI 윈도우 생성!!
- 모든 윈도우는 윈도우 클래스로 부터 만들어진다.
- 배경색, 아이콘, 이름, 윈도우틀(클래스).. 이 필요하다.
- 윈도우 클래스를 시스템에 등록한다.
- 등록된 클래스로 윈도우를 생성한다.
- 윈도우를 보여준다.
- 미리 가져다 쓸수 있는 등록된 클래스가 40~50개가 있다.(button, edit...)
- OS는 윈도우클래스모음 List를 가지고 이를 관리한다. 65536개를 관리 가능하다.
5. 윈도우 핸들
- API함수의 대부분은 핸들만 알고 있다면 윈도우를 조작가능 하다. ex) MoveWindow, Setmenu...
- 핸들을 얻을 수 있는 함수들. ex) FindWindow, WindowFromPoint
- 예제 코드 ( 계산기 자식 윈도우 )
- 예제코드 ( 계산기 자식윈도우 숨기기 )
- API함수의 대부분은 핸들만 알고 있다면 윈도우를 조작가능 하다. ex) MoveWindow, Setmenu...
- 핸들을 얻을 수 있는 함수들. ex) FindWindow, WindowFromPoint
- 예제 코드 ( 계산기 자식 윈도우 )
[ more.. | less.. ]
BOOL CALLBACK foo( HWND hwnd, LPARAM lParam );
int main()
{
HWND hCalc = FindWindowEx( 0, 0, 0, _T("계산기") );
if ( hCalc == 0 )
{
wcout << _T("Not Calc.exe") << endl;
return -1;
}
EnumChildWindows( hCalc, foo, 0 );
}
BOOL CALLBACK foo( HWND hwnd, LPARAM lParam )
{
TCHAR cname[256];
TCHAR title[256];
GetClassName( hwnd, cname, 256);
GetWindowText(hwnd, title, 256);
wcout << hex << hwnd << "-" << cname << "-"<< title << endl;
return TRUE;
}
BOOL CALLBACK foo( HWND hwnd, LPARAM lParam );
int main()
{
HWND hCalc = FindWindowEx( 0, 0, 0, _T("계산기") );
if ( hCalc == 0 )
{
wcout << _T("Not Calc.exe") << endl;
return -1;
}
EnumChildWindows( hCalc, foo, 0 );
}
BOOL CALLBACK foo( HWND hwnd, LPARAM lParam )
{
TCHAR cname[256];
TCHAR title[256];
GetClassName( hwnd, cname, 256);
GetWindowText(hwnd, title, 256);
wcout << hex << hwnd << "-" << cname << "-"<< title << endl;
return TRUE;
}
- 예제코드 ( 계산기 자식윈도우 숨기기 )
[ more.. | less.. ]
int main()
{
HWND hCalc = FindWindow( 0, "계산기" );
if ( hCalc == 0 )
{
cout << "계산기를 먼저 실행하세요." << endl;
return 0;
}
HWND hCalcChild;
hCalcChild = FindWindowEx( hCalc, 0, "button", "5" );
if( IsWindowVisible( hCalcChild ) )
ShowWindow( hCalcChild, SW_HIDE );
else
ShowWindow( hCalcChild, SW_SHOW );
return 0;
}
int main()
{
HWND hCalc = FindWindow( 0, "계산기" );
if ( hCalc == 0 )
{
cout << "계산기를 먼저 실행하세요." << endl;
return 0;
}
HWND hCalcChild;
hCalcChild = FindWindowEx( hCalc, 0, "button", "5" );
if( IsWindowVisible( hCalcChild ) )
ShowWindow( hCalcChild, SW_HIDE );
else
ShowWindow( hCalcChild, SW_SHOW );
return 0;
}