ВЗЛОМRAZ0R HTTP://RAZ0R.NAMEПосле патча контрольная сумма отличалась всеголишь на один байт, и теперь переход выполнен нетуда, куда надоflag_1 = 1end ifelse if sequence = 1if flag_2 = 0proc_2flag_2 = 1end ifend ifend whilemacro proc_1 {proc AnyProcedure1...retendp}macro proc_2 {proc AnyProcedure2....retendp}Проверив этот код, убеждаемся, что процедуры выставляются какнадо, случайно, код не портится.0XDEFACED, ÈËÈ ÎÁÔÓÑÊÀÖÈß: ÄÈÍÀÌÈ×ÅÑÊÎÅÂÛ×ÈÑËÅÍÈÅ ÀÄÐÅÑÎÂОдин из способов противодействия дизассемблерам и обману анализаторов— динамическое вычисление адресов переходов или адресовпеременных. Пример, как можно вычислять адрес:push label - valueadd [esp],valuejmp [esp]....label:add esp,4; èçáàâëÿåìñÿ îò íåíóæíîãîСледует сделать случайными алгоритмы вычисления, варианты реализацииалгоритма, и, естественно, значения для модификации. Примерамиэтого станут представленные ниже макросы o_jmp и olabel:macro o_jmp destination {randomizevariant = rndnum mod 2if variant = 0randomizevalue = rndnum mod IMAGE_BASE060push destination - valueadd [esp],valuejmp [esp]else if variant = 1randomizevalue = rndnum mod (0xFFFFFFFF - IMAGE_BASE- 0x1000)push destination + valuesub [esp],valuejmp [esp]end if}macro o_label name {label nameadd esp,4}Итог работы макросов:68001127b6 | push dword 0xb6271100812c249b10e7b5 | sub dword [esp], 0xb5e7109bff2424| jmp dword near [esp]31c0| xor eax, eax83c404| add esp, 0x431c0| xor eax, eaxБез трассировки и не узнаешь, куда ведет переход, следовательно,статический анализ обламывается. Здесь также стоит учитывать занятые\свободныерегистры в генераторе мусора, так как постоянноеиспользование Esp ставит клеймо на способе, да и само по себе накладно.Еще одной неплохой уловкой является вставка переходов наданные, но переходы эти никогда не выполняются (или выполняютсятолько при наличии отладчика). Это сбивает с толку анализаторы, иони пытаются дизассемблировать данные. Пример макроса:macro facke_code_ref data_addr,jmp_addr {xor eax,eaxinc eaxjnz jmp_addrcall data_addr;trash}В итоге адрес data_addr будет анализироваться как код.0XA55 — ÇÀØÈÔÐÎÂÊÀ ÊÎÄÀ\ÄÀÍÍÛÕЗамечательными функциями макроязыка FASM, отличающими егоот других макроассемблеров, являются load и store. Использовать ихможно для шифрования кода или данных. Простой пример, для шифрованияиспользуется xor:macro xor_data start,length,key {repeat lengthload x from start+%-1x = x xor keystore x at start+%-1end repeat}Очень полезный макрос, я его использовал для зашифровки строковыхданных. Пример использования:randomizeXOR_KEY = rndnum mod 0xFFxor_data strings, strings_size, XOR_KEYstrings:XÀÊÅÐ 08 /139/ 10
Взгляд на многообещающее будущее через окноradareany_string db 'Mate.Feed.Kill.Repeat'strings_size = $ - strings0XABA51A, ÈËÈ ÊÎÍÒÐÎËÜ ÖÅËÎÑÒÍÎÑÒÈ ÊÎÄÀВычислив на стадии компиляции контрольные суммы участков кода,можно защититься от модификации, пересчитывая и проверяя при выполненииэти суммы. Также подобным образом можно детектироватьтрассировку посредством вставки в код прерывания int3, как делаютмногие отладчики. Макрос, вычисляющий crc32 сумму блока кода:CRC32_SUM = 0macro calc_crc32 start, size {local b,cc = 0xffffffffrepeat sizeload b byte from start+%-1c = c xor brepeat 8c = (c shr 1) xor (0xedb88320 * (c and 1))end repeatCRC32_SUM = c xor 0xffffffff}Хочу заметить, что операции вида if(original_hash != current_hash) Error() абсолютно бесполезны! Хотя используются повсеместно,даже в крутых протекторах. А вот нечто подобное:mov eax,address + original_hashsub eax,current_hashcall eaxСовсем другое дело. Двух зайцев сразу: обфускация — динамическое вычислениеадреса перехода, и контроль целостности кода, то есть, если кодбыл каким-либо образом изменен, будет выполнен переход кот знает куда.0XACCEDE, ÈËÈ ÎÁÌÀÍ ÀÍÀËÈÇÀÒÎÐÎÂАнализаторы исполняемых файлов вроде PEiD используют сигнатурныйпоиск, в базе находятся цепочки байт, которые встречаются впопулярных протекторах\упаковщиках. Для того, чтобы сбить с толкувзломщиков своей программы, я создал макрос, добавляющий в EntryPoint программы случайную сигнатуру. Воспользовавшись вышеупомянутыманализатором или его аналогом и получив ложный результат,взломщик попытается распаковать программу либо автоматическимраспаковщиком, либо вручную, следуя описанию. И, конечно же, ничегоне получится, кроме тяжелого ступора.macro facke_sign {randomizevariant = rndnum mod Nif vatiant = 0;PE Protect 0.9 -> Christoph Gablerpush edxpush ecxpush ebppush edidb 0x64, 0x67, 0xA1, 0x30, 0x00;FASM ãåíåðèðóåò äëèííûé ôîðìàò èíñòðóêöèèРезультат работы немного расширенного макроса};mov eax,[fs:0x30], ïîýòîìó çàïèñàë òàêèì îáðàçîìtest eax,eaxjs @f+1call .end.signpop eaxadd eax,7db 0xC6nopret@@:db 0xE9,0x00,0x00,0x00,0x00.end.sign:else if variant = 1;CD-Cops II -> Link Data Securitypush ebxpushadmov ebp,0x90909090lea eax,[ebp-0x70]lea ebx,[ebp-0x70]call $+5lea eax,[ecx]db 0xE9,0x00,0x00,0x00,0x00...else if variant = N...0XAD105. ÇÀÊËÞ×ÅÍÈÅГрамотное использование и комбинирование описанных мною техникпозволяет сделать серьезную защиту. Это и очень удобно: написав,отладив программу, с минимальными правками исходного кода превращаемее в неприступный бастион. После того, как я написал свойнабор макросов, протестировал и применил их к своей программе,мне пришла в голову еще одна замечательная идея. Данный методя еще и автоматизировал следующим способом: поместил на серверисходный код программы и компилятор FASM, при запросе пользователемtrial-версии программы она автоматически компилируется;таким образом получается, что каждому пользователю выдаетсяуникальная версия программы. Универсальные взломщики (патчеры,crack'и и т.п.) просто бессильны — придется ломать каждую копиюотдельно. А это ведь непросто, учитывая, что весь код изменен, а некак у навесных протекторов, только «сверху». Мне, как разработчику,остается только чаще обновлять исходники и совершенно не волноватьсяо том, что мою программу могут взломать. Так что, open youreyes, open your mind! zXÀÊÅÐ 08 /139/ 10 061