http://research.microsoft.com/en-us/projects/detours/

Detours Library란 Hooking 방법의 일종으로, Dummy (Trampoline) 함수를 이용하여 다른 일을 시키고 난 후 원래의 리턴 코드를 그대로 수행해 후킹하는 방법입니다.

기존 코드의  후킹 그 자체도, 복원도 쉽다는 장점이 있습니다.

그래서 런타임 후킹도 쉽게 가능해, 디버깅이나 크래킹에 쉽게 적용 될 수 있습니다.

'Reverse Engineering' 카테고리의 다른 글

Detours Library (Hooking)  (0) 2008.12.24
API hooking ( Dll 바꿔치우기~)  (0) 2008.02.19
Ollydbg - 디버거  (0) 2008.01.15
PumaEngine - 디스 어셈블러 겸 메모리 제어  (0) 2008.01.15
W32Dasm - 디스 어셈블러  (0) 2008.01.15
RecStudio - 디 컴파일러  (0) 2008.01.15
Posted by 엘키 엘키

댓글을 달아 주세요

1.요약

API hooking 하는 방법 중에 Dll을 바꿔버리는 방법을 알아보고 구현시 주의점을 알아봅니다.

2.본문

[API hooking은 무엇인가?]

특정 API를 주시하고 있다가 누군가 그 API를 호출하면 중간에 개입하고자 함입니다.

메시지가 나올때나 윈도우가 생성될 때, 통지받을 수 있는 Windows Hook 과는 달리 공식적으로 문서화된 방법은 없습니다.

[ 왜 API hooking을 하는가? ]
다른 프로그램이 API를 어떻게 사용하고 있는가 지켜보려고..
내 프로그램의 디버깅을 목적으로.. (Deadlock detection이 좋은 예가 되겠네요..)


[ API 는 어떻게 hooking 하는가? ]

1. Import Address Table을 바꿔치는 방법.

이 방법은 이 글에서 다룰 내용이 아니므로, 간단히 설명하겠습니다. 읽으시는 분도 대충 읽으시길..

이 경우는 import library를 사용하는 경우에 해당됩니다. 대부분 GDI32.dll, User32.dll, Kernel32.dll 같은 경우는 import library를 사용해서 링크하고 있으니까, 위 dll에 들어있는 API는 좋은 hooking 대상이 되겠죠.

exe 파일은 프로세스가 생성될 때 자신이 원하는 위치에 로드될 수 있습니다. 가장 먼저 로드되는 모듈이기 때문이죠. 하지만 dll의 경우 에는 자신이 선호하는 위치를 이미 다른 dll이 차지하고 있을 수 있기 때문에, 최종적으로 어느 주소에 로드될지는 아무도 알 수가 없습니다.

다시 말해서, dll 안의 함수의 주소도 실행시간이 되어서야 결정된다는 얘기죠.

그렇다면, dll 안의 함수를 호출하는 클라이언트들은 어셈블리 코드를 어떻게 생산해내야 될까요? 단순히 "몇 번지로 call 해라" 라고는 할 수 없습니다.

결국은 Import Address Table 이라는 것을 중간에 두어서, 클라이언트 의 코드는 "IAT의 어디어디에 있는 주소로 call 해라" 처럼 될것이고, 실행 시간에 dll 이 로드되면 IAT는 적당히 초기화 되겠죠.

(C++의 v-table 개념과 매우 흡사하군요 :)

이런 작동방식 때문에 IAT에서 원하는 API의 주소를, 우리가 만든 함수의 주소로 바꿔버리면 간단하게 hooking이 되겠죠.
(뭐.. 그리 간단하지는 않습니다. -_-;;)

또 하나, 잘 생각해보면 프로세스의 중요한 영역을 함부로 바꾸는 일이다 보니까, 내 프로세스는 그렇다 치더라도, 다른 프로세스까지 hooking을 하려면 내가 만든 dll을 다른 프로세스에 주입하는 기술도 필요하겠죠..

dll을 주입하는 방법에는 dll을 레지스트리에 등록하기, Windows Hook 사용하기, CreateRemoteThread 사용하기, CreateProcess로 아예 디버깅 해버리기 등등 다양한 방법이 있습니다.

2. Dll 바꿔치우기~

자.. 이제 우리가 관심을 가지고 있던 부분입니다.

dll 바꿔치우기의 가장 큰 장점은 import library를 사용했건 LoadLibrary를 사용해서 실행시간에 동적으로 로드했건 다 먹힌다는 점입니다.

물론 시스템의 dll을 내 것으로 바꾸기 때문에 어느 정도의 위험부담은 있겠죠..

구현하기도 아주 쉽습니다. 보통은 다음과 같은 방식이죠..

하나, MSDN 도움말보고 똑같은 원형의 함수를 가진dll을 만든다. 두울, 기존의 dll을 다른 이름으로 바꿔서 보관한다.

세엣, 아무것도 모르는 순진한 클라이언트가 내 dll에 있는 함수를 호출하면, 적당히 체크하고, 원래 dll로 포워딩 시킨다..

끝입니다.. 뭐, 굳이 설명할 것도 없군요..

하나만 예를 들어서..

UINT WINAPI MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR pCaption, UINT uType)
이 API를 후킹한다면 다음과 같이 나만의 MessageBox를 구현할 수 있겠죠.

extern "C" 
UINT WINAPI MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR pCaption, UINT uType) 
{ 
    typedef UINT (WINAPI *FUNC_PTR)(HWND, LPCSTR, LPCSTR, UINT); 
    OutputDebugString("후후.. 순진하기는.. \n"); 

    UINT uRet; 
    // 진짜 user32.dll의 이름을 ~user32.dll로 바꿨다고 가정하고.. 
    HMODULE hMod = ::LoadLibrary("~User32.dll"); 
    if (hMod) 
    {
        FUNC_PTR pfnOrig = (FUNC_PTR)::GetProcAddress(hMod, "MessageBoxA"); 
        if (pfnOrig) 
        { 
            uRet = pfnOrig(hWnd, lpText, pCaption, uType); 
        } 
        ::FreeLibrary(hMod); 
    } 
    return uRet; 
} 

물론 매번 LoadLibrary와 FreeLibrary를 호출하는 것은 비효율적이니까, 적당히 바꿔주면 되겠죠.

자, 이 문서에서 말하려고 하는 것은 이제 시작입니다.

운좋게도 dll에 있는 API가 헤더 파일에도 포함되어 있고, 도움말까지 있다면 걱정이 없겠지만, 때로는 문서화되지 않은 API를 몰래 쓰는 프로그램도 있습니다.

물론 dumpbin이나 dendancy walker같은 툴로 dll을 살펴보면 이런 API의 이름은 알 수 있습니다. 하지만 이름이 전부라는 게 문제죠.. signature는 전혀 알 길이 없는 것 같습니다..( *signature : 반환값, 호출관행, 매개변수 리스트 등등)

그래서 우리의 목표를 이렇게 정하기로 합니다.

"좋다.. 매개변수는 몰라도 좋다.. 하지만 적어도 이 함수가 언제 호출이 되는가는 알고 싶다.."

이런 목표라도 이루고 싶다면 다음과 같은 방법으로 함수를 구현할 수 있습니다.

예를 들어

XXX.dll 에 YYY 라는 함수가 있다라고 치면..
// g_pfnOriginYYY에는 이미 원래 함수의 주소가 들어있다고 가정합니다 :) 
extern PROC g_pfnOriginYYY; 
__declspec( naked ) void YYY() 
{ 
    __asm pushad 

    // 여기서 마음껏 필요한 일을 합니다. 
    ::OutputDebugString("걸렸어~ YYY\n"); 

    __asm popad 
    __asm jmp    g_pfnOriginYYY 
} 
우선 이 함수 구현에 쓰인 알고리즘을 추상적으로 설명한다면 다음과 같습니다.

-> 함수가 호출 되었다 -> 함수가 호출되었음을 체크한다 -> 원래 함수의 주소로 그냥 점프한다.

이제 한 줄씩 설명을 해보죠..

__declspec( naked ) 는 함수의 prolog와 epilog 를 생성하지 않도록 해줍니다. prolog와 epilog란 스택 프레임을 만들고 제거하는 작업을 말합니다. 다시, 스택 프레임이란 ebp 레지스터에 함수 시작 당시의 esp 를 보관함으로써 함수의 인자나 지역변수로의 접근을 편하게 하는 것을 말합니다.

우리가 만든 함수는 정상적으로 리턴하지 않고 그냥 원래 API의 주소로 jmp 해버립니다.
그런데, prolog 때문에 스택이나 레지스터가 지저분해진다면 문제가 생기겠죠.

__asm 은 어셈블리 언어를 C++ 소스에서 사용할 수 있게 해줍니다.

pushad 는 모든 레지스터를 저장하는 명령입니다. 함수가 호출되었을 때 아무것도 하지않고 원래 API로 점프해버린다면 필요없는 명령이지만, 중간에 체크하는 과정에서 레지스터가 변경될 것이 분명한 일이므로, 다시 복구하기 위해서 저장해 둡니다.

popad는 모든 레지스터를 복구하는 명령입니다.

jmp 명령을 통해서 원래 API 의 주소로 제어를 옮깁니다. call 이 아니라는 점에 주의해야겠죠?

다시 한 번 개념적으로 정리해 보겠습니다.

일단은 YYY라는 함수의 구현이 필요합니다. 하지만 우리 역시 함수의 signature를 다 적어줄 필요는 없습니다. 함수의 signature라는 것은 C++ 컴파일러의 마법일 뿐이죠..

그렇더라도 C++ 컴파일러를 사용하는 한은 컴파일러의 마법을 피해나갈 방법은 없습니다. 가장 좋은 방법은 assembly 로 함수를 만든 다음에 이진파일을 함께 링크하는 방법이겠죠. 하지만.. 다행이도 VC++ 에는 __declspec( naked ) 라는 서비스가 있었고, 이는 순수하게 inline assembly 만을 사용해서 프로그래밍 하는 것을 가능하게 해줍니다..


3.예제

예제는 직접 열어보셔야 합니다. 이 항목에서는 예제를 사용하는 법을 설명드립니다.

예제의 Output 폴더를 보시면

PotentialClientExe.exe
MyHookingDll.dll
SystemDll.dll

세 개의 이진파일이 있습니다.

여기서 SystemDll.dll 이 실제 시스템에 설치된 dll 이라고 생각하시면 됩니다.
MyHookingDll.dll 이 바꿔치기할 용도로 만든 dll 이구요.
PotentailClientExe.exe 는 SystemDll 내의 API를 사용하는 잠재적인 어플리케이션 이라고 생각하시면 되겠죠.

우선, PotentailClientExe.exe 를 실행시켜봅니다.

그러면 단순히 메시지 박스가 하나 뜨죠?

이제 후킹을 실행하기 위해서 다음의 절차를 밟습니다.

SystemDll.dll 의 이름을 ~SystemDll.dll 로 바꿉니다.
MyHookingDll.dll 의 이름을 SystemDll.dll 로 바꿉니다.
다시 PotentailClientExe.exe를 실행합니다.

이번에도 마찬가지로 메시지 박스가 뜨지만, 달라진 점이 있습니다.
바로 콘솔창에 후킹되었다는 메시지가 나오는.. 그것이죠~


4.참고

Advanced Windows, Jeffrey Richter Ch.18 "Breaking through Process Boundary Walls"
Debuggin Application, John Robbins Ch.12 "Multithreaded Deadlocks"
Under the Hood, Matt Pietrek , Feb 2000 MSJ
MSDN Library




- 2001.08.19 Smile Seo -

'Reverse Engineering' 카테고리의 다른 글

Detours Library (Hooking)  (0) 2008.12.24
API hooking ( Dll 바꿔치우기~)  (0) 2008.02.19
Ollydbg - 디버거  (0) 2008.01.15
PumaEngine - 디스 어셈블러 겸 메모리 제어  (0) 2008.01.15
W32Dasm - 디스 어셈블러  (0) 2008.01.15
RecStudio - 디 컴파일러  (0) 2008.01.15
Posted by 엘키 엘키

댓글을 달아 주세요

사용자 삽입 이미지

http://www.ollydbg.de/

많은 분들이 사용하고 계시는 디스 어셈블러인 Ollydbg 입니다. 다양한 옵션을 지원하고, 플러그인 기능을 통해 기능 확장이 가능하며, 편리한 프로그램입니다.

'Reverse Engineering' 카테고리의 다른 글

Detours Library (Hooking)  (0) 2008.12.24
API hooking ( Dll 바꿔치우기~)  (0) 2008.02.19
Ollydbg - 디버거  (0) 2008.01.15
PumaEngine - 디스 어셈블러 겸 메모리 제어  (0) 2008.01.15
W32Dasm - 디스 어셈블러  (0) 2008.01.15
RecStudio - 디 컴파일러  (0) 2008.01.15
Posted by 엘키 엘키

댓글을 달아 주세요


사용자 삽입 이미지

메모리 검색에 대한 다양한 옵션을 지원하고, 디스 어셈블러 기능도 강력한 편이라 유용한 유틸리티 입니다.
Posted by 엘키 엘키

댓글을 달아 주세요


사용자 삽입 이미지

디스 어셈블러의 일종인 W32Dasm 입니다.
Posted by 엘키 엘키

댓글을 달아 주세요


사용자 삽입 이미지

디 컴파일러인 RecStudio 입니다.
니모닉과, 레지스터로 뒤덮여있지만 구조화된 상태를 보여주기 때문에 왠만한 디스 어셈블러보다 가독성이 높은 편입니다.
Posted by 엘키 엘키

댓글을 달아 주세요

1.cff crackme #2 Serial Crack

이번에는 acid의 CrackMe들을 풀어 보자.

이글을 쓰기전 acid가 만든 CrackMe를 풀면서

느꼈던 것은 acid라는 사람은 C보다는 Delphi

잘하기 떄문에 Delphi로 CrackMe만든게 아닌지 짐작하여 본다.

어쨰든 Delphi로 만들어진 CrackMe들인 만큼 DeDe를 이용하여

크랙을 한번 하여보자. 시작하기전 한마디 하자면 무지 쉽다.

! abex 솔루션에서 말했던 것처럼 CrackMe풀기전에

Crack Me가 원하는것이 무엇인지 확실이 알고 해야 할것이다.

Crack Me는 단지 Crack Me에 맞는 시리얼만 맞추면 된다.

정말 간단하지 않은가? 먼저 대상을 실행해 보도록 하자.

정말 간단한 인터페이스를 가지고 있다.

시리얼을 입력받을 Edit 한개와 체크 버튼 그리고 종료 버튼이다.

체크 버튼의 이름을 잘 봐두도록 하자. "Check the Serial"이다.

이제 DeDe를 이용하여 대상을 불러오도록 하자

다 불러왔다면 DeDe 메뉴에서 Procedures 메뉴를 누르자.

왼쪽에 표시되어있는 이벤트 목록의 첫번쨰것부터 마우스 오른쪽

버튼으로 클릭하면 나오는 팝업메뉴중 "Show additional data"

메뉴를 눌러 caption이 뭔지 참조하며 Caption이 "Check the Serial"

인것을 찾도록 하자.

첫번쨰 이벤트인 SpeedButton1Click의 Caption이 "Check the Serial" 임을 볼수 있었다.

그럼 이제 첫번쨰 이벤트를 마우스 오른쪽 버튼으로 클릭할떄 나오는 팝업메뉴중

역어셈블 메뉴를 눌러 해당 이벤트를 역어셈블 하여 오자.


! 보면 0x442B4B 줄에서 GetText 델파이 내부 함수로 시리얼 창에서

우리가 입력한 값을 긁어오고 긁어온 결과를 eax에 넣는다.

그리고 edx에는 "12011982"라는 의심가는 문자열을 넣는다.

그리고 0x403B44를 콜한다. 0x403B44지점에 들어와 조금 내려 보니

00403B4B   39D0                   cmp     eax, edx

00403B4D   0F848F000000           jz      00403BE2

이런 부분이 보인다. eax에는 우리가 입력한 키값이 들어있고

edx에는 "12011982"라는 의심가는 문자열이 들어있는데...

두가지를 비교하여 비어 있다면 다시 위로 점프하여 루프(?)

도는 것을 볼수 있다. 만약 0 이 아니라면..

00403B53   85F6                   test    esi, esi

00403B55   7468                   jz      00403BBF

esi[우리가 입력한값]가 비어있나 안비어있나 체크한후...

00403B57   85FF                   test    edi, edi

00403B59   746B                   jz      00403BC6

edi[올바른 시리얼값]도 비어있나 비어있지 않나 체크한다.

00403B5B   8B46FC                 mov     eax, [esi-$04]

00403B5E   8B57FC                 mov     edx, [edi-$04]

00403B61   29D0                   sub     eax, edx

그리고 esi[우리가입력한값]의 길이를 eax에 넣고...

edi[올바른 시리얼값]의 길이를 edx에 넣고 eax에서 edx뺸다.

그리고 입력된 길이가 올바르다면 밑과 같은 곳으로 가서 체크한다.

00403BCE   38D9             CMP CL,BL

00403BD0   75 10            JNZ SHORT CrackMe2.00403BE2

00403BD2   38FD             CMP CH,BH

00403BD4   75 0C            JNZ SHORT CrackMe2.00403BE2

00403BD6   C1E9 10          SHR ECX,10

00403BD9   C1EB 10          SHR EBX,10

00403BDC   38D9             CMP CL,BL

00403BDE   75 02            JNZ SHORT CrackMe2.00403BE2

00403BE0   38FD             CMP CH,BH

00403BE2   5F               POP EDI                            

00403BE3   5E               POP ESI

00403BE4   5B               POP EBX

어쨰든 이건 그런거고 올바른 시리얼 값은 EDI에 저장되어 있다.

바로 "12011982"이다. 한번 직접입력하여 보자


어떤가? 비교적 쉽지 않았는가? 간단한 준비 운동이었다.

2.cff crackme #3 name/serial Crack

여어~ 이번에는 name과 serial두개다를 요구한다.

하지만 본인이 미리 알아본 결과 name과 serial은

이미 정해져 있다. 그럼으로 무지 쉽다. :p

이번 CrackMe역시 Delphi로 작성되 있으니 DeDe

이용 하도록 하고.. 먼저 CrackMe를 실행해 보자.

Name 입력창과 Serial입력창, 등록버튼 그리고

종료 버튼이 보인다. 이전 CrackMe에서 그랬던 것처럼

이번에도 등록버튼의 Capiton을 잘 외워 둔다.

"Register now !"이다. 기억하였으면...

이제 DeDe로 대상을 불러 오도록 하자


로딩이 완료되었으면 DeDe의 Procedures 메뉴를 누르자.



2가지의 이벤트들이 보이는데 Show additional data메뉴의

Caption이 "Register now !"을 찾아 보자.

운이 좋게도 첫번째 이벤트가 Capiton으로 "Register now !"

가지고 있다. 이제 역어셈블 메뉴를 눌러 이벤트를

역어셈블 하여 오자.


역어셈블 해온 코드에서 가장 먼저 보이는 부분이다.

눈에 띄는것은 Name을 읽어온후 비어있는가 비어있지 않는가

체크한후 비어있지 않다면 점프를 하는 것이다.

당연히 점프를 해야 정상일것임으로 점프되는 지점인...

0x440EF2 부분을 보도록 하자.


0x440EF2로 이동해 와보니.. 이곳은 Serial이 비어있는가

비어 있지 않은가를 체크한후 비어있지 않다면 0x440F1E로

점프 하는것을 볼수 있다. 그럼으로 0x440F1E로 이동해 보자.


! 보니 다시 Name을 읽어온후 eax에 저장하고

edx에는 "Resisterd User"라는 의심가는 문자열을 저장한후

0x403B2C라는 의문가는 지점을 콜 하는것을 볼수 있다.

0x403B2C부분으로 보도록 하자.


별로 볼건 없다 그져 비어있는가 안비어있는가를 체크한후

별문제 없다면 0x403BB5로 점프하게 된다.. 0x403BB5로 가보자


'Registered User' 라는 문자열과 우리가 입력한 Name을

한글자씩 가지고 와서 비교하는 루틴이란걸 볼수 있다.

'Registered User'와 비교하는걸 봐서 'Registered User'가

올바른 Name이라는 점을 알수 있다. 용량 문제도 있고 해서

Serial부분은 줄이도록 하겠다. Serial의 올바른 답은..

GFX-754-IER-954라는것은 쉽게 알수 있고 하니 말이다.

Name:Registered User

Serial:GFX-754-IER-954

입력하여 보자.




3.cff crackme #3 name/serial Crack

마지막 3번 CrackMe입니다.

3번인만큼 이번엔 이름에 대한 시리얼 뽑기입니다.

그러나 지금 시간이 12시인 만큼 간단하게 쓰도록

하겠습니다. 자세히 하는건 개인이 해도 충분하니

말이에요. 먼저 대상 CrackMe를 실행하여 봅시다.


이번 CrackMe도 Name 입력창, Serial입력창

체크버튼,종료버튼 등이 보입니다.

이번에도 역시 체크버튼의 제목을 잘 외워 둡시다.

"Check if valid..." 이군요. 이제 알았으니...

DeDe로 이 CrackMe를 불러 오고 Procedures메뉴로

들어가서 이벤트 목록들의 Show additional data를

봐서 Caption이 "Check if valid..." 인것을 찾습니다.

두번쨰 버튼의 Capiton이 "Check if valid..." 이네요.

역어셈블 메뉴를 선택하여 이벤트를 역어셈블 해옵시다.

역어셈블 해온 코드를 보니 맨처음엔 Name이 공갈인지 체크 하네요.

---------------------------------------------------------------------

00457BC7   648920                 mov     fs:[eax], esp

00457BCA   8D55FC                 lea     edx, [ebp-$04]

* Reference to control TForm1.Edit1 : TEdit|

00457BCD   8B83D8020000           mov     eax, [ebx+$02D8]

* Reference to: controls.TControl.GetText(TControl):TCaption;|

00457BD3   E808C3FCFF             call    00423EE0

00457BD8   837DFC00               cmp     dword ptr [ebp-$04], +$00

00457BDC   7518                   jnz     00457BF6 ;<================

00457BDE   6A00                   push    $00

* Possible String Reference to: 'Enter your Name !'|

00457BE0   B9987E4500             mov     ecx, $00457E98

* Possible String Reference to: 'You must enter your Name !'|

00457BE5   BAAC7E4500             mov     edx, $00457EAC

* Reference to TApplication instance|

00457BEA   A198A54500             mov     eax, dword ptr [$0045A598]

00457BEF   8B00                   mov     eax, [eax]

* Reference to : TApplication._PROC_00440130()|

00457BF1   E83A85FEFF             call    00440130

---------------------------------------------------------------------

0x457BD8줄에서 0인지 체크하고 0x457BDC줄에서 0이 아니면 점프하네요.

점프 되는 지점인 0x457BF6으로 가봅시다.

---------------------------------------------------------------------

00457BF6   8D55FC                 lea     edx, [ebp-$04]

* Reference to control TForm1.Edit2 : TEdit

|

00457BF9   8B83DC020000           mov     eax, [ebx+$02DC]

* Reference to: controls.TControl.GetText(TControl):TCaption;

|

00457BFF   E8DCC2FCFF             call    00423EE0

00457C04   837DFC00               cmp     dword ptr [ebp-$04], +$00

00457C08   7518                   jnz     00457C22  ;<==============

00457C0A   6A00                   push    $00

* Possible String Reference to: 'Enter a Serial !'

|

00457C0C   B9C87E4500             mov     ecx, $00457EC8

* Possible String Reference to: 'You must enter a Serial !'

|

00457C11   BADC7E4500             mov     edx, $00457EDC

* Reference to TApplication instance

|

00457C16   A198A54500             mov     eax, dword ptr [$0045A598]

00457C1B   8B00                   mov     eax, [eax]

* Reference to : TApplication._PROC_00440130()

|

00457C1D   E80E85FEFF             call    00440130

---------------------------------------------------------------------

이번에는 Serial을 입력받은후 입력받은 시리얼이 빈것인지

0x457C04에서 체크하고 0x457C08줄에서 비어있지 않다면 점프하네요.

점프 되는 지점인 0x457C22으로 가봅시다.

---------------------------------------------------------------------

00457C22   33C0                   xor     eax, eax  ;eax를 0으로 초기화

* Reference to GlobalVar_0045B840

|

00457C24   A340B84500             mov     dword ptr [$0045B840], eax

00457C29   8D55FC                 lea     edx, [ebp-$04]

* Reference to control TForm1.Edit1 : TEdit

|

00457C2C   8B83D8020000           mov     eax, [ebx+$02D8]

* Reference to: controls.TControl.GetText(TControl):TCaption;

|

00457C32   E8A9C2FCFF             call    00423EE0  ;Name을 다시 읽어옴

00457C37   8B45FC                 mov     eax, [ebp-$04]

* Reference to: System.Proc_00403C38

|

00457C3A   E8F9BFFAFF             call    00403C38  ;Name이 비었는지 체크

* Reference to GlobalVar_0045B844

|

00457C3F   A344B84500             mov     dword ptr [$0045B844], eax

00457C44   A144B84500             mov     eax, dword ptr [$0045B844]

* Reference to: Unit_004069CC.Proc_004079D0

|

00457C49   E882FDFAFF             call    004079D0

00457C4E   83F806                 cmp     eax, +$06  ;6보다 길어야함

00457C51   731D                   jnb     00457C70   ;길거나 같으면 점프

00457C53   6A00                   push    $00

* Possible String Reference to: 'Name too short !'

|

00457C55   B9F87E4500             mov     ecx, $00457EF8

* Possible String Reference to: 'Your Name must be at least 6 Chars

|                                long !'

|

00457C5A   BA0C7F4500             mov     edx, $00457F0C

* Reference to TApplication instance

|

00457C5F   A198A54500             mov     eax, dword ptr [$0045A598]

00457C64   8B00                   mov     eax, [eax]

* Reference to : TApplication._PROC_00440130()

|

00457C66   E8C584FEFF             call    00440130

---------------------------------------------------------------------

0x457C4E줄에서 Name의 길이가 6보다 짧은지 체크하고

0x47C51줄에서 짧지 않으면(길거나 같으면) 점프하네요.

점프 되는 지점인 0x457C70으로 가봅시다.

---------------------------------------------------------------------

00457C70   8D55FC                 lea     edx, [ebp-$04]

* Reference to control TForm1.Edit1 : TEdit

|

00457C73   8B83D8020000           mov     eax, [ebx+$02D8]

* Reference to: controls.TControl.GetText(TControl):TCaption;

|

00457C79   E862C2FCFF             call    00423EE0  ;Name을 다시 읽어옴

00457C7E   8B45FC                 mov     eax, [ebp-$04]

00457C81   BA01000000             mov     edx, $00000001

00457C86   4A                     dec     edx

00457C87   3B50FC                 cmp     edx, [eax-$04]  ;edx와 0비교

00457C8A   7205                   jb      00457C91  ;작으면 점프 (점프할게 당연하다.)

---------------------------------------------------------------------

Name을 다시 읽어온후 0x457C87줄에서 0과 비교하고 0x457C8A줄에서

점프를 해야 한다는것을 알수 있습니다. 점프 되는 지점인 0x457C91로 가보죠.

---------------------------------------------------------------------

00457C91   42                     inc     edx ;0인 edx를 1증가 시켜 1로 만듬

00457C92   0FB64410FF             movzx   eax, byte ptr [eax+edx-$01]  ;Name 첫글자를 eax

00457C97   6BF002                 imul    esi, eax, $02  ;esieax 그리고 2로 곱셈

00457C9A   7105                   jno     00457CA1  ;오버 플로가 왜나오는지 모르겠음

* Reference to: system.@IntOver;

|

00457C9C   E8EBAEFAFF             call    00402B8C

00457CA1   8D55F8                 lea     edx, [ebp-$08]

* Reference to control TForm1.Edit1 : TEdit

|

00457CA4   8B83D8020000           mov     eax, [ebx+$02D8]

 

* Reference to: controls.TControl.GetText(TControl):TCaption;

|

00457CAA   E831C2FCFF             call    00423EE0  ;다시 Name을 읽어온다.

00457CAF   8B45F8                 mov     eax, [ebp-$08]  ;결과를 eax

00457CB2   BA02000000             mov     edx, $00000002  ;edx에는 2를 넣고...

00457CB7   4A                     dec     edx  ;edx를 1로 만들고..

00457CB8   3B50FC                 cmp     edx, [eax-$04]  ;edx와 Name을 비교한다.

00457CBB   7205                   jb      00457CC2  ;작으면 점프 (점프할게 당연하다.)

---------------------------------------------------------------------

0x457B8 지점에서 edx(1)과 비교하여 1보다 길으면 0x457CBB에서 점프한다.

점프 되는 지점인 0x457CC2로 가보자.

---------------------------------------------------------------------

00457CC2   42                     inc     edx

00457CC3   0FB64410FF             movzx   eax, byte ptr [eax+edx-$01]

00457CC8   6BC002                 imul    eax, eax, $02

00457CCB   7105                   jno     00457CD2

* Reference to: system.@IntOver;

|

00457CCD   E8BAAEFAFF             call    00402B8C

00457CD2   03F0                   add     esi, eax

00457CD4   7105                   jno     00457CDB

* Reference to: system.@IntOver;

|

00457CD6   E8B1AEFAFF             call    00402B8C

00457CDB   8D55F4                 lea     edx, [ebp-$0C]

* Reference to control TForm1.Edit1 : TEdit

|

00457CDE   8B83D8020000           mov     eax, [ebx+$02D8]

* Reference to: controls.TControl.GetText(TControl):TCaption;

|

00457CE4   E8F7C1FCFF             call    00423EE0  ;또 이름을 읽어온다.

00457CE9   8B45F4                 mov     eax, [ebp-$0C]

00457CEC   BA03000000             mov     edx, $00000003

00457CF1   4A                     dec     edx

00457CF2   3B50FC                 cmp     edx, [eax-$04]  ;이번엔 2와 비교한다.

00457CF5   7205                   jb      00457CFC  ;작으면 점프(점프하는게 당연.)

---------------------------------------------------------------------

너무 반복적으로 문자열 길이를 체크하는것이 아닌가 하는 생각이 든다.

이런 루틴은 사람을 짜증나게 하며 프로그램의 속도를 저하한다.

어쨰든 0x457CF5지점에서 작으면 점프하게 되는 지점인 0x457CFC으로 가보자.

---------------------------------------------------------------------

00457CFC   42                     inc     edx

00457CFD   0FB64410FF             movzx   eax, byte ptr [eax+edx-$01]

00457D02   6BC002                 imul    eax, eax, $02

00457D05   7105                   jno     00457D0C

* Reference to: system.@IntOver;

|

00457D07   E880AEFAFF             call    00402B8C

00457D0C   03F0                   add     esi, eax

00457D0E   7105                   jno     00457D15

* Reference to: system.@IntOver;

|

00457D10   E877AEFAFF             call    00402B8C

00457D15   8D55F0                 lea     edx, [ebp-$10]

* Reference to control TForm1.Edit1 : TEdit

|

00457D18   8B83D8020000           mov     eax, [ebx+$02D8]

 

* Reference to: controls.TControl.GetText(TControl):TCaption;

|

00457D1E   E8BDC1FCFF             call    00423EE0

00457D23   8B45F0                 mov     eax, [ebp-$10]

00457D26   BA04000000             mov     edx, $00000004

00457D2B   4A                     dec     edx

00457D2C   3B50FC                 cmp     edx, [eax-$04]  ;이번엔 3과 비교

00457D2F   7205                   jb      00457D36  ;작으면 점프(당연히 점프)

---------------------------------------------------------------------

제길... 또 길이 비교다 다시.. 0x457D2F지점에서 점프되는 지점인

0X457D36지점으로 가보자.

---------------------------------------------------------------------

00457D36   42                     inc     edx

00457D37   0FB64410FF             movzx   eax, byte ptr [eax+edx-$01]

00457D3C   6BC002                 imul    eax, eax, $02

00457D3F   7105                   jno     00457D46

* Reference to: system.@IntOver;

|

00457D41   E846AEFAFF             call    00402B8C

00457D46   03F0                   add     esi, eax

00457D48   7105                   jno     00457D4F

* Reference to: system.@IntOver;

|

00457D4A   E83DAEFAFF             call    00402B8C

00457D4F   8D55EC                 lea     edx, [ebp-$14]

* Reference to control TForm1.Edit1 : TEdit

|

00457D52   8B83D8020000           mov     eax, [ebx+$02D8]

 

* Reference to: controls.TControl.GetText(TControl):TCaption;

|

00457D58   E883C1FCFF             call    00423EE0

00457D5D   8B45EC                 mov     eax, [ebp-$14]

00457D60   BA05000000             mov     edx, $00000005

00457D65   4A                     dec     edx

00457D66   3B50FC                 cmp     edx, [eax-$04]  ;이번엔 4와 비교

00457D69   7205                   jb      00457D70  ;작다면 점프(당연히 점프)

---------------------------------------------------------------------

정말 즐기다 또 길이 체크다....0X457D69지점에서 점프되는 지점인

0X457D70으로 가보자....

---------------------------------------------------------------------

00457D70   42                     inc     edx

00457D71   0FB64410FF             movzx   eax, byte ptr [eax+edx-$01]

00457D76   6BC002                 imul    eax, eax, $02

00457D79   7105                   jno     00457D80

* Reference to: system.@IntOver;

|

00457D7B   E80CAEFAFF             call    00402B8C

00457D80   03F0                   add     esi, eax

00457D82   7105                   jno     00457D89

* Reference to: system.@IntOver;

|

00457D84   E803AEFAFF             call    00402B8C

00457D89   8D55E8                 lea     edx, [ebp-$18]

* Reference to control TForm1.Edit1 : TEdit

|

00457D8C   8B83D8020000           mov     eax, [ebx+$02D8]

* Reference to: controls.TControl.GetText(TControl):TCaption;

|

00457D92   E849C1FCFF             call    00423EE0

00457D97   8B45E8                 mov     eax, [ebp-$18]

00457D9A   BA06000000             mov     edx, $00000006

00457D9F   4A                     dec     edx

00457DA0   3B50FC                 cmp     edx, [eax-$04]  ;이제 5와 비교

00457DA3   7205                   jb      00457DAA  ;작다면 점프(당연히 점프)

---------------------------------------------------------------------

정말 지겹지도 않나 별써 6번째이다. 후우... 이제 끝이 나올떄도 된거 같다.

0x457DA3 지점에서 점프 되는 지점인 0X457DAA으로 가보자.

---------------------------------------------------------------------

00457DAA   42                     inc     edx

00457DAB   0FB64410FF             movzx   eax, byte ptr [eax+edx-$01]

00457DB0   6BC002                 imul    eax, eax, $02  ;eax를 곱한다 2

00457DB3   7105                   jno     00457DBA

* Reference to: system.@IntOver;

|

00457DB5   E8D2ADFAFF             call    00402B8C

00457DBA   03F0                   add     esi, eax

00457DBC   7105                   jno     00457DC3

* Reference to: system.@IntOver;

|

00457DBE   E8C9ADFAFF             call    00402B8C

00457DC3   893540B84500           mov     [$0045B840], esi

00457DC9   A144B84500             mov     eax, dword ptr [$0045B844]

* Reference to: Unit_004069CC.Proc_004079D0

|

00457DCE   E8FDFBFAFF             call    004079D0  ;콜

00457DD3   6BC002                 imul    eax, eax, $02  ;eax를 곱한다 2

00457DD6   7305                   jnb     00457DDD  ;크거나 같으면 점프

---------------------------------------------------------------------

드디어 길이 체크가 끝났다....

0x457DD76에서 0x457DDD로 점프하는것을 볼수 있다..

0x457DDD으로 가보자.

---------------------------------------------------------------------

00457DDD   33D2                   xor     edx, edx  ;edx 초기화

00457DDF   52                     push    edx

00457DE0   50                     push    eax

00457DE1   A140B84500             mov     eax, dword ptr [$0045B840]

00457DE6   99                     cdq

00457DE7   030424                 add     eax, [esp]

00457DEA   13542404               adc     edx, [esp+$04]

00457DEE   7105                   jno     00457DF5

* Reference to: system.@IntOver;

|

00457DF0   E897ADFAFF             call    00402B8C

00457DF5   83C408                 add     esp, +$08

00457DF8   50                     push    eax

00457DF9   C1F81F                 sar     eax, $1F

00457DFC   3BC2                   cmp     eax, edx  ;eaxedx를 비교(둘다 0이다)

00457DFE   58                     pop     eax

00457DFF   7405                   jz      00457E06  ;둘다 0이라면 점프

---------------------------------------------------------------------

0x457DFC 지점에서 eaxedx가 0인지 연산하고 0x457DFF지점에서

0이라면 점프한다. 점프되는 지점인 0x457E06으로 가보자.

---------------------------------------------------------------------

00457E06   A340B84500             mov     dword ptr [$0045B840], eax

00457E0B   8D55E4                 lea     edx, [ebp-$1C]

00457E0E   A140B84500             mov     eax, dword ptr [$0045B840]

* Reference to: Unit_004069CC.Proc_00407744

|

00457E13   E82CF9FAFF             call    00407744  ;의심가는 콜-1

00457E18   8B45E4                 mov     eax, [ebp-$1C]

00457E1B   50                     push    eax

00457E1C   8D55FC                 lea     edx, [ebp-$04]

* Reference to control TForm1.Edit2 : TEdit

|

00457E1F   8B83DC020000           mov     eax, [ebx+$02DC]

* Reference to: controls.TControl.GetText(TControl):TCaption;

|

00457E25   E8B6C0FCFF             call    00423EE0  ;Serial을 읽어온다.

00457E2A   8B55FC                 mov     edx, [ebp-$04]

00457E2D   58                     pop     eax

* Reference to: System.Proc_00403B84

|

00457E2E   E851BDFAFF             call    00403B84  ;의심가는 콜-2

00457E33   751A                   jnz     00457E4F

00457E35   6A00                   push    $00

* Possible String Reference to: 'Congratz !'

|

00457E37   B9387F4500             mov     ecx, $00457F38

 

* Possible String Reference to: 'You cracked the CFF CrackMe #4 ! Pl

|                                ease send your solution to acidbyte

|                                s@gmx.net !'

|

00457E3C   BA447F4500             mov     edx, $00457F44

* Reference to TApplication instance

|

00457E41   A198A54500             mov     eax, dword ptr [$0045A598]

00457E46   8B00                   mov     eax, [eax]

* Reference to : TApplication._PROC_00440130()

|

00457E48   E8E382FEFF             call    00440130

---------------------------------------------------------------------

드디어 마지막 부분인듯 하다. 먼저 0x457E13이 수상하다.

알수 없는 Call이로다. 키생성 루틴일 가능성이 크다.

어쨰든 Call의 결과를 0x457E18에서 eax에 넣고.....

0x457E25에서는 Serial을 읽어오고 0x457E2A 지점에서 그걸 edx에 넣는다.

그리고 0x457E2E에서 의심가는 콜-2를 Call 한다. 키비교 루틴일 가능성이 크다.

만약 나의 짐작이 맞다면 0x457E18 줄에서.....

---------------------------------------------------------------------

00457E0B   8D55E4                 lea     edx, [ebp-$1C]

00457E0E   A140B84500             mov     eax, dword ptr [$0045B840]

* Reference to: Unit_004069CC.Proc_00407744

|

00457E13   E82CF9FAFF             call    00407744  ;의심가는 콜-1

00457E18   8B45E4                 mov     eax, [ebp-$1C] <===여기다가 브포를 걸면

----------------------------------------------------------------------

0x457E18줄에 브레이크 포인트를 걸면 올바른 시리얼을 건질수 있을 것이다.

어쨰든 의심가는-2 지점인 0x403B84 지점을 보도록 하자.

----------------------------------------------------------------------

00403B84   53                     push    ebx

00403B85   56                     push    esi

00403B86   57                     push    edi

00403B87   89C6                   mov     esi, eax

00403B89   89D7                   mov     edi, edx

00403B8B   39D0                   cmp     eax, edx  ;eaxedx 비교

00403B8D   0F848F000000           jz      00403C22  ;같다면 점프 (시리얼 비교)

00403B93   85F6                   test    esi, esi

00403B95   7468                   jz      00403BFF

00403B97   85FF                   test    edi, edi

00403B99   746B                   jz      00403C06

00403B9B   8B46FC                 mov     eax, [esi-$04]

00403B9E   8B57FC                 mov     edx, [edi-$04]

00403BA1   29D0                   sub     eax, edx

00403BA3   7702                   jnbe    00403BA7

00403BA5   01C2                   add     edx, eax

00403BA7   52                     push    edx

00403BA8   C1EA02                 shr     edx, $02

00403BAB   7426                   jz      00403BD3

----------------------------------------------------------------------

잡다한 설명은 넣지 않았다. 딱 저 두줄로 모든것이 결정 난다.

eax의 값과 edx의 값을 비교한다. 이전에 봤던 아래의 두줄...

--------------------------------------------------------

00457E18   8B45E4                 mov     eax, [ebp-$1C]

00457E2A   8B55FC                 mov     edx, [ebp-$04]

--------------------------------------------------------

을 기억 한다면 이게 무슨 말인지 쉽게 알수 있을 것이다. eax에는 올바른 시리얼이..

그리고 edx에는 우리가 입력한 시리얼이 있다. 그 두개를 비교 하는 것이다.

이지점에 디버거를 이용해 브레이크 포인트를 걸고 eax레지스터 값을 본다면 거기에

올바른 시리얼이 있을 것이다. 밑의 그림은 실제로 브레이크 포인트를 건 장면이다.


Name: #Dual_Root

Serial: 1060

이라는 결과를 얻을수 있었다.. 여러분도 재대로 했다면 각자의 올바른 결과를 구했으리라..

밑은 한번 위의 결과를 Crack Me에 입력해 본 그림이다.

이로써 모든 acid crack이 끝났다.

즐거운 시간이였다면 영광이다.

물런 감정을 어떻게 느끼던 그것은...

내가 뭐라 말할 바는 아니지만 말이야!

그래도 즐거운 시간이었기를 바란다.

그럼 앞으로도 즐거운 Crack의 도를 쌓기 바란다

Posted by 엘키 엘키

댓글을 달아 주세요


1.abex1
CD-Protection Crack

Learn2Crack에 있는 Windows Crack Me를 한개씩 풀어 봅시다.

첫번쨰 Crack Me는 abex의 abex1입니다. 이 Crack Me가

원하는 것은 C 드라이브가 CD Rom Drive 라는 결과 입니다.

과연 드라이브의 타입을 체크 하는 API는 무엇일까요?

바로 GetDriveTypeA 입니다.  GetDriveTypeA 함수의

리턴값이 0x5라면 바로 CD rom Drive 인것입니다.

밑은 GetDriveTypeA리턴값들입니다.

 

리턴값들:

0 Drive Cannot Be determined

1 Root Dir Does not exist

2 DriveRemoveable

3 A Fixed Disk (HardDrive)

4 Remote Drive(Network)

5 Cd-Rom Drive <<:::::::::::::::

6 RamDisk

 

자 이제 GetDriveTypeA로 드라이브를 체크한다는것을 알았으니

이제 OllyDbg를 이용하여 크렉을 시작하여 봅시다.

먼저 크렉을 하기 위하여 대상 프로그램을 Olly로 불러 옵시다.

그럼 위의 그림과 같은 화면이 뜨게 됩니다.

이제 상단 메뉴의 E버튼을 눌러 대상 프로그램의 모듈을 봅시다.



그럼 이제뜬 Executable Modules 창에서

맨위의 모듈을 마우스 오른쪽 버튼으로 클릭 하여 뜬 팝업메뉴중

View Names메뉴를 눌러 Name 창을 띠워 봅시다.


Name창 중에서 GetDriveTypeA 마우스 오른쪽 버튼으로 클릭하여

뜬 팝업 메뉴중 Find references to import 메뉴를 눌러

이 함수를 참조하는 위치를을 보도록 하죠.


References 창이 떳다면 이제 마우스 오른쪽 버튼으로 클릭하여서

팝업메뉴중 Set Brackpoing on every command 메뉴를 눌러

브레이크 포인트를 설치 합시다.


이제 브레이크 포인트 설치가 완료 되었으니 프로그램을 Run 시켜 보죠.

Olly의 상단 메뉴중 ▶버튼을 누르시면 됩니다.


첫번쨰
뜨는 메시지 박스의 확인을 클릭하고 나면

0x401018 지점에브레이크가 걸려 Olly뜨는것을 볼수 있습니다.


이제 한줄씩 F8 [Step Over]를 눌러 실행하여 봅시다.

실행 하다보면...

00401024  |. 3BC6           CMP EAX,ESI

00401026  |. 74 15          JE SHORT abexcm1.0040103D

00401028  |. 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL

0040102A  |. 68 35204000    PUSH abexcm1.00402035                    ; |Title = "Error"

0040102F  |. 68 3B204000    PUSH abexcm1.0040203B                    ; |Text = "Nah... This is not a CD-ROM Drive!"

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

00401036  |. E8 26000000    CALL <JMP.&USER32.MESSAGEBOXA>           ; \MessageBoxA

0040103B  |. EB 13          JMP SHORT abexcm1.00401050

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 <JMP.&USER32.MESSAGEBOXA>           ; |\MessageBoxA

00401050  \> E8 06000000    CALL <JMP.&KERNEL32.EXITPROCESS>         ; \ExitProcess

이런 부분을 볼수 있습니다.

0x401026줄에서 점프를 하지 않으면 CD-ROM Drive가 아니라는..

메시지 박스를 띄우고 프로그램이 종료되는 것입니다.

그럼으로 우리는 0x401026줄의 JE를 JMP로 바꾸어 무조건

점프로 바꾸어 주면 패치 완료 인것입니다.

밑의 그림처럼 0x401026줄을 마우스 오른쪽 버튼으로 클릭하여

팝업메뉴중 Assemble 메뉴를 눌러 Assemble 창을 띄우고

Assemble 창에서 EDIT아이템에 JMP SHORT 0040103D

라고 입력한후 Asseble 버튼을 눌릅시다. 이제 수정이 완료 됬으니

다시 한번 0x401026줄을 마우스 오른쪽 버튼으로 클릭하면

뜨는 팝업메뉴중 Copy to executeable -> Selection 을 클릭합니다.

그러면 수정된 내용으로된 창이 뜨는데요...

그중에 아무줄이나 마우스오른쪽 버튼으로 클릭하면 뜨는 팝업메뉴중

Save File 메뉴를 눌러 저장하시면 됩니다.


이제 저장한 파일을 실행 시켜 보면 밑과 같이 성공했다는

메시지 창을 보실수 있습니다.


--------------------------------------------------------------------------------------------



2.abex2 name/serial VB Crack

이번에는 abex의 abex2입니다. 이 Crack Me의 특징은

VB로 만들어졌고 이름에 맞는 시리얼을 구하는 것입니다.

VB로 만들어졌기 떄문에 우리가 흔히 크렉하는 C/ASM

프로그램과는 크렉하는 방법이 틀립니다.

어쨰뜬 시작하여 보죠. 방법은 우선 크렉미에 아무값이나

입력한후 Check를 눌러 봅시다. 뭐라구 나오나요???

"Nope, this serial is wron!"이라고 나오는 군요.

이 문자열을 잘 기억해 두시구요~~~

이제 Olly Dbg로 이 타겟을 Attach 하도록 합니다.


이제 Olly의 상단 메뉴중 E라고 써있는 버튼을 눌러

모듈창을 띄운후 거기서 가장 맨위의 모듈을 마우스 오른쪽

버튼으로 클릭하여 나오는 팝업메뉴중....

View Code in CPU 메뉴를 누릅니다.


그럼 이제 모듈의 내용이 역어셈블 되어 표시되었을 겁니다.

이제 아무줄에나 마우스를 올려놓고 마우스 오른쪽 버튼으로

클릭하여 팝업메뉴중 Search for -> All referenced text strings 메뉴를 누릅니다.


이제 text string 목록이 표시되었으면

이제 아까 check 버튼을 눌렀을떄 보았던

메시지 박스의 텍스트인

"Nope, this serial is wrong! 찾을수 있습니다.


그럼 찾은 저 문자열을 마우스 오른쪽 버튼으로

클릭하면 나오는 팝업메뉴중 가장 위의 메뉴인

Follow in Disassembler 메뉴를 누릅니다.


Follow된 부분에서 조금 위로 올리다보면...

밑의 그림과 같은 부분을 만날수 있습니다.


보시다시피 0x403413줄에 > 표시가 있습니다.

이것은 다른곳에서 이곳으로 점프해 왔다는

것을 의미 합니다. 밑에 빨간색으로 네모친곳을

보니 Jump from 0x403406 이라고 써있네요.

바로 0x403406으로 부터 점프해 온것입니다.

그러면 0x403406으로 한번 이동하여 보죠.

바로 위니깐 그냥 스크롤바를 올리시면 됩니다.

점프해온곳인 0x403406으로 부터 조금더

스크롤바를 올려보면 밑의 그림과 같은 곳을 만날수 있습니다.



"Yep, this key is right!" 라는 문자열을 볼수 있는데

아마 키가 맞을떄의메시지라느 것을 짐작하여 볼수 있습니다.

그리고 조금 위를 보면 0x4032E9 지점부터 어딘가로 부터

점프해와서 이 부분이 시작된다는 것을 알수 있습니다.

그렇다면 0x4032E9 지점 부터 브레이크 포인트를 걸고

한줄씩 Step by Step을 하면서 내려오다 보니....


0x403307 줄에서 밑과같이 A8D9C5D0이라는 "Dual"이라는 이름에

올바른 시리얼 키를 찾을수 있었습니다.

그래도 혹시 모르니 올바른 시리얼인지 확인해 보죠.



보다 시피 성공 메시지 박스를 볼수 있었습니다.

여러분도 여러분의 이름을 넣고 한번 확인해 보시기 바랍니다.

--------------------------------------------------------------------------------------------


3.abex3 KeyFile Crack

이번 크렉역시 아주 심플하고 쉽다.

언제나 그렇지만 크렉미가 원하는것이

무언지 알고 시작하는 것이 가장 중요하다.

이번 크렉미가 원하는 것은? keyFile이다.

그렇다면 파일이 있는지 없는지 가장

간단하게 체크 하는 API는 무엇일까?

바로 CreateFileA 이다. CreateFileA

지정된 파일을 open 하는 함수이다.

GetFileSize 함수나 ReadFile 함수나

WriteFile 함수 등을 쓰기전에 해당파일의

핸들을 얻기 위하여 쓰는 함수인 것이다.

만약 해당 파일이 없다면 반환값이 -1일것이다.

크렉미 역시 -1와 비교해서 만약 그렇다면

키파일이 없다고 인식하는것일 것이다.

그럼 지금까지 말한걸 알아두고 시작하여 보자.

API에 브레이크 포인트 거는 법은 위에서 배웠으니

생략 하도록 하고 이번에는 Olly로 대상을 불러오고

CreateFileA 함수에 브레이크를 걸도록 한다.

그리고 대상을 Run 시키면 메시지 박스가 하나 뜨는데

확인을 누르면 밑의 그림과 같이 CreateFileA 함수에

브레이크가 걸린체 Olly팝업되는 것을 볼수 있다.

CreateFileA페러미터중 FileName이 abex.l2c

라는것을 볼수 있다. 절대 경로가 안나와 있음으로...

현재 Crack Me가 있는 폴더에 저 파일이 있어야 한다는 것을

알수 있다. 그럼 현재 Crack Me가 있는 폴더에 abex.l2c라는

파일을 만들고 만들었으면 다시 Step by Step으로 한줄씩

실행하여 나가 보자.

00401034  |. 83F8 FF        CMP EAX,-1

00401037  |. 74 3C          JE SHORT abexcrac.00401075

두줄에서 앞에서 말했던 것처럼 -1과 비교하지만

우리는 해당 폴더에 abex.l2c 파일을 만들어 줬음으로

이것은 그냥 넘어 갈수 있다. 계속 Step  by Step으로 내려 가자.

00401039  |. 6A 00          PUSH 0                                   ; /pFileSizeHigh = NULL

0040103B  |. FF35 CA204000  PUSH DWORD PTR DS:[4020CA]               ; |hFile = 0000005C (window)

00401041  |. E8 4D000000    CALL <JMP.&KERNEL32.GETFILESIZE>         ; \GetFileSize

00401046  |. 83F8 12        CMP EAX,12

00401049  |. 75 15          JNZ SHORT abexcrac.00401060

GetFileSize 함수를 쓰고 구해온 크기는 EAX에 담기는데

구해온 크기가 12(Dec->18)인지 체크 한다. 12가 아니라면

0x401049 줄에서 0x401060 줄로 점프하는것을 볼수 있다.

이것은 점프하게 하면 안됨으로 abex.l2c 파일에 내용을

나는 18자의 스트링으로 "Dual is my Hero!!!" 입력하였다.

이제 Olly 메뉴중 ▶를 눌러 보자. 어떤가 성공 메시지를

볼수 있는가 huh ?



위의 메시지 박스가 떳다면 성공한 것이다.

--------------------------------------------------------------------------------------------

2.abex4 serial / VB Crack

별써 4번쨰 크렉미이다.

이번 크렉미는 짜증나는 VB이다.

제작자는 VB를 좋아하는가 보지?:p

어쨰든 abex2 에서 우리는 이미 한번

VB크렉을 해봤었다. 그떄 우리는

Search for - > All referenced text strings

에서 적절한 스트링을 찾아서 크렉을 하였었다.

이번에는 조금 다른 방법을 이용하여 크렉을 하도록 하겠다.

vbde 라는 프로그램의 도움을 받기로 하였다.(강좌를 간단하게..)

vbde 라는 프로그램을 다운로드 한후 우리의 대상 파일을

열어오자. 열어 오는것에 성공하였다면 Procedures 버튼을 눌러보자.


Text1_Change가 0x2280 임을 볼수 있다.

0x2280에 Base Address 0x400000을 합치면

0x402280 이 된다. Olly Dbg로 대상을 Open 한후

0x402280에 브레이크 포인트를 걸어 보자.

Open이 완료 되었다면 브레이크 포인트를 걸고

시킨후 대상 파일의 Text1에 아무글씨나

써넣어 보자. 브레이크가 걸린후 Olly가 팝업 된다.

밑으로 한줄씩 Step by Step으로 내려가 보자.



0x402308 줄에서 올바른 시리얼이 ECX스택으로

옮겨 지는것을 볼수 있는가? 과연 저게 나의 시리얼이

맞는지 한번 입력하여 보자.



하지만 시리얼은 매일 바뀐다... 왜냐구?

이 시리얼은 날짜에 따라 달라지기 떄문에....:p

어쨰든 이번 크렉역시 완료 이다.

--------------------------------------------------------------------------------------------

5.abex5 serial Crack

드디어 마지막 5이다.

아주 간단한 시리얼 체크 크렉이다.

앞에서 몇번 말했던 것처럼..

크렉에서 가장 중요한것은 크렉미가 원하는 것이

무언가 하는 것이다. 이번 크렉미는 시리얼을 원한다.

크렉미를 실행해 보자! 딱 두개의 객체가 보인다.

한개는 Edit 박스 하나는 Check 버튼 이다.

아마 Check버튼을 누르면 Edit박스의 내용을 가져와서

시리얼과 체크 하는 것일 것이다.

그렇다면 Edit 박스에서 시리얼을 가져 오는 함수는

무엇일까? 두가지로 줄여서 짐작하여 볼수 있다.

한개는 GetWindowTextA 두번쨰는 GetDlgItemTextA이다.

이번 크렉미 같은 경우 다이얼로그 리소스 아이템으로

이루어져 있음으로 GetDlgItemTextA 함수에 브레이크

포인트를 걸어 주어야 할것이다. 자 그럼 이제

대상을 실행한후 대상을 Olly로 Attach 한후

GetDlgItemTextA에 브레이크 포인트를 걸어보자.


이제 Olly에서 ▶을 눌러 Run 시킨다음...

Check 버튼을 눌러 보자.


~ 지금부터 Step by Step을 시작하며 내려가 보자.

Step by Step하며 내려가 보면 밑과 같은 부분을 만날수 있다.


lstrcmpiA
함수를 이용하여

내가 입력한 문자열인 "Dual is My Hero!!!" 과..

"L2C-57816784-ABEX"를 비교하는것을 볼수 있다.

그렇다! "L2C-57816784-ABEX"이것이 올바른 시리얼인 것이다.

과연 맞는지 테스트 하여 보기 위해서 대상의 Edit에

"L2C-57816784-ABEX" 입력한후 Check 버튼을 눌러보자.

어떤가 huh? :p



이로써 모든 abex crack이 끝났다.

즐거운 시간이였었으면 좋겠다.

물런 감정을 어떻게 느끼던 그것은...

내가 뭐라 말할 바는 아니지만 말이야!

그래도 즐거운 시간이었기를 바란다.

그럼 앞으로도 즐거운 Crack의 도를 쌓기 바란다.

혹시라도 이 글에 문제가 있다면

Posted by 엘키 엘키

댓글을 달아 주세요

이전버튼 1 2 이전버튼

블로그 이미지
Software Engineer
엘키

공지사항

Yesterday31
Today27
Total1,605,481

달력

 « |  » 2020.8
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

글 보관함