Цель.......: Sanitarium Версия.....: 1.0 (должно подойти к любой) Защита.....: Cd-Check Разработчик: http://www.ascgames.com Взломцик...: Zaks (tntpcclub@hotmail.com) Переводчик.: NightCat (nightcat@bsuir.com) Инструменты: W32Dasm, Hiew 1) Установите игру. Скопируйте все три диска на винчетсер. Когда закончите с копирование уберите аттрибут "read only" со всех файлов. Если этого не вделть то помо начнутся проблемы со звуком и голосами. Кстати, если у вас будут проблемы с голосами(это может случится при переходе из третьей главы в четвёрту), то сохраните игру, выйдите в Windows идите в папку Data и удалите файл res.002, а затем просто загрузите сохранённую игру. 2) Теперь вернёмся ко взлому. Запустите игру без диска. Вы увидите собщение "Pleas insert ... ". Сделайте копию sntrm.exe и загрузите эту копию во W32Dasm. Поиски этого сообщения в ничего не дадут так что поищем GetDriveTypeA. Первый простутите. Нам нужен второй : * Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh | :00430654 8B3574114400 mov esi, dword ptr [00441174] :0043065A C605E070440041 mov byte ptr [004470E0], 41 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0043069C(C) | * Possible StringData Ref from Data Obj ->"A:\" | :00430661 68E0704400 push 004470E0 :00430666 FFD6 call esi :00430668 83F805 cmp eax, 00000005 :0043066B 7521 jne 0043068E :0043066D A0E0704400 mov al, byte ptr [004470E0] :00430672 6A00 push 00000000 :00430674 6868754500 push 00457568 :00430679 A268754500 mov byte ptr [00457568], al :0043067E E86D750000 call 00437BF0 :00430683 83C408 add esp, 00000008 :00430686 85C0 test eax, eax :00430688 0F8482000000 je 00430710 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0043066B(C) | :0043068E A0E0704400 mov al, byte ptr [004470E0] :00430693 FEC0 inc al :00430695 3C5A cmp al, 5A :00430697 A2E0704400 mov byte ptr [004470E0], al :0043069C 7EC3 jle 00430661 :0043069E C605E070440041 mov byte ptr [004470E0], 41 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004306DE(C) | * Possible StringData Ref from Data Obj ->"A:\" | :004306A5 68E0704400 push 004470E0 :004306AA FFD6 call esi :004306AC 83F804 cmp eax, 00000004 :004306AF 751F jne 004306D0 :004306B1 8A0DE0704400 mov cl, byte ptr [004470E0] :004306B7 6A00 push 00000000 :004306B9 6868754500 push 00457568 :004306BE 880D68754500 mov byte ptr [00457568], cl :004306C4 E827750000 call 00437BF0 :004306C9 83C408 add esp, 00000008 :004306CC 85C0 test eax, eax :004306CE 7415 je 004306E5 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004306AF(C) | :004306D0 A0E0704400 mov al, byte ptr [004470E0] :004306D5 FEC0 inc al :004306D7 3C5A cmp al, 5A :004306D9 A2E0704400 mov byte ptr [004470E0], al :004306DE 7EC5 jle 004306A5 :004306E0 33C0 xor eax, eax :004306E2 5F pop edi :004306E3 5E pop esi :004306E4 C3 ret * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004306CE(C) | * Possible StringData Ref from Data Obj ->"?:\DATA\" | :004306E5 A1E0604400 mov eax, dword ptr [004460E0] :004306EA 8A15E0704400 mov dl, byte ptr [004470E0] :004306F0 8810 mov byte ptr [eax], dl :004306F2 8A0DE0704400 mov cl, byte ptr [004470E0] :004306F8 880DA8914500 mov byte ptr [004591A8], cl :004306FE C7058491450004000000 mov dword ptr [00459184], 00000004 :00430708 B804000000 mov eax, 00000004 :0043070D 5F pop edi :0043070E 5E pop esi :0043070F C3 ret * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00430688(C) | * Possible StringData Ref from Data Obj ->"?:\DATA\" | :00430710 8B15E0604400 mov edx, dword ptr [004460E0] :00430716 8A0DE0704400 mov cl, byte ptr [004470E0] :0043071C 5F pop edi :0043071D 5E pop esi :0043071E 880A mov byte ptr [edx], cl :00430720 A0E0704400 mov al, byte ptr [004470E0] :00430725 A2A8914500 mov byte ptr [004591A8], al :0043072A C7058491450005000000 mov dword ptr [00459184], 00000005 :00430734 B805000000 mov eax, 00000005 :00430739 C3 ret :0043073A 90 nop :0043073B 90 nop :0043073C 90 nop :0043073D 90 nop :0043073E 90 nop :0043073F 90 nop На то чтобы понять эту процедуру проверки у меня ушло много времени. Она не так легка, как кажется. Сперва давайте взглянем на эту часть : :00430661 68E0704400 push 004470E0 :00430666 FFD6 call esi <- вызываем getdrivetypea :00430668 83F805 cmp eax, 00000005 <- проверяем if eax 5 (Cd drive) :0043066B 7521 jne 0043068E <- если нет, продолжаем проверку :0043066D A0E0704400 mov al, byte ptr [004470E0] :00430672 6A00 push 00000000 :00430674 6868754500 push 00457568 :00430679 A268754500 mov byte ptr [00457568], al :0043067E E86D750000 call 00437BF0 :00430683 83C408 add esp, 00000008 :00430686 85C0 test eax, eax :00430688 0F8482000000 je 00430710 <- GoodGye, вот наш джамп Итак, выглдит всё очень легко. Мы нопим jne 0043068E и делаем из je 00430710 -> jump 00430710. Должно получится вот так : :0043066B 90 nop :0043066C 90 nop :0043066D A0E0704400 mov al, byte ptr [004470E0] :00430672 6A00 push 00000000 :00430674 6868754500 push 00457568 :00430679 A268754500 mov byte ptr [00457568], al :0043067E E86D750000 call 00437BF0 :00430683 83C408 add esp, 00000008 :00430686 85C0 test eax, eax :00430688 E983000000 jmp 00430710 :0043068D 90 nop :0043068E A0E0704400 mov al, byte ptr [004470E0] 3) Теперь давайте глянем, что у нас в 00430710. Видим * Possible StringData Ref from Data Obj ->"?:\DATA\". Это очень плохо. Нам нужно заменить ?:\DATA\ на .\DATA\ так чтоигра будет искать свои файлы в папке, куда она установлена. Откройте файл в хекс-редакторе и поищитестроку ?:\DATA\. Нашли и теперь нужно её заменить её на .\DATA\ . Мы видим "3F 3A 5C 44 41 54 41 5C" это знаичит ?:\DATA\ в хексе. Мы меняем 3f(?) на 2e(.), 3a на 5c, 5c на 44, 44 на 41, 41 на 54, 54 на 41, 41 на 5c ну и наконец 5c на 00 (нопим). Теперь сохраните файл и запустите игру. Никаких сообщений "Please ..." и игра начинаег загружаться, заетм мы смотри вступительный ролик и....... игра вылетает с сообщением General Protection Fault Error. Что теперь? 4) Откройте sntrm.bak в W32Dasm. Иопять идём к процедуре проверки и получше посмотим на : * Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh | :00430654 8B3574114400 mov esi, dword ptr [00441174] :0043065A C605E070440041 mov byte ptr [004470E0], 41 <- 004470E0 присваивается значение "A" * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0043069C(C) | * Possible StringData Ref from Data Obj ->"A:\" | :00430661 68E0704400 push 004470E0 <- A :00430666 FFD6 call esi <- Getdrivetypea вызывается со значением в 004470E0 :00430668 83F805 cmp eax, 00000005 <- eax сравнивается с 5 :0043066B 7521 jne 0043068E <- если Cd не найден, то идём к 0043068E :0043066D A0E0704400 mov al, byte ptr [004470E0] :00430672 6A00 push 00000000 :00430674 6868754500 push 00457568 :00430679 A268754500 mov byte ptr [00457568], al :0043067E E86D750000 call 00437BF0 :00430683 83C408 add esp, 00000008 :00430686 85C0 test eax, eax :00430688 0F8482000000 je 00430710 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0043066B(C) | :0043068E A0E0704400 mov al, byte ptr [004470E0] <- al присваевается значение 004470E0. "A" :00430693 FEC0 inc al <- увеличивается, становится "B" затем "C" и т.д. :00430695 3C5A cmp al, 5A <- проверяется все ли буквы перебраны :00430697 A2E0704400 mov byte ptr [004470E0], al <- 004470E0 присваивается значение al. :0043069C 7EC3 jle 00430661 <- если есть еще буквы, то jump to 00430661 :0043069E C605E070440041 mov byte ptr [004470E0], 41 <- Если нет, то 004470E0 присваивается значение "A" Ну, тут действительно сложновато понять эту процедуру, так что я немного разъясню. Сначала Getdrivetypea вызывается со значением 004470E0. Сперва это значение равно "A". Посмотрите: :0043065A C605E070440041 mov byte ptr [004470E0], 41 <- 004470E0 присваивается значение "A" (41 = A) Затем getdrivetypeA возвращает значение eax. если eax = 5, то cd найден и мы следуем вниз где буква нашего диска находится в al а затем в 00457568. Когда мы удалили процедуру проверки значение находящееся в al было равно A. А это неправильный путь. Вот почему игра падает. Так давайте заменим значение в : :0043065A C605E070440041 mov byte ptr [004470E0], 41 Мы хотим, чтобы игра искала свои файлы в в папке, куда мы её проинсталлировали. Нам нужно заменить "A" на ".". Мы знаем, что 41 = A, ну а 2E = ".". Так что нам небходимо заменить строчку выше на эту : :0043065A C605E070440041 mov byte ptr [004470E0], 2E <- присваиваем "." Загрузите файл в хекс-редактор и замените 041 на 02E. F9 - save. ESC - quit. 5) Запустите игру. Теперь она прекрасно запускается. Уф, это было не так и легко. ======================================================================= TEAM-53 TUTORiALs \\ www.BSUiR.com \\ #team-53 , IRC.By, IRC.BYNETS.ORG =======================================================================