초간단 win32 program crack 계시위치 : www.securityproof.net 작성일시 : 2006년 7월 25일작성자 : bps 이문서는 win32 binary 의 reverse engineering 에대한기본내용에대해작성한글입니다. 원래작성한 crackme 를 PECompact 나 upx 등으로 packing 된바이너리를 unpacking 하는것부터시작하려하였으나일단본인의지식이부족하고, 그리고 packing 된바이너리의 OEP 를찾는건지금설명하려는문서보다더심도있게들어가야되므로배보다배꼽이더커지게됩니다. 따라서이문서에서는단순하게 Debug information 이들어가있는간단한 MessageBox 기반의 crackme 를이용하여 debugger 로특정기능을무력화시키는간단한작업을예로들겠습니다. 일단문서와같이첨부된 crack.exe 를실행합니다. 실행해보면아래와같이 MessageBox 가뜹니다. 잠시해당프로그램에대해설명하자면, 이프로그램은자신의실행위치를검색하여 CD- ROM 이아닌기타다른미디어일경우 error 메시지를뿌리고 return 1 을반환하여종료되는프로그램입니다. 일반적으로아주오래전, Game 이나특정프로그램의불법복사및공유를막기위해간단히조치되었던방법들이지요. 확인버튼을누르면위치검색을수행후아래와같이메시지를뿌립니다. 현재 crack.exe 가저장된위치는컴퓨터의하드디스크이므로, 이프로그램은 CD-ROM
이아니므로에러메세지를뿌리게됩니다. 우리는이인증부분을우회하도록하는것이목표입니다. 일단 debugger 를이용하여해당 crackme 를열어봅시다. 이문서에서는 ollydbg 1.10 을사용하겠습니다. Ollydbg 를이용하여해당바이너리를열면아래와같이구성됩니다. 처음 ollydbg 를이용했다면아마 PUSH EBP 에알아서 break point 가걸려있을겁니다. 그이유는 [Options] -> [Debugging Options] 를누르거나 Alt+O 해보시면, 여러옵션을설정할수있는탭이뜨는데여기서 [events] 탭으로이동해보면다음과같이 WinMain 에 BP 가걸리도록설정되어있음을알수있습니다.
WinMain 의위치를알수있을때, 즉 Debug information 이존재할때, 기본적으로 WinMain 에 BP 가걸리도록설정되어있습니다. 편의에따라다른옵션으로바꿔서사용 할수도있으나당분간은이렇게사용하는게더편합니다. 다시메인창으로돌아와서살펴봅시다. PUSH EBP 에 BP가걸려있으므로, 순차적으로실행해나가면서기타창에있는값들의변화도한번씩살펴봅니다. Ollydbg 는 [Debug] -> [Step Over] 를클릭하거나키보드단축키 F8 을누르면됩니다. 참고로, Step Into 는특정 function 이나명령문이있을때해당문으로이동을하지만 Step Over 는이동없이계속순차적으로실행해나갑니다. F8 을계속해서누르며진행해나가다보면 0x401038 에이르러 MessageBox 가실행됩 니다.
[ 첫번째 MessageBox() 호출, 0x401038] [ 프로그램실행 ] 확인을누르고다시 ollydbg 로돌아옵니다. 0x40103e 에서 ESI 와 ESP 를서로비교해보는것을볼수있습니다. (CMP ESI, ESP) 현재에는중요한게아니니계속해서 F8 을눌러해당 crackme 의가장중요한함수인 GetDriveType() 이호출될때까지진행해나갑니다. GetDriveType() 을실행하고난바로다음인 0x40104F 에서좌측의 Registers 창을살펴봅시다. CPU register 의변화를실시간으로보여주는창인데, 여기서변화된값은빨간색으로따로표시됩니다. 여기서 EAX 값을살펴봐야합니다.
[GetDriveType() 실행한후, 0x40104F] [CPU register 변화값확인, EAX 값이 3 으로변화 ] 네. EAX 레지스터의값이 3 으로변화했습니다. GetDriveType() 이실행한후에발생된일 이지요. 여기서우리는 win32 API 의 GetDriveType() 함수가어떤일을하는지알아야합 니다.
MSDN library 를검색해보시면아시겠지만해당함수는드라이브스트링을인자값으로받아들이며해당드라이브의종류를판별하여, 각타입에맞는숫자값을리턴합니다. 즉 GetDriveType( C:\ ), GetDriveType( D:\ ) 등과같이작성한다는거죠. 여기서한가지참고할점은굳이인자로스트링을넣지않은, 즉인자값에 NULL 을삽입하면해당프로그램이실행된위치의드라이브값을읽어오는겁니다. 즉 crack.exe 가 C:\ 밑에있다면 C:\ 를, D:\ 밑에있다면 D:\ 를읽어와해당드라이브의타입값을넘겨주는것이지요. 현재 GetDriveType() 은 3을반환했습니다. 이값이무엇을뜻하는지는 MSDN을살펴보면아래와같이나옵니다. DRIVE_UNKNOWN (0) The drive type cannot be determined. DRIVE_NO_ROOT_DIR (1) The root path is invalid, for example, no volume is mounted at the path. DRIVE_REMOVABLE (2) The drive is a type that has removable media, for example, a floppy drive or removable hard disk. DRIVE_FIXED (3) The drive is a type that cannot be removed, for example, a fixed hard drive. DRIVE_REMOTE (4) The drive is a remote (network) drive. DRIVE_CDROM (5) The drive is a CD-ROM drive. DRIVE_RAMDISK (6) The drive is a RAM disk. 옆에괄호로삽입한숫자가반환되는타입값입니다. 즉, 현재 GetDriveType() 은 3, 즉 DRIVE_FIXED 를반환했으며, 이것은설명에서와같이고정된하드드라이브입니다. 이것으로자신의위치가 CD-ROM 이아닌하드드라이브라는것을알게되는거죠. 우리는이제이것을조작해낼것입니다!!!
일단 ollydbg 의 F8 을눌러서계속진행해나갑시다. 계속 F8 로진행하다가 무언가느낌이오는곳이있습니다. 바로 0x40105d 이지요. 0x40105d 를살펴보면 JNZ short crack.00401080 으로되어있습니다. 즉, 401080 으로 이동하게되는거죠. Ollydbg 의메인창스크롤을내려 0x401080 으로가보시면 네. 바로에러메세지가뜨게됩니다. 우린이것을조작해버리면됩니다. 즉, 0x401080 으로이동해서에러메세지를출력하도록하는 0x40105d 의명령을바꿔버리면되는겁니다. 인증성공메시지는 0x40105f 부터시작합니다. 바로밑이죠. 0x40105d 에커서를위치시키고, 마우스오른쪽클릭으로팝업메뉴를엽니다. 그럼아래와같이 Assemble 을클릭하면해당메모리주소의명령을수정할수있습니다. 마우스를쓰기귀찮으면그냥 space bar 를누르셔도동일한작업이수행됩니다.
여기서우리가원하는명령어를작성해주고 Assemble 버튼을눌러주면됩니다. 일단은 JMP 40105F 로입력합시다. 솔직히그냥 00401080 을 0040105F 로바꿔주면되 지만바뀐게확표시되도록 JMP 문을쓰도록합시다.( 웃음 ) 바뀐화면은아래와같습니다. 40105F 로 JMP 하라는명령이정확하게기입되었습니다. 수정했다고끝이아닙니다. 이제수정된파일을실제 PE포멧실행파일로저장해야겠지요. 다시커서를 0x00105d 로이동합니다. 수정된빨간색글자부분이지요거기서오른쪽마우스를클릭해서팝업메뉴를띄웁니다. 아랫쪽을보시면 Copy to executable 이란항목이있고, 옆으로 selection 과 All modifications 가있습니다. 차례대로 [Copy to executable] -> [selection] 을선택합니다. 그럼새로창이하나더뜰겁니다. 이것이이제완성된 (crack 된 ) 프로그램의코드입니다. 이제파일로저장하면끝이지요. 다시마우스오른쪽버튼을누른후팝업메뉴를띄웁니다.
[save file] 을클릭하면실행파일 (.exe) 로저장할수있습니다. 적당한이름으로저장합시다. 전 crack2.exe 로저장했습니다. 이제새로저장된, crack 한프로그램을실행해봅시다. 아래와같이인증성공메시지가나오면성공!! 입니다. 지금까지 win32 프로그램의 crack 을간단하게설명했습니다. 한가지명심할것은, 이문서에서예제로든프로그램은그야말로정말간단한, 실제에서는사용되지조차않는정도의간단한예제입니다. 실제상용어플리케이션이나게임은 PECompact 나 upx, 기타다른 packer로 packing 되어있으며, 심지어 debug information 이전혀없는상태로배포되기도합니다. Unpacker 로 unpacking 한다해도 packing되기전 binary 와는코드자체가많이틀리며, 따라서 reverser 들은여러가지방법으로 OEP 를찾아들어가어느섹션에서실제코드가풀리는지를계속해서추적합니다. 그러므로 reverse engineering 에대한지식이없는저같은분들은당분간자신이만든 crackme 나, 다른우수한 reverser 들이만들어놓은 crackme 예제로내공을쌓읍시다. 이상으로글을마치겠습니다. 졸필의글을끝까지읽어주신모든분들께감사드립니다. 다음에쓸글은, 아마도 OEP 와관련된 unpacking 에대한글이될꺼같습니다. 감사합니다.