Фундаментальные основы хакерства. Боремся с дизассемблерами и затрудняем реверс программ - «Новости» » Самоучитель CSS
Меню
Наши новости
Учебник CSS

Невозможно отучить людей изучать самые ненужные предметы.

Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3

Надо знать обо всем понемножку, но все о немногом.

Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы

Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)

Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода

Самоучитель CSS

Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5

Новости

Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости

Справочник CSS

Справочник от А до Я
HTML, CSS, JavaScript

Афоризмы

Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы

Видео Уроки


Видео уроки
Наш опрос



Наши новости

       
2-03-2023, 18:15
Фундаментальные основы хакерства. Боремся с дизассемблерами и затрудняем реверс программ - «Новости»
Рейтинг:
Категория: Новости

стра­нице авто­ра.

Про­дол­жаем дер­жать обо­рону нашего при­ложе­ния от атак злоб­ных хакеров — от их попыток «за прос­то так» вос­поль­зовать­ся пло­дами нашего тру­да, от их подоз­ритель­ного инте­реса к нашим прог­раммам и скры­ваемым в них сек­ретам. Для это­го мы про­дол­жим соз­давать изощ­ренные сис­темы защиты, на сей раз — от дизас­сем­бли­рова­ния.


Читайте также - Металлоискатель Nokta Makro Simplex Plus, Nokta Makro Simplex по доступным ценам. Новый бюджетный водонепроницаемый металлоискатель начального уровня с DuobleD катушкой и ЖК дисплеем.

Что­бы спра­вить­ся с задачей, нам необ­ходимо узнать о внут­ренних механиз­мах опе­раци­онной сис­темы, о средс­твах работы с памятью. Так­же при­дет­ся разоб­рать­ся в работе ком­пилято­ров, понять, как они генери­руют код, вычис­лить плю­сы и минусы опти­миза­ции. И наконец, пог­рузить­ся в шиф­рование, научить­ся рас­шифро­вывать прог­рам­мный код на лету непос­редс­твен­но перед выпол­нени­ем.


 

Самомодифицирующийся код в современных операционных системах


В эпо­ху рас­цве­та MS-DOS прог­раммис­ты широко исполь­зовали самомо­дифи­циру­ющий­ся код, без которо­го не обхо­дилась прак­тичес­ки ни одна мало‑маль­ски серь­езная защита. Да и не толь­ко защита — он встре­чал­ся в ком­пилято­рах, ком­пилиру­ющих код непос­редс­твен­но в память, в рас­паков­щиках исполня­емых фай­лов, в полимор­фных генера­торах и так далее.


Ког­да началась мас­совая миг­рация поль­зовате­лей на Windows, раз­работ­чикам приш­лось задумать­ся о перено­се накоп­ленно­го опы­та и при­емов прог­рамми­рова­ния на новую плат­форму. От бес­кон­троль­ного дос­тупа к железу, памяти, ком­понен­там опе­раци­онной сис­темы и свя­зан­ных с ними хит­роум­ных трю­ков прог­рамми­рова­ния приш­лось отвы­кать. В час­тнос­ти, ста­ла невоз­можна непос­редс­твен­ная модифи­кация исполня­емо­го кода при­ложе­ний, пос­коль­ку Windows защища­ет его от неп­редна­мерен­ных изме­нений. Это при­вело к рож­дению нелепо­го убеж­дения, буд­то под Windows соз­дание самомо­дифи­циру­юще­гося кода вооб­ще невоз­можно, по край­ней мере без исполь­зования недоку­мен­тирован­ных воз­можнос­тей опе­раци­онной сис­темы.


На самом деле сущес­тву­ет как минимум два докумен­тирован­ных спо­соба изме­нить код при­ложе­ний, хорошо работа­ющих под Windows NT и впол­не удов­летво­ряющих­ся при­виле­гиями гос­тевого поль­зовате­ля.


Во‑пер­вых, kernel32.dll экспор­тиру­ет фун­кцию WriteProcessMemory, пред­назна­чен­ную, как и сле­дует из ее наз­вания, для модифи­кации памяти про­цес­са. Во‑вто­рых, прак­тичес­ки все опе­раци­онные сис­темы, вклю­чая Windows и Linux, раз­реша­ют выпол­нение и модифи­кацию кода, раз­мещен­ного в сте­ке. Меж­ду тем сов­ремен­ные вер­сии ука­зан­ных опе­раци­онных сис­тем нак­ладыва­ют на стек огра­ниче­ния, мы под­робно погово­рим об этом чуть поз­днее.


В прин­ципе, задача соз­дания самомо­дифи­циру­юще­гося кода может быть решена исклю­читель­но средс­тва­ми язы­ков высоко­го уров­ня, таких, нап­ример, как C/C++ и Delphi, без при­мене­ния ассем­бле­ра.


 

Архитектура памяти Windows


Соз­дание самомо­дифи­циру­юще­гося кода тре­бует зна­ния некото­рых тон­костей архи­тек­туры Windows, не очень‑то хорошо осве­щен­ных в докумен­тации. Точ­нее, сов­сем не осве­щен­ных, но от это­го отнюдь не при­обре­тающих ста­тус «недоку­мен­тирован­ных осо­бен­ностей», пос­коль­ку, во‑пер­вых, они оди­нако­во реали­зова­ны на всех Windows-плат­формах, а во‑вто­рых, их активно исполь­зует ком­пилятор Visual C++ от Microsoft. Отсю­да сле­дует, что никаких изме­нений даже в отда­лен­ном будущем ком­пания не пла­ниру­ет; в про­тив­ном слу­чае код, сге­нери­рован­ный этим ком­пилято­ром, отка­жет в работе, а на это Microsoft не пой­дет (вер­нее, не дол­жна пой­ти, если верить здра­вому смыс­лу).


В режиме обратной сов­мести­мос­ти для адре­сации четырех гигабайт вир­туаль­ной памяти, выделен­ной в рас­поряже­ние про­цес­са, Windows исполь­зует два селек­тора, один из которых заг­ружа­ется в сег­мен­тный регистр CS, а дру­гой — в регис­тры DSES и SS. Оба селек­тора ссы­лают­ся на один и тот же базовый адрес памяти, рав­ный нулю, и име­ют иден­тичные лимиты, рав­ные четырем гигабай­там. Помимо перечис­ленных сег­мен­тных регис­тров, Windows еще исполь­зует регистр FS, в который заг­ружа­ет селек­тор сег­мента, содер­жащего информа­цион­ный блок потока — TIB.


Фак­тичес­ки сущес­тву­ет все­го один сег­мент, вме­щающий в себя и код, и дан­ные, и стек про­цес­са. Бла­года­ря это­му управле­ние коду, рас­положен­ному в сте­ке, переда­ется близ­ким (near) вызовом или перехо­дом, и для дос­тупа к содер­жимому сте­ка исполь­зование пре­фик­са SS совер­шенно необя­затель­но. Нес­мотря на то что зна­чение регис­тра CS не рав­но зна­чению регис­тров DSES и SS, коман­ды


• MOV dest,CS:[src]
MOV dest,DS:[src]
MOV dest,SS:[src]


в дей­стви­тель­нос­ти обра­щают­ся к одной и той же ячей­ке памяти.


Это точ­ный про­образ реали­зован­ной в про­цес­сорах на архи­тек­туре x86-64 RIP-отно­ситель­ной адре­сации памяти, в которой не исполь­зуют­ся сег­менты.


От­личия меж­ду реги­она­ми кода, сте­ка и дан­ных зак­люча­ются в атри­бутах при­над­лежащих им стра­ниц: стра­ницы кода допус­кают чте­ние и исполне­ние, стра­ницы дан­ных — чте­ние и запись, а сте­ка — чте­ние, запись и исполне­ние одновре­мен­но.


По­мимо это­го, каж­дая стра­ница име­ет спе­циаль­ный флаг, опре­деля­ющий уро­вень при­виле­гий, которые необ­ходимы для дос­тупа к этой стра­нице. Некото­рые стра­ницы, нап­ример те, что при­над­лежат опе­раци­онной сис­теме, тре­буют наличия прав супер­визора, которы­ми обла­дает толь­ко код нулево­го коль­ца. Прик­ладные прог­раммы, исполня­ющиеся в коль­це 3, таких прав не име­ют и при попыт­ке обра­щения к защищен­ной стра­нице порож­дают исклю­чение. Манипу­лиро­вать атри­бута­ми стра­ниц, рав­но как и ассо­цииро­вать стра­ницы с линей­ными адре­сами, может толь­ко опе­раци­онная сис­тема или код, исполня­ющий­ся в нулевом коль­це.


Сре­ди начина­ющих прог­раммис­тов ходит совер­шенно нелепая бай­ка о том, что, если обра­тить­ся к коду прог­раммы коман­дой, пред­варен­ной пре­фик­сом DS, Windows яко­бы бес­пре­пятс­твен­но поз­волит его изме­нить. На самом деле это в кор­не невер­но — обра­тить­ся‑то она поз­волит, а вот изме­нить — нет, каким бы спо­собом ни про­исхо­дило обра­щение, так как защита работа­ет на уров­не физичес­ких стра­ниц, а не логичес­ких адре­сов.


 

Использование функции WriteProcessMemory


Ес­ли тре­бует­ся изме­нить некото­рое количес­тво бай­тов сво­его (или чужого) про­цес­са, самый прос­той спо­соб сде­лать это — выз­вать фун­кцию WriteProcessMemory. Она поз­воля­ет модифи­циро­вать сущес­тву­ющие стра­ницы памяти, чей флаг супер­визора не взве­ден, то есть все стра­ницы, дос­тупные из коль­ца 3, в котором выпол­няют­ся прик­ладные при­ложе­ния. Совер­шенно бес­полез­но с помощью WriteProcessMemory пытать­ся изме­нить кри­тичес­кие струк­туры дан­ных опе­раци­онной сис­темы (нап­ример, page directory или page table) — они дос­тупны лишь из нулево­го коль­ца. Поэто­му ука­зан­ная фун­кция не пред­став­ляет никакой угро­зы для безопас­ности сис­темы и успешно вызыва­ется незави­симо от уров­ня при­виле­гий поль­зовате­ля.


Про­цесс, в память которо­го про­исхо­дит запись, дол­жен быть пред­варитель­но открыт фун­кци­ей OpenProcess с атри­бута­ми дос­тупа PROCESS_VM_OPERATION и PROCESS_VM_WRITE. Час­то прог­раммис­ты, ленивые от при­роды, идут более корот­ким путем, уста­нав­ливая все атри­буты — PROCESS_ALL_ACCESS. И это впол­не закон­но, хотя спра­вед­ливо счи­тает­ся дур­ным сти­лем прог­рамми­рова­ния.


Да­лее при­веден прос­той при­мер self-modifying_code, иллюс­три­рующий исполь­зование фун­кции WriteProcessMemory для соз­дания самомо­дифи­циру­юще­гося кода:


#include <Windows.h>using namespace std;int WriteMe(void* addr, int wb){
HANDLE h = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, true, GetCurrentProcessId());
return WriteProcessMemory(h, addr, &wb, 1, NULL);}int main(int argc, char* argv[]){
_asm {push 0x74 ; JMP -> JZpush offset Herecall WriteMeadd esp, 8Here:
JMP short here
}
cout << "#JMP SHORT $-2 was changed to JZ $-2n";
return 0;}

Фун­кция WriteProcessMemory в рас­смат­рива­емой прог­рамме заменя­ет инс­трук­цию бес­конеч­ного цик­ла JMP short $-2 условным перехо­дом JZ $-2, который про­дол­жает нор­маль­ное выпол­нение прог­раммы. Неп­лохой спо­соб зат­руднить взлом­щику изу­чение при­ложе­ния, не прав­да ли? Осо­бен­но если вызов WriteMe не рас­положен воз­ле изме­няемо­го кода, а помещен в отдель­ный поток. Будет еще луч­ше, если модифи­циру­емый код впол­не естес­тве­нен сам по себе и внеш­не не вызыва­ет никаких подоз­рений. В этом слу­чае хакер может дол­го блуж­дать в той вет­ке кода, которая при выпол­нении прог­раммы вооб­ще не получа­ет управле­ния.


Для ком­пиляции это­го при­мера уста­нови 32-бит­ный режим резуль­тиру­юще­го кода.


Ре­зуль­тат выпол­нения при­ложе­ния self-modifying_code

Ес­ли из ассем­блер­ной встав­ки убрать вызов фун­кции WriteMe, которая переза­писы­вает инс­трук­цию JMP на JZ, прог­рамма выпадет в бес­конеч­ный цикл.


Фундаментальные основы хакерства. Боремся с дизассемблерами и затрудняем реверс программ - «Новости»
Вы­зов фун­кции заком­менти­рован
Прог­рамма зацик­лена

Об устройстве Windows: исторический нюанс


Пос­коль­ку Windows для эко­номии опе­ратив­ной памяти раз­деля­ет код меж­ду про­цес­сами, воз­ника­ет воп­рос: а что про­изой­дет, если запус­тить вто­рую копию самомо­дифи­циру­ющей­ся прог­раммы? Соз­даст ли опе­раци­онная сис­тема новые стра­ницы или отош­лет при­ложе­ние к уже модифи­циру­емо­му коду? В докумен­тации на Windows NT ска­зано, что она под­держи­вает копиро­вание при записи (copy on write), то есть авто­мати­чес­ки дуб­лиру­ет стра­ницы кода при попыт­ке их модифи­циро­вать. Нап­ротив, Windows 9x не под­держи­вает такую воз­можность. Озна­чает ли это, что все копии самомо­дифи­циру­юще­гося при­ложе­ния будут вынуж­дены работать с одни­ми и теми же стра­ница­ми кода (а это неиз­бежно при­ведет к кон­флик­там и сбо­ям)?


Нет, и вот почему: нес­мотря на то что копиро­вание при записи в Windows 9x не реали­зова­но, эту заботу берет на себя сама фун­кция WriteProcessMemory, соз­давая копии всех модифи­циру­емых стра­ниц, рас­пре­делен­ных меж­ду про­цес­сами. Бла­года­ря это­му самомо­дифи­циру­ющий­ся код оди­нако­во хорошо работа­ет как под Windows 9x, так и под Windows NT. Одна­ко сле­дует учи­тывать, что все копии при­ложе­ния, модифи­циру­емые любым иным путем (нап­ример, коман­дой mov нулево­го коль­ца), если их запус­тить под Windows 9x, будут раз­делять одни и те же стра­ницы кода со все­ми вытека­ющи­ми отсю­да пос­ледс­тви­ями.


Те­перь об огра­ниче­ниях. Во‑пер­вых, исполь­зовать WriteProcessMemory разум­но толь­ко в ком­пилиру­ющих в память ком­пилято­рах или рас­паков­щиках исполня­емых фай­лов, а в защитах — нес­коль­ко наив­но. Мало‑маль­ски опыт­ный взлом­щик быс­тро обна­ружит под­вох, уви­дев эту фун­кцию в таб­лице импорта. Затем он уста­новит точ­ку оста­нова на вызов WriteProcessMemory и будет кон­тро­лиро­вать каж­дую опе­рацию записи в память. А это никак не вхо­дит в пла­ны раз­работ­чика защиты!


стра­нице авто­ра. Про­дол­жаем дер­жать обо­рону нашего при­ложе­ния от атак злоб­ных хакеров — от их попыток «за прос­то так» вос­поль­зовать­ся пло­дами нашего тру­да, от их подоз­ритель­ного инте­реса к нашим прог­раммам и скры­ваемым в них сек­ретам. Для это­го мы про­дол­жим соз­давать изощ­ренные сис­темы защиты, на сей раз — от дизас­сем­бли­рова­ния. Читайте также - Металлоискатель Nokta Makro Simplex Plus, Nokta Makro Simplex по доступным ценам. Новый бюджетный водонепроницаемый металлоискатель начального уровня с DuobleD катушкой и ЖК дисплеем. Что­бы спра­вить­ся с задачей, нам необ­ходимо узнать о внут­ренних механиз­мах опе­раци­онной сис­темы, о средс­твах работы с памятью. Так­же при­дет­ся разоб­рать­ся в работе ком­пилято­ров, понять, как они генери­руют код, вычис­лить плю­сы и минусы опти­миза­ции. И наконец, пог­рузить­ся в шиф­рование, научить­ся рас­шифро­вывать прог­рам­мный код на лету непос­редс­твен­но перед выпол­нени­ем. Самомодифицирующийся код в современных операционных системах В эпо­ху рас­цве­та MS-DOS прог­раммис­ты широко исполь­зовали самомо­дифи­циру­ющий­ся код, без которо­го не обхо­дилась прак­тичес­ки ни одна мало‑маль­ски серь­езная защита. Да и не толь­ко защита — он встре­чал­ся в ком­пилято­рах, ком­пилиру­ющих код непос­редс­твен­но в память, в рас­паков­щиках исполня­емых фай­лов, в полимор­фных генера­торах и так далее. Ког­да началась мас­совая миг­рация поль­зовате­лей на Windows, раз­работ­чикам приш­лось задумать­ся о перено­се накоп­ленно­го опы­та и при­емов прог­рамми­рова­ния на новую плат­форму. От бес­кон­троль­ного дос­тупа к железу, памяти, ком­понен­там опе­раци­онной сис­темы и свя­зан­ных с ними хит­роум­ных трю­ков прог­рамми­рова­ния приш­лось отвы­кать. В час­тнос­ти, ста­ла невоз­можна непос­редс­твен­ная модифи­кация исполня­емо­го кода при­ложе­ний, пос­коль­ку Windows защища­ет его от неп­редна­мерен­ных изме­нений. Это при­вело к рож­дению нелепо­го убеж­дения, буд­то под Windows соз­дание самомо­дифи­циру­юще­гося кода вооб­ще невоз­можно, по край­ней мере без исполь­зования недоку­мен­тирован­ных воз­можнос­тей опе­раци­онной сис­темы. На самом деле сущес­тву­ет как минимум два докумен­тирован­ных спо­соба изме­нить код при­ложе­ний, хорошо работа­ющих под Windows NT и впол­не удов­летво­ряющих­ся при­виле­гиями гос­тевого поль­зовате­ля. Во‑пер­вых, kernel32.dll экспор­тиру­ет фун­кцию WriteProcessMemory, пред­назна­чен­ную, как и сле­дует из ее наз­вания, для модифи­кации памяти про­цес­са. Во‑вто­рых, прак­тичес­ки все опе­раци­онные сис­темы, вклю­чая Windows и Linux, раз­реша­ют выпол­нение и модифи­кацию кода, раз­мещен­ного в сте­ке. Меж­ду тем сов­ремен­ные вер­сии ука­зан­ных опе­раци­онных сис­тем нак­ладыва­ют на стек огра­ниче­ния, мы под­робно погово­рим об этом чуть поз­днее. В прин­ципе, задача соз­дания самомо­дифи­циру­юще­гося кода может быть решена исклю­читель­но средс­тва­ми язы­ков высоко­го уров­ня, таких, нап­ример, как C/C и Delphi, без при­мене­ния ассем­бле­ра. Архитектура памяти Windows Соз­дание самомо­дифи­циру­юще­гося кода тре­бует зна­ния некото­рых тон­костей архи­тек­туры Windows, не очень‑то хорошо осве­щен­ных в докумен­тации. Точ­нее, сов­сем не осве­щен­ных, но от это­го отнюдь не при­обре­тающих ста­тус «недоку­мен­тирован­ных осо­бен­ностей», пос­коль­ку, во‑пер­вых, они оди­нако­во реали­зова­ны на всех Windows-плат­формах, а во‑вто­рых, их активно исполь­зует ком­пилятор Visual C от Microsoft. Отсю­да сле­дует, что никаких изме­нений даже в отда­лен­ном будущем ком­пания не пла­ниру­ет; в про­тив­ном слу­чае код, сге­нери­рован­ный этим ком­пилято­ром, отка­жет в работе, а на это Microsoft не пой­дет (вер­нее, не дол­жна пой­ти, если верить здра­вому смыс­лу). В режиме обратной сов­мести­мос­ти для адре­сации четырех гигабайт вир­туаль­ной памяти, выделен­ной в рас­поряже­ние про­цес­са, Windows исполь­зует два селек­тора, один из которых заг­ружа­ется в сег­мен­тный регистр CS, а дру­гой — в регис­тры DS, ES и SS. Оба селек­тора ссы­лают­ся на один и тот же базовый адрес памяти, рав­ный нулю, и име­ют иден­тичные лимиты, рав­ные четырем гигабай­там. Помимо перечис­ленных сег­мен­тных регис­тров, Windows еще исполь­зует регистр FS, в который заг­ружа­ет селек­тор сег­мента, содер­жащего информа­цион­ный блок потока — TIB. Фак­тичес­ки сущес­тву­ет все­го один сег­мент, вме­щающий в себя и код, и дан­ные, и стек про­цес­са. Бла­года­ря это­му управле­ние коду, рас­положен­ному в сте­ке, переда­ется близ­ким (near) вызовом или перехо­дом, и для дос­тупа к содер­жимому сте­ка исполь­зование пре­фик­са SS совер­шенно необя­затель­но. Нес­мотря на то что зна­чение регис­тра CS не рав­но зна­чению регис­тров DS, ES и SS, коман­ды • MOV dest,CS:_

Теги: CSS

Просмотров: 526
Комментариев: 0:   2-03-2023, 18:15
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

 
Еще новости по теме:



Другие новости по теме:
Комментарии для сайта Cackle