dekar

[스크랩] abex1 크랙 강좌

전설비 2009. 2. 20. 16:02

출처 -   http://blog.daum.net/ssyangcal/2013923

 

 

이 장에서는 가장 간단한 크랙미 프로그램인 haque-abex1 를 크랙하고

동시에 올리 디버거에 사용방법을 익히겠습니다.

 

우선 크랙미 프로그램을 다운받습니다.

 

haque-abex1.7z ( 3.06 KB)

 

파일을 다운로드 받으시고 압축을 푸시면 실행 파일 두개가 있습니다.

하나는 abexcm1.exe 라는 파일과 abexcm1(cracked).exe 라는 파일이 있는데

abexcm1(cracked).exe 라는 파일은 제가 크랙한 실행파일이므로 실행하시지 마시고

크랙되지 않은 abexcm1.exe 를 실행하세요.

 

실행 화면은 다음과 같습니다.

 

 

 

첫 번째 메세지 박스는 이 프로그램이 여러분의 하드 디스크를 CD-ROM 으로 생각하게 만들라는 내용이며

두 번째 내용은 에러 메세지 상자가 뜨면서 CD-ROM 드라이브가 아니라는 내용입니다.

 

즉, 이 프로그램이 원하는 것은 자신의 하드 디스크를 CD-ROM 으로 생각하게 만들어라 입니다.

 

이제 올리 디버거를 실행시켜봅시다.

 

올리 디버거 실행화면은 다음과 같습니다.

 

 

그리고 File - Open 을 눌러서 우리가 크랙하려는 실행파일을 불러오시면 다음과 같은 창이 뜹니다.

 

 

우리가 크랙하려는 프로그램의 소스 코드가 디스 어셈블 되어서 나오는 것을 볼 수 있습니다.

 

이 크랙미 자체가 매우 쉬우므로 크랙에 그다지 실력이 없는 사람도 디스 어셈블리 된 코드만 봐도

1 ~ 2 초내에 답이 나오는 문제입니다.

물론 저는 크랙을 한 번도 해보지 않았다는 가정하에서 설명해드리겠습니다.

 

위에 그림에서 보시다시피 이 코드에서 크랙을 하기 위해 가장 중요한 곳은 바로 이 부분의 코드입니다.

 

00401024   3BC6  CMP EAX,ESI

00401026   74 15   JE SHORT abexcm1.0040103D

 

CMP 명령어를 통해서 EAX 레지스터와 ESI 레지스터에 값을 서로 비교하는데 이 값이 서로 같다면

40103D 주소로 점프하는 것을 알 수 있습니다.

 

이 주소에 점프하게 되면 다음과 같은 명령어를 실행하게 됩니다.

 

0040103D  |> 6A 00          PUSH 0                                   ; |/Style = MB_OK|MB_APPLMODAL

0040103F  |. 68 5E204000    PUSH abexcm1.0040205E                    ; ||Title = "YEAH!"

00401044  |. 68 64204000    PUSH abexcm1.00402064                    ; ||Text = "Ok, I really think that your HD is a CD-ROM! :p"

00401049  |. 6A 00          PUSH 0                                   ; ||hOwner = NULL

0040104B  |. E8 11000000    CALL           ; |\MessageBoxA

 

보시다시피 이 코드는 Ok, I really think that your HD is a CD-ROM! :p 라는 내용에 메세지 박스를 띄우는 코드입니다.

이 메세지 박스에 내용은 아시 다시피 당신의 하드 디스크를 시디롬으로 생각하게 만들었다는 내용입니다.

즉, 이것은 크랙미가 원하는 크랙의 결과라는 것을 알 수 있습니다.

결론은 크랙을 하기 위해서는 바로 위에 코드를 실행시키면 된다는 것 입니다.

 

하지만 막상 프로그램을 실행시켜보면 이 코드가 실행되지 않습니다.

우선 크랙미 프로그램을 디버깅 해보기 위해서 F8 키 (메뉴의 Debue - Step Over) 를 눌러보겠습니다.

F8키는 위에 그림에서 나온 디스 어셈블리 된 프로그램을 어셈블리 코드 한 줄 한 줄씩 실행하는 기능입니다.

여기서 Step Into 와 Step Over 가 있는데 Step Into 는 어셈블리 코드내에서 함수를 호출하면 그 함수로 들어가서 한줄 한줄씩 실행합니다.

Step Over 는 함수를 호출해도 그 함수안으로 들어가지 않습니다.

 

F8 키를 누르실 때 마다 코드가 한 줄 한줄씩 실행됨을 알 수 있습니다.

코드가 한줄 한줄씩 실행시키시다가 40101D 에서 멈추시게 되면 레지스터에 상태값은 다음과 같습니다.

 

 

EAX 레지스터에 주목하시기 바랍니다.

EAX 레지스터에는 3 이 들어가 있는데 C 드라이브 하드 디스크이면 반드시 3 이 들어가게 됩니다.

왜냐면 바로 위에 코드를 통해서

 

00401013  |. 68 94204000    PUSH abexcm1.00402094                    ; /RootPathName = "c:\"

00401018  |. E8 38000000    CALL       ; \GetDriveTypeA

 

다음과 같이 GetDriveTypeA('c:\'); 식으로 C 드라이브에 드라이브 타입을 읽어오게 되는데

이 때 리턴값이 EAX 레지스터에 저장되게 됩니다.

우선 GetDriveType 라는 API 에 리턴값에 대해서 알고 있어야 되는데 이것은 MSDN 을 통해서 보면 다음과 같이 나옵니다.

(물론 함수 이름만 봐도 머하는 함수인지 알지만..)

 

Value Meaning
DRIVE_UNKNOWN The drive type cannot be determined.
DRIVE_NO_ROOT_DIR The root path is invalid, for example, no volume is mounted at the path.
DRIVE_REMOVABLE The drive is a type that has removable media, for example, a floppy drive or removable hard disk.
DRIVE_FIXED The drive is a type that cannot be removed, for example, a fixed hard drive.
DRIVE_REMOTE The drive is a remote (network) drive.
DRIVE_CDROM The drive is a CD-ROM drive.
DRIVE_RAMDISK The drive is a RAM disk.

이 상수값이 실제로 어떠한 정수값을 가지고 있는 확인하기 위해서는 컴파일러에서 사용하는 윈도우즈 API 함수들이 있는 소스 파일을 보시면 나옵니다.

저 같은 경우에는 델파이를 사용하므로 델파이서 사용하는 windows.pas 에 보시면 다음과 같이 상수가 정의되어 있습니다.

 

const

  DRIVE_UNKNOWN = 0;

  {$EXTERNALSYM DRIVE_UNKNOWN}

  DRIVE_NO_ROOT_DIR = 1;

  {$EXTERNALSYM DRIVE_NO_ROOT_DIR}

  DRIVE_REMOVABLE = 2;

  {$EXTERNALSYM DRIVE_REMOVABLE}

  DRIVE_FIXED = 3;

  {$EXTERNALSYM DRIVE_FIXED}

  DRIVE_REMOTE = 4;

  {$EXTERNALSYM DRIVE_REMOTE}

  DRIVE_CDROM = 5;

  {$EXTERNALSYM DRIVE_CDROM}

  DRIVE_RAMDISK = 6;

  {$EXTERNALSYM DRIVE_RAMDISK}

 

이전에 EAX 레지스터에서 리턴했던 3 이라는 값은 DRIVE_FIXED 이며 이것은 MSDN 을 통해서 보셨다 시피 고정 된 하드 디스크 드라이브를 의미하게 됩니다.

다시 F8 키를 누르셔서 실행하시다가 401024 주소에서 멈추시고 레지스터에 상태를 보시기 바랍니다.

00401024  |. 3BC6           CMP EAX,ESI

이 부분에 코드는 다음과 같으며 당연히 EAX 레지스터와 ESI 레지스터에 있는 내용을 서로 비교하므로

EAX 레지스터와 ESI 레지스터에 값을 주목해야 할 필요가 있습니다.

이 부분에 코드가 바로 실행되기전에 EAX 레지스터에는 1 이 들어가게 됩니다.

왜냐면 이 명령어가 실행되기 전에 DEC 명령어를 두번 사용했기 때문입니다.

그리고 ESI 레지스터에는 쓰레기 값이 들어가게 됩니다.왜냐면 이 코드에서 ESI 레지스터를 사용하는 부분이 없습니다.

ESI 레지스터에 값은 프로그램 실행 시 달라지게 됩니다. ( 물론 간혹가다가 3 이나 0x400~~~ 으로 시작하는 값이 들어가기도 합니다. )

 

F8 키를 눌러봐서 알게 된 것은 CMP 명령어를 사용하는 이 부분에 코드에서 EAX 레지스터와 ESI 레지스터는 다르다는 것 입니다.

결국엔 바로 밑에 JE 명령어를 통해서 401028 주소로 점프해 에러관련 메세지를 출력하게 될껍니다.

따라서 이 부분에 코드를 401028 주소로 점프하지 않고 무조건 40103D 로 점프하게 만들면 됩니다.

 

다음 그림과 같이 따라하시면 됩니다.

 

 

 

클릭 후 바뀐 코드로 적용이 되며 Cancel 을 눌러서 창을 닫아주시면 됩니다.

바뀐 화면은 다음과 같습니다.

 

 

이렇게 코드를 바꿔버리면 CMP 명령은 무시되고 무조건 JMP 명령을 통해서 0x40103D 주소로 점프되게 크랙이 완료되게 되는 것 입니다.

그렇다고 해서 바로 실행하시지 마시고 마우스 오른쪽 버튼을 눌러 다음고 같이 따라하세요.

 

 

 

아무 파일이름으로 저장하시면 JE 명령을 JMP 명령어로 바꿔서 크랙한 실행파일이 생성되고 되고 이것을 직접 실행하시면..

 

 

크랙이 완료되었습니다.

너무나도 설명을 자세하게 했는데 다음부터는 설명을 자세하게 하지 않겠습니다.

출처 : Nohave Name's Money Blog
글쓴이 : 이름없음 원글보기
메모 :