|
#1
|
||||
|
||||
image address
Привет форум!
Такой вот вопрос. Хочу с помощью отдельной программы зашифровать кусок exe файла содержащий некоторую функцию, а при выполнении этого exe он будет сам свой кусок расшифровывать. Вобщем задача тривиальная, определить адреса этого блока в момент шифрации отдельной программой и адрес такого же блока при дешифрации самого себя. Делаю так нахожу всякими череззаднийпроходными способами адрес в памяти самого процесса получаю Addr1 потом загружаю в мемористрим этот же exe нахожу там этот же кусок по адресу Addr2 дальше определяю смещения Ofs1=Addr1-Hinstance Ofs2=Addr2-MS.Memoryв итоге Ofs1<> Ofs2 Если посмотреть в VMMap то адрес имидж блока начинается с header который 4КБ а адрес .tеxt с адреса $00401000 но разница меньше 4КБ Как понять что это за дельта где ее определить получается Ofs1-Ofs2= 3072 байт? Хммм.. перефразирую вопрос. есть тестовое приложение, в нем есть к примеру функция "Test", я могу получить ее адрес: Addr1:=Addr(Test); если по этому адресу просто вычитать данные получим к примеру "C3 8D 40 00 55 8B EC B8 ...." затем я запускаю другое приложение в котором, загружаю в мемористрим exe файл моего тестового приложения и вот вопрос, как мне определить позицию меморитсрима по которой я прочитаю тот же блок "C3 8D 40 00 55 8B EC B8 ...."???? Последний раз редактировалось a.n.d.r.e.w, 24.09.2015 в 16:11. |
#2
|
||||
|
||||
Варианты:
1) Кури спецификацию формата PE (Portable Executable). 2) Сохранить считанный массив байт (к примеру, первые 128 байт) и бинарно найти его в EXE-файле, определить адрес в файле. 3) Сделать в начале и конце функции магические АСМ-вставки с какой-нибудь константой, по которой функцию легко найти в файле. Или же вызов некой ненужной функции из липовой DLL, который потом будет убран, но позволит найти начало и конец для крипты при парсинге файла. Также надо учитывать, что секция кода для записи изначально не доступна, поэтому для расшифровки скорее всего придется делать VirtualProtect. А также не удивляйся, если вдруг какие-нибудь антивирусы начнут генерировать тонны кирпичей на такое поведение. jmp $ ; Happy End! The Cake Is A Lie. |
#3
|
||||
|
||||
Ну вот у меня с помощью меток и определяется этот кусок. Используется VirtualProtect и работает вроде, касперский по крайней мере не ругается. Буду разбираться с PE, хотя боюсь загнаться... щас начну дописывать секции, менять точки входа...
|
#4
|
|||
|
|||
На сколько я знаю, ASProtect, например, работает (работал по крайней мере, давно не анализировал) примерно так:
1. Программист в начале и конце интересующего его метода расставляет метки. Компилит программу. 2. Запускается ASProtect. Он находит помеченные куски кода, вырезает их, забивает старое место NOP'ами, сам код шифрует и складывает в ресурсы. В начало заNOPоеных кусков ставит переход на свои функции. 3. В самом конце он прописывает свой лоадер. 4. При работе программы при достижении такого места происходит переход в функцию ASProtect'а, которая берет нужный ресурс, расшифровывает его в память и выполняет, потом стирает из памяти и делает переход на конец заNOPленного блока. |
#5
|
||||
|
||||
Если переносить код куда-то, возникнут проблемы с относительными адресами: их все надо найти в коде и пересчитать. А так - да, возможно и такое.
jmp $ ; Happy End! The Cake Is A Lie. |
#6
|
|||
|
|||
Ну, как-то он это делает.
При этом извесны проблемы пересечения шифрованных блоков. Т.е. не все так гладко, как кажется, но, в общем, работает. |
#7
|
||||
|
||||
Ну переносить код в ресурс и перенаправлять вызов это круто. Я вот думаю это все по идее должно защищать от реверса? А что мешает хакеру разобрать алгоритм шифрования, переноса там всякого или код лоадера, он же в явном виде в программе будет находиться?
|
#8
|
||||
|
||||
Цитата:
Профессиональные защиты несколько лучше - они защитят от начинающих реверсеров. И то не факт - для многих известных пакеров в кулуарах крякерских сообществ давно есть анпакеры, просто далеко не все публикуются. Цитата:
Только при подборе средства защиты обычно прикидывают цену. Есть смысл тратить 10к на покупку/разработку защиты калькулятора, у которого будет 3 юзера, каждый из которых заплатит 20 рублей? Сомневаюсь. Есть ли смысл тратить 10к на защиту промышленного программного комплекса, который будут ставить тысячи компаний и выкладывать по 50к за копию? Определенно. Также, на популярную и супер-нужную утилиту, скорее всего, найдутся криптоманьяки, которые сломают и выложат ради интереса. Но взлом на редкую и малораспространенную программу скорее всего придется заказывать, и тогда нужно подобрать защиту так, чтобы заказ ее взлома был дороже, чем покупка самой программы. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 28.09.2015 в 14:48. |
#9
|
|||
|
|||
Ну, не совсем так.
Алгоритм шифрования того же ASProtect'а известен, из него никто тайны не делает. Если не ошибаюсь, то это AES. Но тут мы попадаем как раз в ту ситуацию, когда знание алгоритма не сильно помогает взлому (ну, ествественно, там еще и разные защиты от отладки и др. прибабахи есть, они тоже обходятся, но школоту отсекут). Без знания ключа информация об алгоритмах этого семейства ничем не поможет. А при наличии ключа можно взломать (на самом деле собрать по частям) конкретную программу конкретной версии. При появлении взломанной версии разработчик просто перегенерирует секретный ключ и все. Да и сам взлом при грамотном использовании защиты дело не простое и довольно геморройное. Проще просто тыренный ключик выложить. Проблема в "грамотном использовании защиты". Не всегда это даже возможно (в силу особенностей программы). |
#10
|
||||
|
||||
Цитата:
И вообще не стоит рассуждать так какбудто в джунглях живут только слоны и муравьи. Есть множество промежуточных вариантов имеющих право на существование. сегодня твоя защита защищает от школьников а завтра ты находишь кряк на свой "калькулятор" разве это не приятно? Сделать крутую защиту программы это круто, а сделать такую программу защиту которой хотели бы ломать еще круче. Самая надежная защита, я думаю, это динамичная эволюция твоего продукта, ну и востребованность само собой. В этом случае и эволюции защиты твоему продукту будет место. Последний раз редактировалось a.n.d.r.e.w, 28.09.2015 в 22:05. |
#11
|
||||
|
||||
Цитата:
Цитата:
Цитата:
jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 28.09.2015 в 23:32. |
#12
|
||||
|
||||
в общем кактотак
Код:
program TestProj; ... var data_m, data_f: pointer; ofs1, ofs2, pos: Cardinal; dh:TImageDosHeader; _text:TImageSectionHeader; ... begin data_m:=Addr(StartPointProc); //адрес какой-то функции в памяти процесса CopyMemory(@dh, pointer(HInstance), SizeOf(TImageDosHeader)) ; //читаем заголовок dos CopyMemory(@_text, pointer(HInstance+dh._lfanew+ sizeof(TImageNtHeaders)), SizeOf(TImageSectionHeader)) ; //читаем заголовок первой секции (секции кода) ofs1:=Cardinal(data_m)-HInstance; //смещение адреса функции от начала имиджа ofs2:=ofs1-_text.VirtualAddress; //смещение адреса функции от начала секции pos:=_text.PointerToRawData + ofs2; //смещение адреса функции от начала файла ms:=TMemoryStream.Create; ms.LoadFromFile(ParamStr(0)); //загрузим стрим из этого же EXE data_f:= ms.Memory; inc(Cardinal(data_f), pos); //получим адрес того же куска в памяти стрима //теперь если вычитать небольшой кусок данных из // data_m - памяти процесса // data_f - памяти стрима загруженного из файла //они будут эквивалентны http://saveimg.ru/show-image.php?id=...f93eafbd5d213a |