-
-
> "Как?": - ну это вам решать, способов масса.
Знаков препинания многовато )
-
<tfuncdata></tfuncdata></tsectiondata> Это какой-то артефакт?
-
За грмматику согласен, и второй косяк подчищу. По самому материалу, не слишком ли переборщил? Имх стоит его подразбавить немного обьяснениями технических деталей, бо кажется слишком суховато вышло - тупо обьяснение методы и все. Народ может не понять, как мне кажется
-
> Итак TLS Callback и что это за зверь. Спасибо!, не знал о таком.
> Их можно задавать в динамике перед резюмом нити через модификацию резюмом? (вкусный намек на изюминку статьи ) )
Соответственно подумалось что они (TLS Callback) отработают уже только в завершении потока.
Поэтому и вопросы: 1. Когда еще (кроме начального старта, как в статьи) отработает TLS Callback в exe: - создание/завершение потока? - загрузка/выгрузка длл? 2. И для длл-ки?
> подразбавить немного обьяснениями технических деталей, да, но не из-за того, что суховато, а потому что интересно ;)
ЗЫ. И что там с подлым хромом - люблю жанр "технический детектив".
-
Ага понял, хорошая идейка для развития темы статьи. Добавлю что да как
-
// дабы процедура tls_callback появилась в MAP файле // нужно ее вызвать, но вызывать ее мы будем с некоректными параметрами // дабы она лишний раз почем зря не отработала tls_callback(nil, 100, nil); // const ptls_callback : Pointer = @tls_callback; ?
//... F.Position := TlsTable; F.ReadBuffer(OldCallbackTableAddr, 4); Inc(OldCallbackTableAddr, 8); F.Position := TlsTable; F.WriteBuffer(OldCallbackTableAddr, 4); // CallbackTableAddr 'передвинули' на два Pointer-а, \ Writeln('Назначен новый адрес цепочки обработчиков, оффсет: ', IntToHex(TlsTable, 8), ', новое значение: ', IntToHex(OldCallbackTableAddr, 8)); F.Position := TlsTable + HardcodeTLS32Offset; // \а заносим CallbackAddr куда? F.WriteBuffer(CallbackAddr, 4); // \или мы знаем, что OldCallbackTableAddr указывал на (TlsTable + HardcodeTLS32Offset - 8) ? Writeln('Адрес каллбэка выставлен, оффсет: ', IntToHex(TlsTable + HardcodeTLS32Offset, 8)); OldCallbackTableAddr := 0; TlsTable := F.Position; for I := 0 to 15 do // а почему именно 16, вроде хватило бы и одного ? F.WriteBuffer(OldCallbackTableAddr, 4); Writeln('Цепочка калбэков очищена, оффсет: ', IntToHex(TlsTable, 8), ', размер: ', 16 * 4);
//... Writeln('Правлю время создания МАР файла'); // как бы понятно, но зачем?
-
> 3 каллбэка, которые выполняются до загрузки ее в АП процесса.
То есть на эти каллбэки накладываются ограничения более строгие чем на DllEntry? А когда в еxe, то тоже так?
-
Ну это ошметки от тестового кода, где я эксперентировал. Там есть небольшой нюансик если собирать под ХЕ10
В финалке все причешу и код будет ровный, постараюсь сразу и под 64 бита реализовать (изменения в принципе минорные)
-
Есть небольшие ограничения, но только в специфичных случаях, а так по факту считай что это такой-же dllmain, причем не важно где он расположен что в библиотеке что в приложении (логика работы одинаковая)
-
Опс, я там написал "до загрузки"?!!! Это, конечно ошибка. До передачи на ЕР процесса и ЕР библиотеки - подправлю
-
> По самому материалу, не слишком ли переборщил? > Имх стоит его подразбавить немного обьяснениями технических > деталей, бо кажется слишком суховато вышло - тупо обьяснение > методы и все. Народ может не понять, как мне кажется
Кто не поймет, тому и не надо оно.. В попытках объяснить технические детали можно "Windows Internals" переписать в десяти томах )
-
Ну я как раз и пытаюсь простыми словами о сложном, иначе зачем писать?
-
Тогда надо начинать с "На кого рассчитана статья".
-
На работающих с защитой, есесно. Я только про нее и пишу :)
-
Полную вычитку делать долго. Пробежал глазами минут за 10, не вникая в детали, - хоршо, в твоём стиле, всё так нормально, это не вникая в уже в технические детали.
Одну деталь только убери "Ну, во первых: он работает как диод - бесшумно." Диоды работают шумно, как и все приборы.
-
Ну да. Аналогия с диодом совсем не в дугу. Лучше - "Ну во-первых, он работает бесшумно как квалифицированный агент спецслужб." Это ближе по аналогии. Да и к сути статьи это ближе. Кто из работающих с защитой ПО знает о диодах вообще и о том что они из себя представляют в частности?
-
Опять забыл поставить смайлик. :(
-
> [16] Германн © (27.02.16 01:22) > Лучше - "Ну во-первых, он работает бесшумно как квалифицированный агент спецслужб." Это ближе по аналогии.
Агенты тоже бывают шумными, а иные проводят в обе стороны. Не годится. Может обойтись без аналогий, а прямо так текстом рубануть правду, чуть подсластив? Уж не знаю как, но придерживаясь стилистики... Нет, авторская должна быть.
-
> Имх стоит его подразбавить немного обьяснениями технических > деталей, бо кажется слишком суховато вышло - тупо обьяснение > методы и все. Народ может не понять, как мне кажется
и действительно. стоит немного добавить, что такое tls callback и для чего они нужны.
-
Если есть возможность выполнить что-то перед запуском потока, зачем тогда эти заморочки с BeginThread?
-
Ты о делфийской обертке или о чем?
-
BeginThread это сугубо VCL.
-
> Nouser © (26.02.16 23:23) [6]
const ptls_callback: Pointer = @tls_callback; Действительно - век живи, век учись, все равно дураком помрешь :) Чет как-то не знал про такой нюанс :)
-
Подготовил примерчик по антидампу с использованием TLS - щас добавлю через часок, а по антиотладке думаю будет избыточно - все и так у меня в статьях есть. К сожалению момент с динамическим добавлением TLS Callback придется выпилить - посеял я примерчик, там простое что-то было (банально TlsSetValue + немного хитростей с инициализацией структуры), но... почти полдня искал - не найшел :(
-
-
-
-
Эмм, так вроде везде правильно написал "callback" или "калбэк" - гдето очепятался чтоль?
-
Rouse_ © (27.02.16 22:15) [28]
По ссылке пишут "коллбэк".
-
Принято - поправил
-
Блин, еще и текст исходников же еще править - ладно, это завтра :)
-
> Игорь Шевченко © (27.02.16 22:09) [27] > > https://ru.wikipedia.org/wiki/Callback_(%D1%82%D0%B5%D0%BB%D0%B5%D1%84%D0%BE%D0%BD%D0%B8%D1%8F)
В дополнение. колл тоже режет, но слух. Сдвоенные согласные в аглицком редко используются для "продления" звука, как в русском. Более-менее правильная русская транскрипция этого слова - колбэк.
-
Мне вот проще калбэк писать, привык, но раз низя - пусть будет через о и с двумя л :)
-
> Rouse_ © (28.02.16 00:42) [33] > > Мне вот проще калбэк писать, привык, но раз низя - пусть > будет через о и с двумя л :)
Лучше через О. Тут ИШ абсолютно прав. Ты же не говоришь "звоните/звоню в калцентр" :)
-
> Ты же не говоришь "звоните/звоню в калцентр" :)
часто складывается впечатление, что именно туда.
-
болл, волл, колл )
-
Да в принципе... Как скажете, так и будет, главное чтоб техническая часть статьи была без ошибок :)
-
2 Eraser © (28.02.16 00:55) [36] Футбол, файервол, и уже упомянутый колцентр. Нигде нет сдвоенных согласных. Хотя в оригинале они есть.
-
> Rouse_ © (28.02.16 00:55) [37] > > Да в принципе... Как скажете, так и будет, главное чтоб > техническая часть статьи была без ошибок :)
Извини за оффтоп.
-
Да нормально, как мне статью то править, если я все мнения со стороны не услышу? Не для себя ж пишу :)
-
Ну тогда извини, что техническую часть я даже не читал. :(
-
DWORD-ы в примерах (при работе с адресами) было бы поучительно (дженерики то внедрил) заменить на Pointer и/или IntPtr/UIntPtr. Тогда вместо, возможно ошибочного, '(плюс 2 дворда что в 32 битном, что в 64 битном варианте)' два слова сказать про отличия указателей в x64 и заменить '4' на const cbPtr = SizeOf(Pointer/IntPtr) ;) PS. В тексте многовато 'но' - можно попробовать заменить на 'а', 'и', 'а вот' или просто убрать, но )) это так, - косметика. << Но_ это в Visual Studio, а вот в Дельфи такого сделать так сходу нельзя - не умеет она, но!!! Но_ есть небольшой трюк, связанный с тем что разработчики компилера_ Дельфи, уж не знаю по каким причинам, но_ немного нам помогли, создав неинициализированную TLS секцию в исполняемом файле. С какого времени это началось - я не знаю, но_ начиная … >> << то мы инициализирует_ ее >> << убиваем_ ее значение >> PPS. http://pritchi.castle.by/ras-013-402.html ( http://static2.ozone.ru/multimedia/books_covers/1007045216.jpg)
-
> Тогда вместо, возможно ошибочного, > '(плюс 2 дворда что в 32 битном, что в 64 битном варианте)' > два слова сказать про отличия указателей в x64 и заменить > '4' на > const cbPtr = SizeOf(Pointer/IntPtr) ;)
Нет тут код не ошибочный (2 дворда в структуре идет последними в обоих вариантах)
_IMAGE_TLS_DIRECTORY64 = record StartAddressOfRawData: ULONGLONG; EndAddressOfRawData: ULONGLONG; AddressOfIndex: ULONGLONG; // PDWORD AddressOfCallBacks: ULONGLONG; // PIMAGE_TLS_CALLBACK *; SizeOfZeroFill: DWORD; Characteristics: DWORD; end;
_IMAGE_TLS_DIRECTORY32 = record StartAddressOfRawData: DWORD; EndAddressOfRawData: DWORD; AddressOfIndex: DWORD; // PDWORD AddressOfCallBacks: DWORD; // PIMAGE_TLS_CALLBACK *; SizeOfZeroFill: DWORD; Characteristics: DWORD; end;
А про указатели - для демо достаточно и такого, нельзя же все выкладывать на блюдечке с голубой каемкой, человек и сам должен немного мозг включить прежде чем использовать сторонний код. По остальному вечером попричесываю тем более тут один нюансик вскрылся, который придется подправить.
-
Ну вроде как причесал - если за вечер никто ничего не найдет, завтра тогда на паблик выложу
-
Прочитал. Идейно понятно.
Чисто философский вопрос.
Реверсер же сразу поймет при следующем запуске, что его пытаются обхитрить. Неужели он не найдет управу? Да хоть дампы в Parallels Desktop сделать с уже запущенной программой.
Суть вопроса стоит ли делать подобную защиту (у реверсера же наверняка рука набита на противодействии таким трюкам)?
-
> Тимохов Дима © (29.02.16 15:06) [45] > Реверсер же сразу поймет при следующем запуске, что его > пытаются обхитрить.
Конечно поймет.
> Неужели он не найдет управу? Да хоть дампы в Parallels Desktop > сделать с уже запущенной программой. > > Суть вопроса стоит ли делать подобную защиту (у реверсера > же наверняка рука набита на противодействии таким трюкам)? >
Если код защиты под виртуальной машиной - очень долго искать придется.
А так вообще - тут же только сам принцип, на практике антидамп в разы сложнее делается :)
-
> А так вообще - тут же только сам принцип, на практике антидамп > в разы сложнее делается :)
Не, ну все же чем Parallels тебе не нравится? Запустил, снял дамп, потом сколько хочешь восстанавливай. Ты же защищается от повторного запуска по снятому дампу. А тут и запуска не будет повторного.
Я не в части критики, просто интересно. Я то в свое время поставил на виртуальную машину (чужую), которую натравил на некую свою виртуальную машину. Расчет на то - задолбаются 100мб мусора фильтровать. Может, обновляться придется. Вот, думаю - надо ли мне это.
ЗЫ Саш, извиняй плз за оффтоп))
-
> Тимохов Дима © (29.02.16 16:29) [47] > Не, ну все же чем Parallels тебе не нравится? > Запустил, снял дамп, потом сколько хочешь восстанавливай.
Понятно - статью ты не читал, там описано почему нужно делать дамп :)
-
> Понятно - статью ты не читал, там описано почему нужно делать > дамп :)
Читал. Я все понял)) Правда. Я ж тебе говорю - запускаешь программу под виртуалкой, она распаковывется, делаешь дамп при ЗАПУЩЕННОЙ программе. с уже правильными "секретным числом". Потом из дампа сколько хочешь раз восстанавливай и работай - программа то уже запущена.
-
> Тимохов Дима © (29.02.16 17:03) [49] > Читал. Я все понял)) Правда. > Я ж тебе говорю - запускаешь программу под виртуалкой, она > распаковывется, делаешь дамп при ЗАПУЩЕННОЙ программе. с > уже правильными "секретным числом". > Потом из дампа сколько хочешь раз восстанавливай и работай > - программа то уже запущена.
Значит читал но не понял - там в BIN лежит экзешник - сдампь и запусти :)
-
Можешь просто последнюю гифку посмотреть в статье - там показанно что будет и как работает "секретное число" :) (Напомню - при старте оно должно быть равно нулю, иначе никакого фокуса не получится :)
-
// сам колбэк VOID NTAPI tls_callback(HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved) { MessageBox(0, L"TLS Callback Message", L"", 0); } на скрине MyTLS Callback Message
-
Writeln('Какая-то бяда в GetSectionDataList.');
з.ы. "мясной рулет с черносливом" атмосферней будет
-
> virex(home) ©
Угу, код поправлял - картинка старая осталась. А с исключениями - ну ща ченить нормальное напишу, они там вообще по факту не сильно и нужны.
-
-
Блин, ребята с http://delphifeeds.ru/ меня убьют :))) Забыл CAT поставить и к ним в новостную ленту статья целиком залилась, вместо шапки - бггг, ппц :) Тот еще натюрморт :)))
-
А, не - все поправили, оперативно работают - респект :)
-
> Rouse_ © (29.02.16 17:31) [51] > Можешь просто последнюю гифку посмотреть в статье - там > показанно что будет и как работает "секретное число" :) > (Напомню - при старте оно должно быть равно нулю, иначе > никакого фокуса не получится :)
Невнимательное чтение чужого кода-текста - болезнь многих программистов (личное наблюдение).
Еще раз.
Чего ты добиваешься?
Ты хочешь, чтобы реверсер сказал неприличное слово(а) и убился об стену в следующем сценарии: 1. Реверсер запустил твою программу. Допустим, это офигеть как сложно - три дня сидел, не ел, не пил. Но получил в памяти чистый код! 2. Программа при старте заменила 0 на правильное число, без которого работать не может. Число лежит в глоб. переменной. 3. Реверсер снял дамп памяти (с правильным для работы числом - в той самой глоб. переменной). 4. Реверсер запустил дамп. В глоб. переменной лежит правильное для работы число, но не 0. Поэтому после запуска в глоб. перменной не окажется правильного для работы числа (см. п. 2). 5. В итоге программа не работает. 6. Реверсер матерясь убивает себя об стену.
Но реверес мог читать твою статью и не делать шаг 3. Вместо него - сделать snapshot виртуальной машины - с запущенной и работоспобной твоей программой. После чего он может восстанавливать ситуацию из snapshot'а сколько угодно раз - пока не вырежет твой стартовый TLS-callback.
Ну как-то так)))
И где я не прав?
-
> Rouse_ © (29.02.16 17:31) [51] > Можешь просто последнюю гифку посмотреть в статье - там > показанно что будет и как работает "секретное число" :) > (Напомню - при старте оно должно быть равно нулю, иначе > никакого фокуса не получится :)
Невнимательное чтение чужого кода-текста - болезнь многих программистов (личное наблюдение).
Еще раз.
Чего ты добиваешься?
Ты хочешь, чтобы реверсер сказал неприличное слово(а) и убился об стену в следующем сценарии: 1. Реверсер запустил твою программу. Допустим, это офигеть как сложно - три дня сидел, не ел, не пил. Но получил в памяти чистый код! 2. Программа при старте заменила 0 на правильное число, без которого работать не может. Число лежит в глоб. переменной. 3. Реверсер снял дамп памяти (с правильным для работы числом - в той самой глоб. переменной). 4. Реверсер запустил дамп. В глоб. переменной лежит правильное для работы число, но не 0. Поэтому после запуска в глоб. перменной не окажется правильного для работы числа (см. п. 2). 5. В итоге программа не работает. 6. Реверсер матерясь убивает себя об стену.
Но реверес мог читать твою статью и не делать шаг 3. Вместо него - сделать snapshot виртуальной машины - с запущенной и работоспобной твоей программой. После чего он может восстанавливать ситуацию из snapshot'а сколько угодно раз - пока не вырежет твой стартовый TLS-callback.
Ну как-то так)))
И где я не прав?
-
> Невнимательное чтение чужого кода-текста - болезнь многих программистов (личное наблюдение).
- поиск в ознакомительной статье законченного полнофункционального ноу-хау - болезнь ...
-
> han_malign © (02.03.16 11:54) [60] > > > Невнимательное чтение чужого кода-текста - болезнь многих > программистов (личное наблюдение). > > - поиск в ознакомительной статье законченного полнофункционального > ноу-хау - болезнь ...
Не, ты не прав. Нет поиска ноу-хау. Есть попытка разобраться в философии защиты. Я в свое время у Саши многому научился. Чему и благодарен безмерно. Будь я реверсером, я бы люто ненавидел этого Розыча! Любая защита строится на соотношении времени на взлом и ценности. Вот и интересно, насколько указанный прием увеличивает знаменатель указанного отношения.
Собсно сложность взлома - отделить защитный код, от полезного. Если пораскинуть мозгами, то можно, видимо, в этот коллбек засунуть код, который и секрет инициализирует и делает реально что-то полезное, без чего программа работать не будет. Т.е. нельзя будет просто пропустить этот TLS-callback. Видимо, на это расчет идет.
-
> han_malign © (02.03.16 11:54) [60] > > > Невнимательное чтение чужого кода-текста - болезнь многих > программистов (личное наблюдение). > > - поиск в ознакомительной статье законченного полнофункционального > ноу-хау - болезнь ...
Не, ты не прав. Нет поиска ноу-хау. Есть попытка разобраться в философии защиты. Я в свое время у Саши многому научился. Чему и благодарен безмерно. Будь я реверсером, я бы люто ненавидел этого Розыча! Любая защита строится на соотношении времени на взлом и ценности. Вот и интересно, насколько указанный прием увеличивает знаменатель указанного отношения.
Собсно сложность взлома - отделить защитный код, от полезного. Если пораскинуть мозгами, то можно, видимо, в этот коллбек засунуть код, который и секрет инициализирует и делает реально что-то полезное, без чего программа работать не будет. Т.е. нельзя будет просто пропустить этот TLS-callback. Видимо, на это расчет идет.
-
> Ну как-то так))) > > И где я не прав?
В том что в боевом коде естественно должно быть по другому, я же просто идею показал, а на практике все делается в разы сложнее :)
-
Скажите, я верно понял, что всё написанное можно применить на практике лишь для защиты ПО? Или есть другие полезные применения?
-
Ну по мимо того что в TLS Callback-е ты можешь отслеживать старт новых потоков + подгрузку библиотек (через CreateRemoteThread или хуком - там тоже отдельная нить стартует зачем-то) других применений в принципе нет.
-
> Rouse_ © (02.03.16 13:24) [63] > > > Ну как-то так))) > > > > И где я не прав? > > В том что в боевом коде естественно должно быть по другому, > я же просто идею показал, а на практике все делается в > разы сложнее :)
Спасибо, Саша! Полезная, безусловно, статья!
Имхо, самое полезная идея - подход с "правильным" числом. А как это будет сделано (через TLS-колбек или через либу) - не важно. Опять же имхо. В любом случае сложность взлома будет обусловлена разбором кода, выполняющегося при старте - а тут все средства хороши для защиты: и виртуализация кода, и прочее запутывание кода.
-
> Rouse_ © (02.03.16 13:24) [63] > > > Ну как-то так))) > > > > И где я не прав? > > В том что в боевом коде естественно должно быть по другому, > я же просто идею показал, а на практике все делается в > разы сложнее :)
Спасибо, Саша! Полезная, безусловно, статья!
Имхо, самое полезная идея - подход с "правильным" числом. А как это будет сделано (через TLS-колбек или через либу) - не важно. Опять же имхо. В любом случае сложность взлома будет обусловлена разбором кода, выполняющегося при старте - а тут все средства хороши для защиты: и виртуализация кода, и прочее запутывание кода.
|