.. :: ____ _ :: _ ____ _ ____ _ ____ ____\ (________) _/________) _ |_____) \ _____ \\__ _______/ _| /__ | _ \/ /___ / | _ | _ | \ | __// … \\___| \___| \____| \_____| \ … +-------|______//--|_______//---|______//pO!i|_______//-----+ .. ____ _ ____ _ <<:::::::::::::::::::: :: … tEAM-fT … ____| (___\ (_______ ___ ___ ___ ___ ___ ___ ___\ _ _______/__ \\__\\__\\__\\__\\__\\__\ \\___ ___/ | ___// .. … / |__/\___| \ … :: +-----\\______|-------|_______//--+ :: :: TEAM FIFTY THREE TUTORiALS #12 :: ====================================== SLV Code Protector 0.61 - распаковка ====================================== Это обычный тутор. У меня есть какой-то крякмис.exe, который запакован SLVc0deProtector 0.61. Протектор мне не известен, наверное какой-то проект "от балды". Я переименовал exe в target.exe и файл в при запуске показывает, что имя было изменено. Olly сообщает, что файл повреждён или вообще не 32-bit. Это значит, что заголовок PE похерили. 1. Проблемы с заголовком PE Я открыл target.exe в LordPE "PE editor" и увидел вот такие странные/неправильные значения: NumOfRvaandSizes = 48632ABD --> Я должно быть =10(h) Другие вообще-то опционально, но я их тоже исправлю: SizeOfImage = 0000B001 ---> должно быть = 17000 BaseOfCode = 0000000F ---> 00001000 BaseOfData = 0000000F ---> 00005000 TimeDateStamp = DEADC0DE ---> 0 (не важно) CheckSumm = FFFFFFFF ---> 0 (не важно) Секции так же похерили и я исправлю их VirtualSize с -> в (section alignment = 1000): .text = 2A2E -> 3000 .rdata = 07E8 -> 1000 .data = 0ADC -> 1000 .rsrc = 01A8 -> 1000 ::ICU:: = 4001 -> 4000 Заголовок PE, вообще-то DOS, выглядит странно в Olly: 00400000 4D 5A ASCII "MZ" ; DOS EXE Signature 00400002 9000 DW 0090 ; DOS_PartPag = 90 (144.) 00400004 1A4E DW 4E1A ; DOS_PageCnt = 4E1A (19994.) 00400006 4E21 DW 214E ; DOS_ReloCnt = 214E (8526.) 00400008 767D DW 7D76 ; DOS_HdrSize = 7D76 (32118.) 0040000A 70AF DW AF70 ; DOS_MinMem = AF70 (44912.) 0040000C 98FE DW FE98 ; DOS_MaxMem = FE98 (65176.) 0040000E 8E74 DW 748E ; DOS_ReloSS = 748E 00400010 09EE DW EE09 ; DOS_ExeSP = EE09 00400012 F0FB DW FBF0 ; DOS_ChkSum = FBF0 00400014 5320 DW 2053 ; DOS_ExeIP = 2053 00400016 0224 DW 2402 ; DOS_ReloCS = 2402 00400018 A6F4 DW F4A6 ; DOS_TablOff = F4A6 0040001A 215D DW 5D21 ; DOS_Overlay = 5D21 Любой другой файл на моей машине имеет такие значения в DOS заголовке: 00400000 4D 5A ASCII "MZ" ; DOS EXE Signature 00400002 9000 DW 0090 ; DOS_PartPag = 90 (144.) 00400004 0300 DW 0003 ; DOS_PageCnt = 3 00400006 0000 DW 0000 ; DOS_ReloCnt = 0 00400008 0400 DW 0004 ; DOS_HdrSize = 4 0040000A 0000 DW 0000 ; DOS_MinMem = 0 0040000C FFFF DW FFFF ; DOS_MaxMem = FFFF (65535.) 0040000E 0000 DW 0000 ; DOS_ReloSS = 0 00400010 B800 DW 00B8 ; DOS_ExeSP = B8 00400012 0000 DW 0000 ; DOS_ChkSum = 0 00400014 0000 DW 0000 ; DOS_ExeIP = 0 00400016 0000 DW 0000 ; DOS_ReloCS = 0 00400018 4000 DW 0040 ; DOS_TablOff = 40 0040001A 0000 DW 0000 ; DOS_Overlay = 0 Я не знаю влияет ли это на нашу цель, так что я оставлю это. Я заметил еще кое-что тут: 004000F4 0F000000 DD 0000000F ; SizeOfCode = F (15.) Это странно потому что я выставил SizeOfCode в LordPE равным 3000 и я не знаю, почему здесь F, а LordPE показывает 3000. Я это так же оставлю. Позже я могу это изменить, если будет нужно. Теперь файл запускается прекрасно в Оlly и выскакивает то самое сообщение об имени. 2. Первая проверки дебагера Чтобы попасть на проверку имени мне нужно пройти немного обфускации и декриптовки, но я могу немного ускорить этот процесс, потому что там нет ничего интересного. Убираем галки на всех исключениях и жмём Shift+F9 3 раза и в итоге попадём на то самое сообщение. Теперь я жму Shift+F9 два раза и приземляюсь тут: 0040776B DIV EDX 0040776D RDTSC <---------------------- получаем какое-то временнОе значение, 0040776F MOV ECX,EAX <---------------- записываем в ECX, 00407771 RDTSC <---------------------- снова получаем время, 00407774 SUB EAX,ECX <---------------- отнимаем, 00407776 JMP SHORT target.0040777B 00407778 JMP SHORT target.0040777D 0040777A FUCOMIP ST,ST(3) 0040777C STI 0040777D CMP EAX,100000 <------------- проверяем разницу, 00407782 PREFIX REP: 00407783 JA 787686FF <---------------- если больше 100000, прыгаем к "плохому мальчику". 00407789 LEA EAX,DWORD PTR SS:[EBP+40231C] <-- А вот это интересно! Это еще какая-то проверка, 0040778F CMP BYTE PTR DS:[EAX],1 <------------ потому что если EAX!=1, то мы прыгнем 00407792 JNZ target.0040795E <---------------- к сообщению, что задетекчен дебаггер. 00407798 JMP target.004078E7 <---------------- Если поставить брейкпоинт сюда, то я всё это обойду! 0040779D ADD BYTE PTR DS:[EAX],AL 0040779F ADD BYTE PTR DS:[EAX],AL 004077A1 ADD BYTE PTR DS:[EAX],AL Тут есть две проверки; стандартная RDTSC-проверка с проверкой прошедшего времени в случае, что трейсился через код и вторая проверка, которая мне не известна. Чтобы всё это обойти мне нужно поставить "bp" на последний джамп и запустить прогу. Затем продолжаем трейситься. 3. Проверка имени После прыжка я приземлился на проверке времени. Сперва GetModuleFilenameA возвращает имя нашей цели (target.exe) затем выполняется сравнение тут: 00407912 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] Проверим окно регистров, посмотрим EDI и ESI: ESI 004077DA ASCII "target.exe" EDI 00408378 ASCII "Copie de Original.exe" Как вы видите, "target" сравнивается с "Copie de Original" (.exe, само расширение, не сравнивается), т.е. с оригинальным названием крякмиса. Потрейситесь и вы найдёте хороший джамп, который должен быть выполнен (если нет, то выскакивает MessageBoxTimeoutA и крякми закрывается): 0040791E JE SHORT target.0040794D Но этот джамп прыгает на вторую проверку, которая сперва меня смутила: 0040794D CMP BYTE PTR DS:[EDI],2E 00407950 JE SHORT target.0040795E <--- Хороший Джамп! После того, как имя сравнено эта проверка посмотрит есть ли в конце файла символ ".". Это просто трюк, в случае, если мы изменили только первый джамп. Так что я изменил имя файла на "Copie de Original.exe" и запустил. Получил другое сообщение: "PE header has been modified!...". 4. И еще анти-дебаг Заголовку PE придётс я подождать, потому что существуют еще анти-дебаг трюки: IsDebuggerPresent - детектим дебаггер, используйте плагин, чтобы спрятать Оlly. FindWindowA - ищем известные крэк-тулзы, поставьте hw bp на api. OutputDebugStringA - убираем Олльку, пропачьте этот api. Чтобы избавиться от OutputDebugStringA просто поместите последний опкод api в kernel в начало(For OutputDebugStringA just place last opcode of api in kernel to beggining. - слегка не понял, что хотел автор - прим. NCat). У меня это RETN 4. Затем жмём F9 и останавливаемся на FindWindowA... много раз, но вот это интересно: 0012FF9C 00144FA1 /CALL to FindWindowA from 00144F9B 0012FFA0 00143E47 |Class = "OllyDbg" 0012FFA4 00000000 \Title = NULL После выхода из api, просто установите EAX=0, чтобы убить проверку. Остальные тулзы, которые проверяются: 0012FF9C 0014524F /CALL to FindWindowA from 00145249 0012FFA0 00000000 |Class = 0 0012FFA4 00143E8F \Title = "Import REConstructor v1.6 FINAL (C) 2001-2003 MackT/uCF" 0012FF9C 001452B2 /CALL to FindWindowA from 001452AC 0012FFA0 00000000 |Class = 0 0012FFA4 00143EC7 \Title = "Resource Hacker" 0012FF9C 00145315 /CALL to FindWindowA from 0014530F 0012FFA0 00000000 |Class = 0 0012FFA4 00143ED7 \Title = "[ LordPE Deluxe ] by yoda" 0012FF9C 00145378 /CALL to FindWindowA from 00145372 0012FFA0 00000000 |Class = 0 0012FFA4 00143EF1 \Title = "PEiD v0.93" 0012FF9C 001453DB /CALL to FindWindowA from 001453D5 0012FFA0 00000000 |Class = 0 0012FFA4 00143EFC \Title = "PE Tools v1.5 Xmas Edition - by NEOx/[uinC], http://www.uinc.ru/" 0012FF9C 0014543E /CALL to FindWindowA from 00145438 0012FFA0 00000000 |Class = 0 0012FFA4 00143F3D \Title = "BDASM" 0012FF9C 001454A1 /CALL to FindWindowA from 0014549B 0012FFA0 00000000 |Class = 0 0012FFA4 00143F43 \Title = "Process Hunter v1.0" 0012FF9C 00145504 /CALL to FindWindowA from 001454FE 0012FFA0 00000000 |Class = 0 0012FFA4 00143F57 \Title = "[ PEditor 1.7 ] by yoda & M.o.D." 0012FF9C 00145567 /CALL to FindWindowA from 00145561 0012FFA0 00000000 |Class = 0 0012FFA4 00143F79 \Title = "PROTECTiON iD v5.0 FiNAL - the ultimate Protection Scanner - 100% ASM !" 0012FF9C 001455CA /CALL to FindWindowA from 001455C4 0012FFA0 00000000 |Class = 0 0012FFA4 00143FC1 \Title = "Import REConstructor v1.4.3 BETA5 (C) 2001-2002 MackT/uCF" 5. Проверка заголовка PE Возвращаемся в код и трейсимся дальше. Я нашёл где проверяется значение NumberOfRvaAndSizes в заголовке: 001437EA FF95 E52C4000 CALL DWORD PTR SS:[EBP+402CE5] ; kernel32.VirtualProtect 001437F0 B8 BD2A6348 MOV EAX,48632ABD 001437F5 8B57 74 MOV EDX,DWORD PTR DS:[EDI+74] 001437F8 3BC2 CMP EAX,EDX <----------------------------- Проверка!!! 001437FA 74 7F JE SHORT 0014387B <----------------------- Хороший Джамп!!! 001437FC 6A 00 PUSH 0 001437FE 8B85 B52C4000 MOV EAX,DWORD PTR SS:[EBP+402CB5] ; kernel32.FatalExit 00143804 50 PUSH EAX 00143805 8D85 EE204000 LEA EAX,DWORD PTR SS:[EBP+4020EE] 0014380B 8D95 99204000 LEA EDX,DWORD PTR SS:[EBP+402099] 00143811 6A FF PUSH -1 00143813 6A 00 PUSH 0 00143815 6A 30 PUSH 30 00143817 50 PUSH EAX 00143818 52 PUSH EDX 00143819 6A 00 PUSH 0 0014381B FF95 CB2C4000 CALL DWORD PTR SS:[EBP+402CCB] ; USER32.MessageBoxTimeoutA 00143821 C3 RETN 6. Снова проверка дебагера и прыжок на OEP Теперь снова используется FindWindowA-проверка и проверяются кое-какие файлы (softice и т.д.) с использованием CreateFileA. После прохождения этих проверок будет пара декриптовочных циклов, которые расшифровывают секции и после всего этого будет один JMP EAX, который и есть наш прыжок к OEP: 00143A4E -FFE0 JMP EAX ; Copie_de.004011B0 00143A50 2851 03 SUB BYTE PTR DS:[ECX+3],DL 00143A53 6D INS DWORD PTR ES:[EDI],DX ; I/O command 00143A54 51 PUSH ECX 00143A55 B6 CA MOV DH,0CA 00143A57 33BA 49A02535 XOR EDI,DWORD PTR DS:[EDX+3525A049] 00143A5D 8399 9112B461 C3 SBB DWORD PTR DS:[ECX+61B41291],-3D 00143A64 -FFE0 JMP EAX ; Copie_de.004011B0 00143A66 C3 RETN Вот и всё. Всё, что осталось: сдампить файл и использовать ImpREC, чтобы пофиксить импорт. Автор : [haggar] Перевод: nightcat