Windows API Basics

두비니

·

2023. 4. 15. 00:34

 

 

 

Full code

#include <windows.h>        //windows.h: 대부분의 헤더 파일이 정의
#include <stdio.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPRAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("First");

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpszCmdParam, int nCmdShow)
{
	HWND hWnd;
	MSG Message;
	WNDCLASS WndClass;
	g_hInst=hInstance;

	WndClass.cbClsExtra=0;
	WndClass.cbWndExtra=0;
	WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	WndClass.hCursor=LoadCursor(NULL, IDC_ARROW);
	WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
	WndClass.hInstance=hInstance;
	WndClass.lpfnWndProc=WndProc;
	WndClass.lpszClassName=lpszClass;
	WndClass.lpszMenuName=NULL;
	WndClass.style=CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&WndClass);

	hWnd=CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
		CW_USEDFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
		NULL, (HMENU)NULL, hInstance, NULL);
	ShowWindow(hWnd, nCmdShow);	

	while(GetMessage(&Message, NULL, 0,0)){
		TranslateMessage(&Message);
		DispatchMessage(&Message);
	}
	return (int)Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
	switch (iMessage){
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

 

 

1. 함수 정의 부분

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpszCmdParam, int nCmdShow)

윈도우 프로그램의 시작점(굳이 비유하자면 start()정도인듯)

윈도우를 만들고, 화면에 출력하는 일

 

APIENTRY: stdcall형 호출 규약을 사용하겠다는 의미 (stdcall: windows의 호출규약)

HINSTANCE hInstance: 프로그램의 인스턴스 핸들이다. (linux의 pid)

HINSTANCE hPrevInstance: 바로 앞에 실행된 현재 프로그램의 인스턴스 핸들. 16비트 윈도우 시절 사용되었으며 더이상 의미를 가지지 않음 (항상 NULL)

LPSTR lpszCmdParam: 명령줄 인수가 유니코드 문자열로 포함되어있다.

int nCmdShow: 어플리케이션 창이 최소화, 최대화 또는 정상적으로 표시되는지 여부를 나타내는 플래그

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)

대부분의 프로그램 처리는 WndProc에서 진행

주로 사용자와 시스템이 보내는 메시지를 처리함

 

 

2. WinMain 안에서 일어나는 일

1) 윈도우 클래스 정의

	WndClass.cbClsExtra=0;											//공유/여분 메모리(바이트)
	WndClass.cbWndExtra=0;											//공유/여분 메모리 영역
	WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);		//배경색상 지정
	WndClass.hCursor=LoadCursor(NULL, IDC_ARROW);					//마우스 커서 모양 지정
	WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);					//아이콘 모양 지정
	WndClass.hInstance=hInstance;									//윈도우 클래스가 사용할 인스턴스 핸들
	WndClass.lpfnWndProc=WndProc;									//윈도우에서 발생되는 메시지를 어느 함수에서 처리할지 - 보통 WndProc임
	WndClass.lpszClassName=lpszClass;								//윈도우 클래스의 이름 지정
	WndClass.lpszMenuName=NULL;										//프로그램이 사용할 메뉴 지정
	WndClass.style=CS_HREDRAW | CS_VREDRAW;							//윈도우 스타일 옵션

각각 모두 윈도우 클래스를 정의하는 과정이다. 각각이 의미하는 바는 다음과 같다.

 

2) RegisterClass함수를 호출하여 윈도우를 등록

	RegisterClass(&WndClass);

위에 설정한 윈도우를 사용한다는 뜻

 

 

3) CreateWindow 함수로 실제 윈도우 생성 & ShowWindow로 화면에 출력

	hWnd=CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
		CW_USEDFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
		NULL, (HMENU)NULL, hInstance, NULL);
	ShowWindow(hWnd, nCmdShow);

register한 윈도우를 실제로 생성 및 화면에 출력

 

4) 메시지를 받아서 메시지 처리 함수로 보내기

	while(GetMessage(&Message, NULL, 0,0)){
		TranslateMessage(&Message);
		DispatchMessage(&Message);
	}
	return (int)Message.wParam;

메시키를 계속해서 대기 (while문, GetMessage)

while문은 GetMessage()에서 WM_QUIT(FALSE)가 입력될 때 까지 돔. WM_QUIT는 프로그램이 종료될 때 받는 값. 즉 프로그램이 종료되지 않는 이상 계속해서 입력을 대기받는 상태라는 것

TranslateMessage: 키보드의 눌림이 발생할 때, 문자가 입력되었다는 메시지를 만듦

DispatchMessage: 받은 메시지를 메시지 처리 함수(WndProc)으로 전달

 

 

3. WndProc에서 일어나는 일

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
	switch (iMessage){
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

 

switch 구문을 기반으로 해야할 일을 정한다.

WM_DESTROY의 경우 강제적으로 종료되는 경우.

'SYSTEM HACKING' 카테고리의 다른 글

[Cheat Engine] 기본적인 사용법 / 단축키  (0) 2022.01.25
[ZAFL] Some Settings  (0) 2022.01.11
[IDA] 동적디버깅 setting  (0) 2021.07.23