Search

WinMain() (미완. 보면 알아

[- Disclaimer -] 아래 내용은 정보보안 공부 목적으로 작성된 것이나, 이를 토대로 허가되지 않은 대상에 실습을 진행할 경우 해킹 시도로 간주하여 법적 처벌을 받을 수 있음을 알려 드립니다.
WinMain()
✦ Windows GUI 프로그램 시작점
✧ Window 창 생성 과정 처리
→ WndClass부터 ShowWindow()까지
✦ APIENTRY 지시자
✧ __stdcall로 정의되어 있음
✦ Parameter1에 전달되는 Argument1
✧ hInstance
→ 현재 Instance Handle
→ 직접 hInstance를 사용하는 경우는 드물지만 아래의 경우에 사용될 경우 Windows Message 처리 및 Resource 관리에 핵심적 역할 수행
ㄴㄴ RegisterClassEx() 내 WNDCLASSEX 구조체의 hInstance Parameter
ㄴㄴ CreateWindowEx()의 Argument11
ㄴㄴ CreateWindowEx()의 Argument12와 Argument13의 Callback 함수의 NULL이 전달되는 Parameter에도 hInstance가 전달될 수 있으며 이때 OS에서 제공하는 것이 아닌 자체 제작 Resource 사용 // 자체 제작 Resource는 PE 내 Resource Section에 저장 됨
✦ Parameter2에 전달되는 Argument2
✧ hPrevInstance
→ 이전 Instance Handle
→ 없을 경우 NULL 포인터
ㄴㄴ Win32에서는 Default=NULL
ㄴㄴ 16 bit 호환성 때문에 존재 // 과거 16 bit 프로그램에서 동일 프로그램 실행 시 메모리 절약 목적의 Instance 공유를 위해 사용되었으나 현재는 의미 없음
✦ Parameter3에 전달되는 Argument3
✧ lpszCmdLine
→ 프로그래명 포함 명령행 Parameter
→ 통상 실행 직후의 경로 전달
✦ Parameter4에 전달되는 Argument4
✧ nCmdShow
→ Windows Application 팝업 방식이며 프로그램 실행 시 최소화, 모양 등의 형태 전달
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow);
Plain Text
복사
WinMain()의 hInstance Argument <-> _IMAGE_NT_HEADERS 구조체의 ImageBase 간 동일 - Ex)
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, PTSTR pszCmdLine, int nCmdShow) { g_hInstance = hInstance; (...) LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static TCHAR s_szMsg[64]; switch(uMsg) { case WM_CREATE: wsprintf(s_szMsg, C_YHD_MSG, g_hInstance); return TRUE; case WM_PAINT: { (...) DrawText(hDC, s_szMsg, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS); EndPaint(hWnd, &ps); } return 0; (...)
Plain Text
복사
WinMain() Caller
✦ RtlUserThreadStart() → BaseThreadInitThunk() → wWinMainCRTStartup() → _tmainCRTStartup() → wWinMain()
✦ RtlUserThreadStart()
✧ ntdll.dll
✦ BaseThreadInitThunk()
✧ Kernel32.dll
__tmainCRTStartup()
✦ C/C++ Runtime 초기화, WinMain() 호출, Process 종료 처리
__tmainCRTStartup()에서 WinMain() 호출 - Ex)
✦ 전처리기 조건을 GUI와 Unicode로 한정했을 경우에 한 함
(...) // WinMain()의 마지막 Parameter인 nCmdShow 값 획득 __declspec(noinline) int __tmainCRTStartup(void) { _TUCHAR *lpszCommandLine = NULL; WORD showWindowMode = 0; showWindowMode = __crtGetShowWindowMode(); // GetStartupInfo() 호출 후 Return 값 저장 (showWindowMode에 STARTUPINFO.wShowWindow 값 설정) // 초기화 작업을 위한 동기화 처리 __try { void *lock_free = 0; void *fiberid=((PNT_TIB)NtCurrentTeb())->StackBase; int nested=FALSE; while((lock_free = _InterlockedCompareExchangePointer((volatile PVOID *)&__native_startup_lock, fiberid, 0)) != 0) { (...) // c/c++ 관련 초기화 처리 if(__native_startup_state == __initializing) _amsg_exit(_RT_CRT_INIT_CONFLICT); else if(__native_startup_state == __uninitialized) { __native_startup_state == __initializing; if(_initterm_e(__xi_a, __xi_z) != 0) return 255; } if(__native_startup_state == __initializing) { _initterm(__xc_a, __xc_z); __native_startup_state = __initialized; } // WinMain()의 pszCmdLine Parameter에 전달될 명령어 Parsing (...) lpszCommandLine = (wchar_t *)_wcmdln; (...) // WinMain() 호출 mainret = wWinMain((HINSTANCE)&__ImageBase, NULL, lpszCommandLine, showWindowMode); // Process 종료 exit(mainret); } __except(_XcpFilter(GetExceptionCode(), GetExceptionInformation())) { mainret = GetExceptionCode(); _exit(mainret); } return 0; } // 리코엔 두꺼운거 1권_파일 구조 편 192p 이어서
Plain Text
복사