안녕하십니까? 이번 포스팅의 주제는 abex crack me 만들기 입니다.

abex crack me의 동작화면을 한 번 보겠습니다.

간단하게 메세지박스 2개가 출력되는 프로그램입니다.

그럼 이것을 직접 c로 구현해보겠습니다.

저는 visual studio로 작성하겠습니다.

(참고로 저는 visual studio 2010 express 입니다.)


자 소스를 이렇게 작성하였습니다. 한줄씩 설명해드리겠습니다.

-  #include <windows.h> 

windows.h 헤더파일을 선언합니다. 메세지를 띄우기 위한    MessageBox함수와 GetDriveType함수를 사용하기 위해서입니다.

-  int EAX,ESI = 0 

연산에 필요한 변수 EAX와 ESI를 선언하였습니다.

- MessageBox (NULL, L"Make me think your HD is a CD-Rom.", L"abex' 1st crackme", MB_OK);

MessageBox함수입니다. 말 그대로 메세지박스를 띄우기 위한 함수입니다. 자세히 알아보기 위해 MSDN을 참고하겠습니다.

인자가 총 4개입니다. 하나하나씩 살펴 봅시다.

 * hWnd

  첫번 째 인자인 hWnd는 자료형이 HWND입니다. 이 HWND라는 것이 핸들윈도우의 약자를 뜻하는데 이 자료형으로 선언된 변수는 윈도우 창을 식별할 때에 쓰입니다. 

사실 이것을 정확하게 이해할려면 handle에 대한 개념을 알아야 하는데 너무 복잡해지니 그냥 넘어갑시다.

아무튼 결론만 말하면 이 hwnd는 메세지 상자의 소유자에 대한 핸들을 뜻합니다. 우리는 딱히 소유자를 정할 필요가 없으니 NULL값을 주었습니다.

* lpText

앞의 글자는 대문자 I가 아닌 소문자 L입니다. 유념하시기 바랍니다.

이 인자는 메세지창에 표시되는 문자열을 뜻합니다. 그런데? 자료형이 LPCTSTR이죠?

이 것을 간단하게 설명해드리겠습니다.

문자열을 저장하는 자료형이 char인것은 잘 아시죠? 그런데 사실 문자열을 저장하는 자료형이 제법 많습니다.

char, wchar, tchar, LPSTR, LPCSTR, LPCTSTR 등이 있습니다..

다른 자료형도 설명해주면 좋겠지만 그렇게 되면 너무 복잡해지므로 LPCTSTR만 설명하겠습니다.

먼저 LPCTSTR을 설명하기 전에 코드를 잠깐 설명하겠습니다.

코드는 크게 3종류로 나뉩니다.

싱글바이트코드, 멀티바이트코드, 유니코드로 나뉩니다.

싱글바이트 코드는 다른 말로 아스키코드라고도 하며 1바이트로 표현 가능한 문자들을 모아놓은 코드 체계입니다.

멀티바이트코드는 아스키코드문자 집합에 2바이트로 표현가능한 특정 문자를 넣은 코드체계입니다. ex)한글 등

유니코드는 전 세계의 문자를 2바이트로 표현가능하도록 규정해 놓은 코드체계입니다.

여러 코드가 나왔는데 이러한 코드를 설명한 이유는 이 코드 체계를 사용하는 자료형이 따로 나뉘어져 있기 때문입니다. 아래를 살펴보시면

싱글코드 체계를 사용하는 자료형

- char 등

멀티바이트 코드체계를 사용하는 자료형

- char *, const char * 등

유니코드 체계를 사용하는 자료형

- wchar_t, wchar_t *, TCHAR, LPSTR, LPCSTR, LPCTSTR 등

자 여기까지 읽으셨으면 우리가 찾는 LPCTSTR이 유니코드 체계를 사용하는 자료형이라는 것을 알 수 있습니다. 여기서 세부 설명을 하면

LP는 long pointer 즉 *를 의미하고 C는 const, T는 TCHAR의 T, STR은 String 입니다.

즉 LPCTSTR은 const TCHAR * 라고 생각하시면 됩니다. const char * 이 멀티바이트 코드체계를 사용하는 것에 비해 LPCTSTR은 유니코드체계를 사용합니다.

너무 이야기가 길어졌군요.  결론만 얘기하면 자료형이 LPCTSTR인 인자는 const char* 형식으로 값을 넣을 수 없다는 것입니다. 

이렇게 const char* 식으로 값을 넣으면 에러가 뜹니다. 그럼 어떻게 해야 할까요?

이럴때 대문자 L을 사용합니다. 즉 L"문자열" 이렇게 사용합니다.

L이 무엇이냐면 선언입니다.

즉 L 뒤에 오는 문자열이 유니코드 문자열이다 하고 선언해주는 것이지요.

그냥 글자를 적으면 이 글자가 멀티바이트코드체계 문자열인지 유니코드체계 문자열인지 컴퓨터가 인식을 하지 못합니다. 그래서 문자열 앞에 L을 붙임으로써 이 문자열이 유니코드체계문자열임을 선언하겠다라는 뜻입니다.

다음 인자로 넘어갑시다.

* lpCation 

  자료형이 LPCTSTR인 이 인자는 메세지 창의 제목을 뜻합니다. LPCTSTR은 설명했으니 넘어갑시다.

* uType

자료형이 UINT입니다. INT랑 비슷한 자료형인데 INT는 음수까지 저장가능한 것에 비해 UINT는 양수만 저장가능합니다. 하지만 INT보다 많은 범위의 양수를 저장할 수 있습니다.

여기 인자는 메세지에 표시되는 버튼을 뜻합니다. 여기서는 확인 버튼만 필요하므로 이미 정의되어 있는 MB_OK 라는 인자를 사용하였습니다. 

길고 긴 Messagebox 함수 설명이 끝났군요. 혹시 따로 궁금하신 분이 있다면 댓글에 질문을 해주시면 답변드리겠습니다.

- EAX = GetDriveType(L"C:\\");

GetDriveType은 현 컴퓨터의 디스크 드라이브 타입을 가르쳐주는 함수입니다.

MSDN의 설명을 봅시다.

인자가 하나 뿐이군요. lpRootPathName입니다. 자료형은 LPCTSTR인데 설명했으니 넘어갑시다. 

이 인자가 받는 값은 루트 경로를 뜻합니다. 즉 드라이브의 루트 디렉토리 경로를 인자로 받습니다. C드라이브의 루트 디렉토리가 어딜까요? 물론 다들 아시겠지만 확인을 위해 C디스크 안의 아무 폴더나 들어가봅시다.

C드라이브의 프로그램 파일로 들어갔을 때의 폴더주소입니다. 최상위의 경로가 C: 라고 되어있지요? 즉 드라이브의 루트 디렉토리 경로는 C: 입니다. 다만 MSDN의 설명을 참고해보니 경로 끝에 역슬래시(\)가 필요하다고 합니다. 즉 인자로

C:\\가 들어갑니다.

뭔가 이상하지 않습니까? \가 2개나 있습니다. c언어를 잘 배우신 분이라면 특수문자를 표기할 때 \를 붙여야 한다는 것을 아실 겁니다. 

ex) \/, \%, \' , \\ 등

자 이 다음은 설명이 별로 없습니다.

EAX와 ESI를 연산하고 

EAX와 ESI의 값을 비교하여 두 값이 다르면 실패 메세지 박스를 띄우고

성공하면 성공메세지 박스를 띄우는 겁니다.


자 소스코드 설명이 끝났으니 프로그램을 실행시켜 봅시다.

자 이것으로 abex crack me 만들기를 마치....

지 않아야겠죠?

제가 만든 프로그램과 일반 abex crack me가 똑같아 보이십니까? 아니죠?

일반 abex crack me를 실행 시켰을 때 저런 콘솔창 나타나던가요? 아니죠?

저런 콘솔창이 나타나는 이유는 우리가 프로그램을 짤 때 프로젝트 종류를 콘솔 응용 프로그램으로 했기 때문에 저런 콘솔창이 나타는 것입니다.

쓸데 없이 콘솔창이 나오니 멋없어 보이죠? 

그래서 다음 포스트엔 이 콘솔창이 안뜨게 프로그래밍을 해보겠습니다.

즉 콘솔 기반 프로그래밍이 아닌 응용 프로그래밍으로 해보겠습니다.

이상으로 포스팅을 마치겠습니다.

감사합니다.






Posted by englishmath
,