В этой статье мы исследуем аналог одной очень известной программы для Windows под названием «Блокнот» и напишем DLL расширяющее его возможности. Аналог называется NFOPad.
Исходные коды не прилагаются
![](https://habrastorage.org/files/937/daa/4bf/937daa4bfeda4dc1b78f325d40cb5a84.jpg)
Эта программа может обрабатывать текстовые файлы и производить поиск, замену текста то есть по функционалу ничуть не уступает всемирно известному «Блокноту». Сейчас мы научим его обрабатывать зашифрованные файлы. Плагинов на это чудо технологического прогресса тоже нету и поэтому нам понадобится: знание Ассемблера, отладчик, мозги и компилятор способный смолотить код в DLL.
В этой статье мы научим его создавать зашифрованные файлы и сначала нам нужно найти место где происходит запись в файл при сохранении.
Открываем NFOPad в отладчике (лично я использую Cheat Engine) и переходим в функцию WriteFile:
![](https://habrastorage.org/files/3a0/231/655/3a0231655c26488d9d5af6e5563c02fa.jpg)
Вот мы и в теле функции WriteFile. Теперь нам нужно найти откуда будет вызвана эта функция при сохранении файла и для этого ставим брекпоинт на команду ret
![](https://habrastorage.org/files/c8f/d91/3f4/c8fd913f463d400aa61c92d68893e5f6.jpg)
Теперь напечатаем в блокноте какую нибудь ерунду и сохраняем:
![](https://habrastorage.org/files/769/211/bf8/769211bf87db43bb873634a033ac9fef.jpg)
После того как мы приказали блокноту сохранить текст сработал брекпоинт и после нажатия F8 мы отправляемся на адрес возврата:
![](https://habrastorage.org/files/11d/cbe/833/11dcbe83390c45cfa4483ef9cc9fd9fc.jpg)
То что выделено красным это вызов функции WriteFile который сохраняет введенный текст в текстовый файл.
Вот дальнейший план действий. Мы сотворим DLL библиотеку в которой будет функция с идентичными аргументами как у WriteFile и при загрузке она будет подменять адрес вызова функции которая выделена красным на свой.
Открываем Visual Studio и создаем проект DLL. Первым делом напишем функцию которая будет вызываться вместо WriteFile и назовем ее CrackWriteFile. Она будет шифровать переданный текст а затем вызывать WriteFile и передавать ему свои аргументы.
![](https://habrastorage.org/files/320/ca7/b2b/320ca7b2bbe04724a17edd6d41570730.jpg)
Теперь напишем функцию которая будет подменять адрес:
![](https://habrastorage.org/files/da6/a91/352/da6a9135293246cb9005be13ac237999.jpg)
В точке входа еще нужно прописать вызов этой функции.Думаю все понятно и приступаем к тестированию. Инжектим скомпилированную DLL в процесс блокнота и вводим в редактор примерно следующий текст:
![](https://habrastorage.org/files/011/6db/e80/0116dbe8007c4461a2b6ddaab63dab34.jpg)
Теперь в сохраненном файле мы видим не прекрасное стихотворение, а вот это:
![](https://habrastorage.org/files/e0a/406/44e/e0a40644e02e46449179c03bc74499e7.jpg)
Это на самом деле и есть то стихотворение, но зашифрованное нашим алгоритмом. Теперь мы научим его еще и считывать зашифрованные файлы. Для этого также ставим брекпоинт, но уже на функцию ReadFile и при открытии любого файла этот бряк сработает. Потом по уже отработанному сценарию переходим на адрес возврата и узнаем откуда была вызвана функция.
Теперь в наш проект добавляем функцию CrackReadFile которая будет вызываться когда блокнот будет открывать файл.
![](https://habrastorage.org/files/493/811/929/4938119293304002b01953e1da27786c.jpg)
Теперь изменяем функцию OnInject:
![](https://habrastorage.org/files/841/1cc/e4e/8411cce4e6a345a7a7323a532c60ad26.jpg)
Теперь если после инжекта DLL в процесс зашифрованный файл отображается нормально то все сделано правильно. В этой статье мы расширили функционал аналога блокнота. Конечно при желании можно было значительно доработать наше расширение например сделать так, чтобы при инжекте в интерфейсе программы появлялся чекбокс и только если он установлен программа шифрует файлы или можно было улучшить алгоритм шифрования, но эта не суть поскольку целью статьи было рассказать, что при помощи реверс-инжиниринга можно расширять возможности программ. Как будет время я и дальше буду продолжать писать подобные статьи а поскольку сейчас лето то его у меня полным полно.
Надеюсь, моя статья была вам интересна.
Исходные коды не прилагаются
![](https://habrastorage.org/files/937/daa/4bf/937daa4bfeda4dc1b78f325d40cb5a84.jpg)
Эта программа может обрабатывать текстовые файлы и производить поиск, замену текста то есть по функционалу ничуть не уступает всемирно известному «Блокноту». Сейчас мы научим его обрабатывать зашифрованные файлы. Плагинов на это чудо технологического прогресса тоже нету и поэтому нам понадобится: знание Ассемблера, отладчик, мозги и компилятор способный смолотить код в DLL.
В этой статье мы научим его создавать зашифрованные файлы и сначала нам нужно найти место где происходит запись в файл при сохранении.
Открываем NFOPad в отладчике (лично я использую Cheat Engine) и переходим в функцию WriteFile:
![](https://habrastorage.org/files/3a0/231/655/3a0231655c26488d9d5af6e5563c02fa.jpg)
Вот мы и в теле функции WriteFile. Теперь нам нужно найти откуда будет вызвана эта функция при сохранении файла и для этого ставим брекпоинт на команду ret
![](https://habrastorage.org/files/c8f/d91/3f4/c8fd913f463d400aa61c92d68893e5f6.jpg)
Теперь напечатаем в блокноте какую нибудь ерунду и сохраняем:
![](https://habrastorage.org/files/769/211/bf8/769211bf87db43bb873634a033ac9fef.jpg)
После того как мы приказали блокноту сохранить текст сработал брекпоинт и после нажатия F8 мы отправляемся на адрес возврата:
![](https://habrastorage.org/files/11d/cbe/833/11dcbe83390c45cfa4483ef9cc9fd9fc.jpg)
То что выделено красным это вызов функции WriteFile который сохраняет введенный текст в текстовый файл.
Вот дальнейший план действий. Мы сотворим DLL библиотеку в которой будет функция с идентичными аргументами как у WriteFile и при загрузке она будет подменять адрес вызова функции которая выделена красным на свой.
Открываем Visual Studio и создаем проект DLL. Первым делом напишем функцию которая будет вызываться вместо WriteFile и назовем ее CrackWriteFile. Она будет шифровать переданный текст а затем вызывать WriteFile и передавать ему свои аргументы.
![](https://habrastorage.org/files/320/ca7/b2b/320ca7b2bbe04724a17edd6d41570730.jpg)
Теперь напишем функцию которая будет подменять адрес:
![](https://habrastorage.org/files/da6/a91/352/da6a9135293246cb9005be13ac237999.jpg)
В точке входа еще нужно прописать вызов этой функции.Думаю все понятно и приступаем к тестированию. Инжектим скомпилированную DLL в процесс блокнота и вводим в редактор примерно следующий текст:
![](https://habrastorage.org/files/011/6db/e80/0116dbe8007c4461a2b6ddaab63dab34.jpg)
Теперь в сохраненном файле мы видим не прекрасное стихотворение, а вот это:
![](https://habrastorage.org/files/e0a/406/44e/e0a40644e02e46449179c03bc74499e7.jpg)
Это на самом деле и есть то стихотворение, но зашифрованное нашим алгоритмом. Теперь мы научим его еще и считывать зашифрованные файлы. Для этого также ставим брекпоинт, но уже на функцию ReadFile и при открытии любого файла этот бряк сработает. Потом по уже отработанному сценарию переходим на адрес возврата и узнаем откуда была вызвана функция.
Теперь в наш проект добавляем функцию CrackReadFile которая будет вызываться когда блокнот будет открывать файл.
![](https://habrastorage.org/files/493/811/929/4938119293304002b01953e1da27786c.jpg)
Теперь изменяем функцию OnInject:
![](https://habrastorage.org/files/841/1cc/e4e/8411cce4e6a345a7a7323a532c60ad26.jpg)
Теперь если после инжекта DLL в процесс зашифрованный файл отображается нормально то все сделано правильно. В этой статье мы расширили функционал аналога блокнота. Конечно при желании можно было значительно доработать наше расширение например сделать так, чтобы при инжекте в интерфейсе программы появлялся чекбокс и только если он установлен программа шифрует файлы или можно было улучшить алгоритм шифрования, но эта не суть поскольку целью статьи было рассказать, что при помощи реверс-инжиниринга можно расширять возможности программ. Как будет время я и дальше буду продолжать писать подобные статьи а поскольку сейчас лето то его у меня полным полно.
Надеюсь, моя статья была вам интересна.
Комментарии (7)
pfemidi
01.07.2015 01:56Да и вообще инициализация string что в CrackWriteFile, что в CrackReadFile какая-то «безразмерная». Вот так buffer overflow и ловят :)
silvansky
01.07.2015 10:55+1Алгоритм шифрования просто супер! =)
PS: код в скриншотах — не есть хорошо. Лучше тег source использовать.pfemidi
01.07.2015 14:14Согласен. Я три минуты безуспешно пытался скопировать цикл «шифрования» пока не понял что это скриншоты, пришлось самому руками выписывать, сверяясь по буквам.
Sadler
01.07.2015 22:37+1Код не просто в скриншотах,
pravic
01.07.2015 18:07Код ужасен даже для примеров. Прям находка для авторов PVS-Studio: нашли бы не менее дюжины замечаний о том, как не следует писать код на С++.
pfemidi
Наверное в функции CrackWriteFile цикл зашифровки должен быть не
а
а то ерунда какая-то получается.