Фундаментальные основы хакерства. Искусство дизассемблирования [Крис Касперски] (pdf) читать онлайн

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

Êðèñ Êàñïåðñêè

ÔÓ ÍÄÀÌÅÍÒÀËÜÍÛÅ
ÎÑÍÎÂ Û ÕÀ ÊÅÐÑÒÂÀ
ÈÑÊÓÑÑÒÂÎ ÄÈÇÀÑÑÅÌÁËÈÐÎÂÀÍÈß

Ìîñêâà
ÑÎËÎÍ-Ð
2007

Êðèñ Êàñïåðñêè
Ôóíäàìåíòàëüíûå îñíîâû õàêåðñòâà. Èñêóññòâî äèçàññåìáëèðîâàíèÿ / Êðèñ
Êàñïåðñêè — Ì.: ÑÎËÎÍ-Ð, 2007. 448 ñ. — (Ñåðèÿ «Êîäîêîïàòåëü»)
ISBN 5-93455-175-2
Êíèãà, êîòîðóþ âû ñåé÷àñ äåðæèòå â ðóêàõ, îòêðûâàåò äâåðè â óäèâèòåëüíûé
ìèð çàùèòíûõ ìåõàíèçìîâ — çäåñü ðàññêàçûâàåòñÿ î òîì, êàê ñîçäàþòñÿ è
âñêðûâàþòñÿ çàùèòû. Îíà àäðåñîâàíà âñåì, êòî ëþáèò çàõâàòûâàþùèå äóõ ãîëîâîëîìêè, âñåì, êòî ïðîâîäèò ñâîáîäíîå è íåñâîáîäíîå âðåìÿ çà êîïàíèåì â
íåäðàõ ïðîãðàìì è îïåðàöèîííîé ñèñòåìû. Íàêîíåö, ýòà êíèãà ïðåäíàçíà÷åíà
äëÿ òåõ, êòî ïî ðîäó ñâîåé äåÿòåëüíîñòè çàíèìàåòñÿ (ïîñòîÿííî è/èëè ýïèçîäè÷åñêè) íàïèñàíèåì çàùèò è õî÷åò óçíàòü, êàê ãðàìîòíî è óâåðåííî ïðîòèâîñòîÿòü
âåçäåñóùèì õàêåðàì.
Íàñòîÿùèé òîì ïîñâÿùåí áàçîâûì îñíîâàì õàêåðñòâà — òåõíèêå ðàáîòû ñ
îòëàä÷èêîì è äèçàññåìáëåðîì. Çäåñü ïîäðîáíî îïèñàíû ïðèåìû èäåíòèôèêàöèè è ðåêîíñòðóêöèè êëþ÷åâûõ ñòðóêòóð èñõîäíîãî ÿçûêà — ôóíêöèé (â ò. ÷. âèðòóàëüíûõ), ëîêàëüíûõ è ãëîáàëüíûõ ïåðåìåííûõ, âåòâëåíèé, öèêëîâ, îáúåêòîâ è
èõ èåðàðõèé, ìàòåìàòè÷åñêèõ îïåðàòîðîâ è ò. ä.

Ýòó êíèãó ìîæíî çàêàçàòü ïî ïî÷òå (íàëîæåííûì ïëàòåæîì — ñòîèìîñòü 281 ðóá.)
äâóìÿ ñïîñîáàìè:
1) âûñëàòü ïî÷òîâóþ îòêðûòêó èëè ïèñüìî ïî àäðåñó: 123001, Ìîñêâà, à/ÿ 82;
2) ïåðåäàòü çàêàç ïî ýëåêòðîííîé ïî÷òå (e-mail) ïî àäðåñó:
magazin@solon-r.ru.
Íåîáõîäèìî íàïèñàòü ïîëíûé àäðåñ, ïî êîòîðîìó âûñëàòü êíèãè.
Îáÿçàòåëüíî óêàçûâàòü èíäåêñ è Ô. È. Î. ïîëó÷àòåëÿ!
Ïðè íàëè÷èè — óêàçàòü òåëåôîí, ïî êîòîðîìó ñ âàìè ìîæíî ñâÿçàòüñÿ, è àäðåñ
ýëåêòðîííîé ïî÷òû (E-mail).

Öåíû äåéñòâèòåëüíû äî 1 ñåíòÿáðÿ 2002 ã.
Âû ìîæåòå â ëþáîå âðåìÿ ïîëó÷èòü ñâåæèé êàòàëîã èçäàòåëüñòâà «ÑÎËÎÍ-л ïî Èíòåðíåòó, ïîñëàâ ïóñòîå ïèñüìî íà ðîáîò-àâòîîòâåò÷èê ïî àäðåñó katalog@solon-r.ru, à òàêæå ïîäïèñàòüñÿ
íà ðàññûëêó íîâîñòåé î íîâûõ êíèãàõ èçäàòåëüñòâà, ïîñëàâ ïèñüìî ïî àäðåñó news@solon-r.ru ñ
òåêñòîì «SUBSCRIBE» (áåç êàâû÷åê) â òåëå ïèñüìà.

ISBN 5-93455-175-2

© Ìàêåò è îáëîæêà «ÑÎËÎÍ-л, 2007
© Êðèñ Êàñïåðñêè, 2007

Ñâåòëîé ïàìÿòè Ñåðãåÿ Èâàíîâà, ãëàâíîãî ðåäàêòîðà
èçäàòåëüñòâà «ÑÎËÎÍ-л, ïîñâÿùàåòñÿ ýòà êíèãà

Ïðåäèñëîâèå ðåäàêòîðà
The only secure computer is one that's unplugged, locked in a
safe, and buried 20 feets under the ground in a secret location... and I'm not even too sure about that one…
Äýííèñ Õüþæç (Dennis Huges), ÔÁÐ ÑØÀ

Ýòîò ýïèãðàô âûáðàí íå ñëó÷àéíî. Èíôîðìàöèîííàÿ áåçîïàñíîñòü ñåãîäíÿ
ïðåäñòàâëÿåò îäíó èç âåñüìà ãîðÿ÷èõ òåì. Åå àêòóàëüíîñòü ñëîæíî ïðåóâåëè÷èòü,
è êàæäîå ñâÿçàííîå ñ ýòîé òåìîé ïîñîáèå íåèçìåííî ïîäâåðãàåòñÿ àíàëèçó ñî ñòîðîíû, êàê ïðàâèëî, âåñüìà ñêåïòè÷åñêè íàñòðîåííûõ ñïåöèàëèñòîâ. Èññëåäîâàíèå
ïðîãðàìì íàïðÿìóþ ñâÿçàíî ñ âîïðîñàìè èíôîðìàöèîííîé áåçîïàñíîñòè. Êîãäà
àâòîð ýòîé êíèãè ïðèãëàñèë ìåíÿ, êàê ñïåöèàëèñòà, ñòàòü åå íàó÷íûì ðåäàêòîðîì,
ÿ âåñüìà çàèíòåðåñîâàëñÿ ýòèì ïðåäëîæåíèåì.
Ñàìà ìûñëü î âîçìîæíîñòè îïóáëèêîâàíèÿ ïîäîáíûõ ìàòåðèàëîâ çâó÷èò äëÿ
ìíîãèõ íåñêîëüêî êðàìîëüíî, êàê íåêîãäà áûëî, ê ïðèìåðó, ñ êðèïòîãðàôèåé è íåêîòîðûìè îáëàñòÿìè òåîðèè ÷èñåë. Áîëåå òîãî, òåìàòèêà äàííîé êíèãè äî íåêîòîðîãî âðåìåíè ðàñöåíèâàëàñü êàê áëèçêàÿ ê øèðîêî îáñóæäàåìûì êðèìèíàëüíûì
òåìàì è ëèøü â ïîñëåäíåå âðåìÿ âåðíóëàñü â ñâîå åñòåñòâåííîå íàó÷íîå ðóñëî.
Íà ìîé âçãëÿä, ýòà êíèãà áóäåò èíòåðåñíà äëÿ âåñüìà øèðîêîãî êðóãà ÷èòàòåëåé. Íàâåðíÿêà åþ çàèíòåðåñóþòñÿ è òå, êòî ëèøü íà÷èíàåò ñâîé âîñõîä ê Îëèìïó çíàíèé, è óæå ìàòåðûå ñïåöèàëèñòû â îáëàñòè ïðîãðàììèðîâàíèÿ è èññëåäîâàíèÿ ïðîãðàìì (èëè íà èíîñòðàííûé ìàíåð «reverse engineering»). Õî÷åòñÿ îñîáåííî îòìåòèòü, ÷òî ìàòåðèàëû êíèãè ïîäîáðàíû è ñêîìïîíîâàíû òàêèì îáðàçîì, ÷òî
áóäóò ïîëåçíû è îáû÷íîìó ïðîãðàììèñòó, äîïóñòèì, êàê ïîñîáèå ïî îïòèìèçàöèè
ïðîãðàìì äëÿ ñîâðåìåííûõ èíòåëëåêòóàëüíûõ êîìïèëÿòîðîâ, è ñïåöèàëèñòàì
ðàçëè÷íûõ íàïðàâëåíèé (íàïðèìåð, ñïåöèàëèñòàì èíôîðìàöèîííîé çàùèòû — â
êà÷åñòâå ïîñîáèÿ ïî ïîèñêó òàê íàçûâàåìûõ «çàêëàäîê»). Ñòèëü èçëîæåíèÿ «îò
ïðîñòîãî ê ñëîæíîìó» ïîçâîëÿåò ãîâîðèòü è î òîì, ÷òî äàííàÿ êíèãà ïîñëóæèò
òàêæå è ó÷åáíûì ïîñîáèåì äëÿ íà÷èíàþùèõ èññëåäîâàòåëåé è «êîäîêîïàòåëåé».
Êíèãà ñîäåðæèò ìíîæåñòâî óíèêàëüíîãî ïðàêòè÷åñêîãî ìàòåðèàëà. Áîëüøèíñòâî èçäàííûõ çà ðóáåæîì ïîâåðõíîñòíûõ ðàáîò ìàëîèíòåðåñíû ñ ïðàêòè÷åñêîé
òî÷êè çðåíèÿ äëÿ òåõ, êòî èçó÷àåò ïðèêëàäíóþ ìàòåìàòèêó, ïðîãðàììèðîâàíèå è
óñòðîéñòâî êîìïüþòåðîâ. Äà è ñðåäè ïóáëèêàöèé ñîâðåìåííîãî ðîññèéñêîãî íàó÷íîãî ñîîáùåñòâà ÷èòàòåëü, êàê ìíå êàæåòñÿ, íå íàéäåò ëó÷øåãî ïîñîáèÿ ïî èçó÷åíèþ òåõíèêè èññëåäîâàíèÿ ïðîãðàìì.
Îäíàêî, ÿ âñå-òàêè ðåêîìåíäóþ ÷èòàòåëþ ïîäâåðãíóòü ñîìíåíèþ âñå âûøåñêàçàííîå è óáåäèòüñÿ âî âñåì ñàìîñòîÿòåëüíî, ïðî÷èòàâ äàííóþ êíèãó.
Ñ óâàæåíèåì, Õàäè Ð. À.

×òî íîâîãî âî âòîðîì èçäàíèè
Êàê áû ïëîõî âû íè íàïèñàëè âàøó ïîâåñòü, ó âàñ îáÿçàòåëüíî íàéäóòñÿ ÷èòàòåëè, òûñÿ÷è ÷èòàòåëåé, êîòîðûå ñî÷òóò åå øåäåâðîì... Êàê áû õîðîøî âû íè íàïèñàëè ñâîþ ïîâåñòü, îáÿçàòåëüíî íàéäóòñÿ ÷èòàòåëè, è ýòî áóäóò òûñÿ÷è
÷èòàòåëåé, êîòîðûå ñî÷òóò åå ÷èñòûì áàðàõëîì.
Á. H. Ñòðóãàöêèé

Ïåðâîå èçäàíèå «Òåõíèêè è ôèëîñîôèè õàêåðñêèõ àòàê» — äîâîëüíî ôðèâîëüíîå è õàîòè÷íîå — ïî ñòèëþ èçëîæåíèÿ íàïîìèíàëî ñîáîé «Ïóòåâûå çàìåòêè îõîòíèêà» — ÷èòàåòñÿ, ìîæåò áûòü, è ñ èíòåðåñîì, íî íà ó÷åáíèê, óâû, íå òÿíåò. Ê îãðîìíîìó óäèâëåíèþ àâòîðà, êíèãà èìåëà îùóòèìûé óñïåõ è ìíîæåñòâî
îäîáðèòåëüíûõ îòêëèêîâ. Îíî, êîíå÷íî, ïîíÿòíî — íà áåçðûáüå è ðàê ðûáà — çà
ïîñëåäíèå íåñêîëüêî ëåò íè÷åãî ïóòíîãî ïî äàííîé òåìàòèêå íå âûõîäèëî.
Êîãäà æå òèðàæ êíèãè áûë ïîëíîñòüþ ðàñïðîäàí, íî çàÿâêè íà íåå ïî-ïðåæíåìó ïðîäîëæàëè ïîñòóïàòü, âñòàë âîïðîñ: ÷òî äåëàòü äàëüøå: âûïóñêàòü äîïå÷àòêó,
ñêîïèðîâàííóþ îäèí ê îäíîìó, èëè ïåðåðàáîòàííîå è äîïîëíåííîå âòîðîå èçäàíèå? Èçäàòåëü ñêëîíÿëñÿ ê ïîñëåäíåìó, äà è àâòîð, â æåëàíèè óòîëèòü ñâîé ïðîôåññèîíàëüíûé çóä, ïðèçíàòüñÿ, òîæå. Îäíàêî çà âðåìÿ, ïðîøåäøåå ñ ìîìåíòà
ïåðâîãî èçäàíèÿ, àâòîð ñòàë ïèñàòü çíà÷èòåëüíî ñòðóêòóðíåé è «÷èùå». Ïîýòîìó
ïîñëå äîëãèõ êîëåáàíèé, ñîìíåíèé è òÿãîñòíûõ ðàçäóìèé àâòîð ðåøèë ïîëíîñòüþ
ïåðåïèñàòü êíèãó ñ íóëÿ, ïðåâðàòèâ åå â ðåàëüíóþ íàñòîëüíóþ êíèãó õàêåðà. Íàïèñàòü ñâîåîáðàçíûé ñïðàâî÷íèê êîäîêîïàòåëÿ, íî âìåñòå ñ òåì è ó÷åáíèê, ïîìîãàþùèé íà÷èíàþùèì ñäåëàòü â ýòîì ìèðå ñâîè ïåðâûå øàãè.
Ïîïóòíî, äâèæèìûé ïðîñüáàìè ÷èòàòåëåé, îæèäàþùèõ ïîñêîðåå óâèäåòü ïðîäîëæåíèå òðèëîãèè «Îáðàç ìûøëåíèÿ — äèçàññåìáëåð IDA», àâòîð ðèñêíóë
âêëþ÷èòü â íàñòîÿùåå èçäàíèå äâàäöàòü ãëàâ èç áóäóùåé êíèãè «Èñêóññòâî äèçàññåìáëèðîâàíèÿ» (íàçâàíèå ðàáî÷åå).
Îáúåì êíèãè óâåëè÷èëñÿ íàñòîëüêî, ÷òî åå ïðèøëîñü ðàçáèòü íà íåñêîëüêî
òîìîâ. Ýòîò òîì, ïåðâûé èç âñåõ, ïîñâÿùåí áàçîâûì îñíîâàì õàêåðñòâà — òåõíèêå ðàáîòû ñ îòëàä÷èêîì è äèçàññåìáëåðîì, òàêæå çàòðîíóòû âîïðîñû çàùèòû ïðîãðàìì îò èçó÷åíèÿ è ñïîñîáû íåéòðàëèçàöèè ýòèõ çàùèò. Ïîäðîáíûé ðàññêàç î
ìåòîäèêå ñîçäàíèÿ è ñíÿòèÿ çàùèòíûõ ìåõàíèçìîâ — òåìà ïîñëåäóþùèõ òîìîâ.

Êòî òàêèå õàêåðû
...Íàçîâè òû ìåíÿ â÷åðà áûêîì, ÿ áûë áû áûêîì. Íàçâàë
áû òû ìåíÿ ëîøàäüþ — è ÿ áûë áû ëîøàäüþ. Åñëè ëþäè
äàþò èìÿ êàêîé-òî ñóùíîñòè, òî, íå ïðèíÿâ ýòîãî èìåíè,
íàâëå÷åøü íà ñåáÿ áåäó.
Ïðèïèñûâàåòñÿ êèòàéñêîìó ìóäðåöó Ëàî-Öçû

Ïðåæäå ÷åì ïîäàâàòü íà ñòîë áëþäà õàêåðñêîé êóõíè, íåïëîõî áû ðàçîáðàòüñÿ, êòî, ñîáñòâåííî, òàêèå ýòè õàêåðû è ÷òî îíè åäÿò. Çàãëÿíóâ â òîëêîâûé ñëîâàðü àíãëèéñêîãî ÿçûêà, íàïðèìåð â «The American Heritage Dictionary», ìû óáåäèìñÿ, ÷òî ãëàãîë «hack» âîçíèê â àíãëèéñêîì ëåêñèêîíå çàäîëãî äî ïîÿâëåíèÿ
êîìïüþòåðîâ è â ïðÿìîì ñìûñëå îáîçíà÷àë «áèòü, ðóáèòü, êðîìñàòü» (íî íå óðîäîâàòü!) òîïîðîì, ìîòûãîé èëè ìîëîòîì, èíûìè ñëîâàìè, âûïîëíÿòü ôèçè÷åñêè òÿæåëóþ, ìîíîòîííóþ, íóäíóþ, èíòåëëåêòóàëüíî íåïðèòÿçàòåëüíóþ ðàáîòó — ÷òî
âñåãäà áûëî óäåëîì áàòðàêîâ, íåóäà÷íèêîâ è áåçäàðåé. Íåóäèâèòåëüíî, ÷òî ïðîèçâîäíûå îò ãëàãîëà «hack» îáîçíà÷àëè «áèòü áàêëóøè», «õàëòóðèòü», «âûïîëíÿòü
ðàáîòó íàñïåõ», — âåäü íàåìíûå ðàáî÷èå èñïîêîí âåêîâ òðóäèëèñü èç-ïîä ïàëêè!
Òåðìèí ñ÷èòàëñÿ ïðåíåáðåæèòåëüíûì, åñëè íå ðóãàòåëüíûì: «hack» ñòàëî äàæå
ñèíîíèìîì íàøåãî ñëîâà «êëÿ÷à». Ñëîâîì, â äîêîìïüþòåðíóþ ýïîõó òèòóëîì õàêåðà íè îäèí çäðàâîìûñëÿùèé ÷åëîâåê ãîðäèòüñÿ áû íå ñòàë.
Ñåãîäíÿ æå «õàêåð» çâó÷èò ïðàêòè÷åñêè òàê æå, êàê «íàöèîíàëüíûé ãåðîé»,
ïóñêàé è ïðåñòóïíûé, íî âñå æå êðóòîé ìàëûé, êîòîðîìó íå ãðåõ ïîäðàæàòü. ×åì
æå îáúÿñíÿåòñÿ òàêàÿ íåëåïàÿ ìóòàöèÿ äàííîãî ñëîâà?
Ïî îäíîé èç ãèïîòåç â ùåë÷êå, èçäàâàåìîì ðåëå, àìåðèêàíöàì ñëûøàëîñü
«õàê-õàê». Äèíîçàâðû ìàøèííîé ýðû ñîñòîÿëè èç ìíîãèõ òûñÿ÷ ðåëå è «õàêàëè»
âîâñþ, îñîáåííî êîãäà îïåðàòîð ÝÂÌ çàïóñêàë î÷åðåäíóþ ïðîãðàììó íà âûïîëíåíèå. Âîçìîæíî, èìåííî çà ýòî îïåðàòîðîâ è ïðîçâàëè õàêåðàìè. Èëè, ãîâîðÿ ïîðóññêè, êëàöàëüùèêàìè. Ïî äðóãîé ãèïîòåçå çâóê «õàê» ïðèïèñûâàåòñÿ ïåðôîðàòîðó, êðîìñàþùåìó ïåðôîëåíòó íà ìåëêèå êóñêè, òàê ÷òî ùåïêè (òàêèå àêêóðàòíåíüêèå êðóãëûå «ùåïî÷êè») âî âñå ñòîðîíû ëåòÿò!
Åñëè êîïíóòü ãëóáæå, òî íåîæèäàííî îáíàðóæèòñÿ ìíîæåñòâî àññîöèàöèé,
óñèëèâàþùèõ çàêîííîñòü íîâîãî çíà÷åíèÿ ñëîâà «õàê». È ðåëå, è ïåðôîðàòîð èçäàþò ïîâòîðÿþùèåñÿ ìîíîòîííûå óäàðû, ÷åì-òî íàïîìèíàþùèå êàøåëü, à hack
èìåííî ýòî è îáîçíà÷àåò (âûðàæåíèå «êàøëÿòü ñóõèì êàøëåì» — îäíî èç åãî çíà÷åíèé). Ê òîìó æå, ïðîãðàììèðîâàëè «äèíîçàâðîâ» èñêëþ÷èòåëüíî â ìàøèííûõ
êîäàõ, ïîä÷àñ ñ ïîìîùüþ ïåðåêëþ÷àòåëåé èëè ïåðåòûêèâàíèÿ ðàçúåìîâ, — ôèçè÷åñêè òÿæåëàÿ, íóäíàÿ, íåáëàãîäàðíàÿ ðàáîòà, äîñòàþùàÿñÿ íàèìåíåå ïðèâèëåãèðîâàííîé ÷àñòè ïåðñîíàëà. Êàêîé òàì ðîìàíòèçì? Êàêîå èçÿùåñòâî ðåøåíèé èëè
ïîëåò ìûñëè? Õàëòóðà ñïëîøíàÿ... Ðåäêàÿ ïðîãðàììà îáõîäèòñÿ áåç îøèáîê, à
ïðîãðàììà, ñîñòàâëåííàÿ â ìàøèííûõ êîäàõ, — òåì áîëåå. Ïðè æåëàíèè ëþáîãî
îïåðàòîðà ìîæíî áûëî íàçâàòü õàëòóðùèêîì — õàêåðîì â ðóãàòåëüíîì ñìûñëå
ýòîãî ñëîâà. «Âîò, íàäåëàë êó÷ó îøèáîê, õàêåð òû íàø!»

6

Êòî òàêèå õàêåðû

Îáûâàòåëè æå, äàëåêèå îò âû÷èñëèòåëüíîé òåõíèêè è çíàêîìûå ñ íåé èñêëþ÷èòåëüíî ïî ôàíòàñòè÷åñêèì ðîìàíàì, èñïûòûâàëè ïåðåä ÝÂÌ áëàãîãîâåéíîå
óâàæåíèå, ïîäîãðåâàåìîå ãîðäîñòüþ çà íàó÷íî-òåõíè÷åñêèå äîñòèæåíèÿ âñåãî
ðîäà homo sapiens â öåëîì è àìåðèêàíñêîé íàöèè â ÷àñòíîñòè. «Áåëûå âîðîòíè÷êè» — öâåò íàöèè, óïðàâëÿþùèå ìàõèíîé ðàçìåðîì ñ ñóïåðìàðêåò è ñòîÿùåé äîðîæå òûñÿ÷è òàêèõ ñóïåðìàðêåòîâ, âûçûâàëè ó ðÿäîâîãî àìåðèêàíöà ñìåñü âîñòîðãà, çàâèñòè è ñòðåìëåíèÿ ê ïîäðàæàíèþ. Âðîäå êàê «ÿ òîæå õî÷ó áûòü êîñìîíàâòîì», íå çàäóìûâàÿñü î òîì, ÷òî êîñìîíàâòèêà — ýòî òîëüêî ñ âèäó ðîìàíòèêà,
à â äåéñòâèòåëüíîñòè êàòîðæíàÿ ðàáîòà.
Íî åñëè æåëàíèå ïîáûâàòü â êîñìîñå äî ñèõ ïîð ñìîãëè ðåàëèçîâàòü ëèøü
åäèíèöû, òî ÝÂÌ ñòàëè øèðîêî äîñòóïíûìè óæå â íà÷àëå øåñòèäåñÿòûõ ãîäîâ.
Ê òîìó âðåìåíè èõ ìîæíî áûëî âñòðåòèòü è â ïîäâàëàõ óíèâåðñèòåòîâ, è â ñòåíàõ
êðóïíûõ êîðïîðàöèé, è ïðàêòè÷åñêè âî âñåõ èññëåäîâàòåëüñêèõ ó÷ðåæäåíèÿõ.
Ñåñòü çà ïóëüò ÝÂÌ â ñîçíàíèè ñòóäåíòà îçíà÷àëî ïðàêòè÷åñêè òî æå ñàìîå, ÷òî
ñåñòü çà øòóðâàë ðåàêòèâíîãî áîìáàðäèðîâùèêà. Ïðîãðàììèðîâàíèå àññîöèèðîâàëîñü îòíþäü íå ñ áàòðà÷åñòâîì, à ñ èíòåëëåêòóàëüíîé èãðîé. È ñòàðøèå íàñòàâíèêè ñòóäåíòîâ — îïåðàòîðû ÝÂÌ — áûëè íå òîëüêî èõ ðóêîâîäèòåëÿìè, íî è
êóìèðàìè. Ñòóäåíòû, îäåðæèìûå âû÷èñëèòåëüíîé òåõíèêîé, ñòðåìèëèñü âî âñåì
ïîäðàæàòü ïåðñîíàëó, îáñëóæèâàþùåìó áîëüøèå ÝÂÌ, ÷àñòî áåç ïîíèìàíèÿ
ñóòè ïðîèñõîäÿùåãî. Óñëûøàâ æàðãîííîå ïðîçâèùå îïåðàòîðîâ, ñòóäåíòû, íå äîãàäûâàÿñü î åãî èðîíè÷íî-îñêîðáèòåëüíîì îòòåíêå, ñ äîñòîèíñòâîì ñòàëè íàçûâàòü õàêåðàìè è ñåáÿ, è ñâîèõ òîâàðèùåé, è äàæå ñâîþ ðàáîòó îêðåñòèëè õàêåðñòâîì.  èõ óñòàõ ñëîâî «õàêåð» çâó÷àëî îòíþäü íå íàñìåøêîé, à ðàñöåíèâàëîñü êàê
òèòóë. Òû — õàêåð, çíà÷èò, òû òàêîé æå ìàñòåð, êàê è íàñòîÿùèé îïåðàòîð ÝÂÌ,
çíà÷èò, òû êðóòîé ïàðåíü è ïåðåä òîáîé äðóãèì íå ñòûäíî ñíÿòü øëÿïó.
Òàê õàêåðû èç ðàáîòÿã ïðåâðàòèëèñü â ïðîãðàììèñòîâ-ýíòóçèàñòîâ, ïîìåøàííûõ íà êîìïüþòåðàõ è âûäåëûâàþùèõ íà íèõ òàêîå... òàêîå, ÷òî äðóãèì è íå ñíèëîñü. Çíà÷åíèå òåðìèíà «hack» âñå áîëåå èçìåíÿëîñü â ñòîðîíó «êðóòîãî òðþêà»,
«çàáàâíîãî ýôôåêòà», «âûïîëíåííîãî ñî âêóñîì ðîçûãðûøà». Ýòîò äóõ ïîäõâàòèëè è äðóãèå ôàêóëüòåòû, ïîðîé âîâñå íå ñâÿçàííûå íè ñ ýëåêòðîíèêîé, íè ñ âû÷èñëèòåëüíîé òåõíèêîé, íè äàæå ñ òî÷íûìè íàóêàìè âîîáùå. Õàêîì ñòàëè íàçûâàòü ëþáîé êëàññíûé ðîçûãðûø èëè íåñòàíäàðòíîå ðåøåíèå çíàêîìîé çàäà÷è —
æàðãîííûé òåðìèí òåõíè÷åñêîãî ÿçûêà ïðåâðàòèëñÿ â ìîäåðíîâîå ñëîâå÷êî, óïîòðåáëÿåìîå âñåìè, êîìó íå ëåíü.
Òåì âðåìåíåì ìóòàöèÿ ïîíÿòèÿ «õàêåð» ïðîäîëæàëàñü... ×òîáû ïîíÿòü åå
ïðè÷èíû, ïðèäåòñÿ ìûñëåííî ïåðåíåñòèñü â êîíåö øåñòèäåñÿòûõ — íà÷àëî ñåìèäåñÿòûõ, à ìîæåò, äàæå ÷óòî÷êó ïîçæå.  òå âðåìåíà ñðåäè çàïàäíîé ìîëîäåæè
âèòàë äóõ áîðüáû. Áîðüáû ñ êåì? Äà ðàçâå ýòî âàæíî! Ïðîòåñòîâàëè ïðîòèâ âîéíû
âî Âüåòíàìå (êòî íå õîòåë ñëóæèòü â àðìèè — æãëè ïîâåñòêè), ëîìàëè ïóðèòàíñêèå óñòîè ñòàðîãî ìèðà, ïðîâîçãëàøàÿ ñâîáîäó ëþáâè, ïðåçèðàëè äåíüãè (èëè
òîëüêî äåëàëè âèä, ÷òî ïðåçèðàëè, çàâèñòëèâî ïîãëÿäûâàÿ â ñòîðîíó òîãî, ó êîãî
îíè åñòü). Ïî áîëüøîìó ñ÷åòó âñÿ áîðüáà ñâîäèëàñü ê ñóåòå â ïåñî÷íèöå, è âëàñòü
èìóùèõ â îáùåì-òî íè÷óòü íå áåñïîêîèëà. Ìîëîäåæíûå ëèäåðû íå èìåëè â ñâîèõ
ðóêàõ íèêàêîãî îðóæèÿ — íè îãíåñòðåëüíîãî, íè ïîëèòè÷åñêîãî, íè ýêîíîìè÷å-

Êòî òàêèå õàêåðû

7

ñêîãî, íè èäåîëîãè÷åñêîãî. Ê òîìó æå ÷åðåç äåñÿòîê ëåò äóõ áîðüáû â Àìåðèêå èññÿê, âåñü øóì ñîøåë íà íåò.
Ñ÷àñòëèâîå èñêëþ÷åíèå ñîñòàâèëè ïðîãðàììèñòû.  òå äíè êîìïüþòåðíûå
ñèñòåìû åùå íå óñïåëè îáçàâåñòèñü äîñòîéíîé çàùèòîé, íî óæå óïðàâëÿëè
âàæíûìè ñòðàòåãè÷åñêèìè è ýêîíîìè÷åñêèìè îáúåêòàìè. Âëàñòü íàä êîìïüþòåðàìè ïîçâîëÿëà äàòü õîðîøåãî ïèíêà è ïðàâèòåëüñòâåííûì îðãàíèçàöèÿì, è ôèíàíñîâûì ìàãíàòàì, è êîðïîðàöèÿì, è äðóãèì ñèëüíûì ìèðà ñåãî, ïðè÷åì îñòàâàÿñü áåçíàêàçàííûì. Íå ñóùåñòâîâàëî íè ñîîòâåòñòâóþùèõ çàêîíîâ, íè êîìïüþòåðíîé ïîëèöèè, ñïîñîáíîé âû÷èñëèòü ïðåñòóïíèêà... Ñëîâîì, Äèêèé Çàïàä
âðåìåí ðàçáîÿ, ðîìàíòèêè è áåñïðåäåëà, êîãäà ÷åëîâåê ñ êîëüòîì ìîã çàñòàâèòü
øåðèôà ëþáîãî óåçäíîãî ãîðîäêà «ñëóøàòü Øîïåíà ëåæà». Ó àìåðèêàíöåâ,
íàäî ñêàçàòü, ïî ïîâîäó îñâîåíèÿ Àìåðèêè î÷åíü ñèëüíûé êîìïëåêñ — îäíèõ
âåñòåðíîâ îíè ñíÿëè áîëüøå, ÷åì ìû ôèëüìîâ ïðî Âåëèêóþ Îòå÷åñòâåííóþ
âîéíó. Ïîíÿòíîå äåëî, êàæäûé þíûé àìåðèêàíåö â äóøå ìíèò ñåáÿ ïîëíîïðàâíûì êîâáîåì!
Êîìïüþòåðû æå ïîçâîëèëè âîïëîòèòü ýòó ìå÷òó â æèçíü. Îñâîé ÝÂÌ è íîñèñü
ïî ýëåêòðîííûì ñåòÿì êàê íåóëîâèìûé Äæî, îòñòðåëèâàþùèé èíäåéöåâ (áàíêèðîâ,
àãåíòîâ ÖÐÓ è ò. ä.). Äà è êàê íå íîñèòüñÿ, êîãäà íà êíèæíûõ ëîòêàõ êàê ãðèáû ïîÿâëÿëèñü ôàíòàñòè÷åñêèå ðîìàíû, ãëàâíûìè ãåðîÿìè êîòîðûõ áûëè êîìïüþòåðíûå
âçëîìùèêè — õàêåðû. Ïèñàòåëè, íèêîãäà â æèçíè íå âèäåâøèå ÝÂÌ, ïëîõî ðàçáèðàëèñü â òåõíè÷åñêîì æàðãîíå è óïîòðåáëÿëè åãî íà èíòóèòèâíî-áåññîçíàòåëüíîì
óðîâíå áåçî âñÿêîãî ïîíèìàíèÿ. Äîñòàòî÷íî ïåðåëèñòàòü «The Shockware Rider»
Äæîíà Áðóííåðà (John Brunner) èçäàíèÿ 1975 ãîäà, «The Adolescence of P-1» Òîìàñà Ðèàíà (Thomas Ryan) èçäàíèÿ 1977 ãîäà èëè «Neuromancer» Âèëüÿìà Ãèáñîíà
(William Gibson), îïóáëèêîâàííûé â 1984 ãîäó, ÷òîáû óáåäèòüñÿ, íàñêîëüêî áåñêîíå÷íî èõ àâòîðû áûëè äàëåêè îò âû÷èñëèòåëüíîé òåõíèêè. Âïðî÷åì, ëèòåðàòóðíûõ
äîñòîèíñòâ ïðîèçâåäåíèé ýòî íè÷óòü íå óìàëÿëî, è ó ÷èòàòåëåé ñëîæèëñÿ óñòîé÷èâûé îáðàç: ÝÂÌ — ýòî êðóòî, à õàê — ýòî âîîáùå êðóòî. «Íåéðîìàòèê», êñòàòè,
áûë ñàìîé ëþáèìîé êíèãîé Ðîáåðòà Òàïïëàíà Ìîððèñà, ñîçäàâøåãî ñâîé çíàìåíèòûé âèðóñ-÷åðâü, íàäî ïîëàãàòü, íå áåç âëèÿíèÿ Âèëüÿìà Ãèáñîíà.
Æóðíàëèñòû, íå îáðåìåíåííûå íè çíàíèÿìè ÝÂÌ, íè ëèíãâèñòè÷åñêèì îáðàçîâàíèåì, èç âñåãî ýòîãî ïîíÿëè òîëüêî îäíî: íåêòî, íàçûâàþùèå ñåáÿ õàêåðàì,
ëîìàþò êîìïüþòåðû ïî âñåé ñòðàíå, ïðè÷åì ëîìàþò âåñüìà êðóòî, ñ íàíåñåíèåì
óùåðáà â îñîáî êðóïíûõ ðàçìåðàõ.
Ñëîâî «õàêåð» âûðâàëîñü íà ñòðàíèöû ãàçåò, íî â øèðîêèõ ìàññàõ ãëàãîë
«hack» ïî-ïðåæíåìó îçíà÷àë âñå òî æå «áèòü», «êðîìñàòü», è àìåðèêàíöû, âïîëíå
åñòåñòâåííî, çàêëþ÷èëè, ÷òî õàêåð — ýòî òîò, êòî âëàìûâàåòñÿ â ÷óæèå ñèñòåìû
è ðàçáèâàåò èõ â ïóõ è ïðàõ.
Âîò, ñîáñòâåííî, è âñå... Êîëüöî çàìêíóëîñü — òåðìèí «õàêåð» âåðíóë ñâîå
èñòîðè÷åñêîå çíà÷åíèå, íî íå ïðåêðàòèë ýâîëþöèþ! Õàêåðàì ïðîøëîãî ïîêîëåíèÿ (ò. å. ýíòóçèàñòàì ïðîãðàììèðîâàíèÿ) î÷åíü íå ïîíðàâèëîñü, ÷òî èõ òèòóë
ñìåøàëè, ìÿãêî âûðàæàÿñü, ñ äåðüìîì, è ïðè åãî óïîìèíàíèè âñå ñòàëè øàðàõàòüñÿ îò íèõ, êàê îò îãíÿ. Äàáû ðåàáèëèòèðîâàòüñÿ â ãëàçàõ îáùåñòâåííîñòè, õàêåðû
ïðåäïðèíÿëè ïîïûòêó ðàçäåëèòü âñåõ ñâîèõ íà «õîðîøèõ» è «ïëîõèõ», îñòàâèâ çà
õîðîøèìè ïàðíÿìè ïðàâî íàçûâàòüñÿ õàêåðàìè, à äëÿ ïëîõèõ ïðèäóìàâ ñïåöèàëü-

8

Êòî òàêèå õàêåðû

íûé òåðìèí «êðàêåð» — îò ñëîâà crack — ëîìàòü (êñòàòè, ïî÷åìó íå «áðåéêåð» —
îò ñëîâà break?), â áóêâàëüíîì ñìûñëå îáîçíà÷àþùèé «ëîìàòåëü». Çàòåÿ ñ òðåñêîì ïðîâàëèëîñü — äàëåêî íå êàæäûé âçëîìùèê áûë ãîòîâ íàöåïèòü íà ñåáÿ ÿðëûê ïëîõîãî ïàðíÿ. Íàçûâàòüñÿ õàêåðîì ïî-ïðåæíåìó ñ÷èòàëîñü è ìîäíî, è ïðåñòèæíî, ïóñêàé âñå «õàêåðñòâî» îãðàíè÷èëîñü wannabe (â äîñëîâíîì ðóññêîì ïåðåâîäå «õî÷óáûòüêàê», ò. å. ïîäðàæàòåëüñòâîì). Ïðåäìåòû õàêåðñêîé êóëüòóðû
îáîæåñòâëÿëèñü, ñòàíîâÿñü ïðåäìåòîì ïîêëîíåíèÿ, ôåòèøåì, èêîíîé íà ñòåíå.
Ýòà âåòêà ãåíåàëîãè÷åñêîãî äðåâà «õàêåðîâ» íå èìååò áóäóùåãî è îáðå÷åíà íà
ìåäëåííîå, íî íåîòâðàòèìîå âûìèðàíèå. Óæå ñåãîäíÿ, â íà÷àëå ïåðâîãî äåñÿòèëåòèÿ XXI âåêà, òåðìèí «õàêåð» ñòàë âñåîáúåìëþùèì è óòðàòèë âñÿêèé ñìûñë. Êòî
ïèøåò âèðóñû? Õàêåðû! Êòî ëîìàåò ïðîãðàììû? Õàêåðû! Êòî êðàäåò äåíüãè èç
áàíêîâ? Õàêåðû! Êòî ïàêîñòèò â ñåòè? Õàêåðû! Êòî ïðîãðàììèðóåò íà àññåìáëåðå? Õàêåðû! Êòî çíàåò âñå òîíêîñòè îïåðàöèîííîé ñèñòåìû è «æåëåçà»? Õàêåðû!
Ñêàçàòü ñîáåñåäíèêó, ÷òî òû õàêåð, íå óòî÷íèâ, ÷òî êîíêðåòíî òû èìååøü ïîä
ýòèì â âèäó, âñå ðàâíî ÷òî íè÷åãî íå ñêàçàòü.
Òåðìèí «õàêåð» óìåð, íî âåäü õàêåðû îñòàëèñü! Îñòàëèñü è ðàáîòÿãè-êîäåðû,
ïóñêàé óæå íå êëàöàþùèå ðåëå, íî çàòî øóìÿùèå ïðîïåëëåðàìè âåíòèëÿòîðîâ,
îñòàëèñü è ýíòóçèàñòû ïðîãðàììèðîâàíèÿ, óïîåííî ïðîãðàììèðóþùèå è íà äðåâíèõ, è íà ñîâðåìåííûõ ÿçûêàõ, îñòàëèñü è èññëåäîâàòåëè çàùèò, è óìåëüöû ïî èõ
âçëîìó... Ëþäè åñòü, à òåðìèíà, îïðåäåëÿþùåãî èõ ïðèíàäëåæíîñòü, óæå íåò.
Ïî÷åìó áû íå íàçâàòü îïðåäåëåííóþ êàòåãîðèþ êîìïüþòåðùèêîâ êîäîêîïàòåëÿìè? Ýòîò òåðìèí, âïåðâûå óïîòðåáëåííûé Áåçðóêîâûì, íà ìîé âçãëÿä, î÷åíü óäà÷åí
è èíòóèòèâíî ïîíÿòåí áåç äîïîëíèòåëüíûõ îáúÿñíåíèé. Ëþáîé, êòî ëþáèò êîïàòüñÿ
â êîäå (íå îáÿçàòåëüíî ìàøèííîì), ïî ïðàâó ìîæåò ñ÷èòàòü ñåáÿ êîäîêîïàòåëåì.
Òàêèì ëþäÿì, ñîáñòâåííî, è ïîñâÿùåíà ýòà êíèãà...

×åì ìû áóäåì çàíèìàòüñÿ
Íà ïðîòÿæåíèè âñåé êíèãè ìû áóäåì çàíèìàòüñÿ óâëåêàòåëüíîé èíòåëëåêòóàëüíîé èãðîé — ñîçäàíèåì çàùèòíûõ ìåõàíèçìîâ è èññëåäîâàíèåì èõ ñòîéêîñòè. Ñêàæó ñðàçó — íè÷åãî îáùåãî ñî âçëîìîì êîììåð÷åñêèõ ïðîãðàìì èëè êðàæåé äåíåã èç áàíêà ýòî çàíÿòèå íå èìååò. Àâòîð èñêðåííå íàäååòñÿ, ÷òî åãî ÷èòàòåëè — ãðàæäàíå â ñâîåé ìàññå çàêîíîïîñëóøíûå è âûñîêîíðàâñòâåííûå.
Óìåíèå íåéòðàëèçîâàòü çàùèòû íå äàåò ïðàâà ïðèìåíÿòü ýòî óìåíèå â ïðåñòóïíûõ öåëÿõ. Êàêèå æå öåëè ÿâëÿþòñÿ ïðåñòóïíûìè, à êàêèå íåò — âîïðîñ, îòíîñÿùèéñÿ óæå íå ê õàêåðñòâó, à ê þðèñïðóäåíöèè, â êîòîðîé àâòîð íå ñèëåí, è
âñå, ÷òî îí ìîæåò ïîðåêîìåíäîâàòü — ïðè âîçíèêøèõ ó âàñ ñîìíåíèÿõ â ïðàâîìåðíîñòè ñîâåðøåíèÿ íåêîòîðûõ äåéñòâèé îáðàòèòåñü ê þðèñòàì.
Îäíàêî ýêñïåðèìåíòèðîâàòü ñ âàøåé ëè÷íîé èíòåëëåêòóàëüíîé ñîáñòâåííîñòüþ — ïðîãðàììàìè, íàïèñàííûìè âàìè ñàìèìè, — íè îäèí çàêîí íå âïðàâå çàïðåòèòü, äà íè îäèí çàêîí ýòîãî, ñîáñòâåííî, è íå çàïðåùàåò.
À ðàç òàê, ðþêçàê íà ïëå÷è, îõîòíè÷èé íîæèê â êàðìàí è — â ãóñòîé òàåæíûé ëåñ...

Êòî òàêèå õàêåðû

9

×òî íàì ïîíàäîáèòñÿ
Âûáîð ðàáî÷åãî èíñòðóìåíòàðèÿ — äåëî ñóãóáî ëè÷íîå è èíòèìíîå. Òóò íà
âêóñ è öâåò òîâàðèùåé íåò. Ïîýòîìó ïðèìèòå âñå íèæåñêàçàííîå íå êàê äîãìó, à
êàê ðåêîìåíäàöèþ ê äåéñòâèþ. Èòàê, äëÿ ÷òåíèÿ êíèãè íàì ïîíàäîáèòñÿ:
• îòëàä÷èê Soft-Ice âåðñèè 3.25 èëè áîëåå ñòàðøèé;
• äèçàññåìáëåð IDA âåðñèè 3.7õ (ðåêîìåíäóåòñÿ 3.8, à åùå ëó÷øå 4.x);
• HEX-ðåäàêòîð HIEW ëþáîé âåðñèè;
• ëþáîé Ñ\Ñ++ è Pascal-êîìïèëÿòîð ïî âêóñó (â êíèãå ïîäðîáíî îïèñûâàþò-

ñÿ îñîáåííîñòè êîìïèëÿòîðîâ Microsoft Visual C++, Borland C++, WATCOM C, GNU C, FreePascal, à çà îñíîâó âçÿò Microsoft Visual C++ 6.0);
• ïàêåòû SDK è DDK (ïîñëåäíèé íå îáÿçàòåëåí, íî î÷åíü æåëàòåëåí);
• îïåðàöèîííàÿ ñèñòåìà — ëþáàÿ èç ñåìåéñòâà Windows, íî íàñòîÿòåëüíî
ðåêîìåíäóåòñÿ Windows 2000.
Òåïåðü îáî âñåì ýòîì ïîäðîáíåå.
Soft-Ice. Îòëàä÷èê Soft-Ice — îñíîâíîå îðóæèå õàêåðà. Õîòÿ ñ íèì êîíêóðèðóþò áåñïëàòíûå windeb îò Microsoft è TRW îò LiuTaoTao, Soft-Ice íàìíîãî ëó÷øå è óäîáíåå èõ âñåõ, âìåñòå âçÿòûõ. Äëÿ íàøèõ ýêñïåðèìåíòîâ ïîäîéäåò ïðàêòè÷åñêè ëþáàÿ âåðñèÿ Àéñà, íàïðèìåð, àâòîð èñïîëüçóåò äàâíî àïðîáèðîâàííóþ è
óñòîé÷èâî ðàáîòàþùóþ âåðñèþ 3.26, çàìå÷àòåëüíî óæèâàþùóþñÿ ñ Windows 2000. Íîâîìîäíàÿ âåðñèÿ 4.x íå î÷åíü-òî äðóæèò ñ âèäåîàäàïòåðîì àâòîðà
(Matrox Millennium G450, äëÿ ñïðàâêè) è âîîáùå âðåìåíàìè «åäåò êðûøåé».
Ê òîìó æå èç âñåõ íîâûõ âîçìîæíîñòåé ÷åòâåðòîé âåðñèè ïîëåçíà ëèøü ïîääåðæêà FPO (Frame point omission — ñì. ãëàâó «Èäåíòèôèêàöèÿ ëîêàëüíûõ ñòåêîâûõ ïåðåìåííûõ») — ëîêàëüíûõ ïåðåìåííûõ, íàïðÿìóþ àäðåñóåìûõ ÷åðåç ðåãèñòð ESP, — áåññïîðíî ïîëåçíî, íî áåç ýòîãî ìîæíî è îáîéòèñü. Íàéòè Soft-Ice
ìîæíî íà äèñêàõ èçâåñòíîãî ïðîèñõîæäåíèÿ èëè ó ðîññèéñêîãî äèñòðèáüþòîðà:
http://www.quarta.ru/bin/soft/winntutils/softicent.asp?ID=59. Êóïèòå, íå ïîæàëååòå (õàêåðñòâî — ýòî âåäü íå òî æå ñàìîå ÷òî ïèðàòñòâî, è ÷åñòíîñòü åùå íèêòî íå îòìåíÿë).
IDA Pro. Áåññïîðíî, ñàìûé ìîùíûé äèçàññåìáëåð â ìèðå — ýòî IDA. Ïðîæèòü áåç íåå, êîíå÷íî, ìîæíî, íî... íóæíî ëè? IDA îáåñïå÷èâàåò óäîáíóþ íàâèãàöèþ ïî èññëåäóåìîìó òåêñòó, àâòîìàòè÷åñêè ðàñïîçíàåò áèáëèîòå÷íûå ôóíêöèè
è ëîêàëüíûå ïåðåìåííûå, â òîì ÷èñëå è àäðåñóåìûå ÷åðåç ðåãèñòð ESP, ïîääåðæèâàåò ìíîæåñòâî ïðîöåññîðîâ è ôîðìàòîâ ôàéëîâ. Îäíèì ñëîâîì, õàêåð áåç IDA —
íå õàêåð. Âïðî÷åì, àãèòàöèè èçëèøíè, åäèíñòâåííàÿ ïðîáëåìà: ãäå æå ýòó IDA
âçÿòü? Íà ïèðàòñêèõ äèñêàõ îíà âñòðå÷àåòñÿ êðàéíå ðåäêî (ñàìàÿ ïîñëåäíÿÿ âèäåííàÿ àâòîðîì âåðñèÿ — 3.74, äà è òî íåñòàáèëüíî ðàáîòàþùàÿ), íà ñàéòàõ â Èíòåðíåòå — åùå ðåæå. Ôèðìà-ðàçðàáîò÷èê æåñòêî ïðåñåêàåò ëþáûå ïîïûòêè íåñàíêöèîíèðîâàííîãî ðàñïðîñòðàíåíèÿ ñâîåãî ïðîäóêòà, è åäèíñòâåííûé íàäåæíûé ïóòü
åãî ïðèîáðåòåíèÿ — ïîêóïêà â ñàìîé ôèðìå èëè ó ðîññèéñêîãî äèñòðèáüþòîðà
(GelioSoft Ltd ). Ê ñîæàëåíèþ, ñ äèçàññåìáëåðîì íå

10

Êòî òàêèå õàêåðû

ðàñïðîñòðàíÿåòñÿ íèêàêîé äîêóìåíòàöèè (íå ñ÷èòàÿ âñòðîåííîãî õåëïà — î÷åíü
êîðîòêîãî è áåññèñòåìíîãî), ïîýòîìó àâòîðó íè÷åãî íå îñòàåòñÿ, êàê ïîðåêîìåíäîâàòü ñîáñòâåííûé òðåõòîìíèê «Îáðàç ìûøëåíèÿ — äèçàññåìáëåð IDA», ïîäðîáíî ðàññêàçûâàþùèé è î ñàìîé IDA, è î äèçàññåìáëèðîâàíèè âîîáùå.
HIEW. «Õüþâåâ» — ýòî íå òîëüêî HEX-ðåäàêòîð, íî è äèçàññåìáëåð, àññåìáëåð è êðèïò «â îäíîì ôëàêîíå». Îí íå èçáàâèò îò íåîáõîäèìîñòè ïðèîáðåòåíèÿ
IDA, íî ñ ëèõâîé çàìåíèò IDA â ðÿäå ñëó÷àåâ (IDA î÷åíü ìåäëåííî ðàáîòàåò, è
îáèäíî òðàòèòü êó÷ó âðåìåíè, åñëè âñå, ÷òî íàì íóæíî, ïîñìîòðåòü íà ïðåïàðèðóåìûé ôàéë îäíèì ãëàçêîì). Âïðî÷åì, îñíîâíîå íàçíà÷åíèå «õüþâåâà» îòíþäü íå
äèçàññåìáëèðîâàíèå, à bit hack — íåáîëüøîå õèðóðãè÷åñêîå âìåøàòåëüñòâî â
äâîè÷íûé ôàéë — îáû÷íîå âûðåçàíèå æèçíåííî âàæíîãî îðãàíà çàùèòíîãî ìåõàíèçìà, áåç êîòîðîãî îí ïåðåñòàåò ðàáîòàòü.
SDK (Software Development Kit — êîìïëåêò ïðèêëàäíîãî ðàçðàáîò÷èêà). Èç ïàêåòà SDK íàì â ïåðâóþ î÷åðåäü ïîíàäîáèòñÿ äîêóìåíòàöèÿ ïî
Win32 API è óòèëèòà äëÿ ðàáîòû ñ PE-ôàéëàìè BUMPBIN. Áåç äîêóìåíòàöèè íè
õàêåðàì, íè ðàçðàáîò÷èêàì íèêàê íå îáîéòèñü. Ïî êðàéíåé ìåðå, íåîáõîäèìî
çíàòü ïðîòîòèïû è íàçíà÷åíèå îñíîâíûõ ôóíêöèé ñèñòåìû. Ýòó èíôîðìàöèþ â
ïðèíöèïå ìîæíî ïî÷åðïíóòü è èç ìíîãî÷èñëåííûõ ðóññêîÿçû÷íûõ êíèã ïî ïðîãðàììèðîâàíèþ, íî íè îäíà èç íèõ íå ìîæåò ïîõâàñòàòüñÿ ïîëíîòîé è ãëóáèíîé
èçëîæåíèÿ. Ïîýòîìó ðàíî èëè ïîçäíî, íî âñå-òàêè ïðèäåòñÿ îáðàùàòüñÿ ê SDK.
Ïðàâäà, íåêîòîðûì ïðèäåòñÿ ïëîòíî çàñåñòü çà àíãëèéñêèé, ïîñêîëüêó âñÿ äîêóìåíòàöèÿ íàïèñàíà èìåííî íà ýòîì ÿçûêå è æäàòü åå ïåðåâîäà — âñå ðàâíî ÷òî
êàðàóëèòü ó ìîðÿ ïîãîäó (ïðàâäà, ñ íåêîòîðûõ ïîð íà ñàéòå Microsoft ñòàëî ïîÿâëÿòüñÿ ìíîãî èíôîðìàöèè äëÿ ðàçðàáîò÷èêîâ è íà ðóññêîì ÿçûêå). Ãäå ïðèîáðåñòè SDK? Âî-ïåðâûõ, SDK âõîäèò â ñîñòàâ MSDN, à ñàì MSDN åæåêâàðòàëüíî
èçäàåòñÿ íà êîìïàêò-äèñêàõ è ðàñïðîñòðàíÿåòñÿ ïî ïîäïèñêå (ïîäðîáíåå îá óñëîâèÿõ åãî ïðèîáðåòåíèÿ ìîæíî óçíàòü íà îôèöèàëüíîì ñàéòå msdn.Microsoft.com).
Ïðèëàãàåòñÿ MSDN è ê êîìïèëÿòîðó Microsoft Visual C++ 6.0, íî, óâû, äàëåêî íå
ïåðâîé ñâåæåñòè. Âïðî÷åì, ïîëüçîâàòüñÿ èì âïîëíå ìîæíî, âî âñÿêîì ñëó÷àå, äëÿ
÷òåíèÿ äàííîé êíèãè åãî áóäåò âïîëíå äîñòàòî÷íî.
DDK (Driver Development Kit — êîìïëåêò ðàçðàáîò÷èêà äðàéâåðîâ). Êàêóþ ïîëüçó ìîæåò èçâëå÷ü õàêåð èç ïàêåòà DDK? Íó, â ïåðâóþ î÷åðåäü
îí ïîìîæåò ðàçîáðàòüñÿ, êàê óñòðîåíû, ðàáîòàþò è ëîìàþòñÿ äðàéâåðû. Ïîìèìî
îñíîâîïîëàãàþùåé äîêóìåíòàöèè è ìíîæåñòâà ïðèìåðîâ â íåãî âõîäèò î÷åíü öåííûé ôàéë NTDDK.h, ñîäåðæàùèé îïðåäåëåíèÿ áîëüøèíñòâà íåäîêóìåíòèðîâàííûõ ñòðóêòóð è áóêâàëüíî íàøïèãîâàííûé êîììåíòàðèÿìè, ðàñêðûâàþùèìè íåêîòîðûå ëþáîïûòíûå ïîäðîáíîñòè ôóíêöèîíèðîâàíèÿ ñèñòåìû. Íåëèøíèì áóäåò
è èíñòðóìåíòàðèé, ïðèëàãàþùèéñÿ ê DDK. Ñðåäè ïðî÷åãî, ñþäà âõîäèò è îòëàä÷èê windeb. Âåñüìà íåïëîõîé, êñòàòè, îòëàä÷èê, íî âñå æå çíà÷èòåëüíî óñòóïàþùèé Soft-Ice, ïîýòîìó è íå ðàññìàòðèâàåìûé â äàííîé êíèãå (íî åñëè âû íå íàéäåòå Àéñà — ñãîäèòñÿ è windeb). Áîëåå ïîëåçíûì îêàæåòñÿ àññåìáëåð MASM, íà
êîòîðîì, ñîáñòâåííî, è ïèøóòñÿ äðàéâåðû, à òàêæå äðóãèå ïîëåçíûå ïðîãðàììêè,
îáëåã÷àþùèå æèçíü õàêåðó. Ïîñëåäíþþ âåðñèþ DDK ìîæíî áåñïëàòíî ñêà÷àòü

Êòî òàêèå õàêåðû

11

ñ ñàéòà Microsoft, òîëüêî èìåéòå â âèäó, ÷òî äëÿ NT ïîëíûé DDK çàíèìàåò ñâûøå
40 ìåãàáàéòîâ â óïàêîâàííîì âèäå, è åùå áîëüøå òðåáóåò ìåñòà íà äèñêå.
Îïåðàöèîííàÿ ñèñòåìà. Âîâñå íå ñîáèðàÿñü íàâÿçûâàòü ÷èòàòåëþ ñîáñòâåííûå âêóñû è ïðèñòðàñòèÿ, àâòîð òåì íå ìåíåå íàñòîÿòåëüíî ðåêîìåíäóåò óñòàíîâèòü èìåííî Windows 2000. Ìîòèâàöèÿ — ýòî äåéñòâèòåëüíî ñòàáèëüíàÿ è
óñòîé÷èâî ðàáîòàþùàÿ îïåðàöèîííàÿ ñèñòåìà, ìóæåñòâåííî ïåðåíîñÿùàÿ êðèòè÷åñêèå îøèáêè ïðèëîæåíèé. Ñïåöèôèêà ðàáîòû õàêåðà òàêîâà, ÷òî õèðóðãè÷åñêèå âìåøàòåëüñòâà â íåäðà ïðîãðàìì ÷àñòî ñðûâàþò èì «êðûøó», äîâîäÿ ëîìàåìîå ïðèëîæåíèå äî áóéíîãî ïîìåøàòåëüñòâà ñ íåïðåäñêàçóåìûì ïîâåäåíèåì.
Windows 9x, äåìîíñòðèðóÿ ñîöèàëèñòè÷åñêóþ ñîëèäàðíîñòü, î÷åíü ÷àñòî «ëîæèòñÿ» ðÿäîì ñ çàâèñøåé ïðîãðàììîé. Ïîðîé êîìïüþòåð ïðèõîäèòñÿ ïåðåçàãðóæàòü
íå îäèí äåñÿòîê ðàç íà äíþ! È õîðîøî åñëè òîëüêî ïåðåçàãðóæàòü, à íå âîññòàíàâëèâàòü ðàçðóøåííûå ñáîåì äèñêè (òàêîå õîòÿ è ðåäêî, íî ñëó÷àåòñÿ). Çàâåñèòü æå
Windows 2000 íà ïîðÿäîê ñëîæíåå — àâòîðó ýòî «óäàåòñÿ» íå ÷àùå îäíîãî-äâóõ
ðàç â ìåñÿö, äà è òî ñ íåäîñûïó èëè ïî íåáðåæíîñòè. Êðîìå òîãî, Windows 2000
ïîçâîëÿåò çàãðóæàòü Soft-Ice â ëþáîé ìîìåíò áåç íåîáõîäèìîñòè ïåðåçàãðóçêè,
÷òî î÷åíü óäîáíî! Íàêîíåö, âåñü ìàòåðèàë ýòîé êíèãè ðàññ÷èòàí èìåííî íà Windows 2000 — à åå îòëè÷èÿ îò äðóãèõ ñèñòåì óïîìèíàþòñÿ äàëåêî íå âñåãäà. Âñå
ðàâíî âñå ìû êîãäà-íèáóäü ïåðåéäåì íà Windows 2000 è çàáóäåì î Windows 9x
êàê î ñòðàøíîì ñíå, òàê ñòîèò ëè õâàòàòüñÿ çà ýòó óìèðàþùóþ ïëàòôîðìó? Ê ñëîâó ñêàçàòü, Windows Me — ýòî íå òî æå ñàìîå, ÷òî Windows 2000, è ñòàâèòü Me
íà ñâîé êîìïüþòåð àâòîð íèêîìó íå ðåêîìåíäóåò (òàêîå âïå÷àòëåíèå, ÷òî Windows Me âîîáùå íå òåñòèðîâàëè, à î òîì, ÷òî åå ïèñàëè ñàäèñòû — êòî ñòàâèë,
òîò ïîéìåò, — àâòîð âîîáùå ìîë÷èò).
Õóäî-áåäíî ðàçîáðàâøèñü ñ èíñòðóìåíòàðèåì, ïîãîâîðèì î ñåðîì âåùåñòâå,
èáî â åãî îòñóòñòâèè âåñü ñîáðàííûé èíñòðóìåíò áåñïîëåçåí. Àâòîð ïîëàãàåò, ÷òî
÷èòàòåëü óæå çíàêîì ñ àññåìáëåðîì, è åñëè íå ïèøåò ïðîãðàìì íà ýòîì ÿçûêå, òî
ïî êðàéíåé ìåðå ïðåäñòàâëÿåò ñåáå, ÷òî òàêîå ðåãèñòðû, ñåãìåíòû, ìàøèííûå èíñòðóêöèè è ò. ä.  ïðîòèâíîì ñëó÷àå ýòà êíèãà ðèñêóåò ïîêàçàòüñÿ ÷åðåñ÷óð ñëîæíîé è íåïîíÿòíîé. Îòûùèòå â ìàãàçèíå ëþáîé ó÷åáíèê ïî àññåìáëåðó (íàïðèìåð,
Â. Þðîâà «ASSEMBLER — ó÷åáíèê», Ï. È. Ðóäàêîâà «Ïðîãðàììèðóåì íà ÿçûêå àññåìáëåðà IBM PC» èëè «Assembler — ÿçûê íåîãðàíè÷åííûõ âîçìîæíîñòåé» Ñ. Â. Çóáêîâà) è îñíîâàòåëüíî ïðîøòóäèðóéòå åãî.
Ïîìèìî çíàíèÿ àññåìáëåðà òàêæå íàäî èìåòü õîòÿ áû îáùèå ïîíÿòèÿ î ôóíêöèîíèðîâàíèè îïåðàöèîííîé ñèñòåìû. Êóïèòå è âäóì÷èâî èçó÷èòå (åñëè íå ñäåëàëè ýòîãî äî ñèõ ïîð) «Windows äëÿ ïðîôåññèîíàëîâ» Äæåôðè Ðèõòåðà1 è (åñëè
íàéäåòå) «Ñåêðåòû ñèñòåìíîãî ïðîãðàììèðîâàíèÿ â Windows 95» Ìýòà Ïèòðåêà. Õîòÿ åãî êíèãà ïîñâÿùåíà Windows 95, ÷àñòè÷íî îíà ñïðàâåäëèâà è äëÿ
Windows 2000. Äëÿ çíàêîìñòâà ñ àðõèòåêòóðîé ñàìîé æå Windows 2000 ðåêîìåíäóåòñÿ îçíàêîìèòüñÿ ñ øåäåâðîì Õåëåí Êàñòåð «Îñíîâû Windows NT» è áðîøþðîé «Íåäîêóìåíòèðîâàííûå âîçìîæíîñòè Windows NT» À. Â. Êîáåðíè÷åíêî.
1

Ñì. «Ïðèëîæåíèå», «Îøèáêè Äæåôðè Ðèõòåðà».

12

Êòî òàêèå õàêåðû

×òî êàñàåìî îáùåé òåîðèè èíôîðìàòèêè è àëãîðèòìîâ — áåññïîðíûé àâòîðèòåò Êíóò. Âïðî÷åì, íà âêóñ àâòîðà, ìîíîãðàôèÿ Ì. Áðîÿ «Èíôîðìàòèêà» êóäà
ëó÷øå — ïðè òîì, ÷òî îíà íàìíîãî êîðî÷å, êðóã îõâàòûâàåìûõ åþ òåì è ãëóáèíà
èçëîæåíèÿ íàìíîãî øèðå. Çà÷åì õàêåðó òåîðèÿ èíôîðìàòèêè? Äà êóäà æå áåç
íåå! Âîò, ñêàæåì, âñòðåòèòñÿ åìó çàùèòà ñî âñòðîåííûì ýìóëÿòîðîì ìàøèíû
Òüþðèíãà. Ñ ëåòó åå íå ñëîìàòü — íàäî êàê ìèíèìóì îïîçíàòü ñàì àëãîðèòì: ÷òî
ýòî âîîáùå òàêîå — Òüþðèíã, Ìàðêîâ, ñåòü Ïåòðè, à çàòåì îòîáðàçèòü åãî íà
ÿçûê âûñîêîãî óðîâíÿ, äàáû â óäîáî÷èòàåìîì âèäå àíàëèçèðîâàòü ðàáîòó çàùèòû.
Êóäà æå òóò áåç òåîðèè èíôîðìàòèêè!
Çàñèì âñå. Íó, ðàçâå ÷òî ñòîèò äîïîëíèòü íàø ïîõîäíûé ðþêçà÷îê ïàðîé
ó÷åáíèêîâ ïî àíãëèéñêîìó (îíè ïðèãîäÿòñÿ, ïîâåðüòå) è âûêà÷àòü ñ ñàéòîâ Intel è
AMD âñþ èìåþùóþñÿ òàì äîêóìåíòàöèþ ïî ïðîöåññîðàì. Íà õóäîé êîíåö ïîäîéäåò è åå ðóññêèé ïåðåâîä, íàïðèìåð, À. À. Ðîâäî «Ìèêðîïðîöåññîðû îò 8086 äî
Pentium III Xeon è AMD K6-3». Íó-ñ, ðþêçà÷îê íà ïëå÷î è â ïóòü...

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè
ðàáîòû õàêåðà

Ââåäåíèå
Êëàññèôèêàöèÿ çàùèò
Ñòàòü õàêåðîì î÷åíü ïðîñòî. Äîñòàòî÷íî âûó÷èòü è ïîíÿòü:
ìàòåìàòè÷åñêèé àíàëèç, òåîðèþ ôóíêöèé êîìïëåêñíîãî ïåðåìåííîãî, àëãåáðó, ãåîìåòðèþ, òåîðèþ âåðîÿòíîñòåé, ìàòåìàòè÷åñêóþ ñòàòèñòèêó, ìàòåìàòè÷åñêóþ ëîãèêó è äèñêðåòíóþ ìàòåìàòèêó...
Á. Ëåîíòüåâ. Õàêåðû & Internet

Ïðîâåðêà àóòåíòè÷íîñòè (îò ãðå÷. authentikos — ïîäëèííûé) — «ñåðäöå»
ïîäàâëÿþùåãî áîëüøèíñòâà çàùèòíûõ ìåõàíèçìîâ. Äîëæíû æå ìû óäîñòîâåðèòüñÿ: òî ëè ëèöî, çà êîòîðîå îíî ñåáÿ âûäàåò, ðàáîòàåò ñ ïðîãðàììîé, è ðàçðåøåíî
ëè ýòîìó ëèöó ðàáîòàòü ñ ïðîãðàììîé âîîáùå!
 êà÷åñòâå «ëèöà» ìîæåò âûñòóïàòü íå òîëüêî ïîëüçîâàòåëü, íî è åãî êîìïüþòåð èëè íîñèòåëü èíôîðìàöèè, õðàíÿùèé ëèöåíçèîííóþ êîïèþ ïðîãðàììû. Òàêèì
îáðàçîì, âñå çàùèòíûå ìåõàíèçìû ìîæíî ðàçäåëèòü íà äâå îñíîâíûå êàòåãîðèè:
• çàùèòû, îñíîâàííûå íà çíàíèè (ïàðîëÿ, ñåðèéíîãî íîìåðà);
• çàùèòû, îñíîâàííûå íà îáëàäàíèè (êëþ÷åâîãî äèñêà, äîêóìåíòàöèè).

Çàùèòû, îñíîâàííûå íà çíàíèè, áåñïîëåçíû, åñëè îáëàäàòåëü çàùèùåííîé ñ
èõ ïîìîùüþ ïðîãðàììû íå çàèíòåðåñîâàí â ñîõðàíåíèè åå ñåêðåòíîñòè. Îí ìîæåò ñîîáùèòü ïàðîëü (ñåðèéíûé íîìåð) êîìó óãîäíî, ïîñëå ÷åãî ëþáîé ñìîæåò
çàïóñòèòü òàêóþ ïðîãðàììó íà ñâîåì êîìïüþòåðå. Ïîýòîìó ïàðîëüíûå çàùèòû
äëÿ ïðåäîòâðàùåíèÿ ïèðàòñêîãî êîïèðîâàíèÿ ïðîãðàìì íåïðèãîäíû. Ïî÷åìó æå
òîãäà ïðàêòè÷åñêè âñå êðóïíûå ïðîèçâîäèòåëè â îáÿçàòåëüíîì ïîðÿäêå èñïîëüçóþò ñåðèéíûå íîìåðà? Îòâåò ïðîñò — äëÿ çàùèòû ñâîåé èíòåëëåêòóàëüíîé ñîáñòâåííîñòè îò ãðóáîé ôèçè÷åñêîé ñèëû. Ïðîèñõîäèò ýòî ïðèáëèçèòåëüíî òàê: ðàáî÷àÿ òèøèíà òàêîé-òî ôèðìû âíåçàïíî íàðóøàåòñÿ òîïîòîì ïàðíåé â êàìóôëÿæå,
ñâåðÿþùèõ ëèöåíçèîííûå íîìåðà Windows (Microsoft Office, Microsoft Visual Studio) ñ ëèöåíçèîííûìè ñîãëàøåíèÿìè, è ñòîèò îáíàðóæèòüñÿ õîòÿ áû îäíîé «ëåâîé» êîïèè, êàê ïîÿâèâøèéñÿ ñëîâíî èç-ïîä çåìëè ñîòðóäíèê ôèðìû íà÷èíàåò ðàäîñòíî ïîòèðàòü ðóêè â ïðåäâêóøåíèè äîæäÿ âå÷íîçåëåíûõ...  ëó÷øåì ñëó÷àå —
çàñòàâÿò êóïèòü âñå «ëåâûå» êîïèè, â õóäøåì æå...
Ê äîìàøíèì ïîëüçîâàòåëÿì â êâàðòèðó, ïîíÿòíîå äåëî, íèêòî íå âðûâàåòñÿ — ÷àñòíàÿ ñîáñòâåííîñòü è âñå òàêîå, äà ê ýòîìó íèêòî, âïðî÷åì, è íå ñòðåìèò-

14

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

ñÿ. ×òî ñ äîìàøíåãî ïîëüçîâàòåëÿ âîçüìåøü-òî? Ê òîìó æå ñàìèì ôèðìàì âûãîäíî ìàññîâîå ðàñïðîñòðàíåíèå èõ ïðîäóêöèè, à êòî åãî îáåñïå÷èò ëó÷øå ïèðàòîâ?
Íî è çäåñü ñåðèéíûå íîìåðà íå ëèøíèå — îíè ðàçãðóæàþò ñëóæáó òåõíè÷åñêîé
ïîääåðæêè îò «ëåâûõ» çâîíêîâ íåçàðåãèñòðèðîâàííûõ ïîëüçîâàòåëåé, îäíîâðåìåííî ñ ýòèì ñêëîíÿÿ ïîñëåäíèõ ê ïîêóïêå ëåãàëüíîé âåðñèè.
Òàêàÿ ñõåìà çàùèòû èäåàëüíà äëÿ êîðïîðàöèé-ãèãàíòîâ, íî îíà íå ïîäõîäèò
äëÿ ìåëêèõ ïðîãðàììèñòñêèõ êîëëåêòèâîâ è èíäèâèäóàëüíûõ ðàçðàáîò÷èêîâ, îñîáåííî åñëè îíè çàðàáàòûâàþò íà æèçíü íàïèñàíèåì óçêîñïåöèàëèçèðîâàííûõ
ïðîãðàìì ñ îãðàíè÷åííûì ðûíêîì ñáûòà (ñêàæåì, àíàëèçàòîðîâ çâåçäíûõ ñïåêòðîâ èëè ñèñòåìû ìîäåëèðîâàíèÿ ÿäåðíûõ ðåàêöèé). Íå èìåÿ äîñòàòî÷íîãî âëèÿíèÿ, ðàñêà÷àòü ñîòðóäíèêîâ èçâåñòíûõ îðãàíîâ íà îáëàâó äëÿ ïðîâåðêè ëèöåíçèîííîñòè ñâîåãî ÏÎ íåðåàëüíî, à âûáèòü äåíüãè èç íåëåãàëüíûõ ïîëüçîâàòåëåé
ìîæíî ðàçâå ÷òî ñ ïîìîùüþ êðèìèíàëüíûõ ñòðóêòóð, äà è òî íàâðÿä ëè. Âîò è
ïðèõîäèòñÿ ðàññ÷èòûâàòü ëèøü íà ñîáñòâåííóþ ñèëó è ñìåêàëêó.
Òóò ëó÷øå ïîäõîäèò òèï çàùèò, îñíîâàííûõ íà îáëàäàíèè íåêîòîðûì óíèêàëüíûì ïðåäìåòîì, ñêîïèðîâàòü êîòîðûé ÷ðåçâû÷àéíî òÿæåëî, à â èäåàëå âîîáùå íåâîçìîæíî. Ïåðâûå ëàñòî÷êè ýòîé ñåðèè — êëþ÷åâûå äèñêåòû, çàïèñàííûå ñ
òàêèì ðàñ÷åòîì, ÷òîáû ïðè èõ êîïèðîâàíèè êîïèÿ ÷åì-íèáóäü äà îòëè÷àëàñü îò
îðèãèíàëà. Ñàìîå ïðîñòîå (íî íå ñàìîå ëó÷øåå) — ñëåãêà èçóðîäîâàòü äèñêåòó
ãâîçäåì (øèëîì, ïåðî÷èííûì íîæîì), à çàòåì, îïðåäåëèâ ìåñòîïîëîæåíèå äåôåêòà îòíîñèòåëüíî ñåêòîðà (ýòî ìîæíî ñäåëàòü çàïèñüþ-÷òåíèåì íåêîòîðîé òåñòîâîé èíôîðìàöèè — äî êàêîãî-òî ìîìåíòà ÷òåíèå áóäåò èäòè íîðìàëüíî, à ïîòîì
íà÷íåòñÿ «ìóñîð»), æåñòêî ïðîïèñàòü åãî â ïðîãðàììå è ïðè êàæäîì çàïóñêå ïðîâåðÿòü, íà òîì æå ñàìîì ìåñòå äåôåêò èëè íåò. Êîãäà æå äèñêåòû âûøëè èç óïîòðåáëåíèÿ, ýòà æå òåõíèêà áûëà àäàïòèðîâàíà è äëÿ êîìïàêò-äèñêîâ. Êòî ïîáîãà÷å, óðîäóåò èõ ëàçåðîì, êòî ïîáåäíåå — âñå òåì æå øèëîì èëè ãâîçäåì.

Ðèñ. 1. Îñíîâíûå òèïû çàùèò

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

15

Òàêèì îáðàçîì, ïðîãðàììà æåñòêî ïðèâÿçàíà ê äèñêó (äèñêåòå) è òðåáóåò
åå ïðèñóòñòâèÿ äëÿ ñâîåé ðàáîòû, à ïîñêîëüêó ñêîïèðîâàòü òàêîé äèñê íåðåàëüíî (ïîïðîáóé-êà äîáèòüñÿ èäåíòè÷íûõ äåôåêòîâ íà êîïèÿõ), ïèðàòû îñòàþòñÿ
íå ó äåë.
Çàùèòíûå ìåõàíèçìû, îñíîâàííûå íà îáëàäàíèè, ÷àñòî ìîäèôèöèðóþò ïðåäìåò îáëàäàíèÿ â ïðîöåññå ðàáîòû, îãðàíè÷èâàÿ êîëè÷åñòâî çàïóñêîâ ïðîãðàììû
èëè âðåìÿ åå èñïîëüçîâàíèÿ. Îñîáåííî ÷àñòî òàêîé ïðèåì èñïîëüçóåòñÿ â èíñòàëëÿòîðàõ: ÷òîáû íå íåðâèðîâàòü ïîëüçîâàòåëÿ, êëþ÷ çàïðàøèâàåòñÿ ëèøü îäíàæäû — íà ñòàäèè óñòàíîâêè ïðîãðàììû, à ðàáîòàòü ñ íåé ìîæíî è áåç íåãî. Åñëè
êîëè÷åñòâî èíñòàëëÿöèé îãðàíè÷åíî, óùåðáîì îò íåñàíêöèîíèðîâàííûõ óñòàíîâîê îäíîé êîïèè ïðîãðàììû íà íåñêîëüêî êîìïüþòåðîâ ìîæíî ïðåíåáðå÷ü.
Åäèíñòâåííàÿ ïðîáëåìà — âñå ýòî óùåìëÿåò ïðàâà ëåãàëüíîãî ïîëüçîâàòåëÿ.
Êîìó ïîíðàâèòñÿ îãðàíè÷åíèå íà êîëè÷åñòâî èíñòàëëÿöèé? (À âåäü íåêîòîðûå
ëþäè ïåðåóñòàíàâëèâàþò ñèñòåìó è âñå ÏÎ áóêâàëüíî êàæäûé ìåñÿö, à òî è íåñêîëüêî ðàç íà äíþ.) Êëþ÷åâûå äèñêè ðàñïîçíàþòñÿ íå âñåìè òèïàìè ïðèâîäîâ,
çà÷àñòóþ «íåâèäèìû» ïî ñåòè, à åñëè çàùèòíûé ìåõàíèçì äëÿ óâåëè÷åíèÿ ñòîéêîñòè ê âçëîìó îáðàùàåòñÿ ê îáîðóäîâàíèþ íàïðÿìóþ, â îáõîä äðàéâåðîâ, òî òàêàÿ
ïðîãðàììà íàâåðíÿêà íå áóäåò ôóíêöèîíèðîâàòü ïîä Windows NT\2000 è, âåñüìà
âåðîÿòíî, îòêàæåò â ðàáîòå ïîä Windows 9x (åñëè, êîíå÷íî, îíà íå áûëà çàðàíåå
ñïðîåêòèðîâàíà ñîîòâåòñòâóþùèì îáðàçîì, íî åñëè òàê — òåì õóæå, èáî íåêîððåêòíî ðàáîòàþùàÿ çàùèòà, èñïîëíÿþùàÿñÿ ñ íàèâûñøèìè ïðèâèëåãèÿìè, ìîæåò
ïðè÷èíèòü íåìàëûé óðîí ñèñòåìå). Ïîìèìî ýòîãî, êëþ÷åâîé ïðåäìåò ìîæíî ïîòåðÿòü, åãî ìîãóò óêðàñòü, äà è ñàì îí ìîæåò âûéòè èç ñòðîÿ (äèñêåòû ñêëîííû ñûïàòüñÿ è ðàçìàãíè÷èâàòüñÿ, äèñêè — öàðàïàòüñÿ, à ýëåêòðîííûå êëþ÷è — «ñãîðàòü»).
Êîíå÷íî, ýòè ïðåòåíçèè îòíîñÿòñÿ ê êà÷åñòâó ðåàëèçàöèè, à íå ê èäåå êëþ÷åé
âîîáùå, íî êîíå÷íûì ïîëüçîâàòåëÿì îò ýòîãî íè÷óòü íå ëåã÷å! Åñëè æå çàùèòà ñîçäàåò íåóäîáñòâà, ó ïîëüçîâàòåëåé ïîÿâëÿåòñÿ î÷åíü ñèëüíàÿ ìîòèâàöèÿ ê ïîñåùåíèþ áëèæàéøåãî äîñòóïíîãî ïèðàòà íà ïðåäìåò ïðèîáðåòåíèÿ ó íåãî êîíòðôàêòíîãî ïðîãðàììíîãî îáåñïå÷åíèÿ. È íèêàêèå ðàçãîâîðû î ìîðàëè, ýòèêå, äîáðîïîðÿäî÷íîñòè è ò. ä. íå ïîäåéñòâóþò — ñâîÿ ðóáàøêà áëèæå ê òåëó, à î
äîáðîïîðÿäî÷íîñòè â ïåðâóþ î÷åðåäü íóæíî çàäóìàòüñÿ ðàçðàáîò÷èêàì òàêèõ çàùèò. Òîâ... òüôó, ãîñïîäà, íå îòðàâëÿéòå æèçíü ïîëüçîâàòåëÿì! Ïîëüçîâàòåëè
òîæå ëþäè!
 ïîñëåäíåå âðåìÿ íàèáîëüøóþ ïîïóëÿðíîñòü îáðåëè çàùèòû, îñíîâàííûå íà
ðåãèñòðàöèîííûõ íîìåðàõ. Ïðè ïåðâîì çàïóñêå ïðîãðàììà ïðèâÿçûâàåòñÿ ê
êîìïüþòåðó è âêëþ÷àåò «ñ÷åò÷èê» (âàðèàíò — áëîêèðóåò íåêîòîðûå ôóíêöèîíàëüíûå âîçìîæíîñòè). À ÷òîáû åå «îñâîáîäèòü», íåîáõîäèìî ââåñòè ïàðîëü, ñîîáùàåìûé ðàçðàáîò÷èêîì çà íåêîòîðîå ìàòåðèàëüíîå âîçíàãðàæäåíèå. ×àñòî äëÿ
ïðåäîòâðàùåíèÿ ïèðàòñêîãî êîïèðîâàíèÿ ïàðîëü ïðåäñòàâëÿåò ñîáîé íåêîòîðóþ
ïðîèçâîäíóþ îò êëþ÷åâûõ ïàðàìåòðîâ êîìïüþòåðà (èëè ïðîèçâîäíóþ îò èìåíè
ïîëüçîâàòåëÿ â ïðîñòåéøåì ñëó÷àå).
Ðàçóìååòñÿ, â ýòîì êðàòêîì îáçîðå òèïîâ çàùèò î÷åíü ìíîãîå îñòàëîñü çà
êàäðîì, íî ïîäðîáíûé ðàçãîâîð î êëàññèôèêàöèè çàùèò âûõîäèò çà ðàìêè ýòîé
êíèãè, òàê ÷òî îòëîæèì åãî äî âòîðîãî òîìà.

16

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Ôèëîñîôèÿ ñòîéêîñòè
Îäíàæäû îäèí èç äðóçåé ñêàçàë Êàòîíó Ñòàðøåìó: «Êàêîå áåçîáðàçèå, ÷òî â Ðèìå òåáå äî ñèõ
ïîð íå âîçäâèãëè ïàìÿòíèêà! ß îáÿçàòåëüíî ïîçàáî÷óñü îá ýòîì».
«Íå íàäî, — îòâåòèë Êàòîí, — ÿ ïðåäïî÷èòàþ,
÷òîáû ëþäè ñïðàøèâàëè, ïî÷åìó íåò ïàìÿòíèêà Êàòîíó, ÷åì ïî÷åìó îí åñòü».
Ò. Ìåññîí

Åñëè çàùèòà áàçèðóåòñÿ íà îäíîì ëèøü ïðåäïîëîæåíèè, ÷òî åå êîä íå áóäåò
èçó÷åí è/èëè èçìåíåí, — ýòî ïëîõàÿ çàùèòà. Îòñóòñòâèå èñõîäíûõ òåêñòîâ îòíþäü íå ÿâëÿåòñÿ íåïðåîäîëèìûì ïðåïÿòñòâèåì äëÿ èçó÷åíèÿ è ìîäèôèêàöèè
ïðèëîæåíèÿ. Ñîâðåìåííûå òåõíîëîãèè îáðàòíîãî ïðîåêòèðîâàíèÿ ïîçâîëÿþò àâòîìàòè÷åñêè ðàñïîçíàâàòü áèáëèîòå÷íûå ôóíêöèè, ëîêàëüíûå ïåðåìåííûå, ñòåêîâûå àðãóìåíòû, òèïû äàííûõ, âåòâëåíèÿ, öèêëû è ò. ä. À â íåäàëåêîì áóäóùåì
äèçàññåìáëåðû, âåðîÿòíî, âîîáùå íàó÷àòñÿ ãåíåðèðîâàòü ëèñòèíãè, áëèçêèå ïî
âíåøíåìó âèäó ê ÿçûêàì âûñîêîãî óðîâíÿ.
Íî äàæå ñåãîäíÿ òðóäîåìêîñòü àíàëèçà äâîè÷íîãî êîäà íå íàñòîëüêî âåëèêà,
÷òîáû íàäîëãî îñòàíîâèòü çëîóìûøëåííèêîâ. Îãðîìíîå êîëè÷åñòâî ïîñòîÿííî ñîâåðøàåìûõ âçëîìîâ — ëó÷øåå òîìó ïîäòâåðæäåíèå.  èäåàëüíîì ñëó÷àå çíàíèå
àëãîðèòìà ðàáîòû çàùèòû íå äîëæíî âëèÿòü íà åå ñòîéêîñòü, íî ýòî äîñòèæèìî
äàëåêî íå âñåãäà. Íàïðèìåð, åñëè ðàçðàáîò÷èê ñåðâåðíîé ïðîãðàììû ðåøèò óñòàíîâèòü â äåìîíñòðàöèîííîé âåðñèè îãðàíè÷åíèå íà êîëè÷åñòâî îäíîâðåìåííî îáðàáàòûâàåìûõ ñîåäèíåíèé (êàê ÷àñòî è ñëó÷àåòñÿ), çëîóìûøëåííèêó äîñòàòî÷íî
íàéòè èíñòðóêöèþ ïðîöåññîðà, îñóùåñòâëÿþùóþ òàêóþ ïðîâåðêó è óäàëèòü åå.
Ìîäèôèêàöèè ïðîãðàììû ìîæíî âîñïðåïÿòñòâîâàòü ïîñòîÿííîé ïðîâåðêîé åå öåëîñòíîñòè, íî îïÿòü-òàêè, êîä, ïðîâåðÿþùèé öåëîñòíîñòü, ìîæåò áûòü íàéäåí è
óäàëåí.
Ñêîëüêî áû óðîâíåé çàùèòû íè ñóùåñòâîâàëî, îäèí èëè ìèëëèîí, ïðîãðàììà
ìîæåò áûòü âçëîìàíà! Ýòî òîëüêî âîïðîñ âðåìåíè è óñèëèé. Íî â îòñóòñòâèå ðåàëüíî äåéñòâóþùèõ çàêîíîâ çàùèòû èíòåëëåêòóàëüíîé ñîáñòâåííîñòè ðàçðàáîò÷èêàì ïðèõîäèòñÿ áîëüøå ïîëàãàòüñÿ íà ñòîéêîñòü ñâîåé çàùèòû, ÷åì íà ïîìîùü
ïðàâîîõðàíèòåëüíûõ îðãàíîâ. Áûòóåò ìíåíèå, ÷òî åñëè çàòðàòû íà íåéòðàëèçàöèþ çàùèòíîãî ìåõàíèçìà áóäóò íå íèæå ñòîèìîñòè ëåãàëüíîé êîïèè, åå íèêòî íå
áóäåò ëîìàòü. Ýòî íåâåðíî! Ìàòåðèàëüíûé ñòèìóë — íå åäèíñòâåííîå, ÷òî äâèæåò õàêåðîì. Ãîðàçäî áîëåå ñèëüíîé ìîòèâàöèåé îêàçûâàåòñÿ èíòåëëåêòóàëüíàÿ áîðüáà (êòî óìíåå: ÿ èëè àâòîð çàùèòû?), ñïîðòèâíûé àçàðò (êòî èç õàêåðîâ ñëîìàåò áîëüøå âñåãî çàùèò?), ëþáîïûòñòâî (à êàê ýòî ðàáîòàåò?), ïîâûøåíèå ñâîåãî ïðîôåññèîíàëèçìà (÷òîáû íàó÷èòüñÿ ñîçäàâàòü çàùèòû, ñíà÷àëà
íóæíî íàó÷èòüñÿ èõ ñíèìàòü), äà è ïðîñòî èíòåðåñíîå âðåìÿïðîâîæäåíèå (åñëè
åãî íå÷åì çàíÿòü). Ìíîãèå ëþäè ìîãóò íåäåëÿìè êîðïåòü íàä îòëàä÷èêîì, ñíèìàÿ
çàùèòó ñ ïðîãðàììû ñòîèìîñòüþ â íåñêîëüêî äîëëàðîâ, à òî è âîâñå ðàñïðîñòðàíÿåìîé áåñïëàòíî (íàïðèìåð, ôàéë-ìåíåäæåð FAR äëÿ æèòåëåé Ðîññèè è ÑÍÃ àáñîëþòíî áåñïëàòåí, íî ýòî íå ñïàñàåò åãî îò âçëîìà).

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

17

Öåëåñîîáðàçíîñòü çàùèòû îãðàíè÷èâàåòñÿ êîíêóðåíöèåé, ïðè ïðî÷èõ ðàâíûõ
óñëîâèÿõ êëèåíò âñåãäà âûáèðàåò íåçàùèùåííûé ïðîäóêò, äàæå åñëè çàùèòà íå
óùåìëÿåò åãî ïðàâ.  íàñòîÿùåå âðåìÿ ñïðîñ íà ïðîãðàììèñòîâ çíà÷èòåëüíî ïðåâûøàåò ïðåäëîæåíèå, íî â îòäàëåííîì áóäóùåì ðàçðàáîò÷èêàì ïðèäåòñÿ ëèáî
ñãîâîðèòüñÿ, ëèáî ïîëíîñòüþ îòêàçàòüñÿ îò çàùèò. È ñïåöèàëèñòû ïî çàùèòàì áóäóò âûíóæäåíû èñêàòü ñåáå äðóãóþ ðàáîòó.
Ýòî íå çíà÷èò, ÷òî äàííàÿ êíèãà áåñïîëåçíà, íàïðîòèâ, ïîëó÷åííûå çíàíèÿ
ñëåäóåò ïðèìåíèòü êàê ìîæíî áûñòðåå, ïîêà â çàùèòàõ åùå íå îòïàëà íåîáõîäèìîñòü.

Øàã ïåðâûé. Ðàçìèíî÷íûé
Áîðîòüñÿ ñî ñâîèìè ìûñëÿìè — ýòî óïîäîáèòüñÿ îäíîìó ãëóïöó, êîòîðûé â öåëÿõ àêêóðàòíîñòè è ãèãèåíû ðåøèë áîëüøå íå êàêàòü. Äåíü íå êàêàë, äâà íå
êàêàë. Ïîòîì, êîíå÷íî, íå âûäåðæàë, íî âñåõ ïðîäîëæàë óâåðÿòü, ÷òî íå êàêàåò.
Àíîíèì

Àëãîðèòì ïðîñòåéøåãî ìåõàíèçìà àóòåíòèôèêàöèè ñîñòîèò â ïîñèìâîëüíîì
ñðàâíåíèè ââåäåííîãî ïîëüçîâàòåëåì ïàðîëÿ ñ ýòàëîííûì çíà÷åíèåì, õðàíÿùèìñÿ ëèáî â ñàìîé ïðîãðàììå (êàê ÷àñòî è áûâàåò), ëèáî âíå åå, íàïðèìåð, â êîíôèãóðàöèîííîì ôàéëå èëè ðååñòðå (÷òî âñòðå÷àåòñÿ ðåæå).
Äîñòîèíñòâî òàêîé çàùèòû — êðàéíå ïðîñòàÿ ïðîãðàììíàÿ ðåàëèçàöèÿ. Åå
ÿäðî ñîñòîèò ôàêòè÷åñêè èç îäíîé ñòðîêè, êîòîðóþ íà ÿçûêå Ñ ìîæíî çàïèñàòü òàê:
if (strcmp(ââåäåííûé ïàðîëü, ýòàëîííûé ïàðîëü)) {/* Ïàðîëü íåâåðåí */} else
{/* Ïàðîëü ÎÊ */}
Äàâàéòå äîïîëíèì ýòîò êîä ïðîöåäóðàìè çàïðîñà ïàðîëÿ è âûâîäà ðåçóëüòàòîâ ñðàâíåíèÿ, à çàòåì èñïûòàåì ïîëó÷åííóþ ïðîãðàììó íà ïðî÷íîñòü, ò. å. íà
ñòîéêîñòü ê âçëîìó:
Ëèñòèíã 1. Ïðèìåð ïðîñòåéøåé ñèñòåìû àóòåíòèôèêàöèè

// Ïðîñòåéøàÿ ñèñòåìà àóòåíòèôèêàöèè
// ïîñèìâîëüíîå ñðàâíåíèå ïàðîëÿ
#include
#include
#define PASSWORD_SIZE 100
#define PASSWORD
"myGOODpassword\n"
// ýòîò ïåðåíîñ íóæåí çàòåì, ÷òîáû ^^^^
// íå âûêóñûâàòü ïåðåíîñ èç ñòðîêè,
// ââåäåííîé ïîëüçîâàòåëåì
int main()
{
// Ñ÷åò÷èê íåóäà÷íûõ ïîïûòîê àóòåíòèôèêàöèè
int count=0;

18

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
// Áóôåð äëÿ ïàðîëÿ, ââåäåííîãî ïîëüçîâàòåëåì
char buff[PASSWORD_SIZE];
// Ãëàâíûé öèêë àóòåíòèôèêàöèè
for(;;)
{
// Çàïðàøèâàåì è ñ÷èòûâàåì ïîëüçîâàòåëüñêèé
// ïàðîëü
printf("Enter password:");
fgets(&buff[0],PASSWORD_SIZE,stdin);
// Ñðàâíèâàåì îðèãèíàëüíûé è ââåäåííûé ïàðîëü
if (strcmp(&buff[0],PASSWORD))
// Åñëè ïàðîëè íå ñîâïàäàþò - "ðóãàåìñÿ"
printf("Wrong password\n");
// Èíà÷å (åñëè ïàðîëè èäåíòè÷íû)
// âûõîäèì èç öèêëà àóòåíòèôèêàöèè
else break;
//
//
//
if

Óâåëè÷èâàåì ñ÷åò÷èê íåóäà÷íûõ ïîïûòîê
àóòåíòèôèêàöèè è, åñëè âñå ïîïûòêè
èñ÷åðïàíû, çàâåðøàåì ïðîãðàììó
(++count>3) return -1;

}
// Ðàç ìû çäåñü, òî ïîëüçîâàòåëü ââåë ïðàâèëüíûé ïàðîëü
printf("Password OK\n");
}

 ïîïóëÿðíûõ êèíîôèëüìàõ êðóòûå õàêåðû ëåãêî ïðîíèêàþò â ëþáûå æóòêî
çàùèùåííûå ñèñòåìû, êàêèì-òî íåïîñòèæèìûì îáðàçîì óãàäûâàÿ èñêîìûé ïàðîëü ñ íåñêîëüêèõ ïîïûòîê. Ïî÷åìó áû íå ïîïðîáîâàòü ïîéòè èõ ïóòåì?
Íå òàê óæ ðåäêî ïàðîëè ïðåäñòàâëÿþò ñîáîé îñìûñëåííûå ñëîâà íàïîäîáèå
«Ferrari», «QWERTY», èìåíà ëþáèìûõ õîìÿ÷êîâ, íàçâàíèÿ ãåîãðàôè÷åñêèõ ïóíêòîâ è ò. ä. Óãàäûâàíèå ïàðîëÿ ñðîäíè ãàäàíèþ íà êîôåéíîé ãóùå — íèêàêèõ ãàðàíòèé íà óñïåõ íåò, îñòàåòñÿ ðàññ÷èòûâàòü íà îäíî ëèøü âåçåíèå. À óäà÷à, êàê
èçâåñòíî, ïòèöà ãîðäàÿ — ïàëåö â ðîò åéíå êëàäè. Íåò ëè áîëåå íàäåæíîãî ñïîñîáà âçëîìà?
Äàâàéòå ïîäóìàåì. Ðàç ýòàëîííûé ïàðîëü õðàíèòñÿ â òåëå ïðîãðàììû, òî,
åñëè îí íå çàøèôðîâàí êàêèì-íèáóäü õèòðûì îáðàçîì, åãî ìîæíî îáíàðóæèòü
òðèâèàëüíûì ïðîñìîòðîì äâîè÷íîãî êîäà ïðîãðàììû. Ïåðåáèðàÿ âñå âñòðåòèâøèåñÿ â íåé òåêñòîâûå ñòðîêè, íà÷èíàÿ ñ òåõ, ÷òî áîëåå âñåãî ñìàõèâàþò íà
ïàðîëü, ìû î÷åíü áûñòðî ïîäáåðåì íóæíûé êëþ÷ è îòêðîåì èì ïðîãðàììó!
Ïðè÷åì îáëàñòü ïðîñìîòðà ìîæíî ñóùåñòâåííî ñóçèòü — â ïîäàâëÿþùåì áîëüøèíñòâå ñëó÷àåâ êîìïèëÿòîðû ðàçìåùàþò âñå èíèöèàëèçèðîâàííûå ïåðåìåííûå â ñåãìåíòå äàííûõ (â PE-ôàéëàõ îí ðàçìåùàåòñÿ â ñåêöèè .data). Èñêëþ÷åíèå ñîñòàâëÿþò, ïîæàëóé, ðàííèå áàãäàäñêèå (Borland'âûå) êîìïèëÿòîðû ñ èõ
ìàíèàêàëüíîé ëþáîâüþ âñîâûâàòü òåêñòîâûå ñòðîêè â ñåãìåíò êîäà — íåïîñðåäñòâåííî ïî ìåñòó èõ âûçîâà. Ýòî óïðîùàåò ñàì êîìïèëÿòîð, íî ïîðîæäàåò
ìíîæåñòâî ïðîáëåì. Ñîâðåìåííûå îïåðàöèîííûå ñèñòåìû, â îòëè÷èå îò ñòàðóøêè MS-DOS, çàïðåùàþò ìîäèôèêàöèþ êîäîâîãî ñåãìåíòà, è âñå ðàçìåùåí-

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

19

íûå â íåì ïåðåìåííûå äîñòóïíû ëèøü äëÿ ÷òåíèÿ. Ê òîìó æå íà ïðîöåññîðàõ ñ
ðàçäåëüíîé ñèñòåìîé êýøèðîâàíèÿ (íà òåõ æå Pentium'àõ, íàïðèìåð) îíè «çàñîðÿþò» êîäîâûé êýø, ïîïàäàÿ òóäà ïðè óïðåæäàþùåì ÷òåíèè, íî ïðè ïåðâîì æå
îáðàùåíèè ê íèì âíîâü çàãðóæàþòñÿ èç ìåäëåííîé îïåðàòèâíîé ïàìÿòè (êýøà
âòîðîãî óðîâíÿ) â êýø äàííûõ. Â ðåçóëüòàòå — òîðìîçà è ïàäåíèå ïðîèçâîäèòåëüíîñòè.
×òî æ, ïóñòü ýòî áóäåò ñåêöèÿ äàííûõ! Îñòàåòñÿ òîëüêî íàéòè óäîáíûé èíñòðóìåíò äëÿ ïðîñìîòðà äâîè÷íîãî ôàéëà. Ìîæíî, êîíå÷íî, íàæàòü êëàâèøó
â ñâîåé ëþáèìîé îáîëî÷êå (FAR, DOS Navigator) è, ïðèäàâèâ êèðïè÷îì êëàâèøó
, ëþáîâàòüñÿ áåãóùèìè öèôèðüêàìè äî òåõ ïîð, ïîêà íå íàäîåñò.
Ìîæíî âîñïîëüçîâàòüñÿ ëþáûì hex-ðåäàêòîðîì (QVIEW, HIEW...) — êîìó
êàêîé ïî âêóñó, — íî â êíèãå ïî ñîîáðàæåíèÿì íàãëÿäíîñòè àâòîð ïðèâåäåò
ðåçóëüòàò ðàáîòû óòèëèòû DUMPBIN èç øòàòíîé ïîñòàâêè Microsoft Visual
Studio.
Ïîïðîñèì åå ðàñïå÷àòàòü ñåêöèþ äàííûõ (êëþ÷ /SECTION:.data) â «ñûðîì»
âèäå (êëþ÷ /RAWDATA:BYTES), óêàçàâ çíà÷îê «>» äëÿ ïåðåíàïðàâëåíèÿ âûâîäà â
ôàéë (îòâåò ïðîãðàììû çàíèìàåò ìíîãî ìåñòà, è íà ýêðàíå ïîìåùàåòñÿ îäèí ëèøü
«õâîñò»).
> dumpbin /RAWDATA:BYTES /SECTION:.data simple.exe >filename
RAW DATA #3
00406000: 00
00406010: A4
00406020: 00
00406030: 45
00406040: 6D

00
40
00
6E
79

00
40
00
74
47

00
00
00
65
4F

00
00
00
72
4F

00
00
00
20
44

00
00
00
70
70

00
00
00
61
61

00
00
00
73
73

00
00
00
73
73

00
00
00
77
77

00
00
00
6F
6F

3B
E0
00
72
72

11
11
00
64
64

40
40
00
3A
0A

00
00
00
00
00

............;.@.
ä@@.........ð.@.
................
Enter password:.
myGOODpassword..
^^^^^^^^^^^^^^
00406050: 57 72 6F 6E 67 20 70 61 73 73 77 6F 72 64 0A 00 Wrong password..
00406060: 50 61 73 73 77 6F 72 64 20 4F 4B 0A 00 00 00 00 Password OK.....
00406070: 40 6E 40 00 00 00 00 00 40 6E 40 00 01 01 00 00 @n@.....@n@.....

Ñìîòðèòå! Ñðåäè âñåãî ïðî÷åãî òóò åñòü îäíà ñòðîêà, äî áîëè ïîõîæàÿ íà ýòàëîííûé ïàðîëü (â òåêñòå îíà âûäåëåíà æèðíûì øðèôòîì). Èñïûòàåì åå? Âïðî÷åì, êàêîé ñìûñë — ñóäÿ ïî èñõîäíîìó òåêñòó ïðîãðàììû ýòî äåéñòâèòåëüíî èñêîìûé ïàðîëü, îòêðûâàþùèé çàùèòó, ñëîâíî çîëîòîé êëþ÷èê. Ñëèøêîì óæ âèäíîå ìåñòî âûáðàë êîìïèëÿòîð äëÿ åãî õðàíåíèÿ — ïàðîëü íå ìåøàëî áû çàïðÿòàòü è ïîëó÷øå.
Îäèí èç ñïîñîáîâ ñäåëàòü ýòî — íàñèëüíî ïîìåñòèòü ýòàëîííûé ïàðîëü â
ñîáñòâåííîðó÷íî âûáðàííóþ íàìè ñåêöèþ. Òàêàÿ âîçìîæíîñòü íå ïðåäóñìîòðåíà
ñòàíäàðòîì, è ïîòîìó êàæäûé ðàçðàáîò÷èê êîìïèëÿòîðà (ñòðîãî ãîâîðÿ, íå êîìïèëÿòîðà, à ëèíêåðà, íî ýòî íå ñóòü âàæíî) âîëåí ðåàëèçîâûâàòü åå ïî-ñâîåìó èëè
íå ðåàëèçîâûâàòü âîîáùå. Â Microsoft Visual C++ äëÿ ýòîé öåëè ïðåäóñìîòðåíà
ñïåöèàëüíàÿ ïðàãìà data_seg, óêàçûâàþùàÿ, â êàêóþ ñåêöèþ ïîìåùàòü ñëåäóþùèå çà íåé èíèöèàëèçèðîâàííûå ïåðåìåííûå. Íåèíèöèàëèçèðîâàííûå ïåðåìåííûå ïî óìîë÷àíèþ ðàñïîëàãàþòñÿ â ñåêöèè .bss è óïðàâëÿþòñÿ ïðàãìîé bss_seg
ñîîòâåòñòâåííî.

20

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Äîáàâèì â ëèñòèíã 1 ñëåäóþùèå ñòðîêè è ïîñìîòðèì, ÷òî ó íàñ èç ýòîãî ïîëó÷èòñÿ.
int count=0;
// Ñ ýòîãî ìîìåíòà âñå èíèöèàëèçèðîâàííûå ïåðåìåííûå áóäóò
// ðàçìåùàòüñÿ â ñåêöèè .kpnc
#pragma data_seg(.kpnc)
// òî÷êó ïåðåä èìåíåì ñòàâèòü
// íå îáÿçàòåëüíî - ïðîñòî òàê
// ïðèíÿòî
char passwd[]=PASSWORD;
#pragma data_seg()
// Òåïåðü âñå èíèöèàëèçèðîâàííûå ïåðåìåííûå âíîâü áóäóò
// ðàçìåùàòüñÿ â ñåêöèè ïî óìîë÷àíèþ, ò.å. .data
char buff[PASSWORD_SIZE]="";
...
if (strcmp(&buff[0],&passwd[0]))
> dumpbin /RAWDATA:BYTES /SECTION:.data simple2.exe >filename
RAW DATA #3
00406000: 00
00406010: 04
00406020: 00
00406030: 45
00406040: 57
00406050: 50
00406060: 20
00406070: 00

00
41
00
6E
72
61
6E
00

00
40
00
74
6F
73
40
00

00
00
00
65
6E
73
00
00

00
00
00
72
67
77
00
00

00
00
00
20
20
6F
00
00

00
00
00
70
70
72
00
00

00
00
00
61
61
64
00
00

00
00
00
73
73
20
20
00

00
00
00
73
73
4F
6E
10

00
00
00
77
77
4B
40
00

00
00
00
6F
6F
0A
00
00

9B
40
00
72
72
00
01
00

11
12
00
64
64
00
01
00

40
40
00
3A
0A
00
00
00

00
00
00
00
00
00
00
00

............Û.@.
.A@.........@.@.
................
Enter password:.
Wrong password..
Password OK.....
n@..... n@.....
................

Àãà, òåïåðü â ñåêöèè äàííûõ ïàðîëÿ íåò è õàêåðû «îòäûõàþò»! Íî íå ñïåøèòå
ñ âûâîäàìè. Äàâàéòå ñíà÷àëà âûâåäåì íà ýêðàí ñïèñîê âñåõ ñåêöèé, èìåþùèõñÿ â
ôàéëå:
> dumpbin simple2.exe
Summary
2000 .data
1000 .kpnc
^^^^
1000 .rdata
4000 .text

Íåñòàíäàðòíàÿ ñåêöèÿ .kpnc ñðàçó æå ïðèêîâûâàåò ê ñåáå âíèìàíèå. À íó-êà
ïîñìîòðèì, ÷òî òàì â íåé?
dumpbin /SECTION:.kpnc /RAWDATA simple2.exe
RAW DATA #4
00408000: 6D 79 47 4F 4F 44 70 61 73 73 77 6F 72 64 0A 00 myGOODpassword..
^^^^^^^^^^^^^^

Âîò îí, ïàðîëü! Ñïðÿòàëè, íàçûâàåòñÿ... Ìîæíî, êîíå÷íî, èçâðàòèòüñÿ è çàñóíóòü ñåêðåòíûå äàííûå â ñåêöèþ íåèíèöèàëèçèðîâàííûõ äàííûõ (.bss), ñëóæåáíóþ RTL-ñåêöèþ (.rdata) èëè äàæå ñåêöèþ êîäà (.text) — íå âñå òàì äîãàäàþòñÿ
ïîèñêàòü, à ðàáîòîñïîñîáíîñòü ïðîãðàììû òàêîå ðàçìåùåíèå íå íàðóøèò. Íî íå

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

21

ñòîèò çàáûâàòü î âîçìîæíîñòè àâòîìàòèçèðîâàííîãî ïîèñêà òåêñòîâûõ ñòðîê â
äâîè÷íîì ôàéëå.  êàêîé áû ñåêöèè íè ñîäåðæàëñÿ ýòàëîííûé ïàðîëü, ôèëüòð áåç
òðóäà åãî íàéäåò (åäèíñòâåííàÿ ïðîáëåìà — îïðåäåëèòü, êàêàÿ èç ìíîæåñòâà òåêñòîâûõ ñòðîê ïðåäñòàâëÿåò ñîáîé èñêîìûé êëþ÷; âîçìîæíî, ïîòðåáóåòñÿ ïåðåáðàòü ñ äåñÿòîê-äðóãîé ïîòåíöèàëüíûõ «êàíäèäàòîâ»).
Ïðàâäà, åñëè ïàðîëü çàïèñàí â óíèêîäå, åãî ïîèñê íåñêîëüêî îñëîæíÿåòñÿ,
òàê êàê íå âñå óòèëèòû ïîääåðæèâàþò ýòó êîäèðîâêó, íî íàäåÿòüñÿ, ÷òî ýòî ïðåïÿòñòâèå íàäîëãî çàäåðæèò õàêåðà, íåñêîëüêî íàèâíî.

Øàã âòîðîé.
Çíàêîìñòâî ñ äèçàññåìáëåðîì
Íàäî ëè ìèëîñòèâîãî Áîãà âñå âðåìÿ ïðîñèòü î ïîùàäå?
Âåëèìèð

Î'êåé, ïàðîëü ìû óçíàëè. Íî êàê æå óòîìèòåëüíî ââîäèòü åãî êàæäûé ðàç ñ
êëàâèàòóðû ïåðåä çàïóñêîì ïðîãðàììû! Õîðîøî áû åå õàêíóòü òàê, ÷òîáû íèêàêîé ïàðîëü âîîáùå íå çàïðàøèâàëñÿ èëè ëþáîé ââåäåííûé ïàðîëü ïðîãðàììà âîñïðèíèìàëà áû êàê ïðàâèëüíûé.
Õàêíóòü, ãîâîðèòå?! ×òî æ, ýòî íåñëîæíî! Êóäà ïðîáëåìàòè÷íåå îïðåäåëèòüñÿ, ÷åì èìåííî åå õàêàòü. Èíñòðóìåíòàðèé õàêåðîâ ÷ðåçâû÷àéíî ðàçíîîáðàçåí,
÷åãî òóò òîëüêî íåò: è äèçàññåìáëåðû, è îòëàä÷èêè, è API-, è message-øïèîíû, è
ìîíèòîðû îáðàùåíèé ê ôàéëàì (ïîðòàì, ðååñòðó), è ðàñïàêîâùèêè èñïîëíÿåìûõ
ôàéëîâ, è... Ñëîæíîâàòî íà÷èíàþùåìó êîäîêîïàòåëþ ñî âñåì ýòèì õîçÿéñòâîì
ðàçîáðàòüñÿ!
Âïðî÷åì, øïèîíû, ìîíèòîðû, ðàñïàêîâùèêè — âòîðîñòåïåííûå óòèëèòû çàäíåãî ïëàíà, à îñíîâíîå îðóæèå âçëîìùèêà — îòëàä÷èê è äèçàññåìáëåð. Ðàññìîòðèì èõ ïîáëèæå.
Êàê è ñëåäóåò èç åãî íàçâàíèÿ, äèç-àññåìáëåð ïðåäíàçíà÷åí äëÿ äèç-àññåìáëèðîâàíèÿ èëè «ðàç-àññåìáëèðîâàíèÿ». Åñëè ïåðåéòè ñ ëàòûíè íà ðóññêèé ÄÈÑ...
ÄÈÇ... [ëàò. dis, ãå. dys] — ïðèñòàâêà, îáîçíà÷àþùàÿ ðàçäåëåíèå, îòäåëåíèå, îòðèöàíèå; ñîîòâåòñòâóåò ðóññêèì «ðàç...», «íå...», ñîîáùàåò ïîíÿòèþ, ê êîòîðîìó
ïðèëàãàåòñÿ, îòðèöàòåëüíûé èëè ïðîòèâîïîëîæíûé ñìûñë, íàïðèìåð, äèçàññîöèàöèÿ, äèñãàðìîíèÿ — Ñëîâàðü èíîñòðàííûõ ñëîâ. Òî åñòü åñëè àññåìáëèðîâàíèå — ïåðåâîä àññåìáëåðíûõ êîìàíä â ìàøèííûé êîä, òî äèçàññåìáëèðîâàíèå —
íàïðîòèâ, ïåðåâîä ìàøèííîãî êîäà â àññåìáëåðíûå êîìàíäû.
Íî ïóñòü íàçâàíèå íå ââîäèò âàñ â çàáëóæäåíèå: äèçàññåìáëåð ïðèãîäåí äëÿ
èçó÷åíèÿ íå òîëüêî òåõ ïðîãðàìì, ÷òî áûëè íàïèñàíû íà àññåìáëåðå, êðóã åãî
ïðèìåíåíèÿ î÷åíü øèðîê, õîòÿ è íå áåçãðàíè÷åí. Ñïðàøèâàåòå: ãäå æå ïðîëåãàåò
ýòà ãðàíèöà? Îòâå÷àþ. Ãðóáî ãîâîðÿ, âñå ðåàëèçàöèè ÿçûêîâ ïðîãðàììèðîâàíèÿ
äåëÿòñÿ íà êîìïèëÿòîðû è èíòåðïðåòàòîðû.
Èíòåðïðåòàòîðû âûïîëíÿþò ïðîãðàììó â òîì âèäå, â êàêîì îíà áûëà ñîñòàâëåíà ïðîãðàììèñòîì. Äðóãèìè ñëîâàìè ãîâîðÿ, èíòåðïðåòàòîðû «ïåðåæåâû-

22

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

âàþò» èñõîäíûé òåêñò, ïðè ýòîì êîä ïðîãðàììû äîñòóïåí äëÿ íåïîñðåäñòâåííîãî
èçó÷åíèÿ áåçî âñÿêèõ äîïîëíèòåëüíûõ ñðåäñòâ. Ïðèìåðîì ìîãóò ñëóæèòü ïðèëîæåíèÿ, íàïèñàííûå íà Áàöèêå èëè Ïåðëå. Êàê èçâåñòíî, äëÿ èõ çàïóñêà, ïîìèìî
èñõîäíîãî òåêñòà ïðîãðàììû, òðåáóåòñÿ èìåòü åùå è ñàì èíòåðïðåòàòîð, ÷òî íåóäîáíî íè ïîëüçîâàòåëÿì (äëÿ èñïîëíåíèÿ ïðîãðàììû â 10 êèëîáàéòîâ ïðèõîäèòñÿ
óñòàíàâëèâàòü èíòåðïðåòàòîð â 10 ìåãàáàéòîâ), íè ðàçðàáîò÷èêàì (â çäðàâîì óìå
è òðåçâîé ïàìÿòè ðàçäàâàòü âñåì èñõîäíûå òåêñòû ñâîåé ïðîãðàììû!), ê òîìó æå
ñèíòàêñè÷åñêèé ðàçáîð îòíèìàåò ìíîãî âðåìåíè è íè îäèí èíòåðïðåòàòîð íå ìîæåò ïîõâàñòàòüñÿ ïðîèçâîäèòåëüíîñòüþ.
Êîìïèëÿòîðû âåäóò ñåáÿ èíà÷å — ïðè ïåðâîì çàïóñêå îíè «ïåðåìàëûâàþò» ïðîãðàììó â ìàøèííûé êîä, èñïîëíÿåìûé íåïîñðåäñòâåííî ñàìèì ïðîöåññîðîì áåç îáðàùåíèé ê èñõîäíûì òåêñòàì èëè ñàìîìó êîìïèëÿòîðó. Ñ ÷åëîâå÷åñêîé òî÷êè çðåíèÿ, îòêîìïèëèðîâàííàÿ ïðîãðàììà ïðåäñòàâëÿåò áåññìûñëåííóþ
ìåøàíèíó øåñòíàäöàòåðè÷íûõ áàéòîâ, ðàçîáðàòüñÿ â êîòîðîé íåñïåöèàëèñòó àáñîëþòíî íåâîçìîæíî. Ýòî îáëåã÷àåò ðàçðàáîòêó çàùèòíûõ ìåõàíèçìîâ — íå
çíàÿ àëãîðèòìà, âñëåïóþ çàùèòó íå ñëîìàåøü, íó ðàçâå ÷òî îíà áóäåò ñîâñåì
ïðîñòîé.
Ìîæíî ëè èç ìàøèííîãî êîäà ïîëó÷èòü èñõîäíûé òåêñò ïðîãðàììû? Íåò!
Êîìïèëÿöèÿ — ïðîöåññ îäíîíàïðàâëåííûé. È äåëî òóò íå òîëüêî â òîì, ÷òî áåçâîçâðàòíî óäàëÿþòñÿ ìåòêè è êîììåíòàðèè (ðððàçáåðåìñÿ è áåç êîììåíòàðèåâ —
õàêåðû ìû èëè íåò?!), îñíîâíîé êàìåíü ïðåòêíîâåíèÿ — íåîäíîçíà÷íîñòü ñîîòâåòñòâèÿ ìàøèííûõ èíñòðóêöèé êîíñòðóêöèÿì ÿçûêîâ âûñîêîãî óðîâíÿ. Áîëåå òîãî, àññåìáëèðîâàíèå òàêæå ÿâëÿåò ñîáîé îäíîíàïðàâëåííûé ïðîöåññ è àâòîìàòè÷åñêîå äèçàññåìáëèðîâàíèå ïðèíöèïèàëüíî íåâîçìîæíî. Âïðî÷åì, íå áóäåì
ñåé÷àñ çàáèâàòü ãîëîâó íà÷èíàþùèõ êîäîêîïàòåëåé òàêèìè òîíêîñòÿìè è îñòàâèì
ýòó ïðîáëåìó íà ïîòîì.
Ðÿä ñèñòåì ðàçðàáîòêè çàíèìàåò ïðîìåæóòî÷íîå ïîëîæåíèå ìåæäó êîìïèëÿòîðàìè è èíòåðïðåòàòîðàìè — èñõîäíàÿ ïðîãðàììà ïðåîáðàçóåòñÿ íå â ìàøèííûé êîä, à â íåêîòîðûé äðóãîé èíòåðïðåòèðóåìûé ÿçûê, äëÿ èñïîëíåíèÿ êîòîðîãî
ê îòêîìïèëèðîâàííîìó ôàéëó äîïèñûâàåòñÿ ñîáñòâåííûé èíòåðïðåòàòîð. Èìåííî
ïî òàêîé ñõåìå ôóíêöèîíèðóþò FoxPro, Clipper, ìíîãî÷èñëåííûå äèàëåêòû Áàöèêà è íåêîòîðûå äðóãèå ÿçûêè.
Äà, êîä ïðîãðàììû ïî-ïðåæíåìó èñïîëíÿåòñÿ â ðåæèìå èíòåðïðåòàöèè, íî òåïåðü èç íåãî óäàëåíà âñÿ èçáûòî÷íàÿ èíôîðìàöèÿ — ìåòêè, èìåíà ïåðåìåííûõ,
êîììåíòàðèè, à îñìûñëåííûå íàçâàíèÿ îïåðàòîðîâ çàìåíåíû èõ öèôðîâûìè êîäàìè. Ýòîò âûñòðåë óêëàäûâàåò ñðàçó äâóõ çàéöåâ: à) ÿçûê, íà êîòîðûé ïåðåâåäåíà
ïðîãðàììà, çàðàíåå «çàòî÷åí» ïîä áûñòðóþ èíòåðïðåòàöèþ è îïòèìèçèðîâàí ïî
ðàçìåðó; á) êîä ïðîãðàììû òåïåðü íåäîñòóïåí äëÿ íåïîñðåäñòâåííîãî èçó÷åíèÿ
(è/èëè ìîäèôèêàöèè).
Äèçàññåìáëèðîâàíèå òàêèõ ïðîãðàìì íåâîçìîæíî — äèçàññåìáëåð íàöåëåí
èìåííî íà ìàøèííûé êîä, à íåèçâåñòíûé åìó èíòåðïðåòèðóåìûé ÿçûê (òàêæå íàçûâàåìûé π-êîäîì) îí «íå ïåðåâàðèâàåò». Ðàçóìååòñÿ, π-êîä íå ïåðåâàðèâàåò è
ïðîöåññîð! Åãî èñïîëíÿåò èíòåðïðåòàòîð, äîïèñàííûé ê ïðîãðàììå. Âîò èíòåðïðåòàòîð-òî äèçàññåìáëåð è áåðåò! Èçó÷àÿ àëãîðèòì åãî ðàáîòû, ìîæíî ïîíÿòü

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

23

«óñòðîéñòâî» π-êîäà è âûÿñíèòü íàçíà÷åíèå âñåõ åãî êîìàíä. Ýòî î÷åíü òðóäîåìêèé ïðîöåññ! Èíòåðïðåòàòîðû ïîðîé òàê ñëîæíû è çàíèìàþò òàê ìíîãî ìåãàáàéòîâ, ÷òî èõ àíàëèç ðàñòÿãèâàåòñÿ íà ìíîãèå ìåñÿöû, à òî è ãîäû. Ê ñ÷àñòüþ, íåò
íóæäû àíàëèçèðîâàòü êàæäóþ ïðîãðàììó — âåäü èíòåðïðåòàòîðû îäíîé âåðñèè
èäåíòè÷íû, à ñàì π-êîä îáû÷íî ìàëî ìåíÿåòñÿ îò âåðñèè ê âåðñèè, âî âñÿêîì ñëó÷àå, åãî ÿäðî íå ïåðåïèñûâàåòñÿ êàæäûé äåíü. Ïîýòîìó âïîëíå âîçìîæíî ñîçäàòü
ïðîãðàììó, çàíèìàþùóþñÿ ïåðåâîäîì π-êîäà îáðàòíî â èñõîäíûé ÿçûê. Êîíå÷íî,
ñèìâîëüíûå èìåíà âîññòàíîâèòü íå óäàñòñÿ, íî â îñòàëüíîì ëèñòèíã áóäåò âûãëÿäåòü âïîëíå ÷èòàáåëüíî.
Èòàê, äèçàññåìáëåð ïðèìåíèì äëÿ èññëåäîâàíèÿ îòêîìïèëèðîâàííûõ ïðîãðàìì è ÷àñòè÷íî ïðèãîäåí äëÿ àíàëèçà ïñåâäîêîìïèëèðîâàííîãî êîäà. Ðàç òàê,
îí äîëæåí ïîäîéòè äëÿ âñêðûòèÿ ïàðîëüíîé çàùèòû simple.exe. Âåñü âîïðîñ â
òîì, êàêîé äèçàññåìáëåð âûáðàòü.
Íå âñå äèçàññåìáëåðû îäèíàêîâû. Åñòü ñðåäè íèõ è «èíòåëëåêòóàëû», àâòîìàòè÷åñêè ðàñïîçíàþùèå ìíîãèå êîíñòðóêöèè, êàê òî: ïðîëîãè è ýïèëîãè ôóíêöèé,
ëîêàëüíûå ïåðåìåííûå, ïåðåêðåñòíûå ññûëêè è ò. ä., — à åñòü è «ïðîñòàêè», ÷üè
ñïîñîáíîñòè îãðàíè÷åíû îäíèì ëèøü ïåðåâîäîì ìàøèííûõ êîìàíä â àññåìáëåðíûå èíñòðóêöèè.
Ëîãè÷íåå âñåãî âîñïîëüçîâàòüñÿ óñëóãàìè äèçàññåìáëåðà-èíòåëëåêòóàëà
(åñëè îí åñòü), íî... äàâàéòå íå áóäåì ñïåøèòü, à ïîïðîáóåì âûïîëíèòü âåñü àíàëèç âðó÷íóþ. Òåõíèêà, ïîíÿòíîå äåëî, øòóêà õîðîøàÿ, äà âîò íå âñåãäà îíà îêàçûâàåòñÿ ïîä ðóêîé è íåïëîõî áû çàðàíåå íàó÷èòüñÿ ðàáîòå â ïîëåâûõ óñëîâèÿõ.
Ê òîìó æå îáùåíèå ñ ïëîõèì äèçàññåìáëåðîì êàê íåëüçÿ ëó÷øå ïîä÷åðêèâàåò
«âêóñíîñòè» õîðîøåãî.
Âîñïîëüçóåìñÿ óæå çíàêîìîé íàì óòèëèòîé DUMPBIN, íàñòîÿùèì «øâåéöàðñêèì íîæèêîì» ñî ìíîæåñòâîì ïîëåçíûõ ôóíêöèé, ñðåäè êîòîðûõ ïðèòàèëñÿ è
äèçàññåìáëåð. Äèçàññåìáëèðóåì ñåêöèþ êîäà (êàê ìû ïîìíèì, íîñÿùóþ èìÿ
.text), ïåðåíàïðàâèâ âûâîä â ôàéë, òàê êàê íà ýêðàí îí, î÷åâèäíî, íå ïîìåñòèòñÿ:
> dumpbin /SECTION:.text /DISASM simple.exe >.code

Èòàê, ìåíåå ÷åì ÷åðåç ñåêóíäó îáðàçîâàëñÿ ôàéë .code ðàçìåðîì... ðàçìåðîì
â öåëûõ òðèñòà ñ ÷åòâåðòüþ êèëîáàéòîâ. Äà, èñõîäíàÿ ïðîãðàììà áûëà íà äâà ïîðÿäêà êîðî÷å! Ýòî æå ñêîëüêî âðåìåíè ïîòðåáóåòñÿ, ÷òîáû ñî âñåé ýòîé øàìàíñêîé ãðàìîòîé ðàçîáðàòüñÿ?! Ñàìîå îáèäíîå — ïîäàâëÿþùàÿ ìàññà êîäà íèêàêîãî
îòíîøåíèÿ ê çàùèòíîìó ìåõàíèçìó íå èìååò è ïðåäñòàâëÿåò ñîáîé ôóíêöèè ñòàíäàðòíûõ áèáëèîòåê êîìïèëÿòîðà, àíàëèçèðîâàòü êîòîðûå íàì íè ê ÷åìó. Íî êàê
æå èõ îòëè÷èòü îò «ïîëåçíîãî» êîäà?
Äàâàéòå ïîäóìàåì. Ìû íå çíàåì, ãäå èìåííî ðàñïîëîæåíà ïðîöåäóðà ñðàâíåíèÿ ïàðîëåé, è íàì íåèçâåñòíî åå óñòðîéñòâî, íî ìîæíî ñ óâåðåííîñòüþ óòâåðæäàòü, ÷òî îäèí èç åå àðãóìåíòîâ — óêàçàòåëü íà ýòàëîííûé ïàðîëü. Îñòàåòñÿ
òîëüêî âûÿñíèòü, ïî êàêîìó àäðåñó ðàñïîëîæåí ýòîò ïàðîëü â ïàìÿòè, — îí-òî è
áóäåò èñêîìûì çíà÷åíèåì óêàçàòåëÿ.
Çàãëÿíåì åùå ðàç â ñåêöèþ äàííûõ (èëè â äðóãóþ — â çàâèñèìîñòè îò òîãî,
ãäå õðàíèòñÿ ïàðîëü):

24

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

> dumpbin /SECTION:.data /RAWDATA simple.exe >.data
RAW DATA #3
00406000: 00
00406010: E4
00406020: 00
00406030: 45
00406040: 6D
^^^^^^^^^
00406050: 57
00406060: 50

00
40
00
6E
79

00
40
00
74
47

00
00
00
65
4F

00
00
00
72
4F

00
00
00
20
44

00
00
00
70
70

00
00
00
61
61

00
00
00
73
73

00
00
00
73
73

00
00
00
77
77

00
00
00
6F
6F

7B
20
00
72
72

11
12
00
64
64

40
40
00
3A
0A

00
00
00
00
00

............{.@.
ô@@......... .@.
................
Enter password:.
myGOODpassword..
^^^^^^^^^^^^^^^
72 6F 6E 67 20 70 61 73 73 77 6F 72 64 0A 00 Wrong password..
61 73 73 77 6F 72 64 20 4F 4B 0A 00 00 00 00 Password OK.....

Àãà, ïàðîëü ðàñïîëîæåí ïî ñìåùåíèþ 0x406040 (ëåâàÿ êîëîíêà ÷èñåë), ñòàëî
áûòü, è óêàçàòåëü íà íåãî ðàâåí 0x406040. Ïîïðîáóåì íàéòè ýòî ÷èñëî â äèçàññåìáëèðîâàííîì ëèñòèíãå òðèâèàëüíûì êîíòåêñòíûì ïîèñêîì â ëþáîì òåêñòîâîì ðåäàêòîðå.
Íàøëè? Âîò îíî (â òåêñòå âûäåëåíî æèðíûì øðèôòîì):
00401045:
0040104A:
0040104D:
0040104E:
00401053:
00401056:
00401058:

68
8D
52
E8
83
85
74

40 60 40 00
55 98
4D 00 00 00
C4 08
C0
0F

push
lea
push
call
add
test
je

406040h
edx,[ebp-68h]
edx
004010A0
esp,8
eax,eax
00401069

Ýòî îäèí èç äâóõ àðãóìåíòîâ ôóíêöèè 0õ04010A0, çàíîñèìûõ â ñòåê ìàøèííîé
êîìàíäîé push. Âòîðîé àðãóìåíò — óêàçàòåëü íà ëîêàëüíûé áóôåð, âåðîÿòíî ñîäåðæàùèé ââåäåííûé ïîëüçîâàòåëåì ïàðîëü.
Òóò íàì ïðèäåòñÿ íåìíîãî îòêëîíèòüñÿ îò òåìû ðàçãîâîðà è ïîäðîáíî ðàññìîòðåòü ïåðåäà÷ó ïàðàìåòðîâ. Íàèáîëåå ðàñïðîñòðàíåííû ñëåäóþùèå ñïîñîáû
ïåðåäà÷è àðãóìåíòîâ ôóíêöèè — ÷åðåç ðåãèñòðû è ÷åðåç ñòåê.
Ïåðåäà÷à ïàðàìåòðîâ ÷åðåç ðåãèñòðû íàèáîëåå áûñòðà, íî íå ëèøåíà íåäîñòàòêîâ, — âî-ïåðâûõ, êîëè÷åñòâî ðåãèñòðîâ âåñüìà îãðàíè÷åííî, à âî-âòîðûõ,
ýòî çàòðóäíÿåò ðåàëèçàöèþ ðåêóðñèè — âûçîâà ôóíêöèè èç ñàìîé ñåáÿ. Ïðåæäå
÷åì çàíîñèòü â ðåãèñòðû íîâûå àðãóìåíòû, íåîáõîäèìî ïðåäâàðèòåëüíî ñîõðàíèòü
ñòàðûå â îïåðàòèâíîé ïàìÿòè. À ðàç òàê, íå ïðîùå ëè ñðàçó ïåðåäàòü àðãóìåíòû
÷åðåç îïåðàòèâíóþ ïàìÿòü, íå ìó÷àÿñü ñ ðåãèñòðàìè?
Ïîäàâëÿþùåå áîëüøèíñòâî êîìïèëÿòîðîâ ïåðåäàåò àðãóìåíòû ÷åðåç ñòåê.
Åäèíîãî ìíåíèÿ ïî âîïðîñàì ïåðåäà÷è ó ðàçðàáîò÷èêîâ êîìïèëÿòîðîâ íåò, ïîýòîìó âñòðå÷àåòñÿ ïî êðàéíåé ìåðå äâà ðàçëè÷íûõ ìåõàíèçìà, èìåíóåìûå ñîãëàøåíèÿìè Ñè è Ïàñêàëü.
Ñè-ñîãëàøåíèå ïðåäïèñûâàåò çàòàëêèâàòü â ñòåê àðãóìåíòû ñïðàâà íàëåâî,
ò. å. ñàìûé ïåðâûé àðãóìåíò ôóíêöèè çàíîñèòñÿ â ñòåê ïîñëåäíèì è îêàçûâàåòñÿ
íà åãî âåðõóøêå. Óäàëåíèå àðãóìåíòîâ èç ñòåêà âîçëîæåíî íå íà ñàìó ôóíêöèþ, à
íà âûçûâàåìûé åþ êîä. Ýòî äîâîëüíî ðàñòî÷èòåëüíîå ðåøåíèå, òàê êàê êàæäûé
âûçîâ ôóíêöèè óòÿæåëÿåò ïðîãðàììó íà íåñêîëüêî áàéòîâ êîäà, íî çàòî ýòî ïîçâîëÿåò ñîçäàâàòü ôóíêöèè ñ ïåðåìåííûì ÷èñëîì àðãóìåíòîâ — âåäü óäàëÿåò-òî
èõ èç ñòåêà íå ñàìà ôóíêöèÿ, à âûçûâàþùèé åå êîä, êîòîðûé íàâåðíÿêà çíàåò òî÷íîå êîëè÷åñòâî ïåðåäàííûõ àðãóìåíòîâ.

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

25

Î÷èñòêà ñòåêà îáû÷íî âûïîëíÿåòñÿ êîìàíäîé ADD ESP,xxx, ãäå xxx êîëè÷åñòâî
óäàëÿåìûõ áàéòîâ. Ïîñêîëüêó, â 32-ðàçðÿäíîì ðåæèìå êàæäûé àðãóìåíò, êàê
ïðàâèëî, çàíèìàåò ÷åòûðå áàéòà, êîëè÷åñòâî àðãóìåíòîâ ôóíêöèè âû÷èñëÿåòñÿ
xxx
. Îïòèìèçèðóþùèå êîìïèëÿòîðû ìîãóò èñïîëüçîâàòü áîëåå
òàê: n _ args =
4
õèòðûé êîä — äëÿ î÷èñòêè ñòåêà îò íåñêîëüêèõ àðãóìåíòîâ îíè ÷àñòåíüêî èõ «âûòàëêèâàþò» â íåèñïîëüçóåìûå ðåãèñòðû êîìàíäîé POP èëè âîâñå î÷èùàþò ñòåê íå
ñðàçó æå ïîñëå âûõîäà èç ôóíêöèè, à ñîâñåì â äðóãîì ìåñòå — ãäå ýòî óäîáíåå
êîìïèëÿòîðó.
Ïàñêàëü-ñîãëàøåíèå ïðåäïèñûâàåò çàíîñèòü àðãóìåíòû â ñòåê ñëåâà íàïðàâî, ò. å. ñàìûé ïåðâûé àðãóìåíò ôóíêöèè çàíîñèòñÿ â ñòåê â ïåðâóþ î÷åðåäü è
îêàçûâàåòñÿ â åãî «íèçó». Óäàëåíèå àðãóìåíòîâ èç ôóíêöèè âîçëîæåíî íà ñàìó
ôóíêöèþ è îáû÷íî îñóùåñòâëÿåòñÿ êîìàíäîé RET xxx, ò. å. âîçâðàò èç ïîäïðîãðàììû ñî ñíÿòèåì xxx áàéòîâ ñî ñòåêà.
Âîçâðàùàåìîå ôóíêöèåé çíà÷åíèå â îáîèõ ñîãëàøåíèÿõ ïåðåäàåòñÿ ÷åðåç ðåãèñòð EAX (èëè EDX:EAX ïðè âîçâðàùåíèè 64-ðàçðÿäíûõ ïåðåìåííûõ).
Ïîñêîëüêó èññëåäóåìàÿ íàìè ïðîãðàììà íàïèñàíà íà ÿçûêå Ñ è, ñòàëî áûòü, çàíîñèò àðãóìåíòû ñïðàâà íàëåâî, åå èñõîäíûé òåêñò âûãëÿäèò ïðèáëèçèòåëüíî òàê:
*0x4010A0) (ebp-68, "myGOODpassword")

 òîì, ÷òî àðãóìåíòîâ èìåííî äâà, à íå, ñêàæåì, ÷åòûðå èëè äåñÿòü, íàñ óáåæäàåò êîìàíäà ADD ESP,8, ðàñïîëîæåííàÿ âñëåä çà CALL.
0040104E: E8 4D 00 00 00 call 004010A0
00401053: 83 C4 08 add esp,8

Îñòàåòñÿ âûÿñíèòü íàçíà÷åíèå ôóíêöèè 0x4010A0, õîòÿ, åñëè ïîäíàïðÿ÷ü
ñâîþ èíòóèöèþ, òî ýòîãî ìîæíî è íå äåëàòü! È òàê ÿñíî — ýòà ôóíêöèÿ ñðàâíèâàåò ïàðîëü, èíà÷å çà÷åì áû åé åãî ïåðåäàâàëè? Êàê îíà ýòî äåëàåò — âîïðîñ äåñÿòûé, à âîò ÷òî íàñ äåéñòâèòåëüíî èíòåðåñóåò, òàê âîçâðàùåííîå åþ çíà÷åíèå.
Èòàê, îïóñêàåìñÿ íà îäíó ñòðî÷êó íèæå:
0040104E:
00401053:
00401056:
00401058:

E8
83
85
74

4D 00 00 00
C4 08
C0
0F

call
add
test
je

004010A0
esp,8
eax,eax
00401069

×òî ìû âèäèì? Êîìàíäà TEST EAX,EAX ïðîâåðÿåò âîçâðàùåííîå ôóíêöèåé çíà÷åíèå íà ðàâåíñòâî íóëþ, è åñëè îíî äåéñòâèòåëüíî ðàâíî íóëþ, ñëåäóþùàÿ çà
íåé êîìàíäà JE ñîâåðøàåò ïðûæîê íà 0x401096 ñòðîêó.
 ïðîòèâíîì æå ñëó÷àå (ò. å. åñëè EAX !=0)...
0040105A: 68 50 60 40 00

push

406050h

Ïîõîæå åùå íà îäèí óêàçàòåëü, íå ïðàâäà ëè? Ïðîâåðèì ýòî ïðåäïîëîæåíèå,
çàãëÿíóâ â ñåãìåíò äàííûõ:
00406050: 57 72 6F 6E 67 20 70 61 73 73 77 6F 72 64 0A 00 Wrong password..

26

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Óæå òåïëåå! Óêàçàòåëü âûâåë íàñ íà ñòðîêó Wrong password, î÷åâèäíî, âûâîäèìóþ ñëåäóþùåé ôóíêöèåé íà ýêðàí. Çíà÷èò, íåíóëåâîå çíà÷åíèå EAX ñâèäåòåëüñòâóåò î ëîæíîì ïàðîëå, à íîëü — îá èñòèííîì.
Î'êåé, òîãäà ïåðåõîäèì ê àíàëèçó âàëèäíîé âåòâè ïðîãðàììû...
0040105F:
00401064:
00401067:
00401069:
...
00401081:
00401086:

E8
83
EB
EB

D0 01 00 00
C4 04
02
16

call
add
jmp
jmp

00401234
esp,4
0040106B
00401081

68 60 60 40 00
E8 A9 01 00 00

push
call

406060h
00401234

Òàê, åùå îäèí óêàçàòåëü. Ñ ôóíêöèåé 0x401234 ìû óæå âñòðå÷àëèñü âûøå — îíà
(ïðåäïîëîæèòåëüíî) ñëóæèò äëÿ âûâîäà ñòðîê íà ýêðàí. Íó à ñàìè ñòðîêè ìîæíî
îòûñêàòü â ñåãìåíòå äàííûõ. Íà ýòîò ðàç òàì ïðèòàèëîñü Password OK.
Îïåðàòèâíûå ñîîáðàæåíèÿ ñëåäóþùèå: åñëè çàìåíèòü êîìàíäó JE íà JNE, òî
ïðîãðàììà îòâåðãíåò èñòèííûé ïàðîëü êàê íåïðàâèëüíûé, à ëþáîé íåïðàâèëüíûé
ïàðîëü âîñïðèìåò êàê èñòèííûé. À åñëè çàìåíèòü TEST EAX,EAX íà XOR
EAX,EAX, òî ïîñëå èñïîëíåíèÿ ýòîé êîìàíäû ðåãèñòð EAX áóäåò âñåãäà ðàâåí
íóëþ, êàêîé áû ïàðîëü íè ââîäèëñÿ.
Äåëî çà ìàëûì — íàéòè ýòè ñàìûå áàéòèêè â èñïîëíÿåìîì ôàéëå è ìàëîñòü
ïîäïðàâèòü èõ.

Øàã òðåòèé. Õèðóðãè÷åñêèé
Íå òîðîïèòåñü íà âñòðå÷ó ñ Áîãîì, åùå âñòðåòèòåñü.
Íàðîäíàÿ ìóäðîñòü

Âíåñåíèå èçìåíåíèé íåïîñðåäñòâåííî â èñïîëíÿåìûé ôàéë — äåëî ñåðüåçíîå. Ñòèñíóòûì óæå ñóùåñòâóþùèì êîäîì, íàì ïðèõîäèòñÿ äîâîëüñòâîâàòüñÿ
òîëüêî òåì, ÷òî åñòü, è íè ðàçäâèíóòü êîìàíäû, íè äàæå ñäâèíóòü èõ, âûêèíóâ èç
çàùèòû «ëèøíèå çàï÷àñòè», íå ïîëó÷èòñÿ. Âåäü ýòî ïðèâåëî áû ê ñäâèãó ñìåùåíèé âñåõ îñòàëüíûõ êîìàíä, òîãäà êàê çíà÷åíèÿ óêàçàòåëåé è àäðåñîâ ïåðåõîäîâ
îñòàëèñü áû áåç èçìåíåíèé è ñòàëè áû óêàçûâàòü ñîâñåì íå òóäà, êóäà íóæíî!
Íó, ñ «âûêèäûâàíèåì çàï÷àñòåé» ñïðàâèòüñÿ êàê ðàç òàêè ïðîñòî — äîñòàòî÷íî çàáèòü êîä êîìàíäàìè NOP (îïêîä êîòîðûé 0x90, à âîâñå íå 0õ0, êàê ïî÷åìó-òî
äóìàþò ìíîãèå íà÷èíàþùèå êîäîêîïàòåëè), ò. å. ïóñòîé îïåðàöèåé (âîîáùå-òî
NOP — ýòî ïðîñòî äðóãàÿ ôîðìà çàïèñè èíñòðóêöèè XCHG EAX,EAX — åñëè èíòåðåñíî). Ñ «ðàçäâèæêîé» êóäà ñëîæíåå! Ê ñ÷àñòüþ, â PE-ôàéëàõ âñåãäà ïðèñóòñòâóåò
ìíîæåñòâî «äûð», îñòàâøèõñÿ îò âûðàâíèâàíèÿ, â íèõ-òî è ìîæíî ðàçìåñòèòü
ñâîé êîä èëè ñâîè äàííûå.
Íî íå ïðîùå ëè ïðîñòî îòêîìïèëèðîâàòü àññåìáëèðîâàííûé ôàéë, ïðåäâàðèòåëüíî âíåñÿ â íåãî òðåáóåìûå èçìåíåíèÿ? Íåò, íå ïðîùå, è âîò ïî÷åìó: åñëè àññåìáëåð íå ðàñïîçíàåò óêàçàòåëè, ïåðåäàâàåìûå ôóíêöèè (à êàê ìû âèäåëè, íàø

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

27

äèçàññåìáëåð íå ñìîã îòëè÷èòü èõ îò êîíñòàíò), îí ñîîòâåòñòâåííî íå ïîçàáîòèòñÿ äîëæíûì îáðàçîì èõ ñêîððåêòèðîâàòü, è, åñòåñòâåííî, ïðîãðàììà ðàáîòàòü íå
áóäåò.
Ïðèõîäèòñÿ ðåçàòü ïðîãðàììó âæèâóþ. Ëåã÷å âñåãî ýòî äåëàòü ñ ïîìîùüþ
óòèëèòû HIEW, «ïåðåâàðèâàþùåé» PE-ôîðìàò ôàéëîâ è óïðîùàþùåé òåì ñàìûì
ïîèñê íóæíîãî ôðàãìåíòà. Çàïóñòèì åãî, óêàçàâ èìÿ ôàéëà â êîìàíäíîé ñòðîêå
hiew simple.exe, äâîéíûì íàæàòèåì êëàâèøè , ïåðåêëþ÷èìñÿ â ðåæèì
àññåìáëåðà è ïðè ïîìîùè êëàâèøè ïåðåéäåì ê òðåáóåìîìó àäðåñó. Êàê ìû
ïîìíèì, êîìàíäà TEST, ïðîâåðÿþùàÿ ðåçóëüòàò, âîçâðàùåííûé ôóíêöèåé, íà ðàâåíñòâî íóëþ, ðàñïîëàãàëàñü ïî àäðåñó 0x401056.
0040104E:
00401053:
00401056:
^^^^^^^^^
00401058:

E8 4D 00 00 00
83 C4 08
85 C0
74 0F

call
004010A0
add
esp,8
test
eax,eax
^^^^^^^^^^^^^^^^^^^^^
je
00401069

×òîáû HIEW ìîã îòëè÷èòü àäðåñ îò ñìåùåíèÿ â ñàìîì ôàéëå, ïðåäâàðèì åãî
ñèìâîëîì òî÷êè: .401056:
00401056: 85C0
00401058: 740F

test
je

eax,eax
.000401069

———————— (1)

Àãà, êàê ðàç òî, ÷òî íàì íàäî! Íàæìåì êëàâèøó äëÿ ïåðåâîäà HIEW â
ðåæèì ïðàâêè, ïîäâåäåì êóðñîð ê êîìàíäå TEST EAX, EAX è, íàæàâ êëàâèøó
, çàìåíèì åå íà XOR EAX, EAX.
00001056: 33C0
00001058: 740F

xor
je

eax,eax
000001069

Ñ óäîâëåòâîðåíèåì çàìåòèâ, ÷òî íîâàÿ êîìàíäà â àêêóðàò âïèñàëàñü â ïðåäûäóùóþ, íàæìåì êëàâèøó äëÿ ñîõðàíåíèÿ èçìåíåíèé íà äèñêå, à çàòåì âûéäåì
èç HIEW è ïîïðîáóåì çàïóñòèòü ïðîãðàììó, ââîäÿ ïåðâûé ïðèøåäøèé íà óì ïàðîëü:
>simple.exe
Enter password:Ïðèâåò, øëÿïà!
Password OK

Ïîëó÷èëîñü! Çàùèòà ïàëà! Õîðîøî, à êàê áû ìû äåéñòâîâàëè, íå óìåé
HIEW «ïåðåâàðèâàòü» PE-ôàéëû? Òîãäà ïðèøëîñü áû ïðèáåãíóòü ê êîíòåêñòíîìó ïîèñêó. Îáðàòèì ñâîé âçîð íà øåñòíàäöàòåðè÷íûé äàìï, ðàñïîëîæåííûé
äèçàññåìáëåðîì ñëåâà îò àññåìáëåðíûõ êîìàíä. Êîíå÷íî, åñëè ïûòàòüñÿ íàéòè
ïîñëåäîâàòåëüíîñòü 85 C0 — êîä êîìàíäû TEST EAX, EAX, íè÷åãî õîððîøåãî èç
ýòîãî íå âûéäåò, — ýòèõ ñàìûõ TEST'îâ â ïðîãðàììå ìîæåò áûòü íåñêîëüêî ñîòåí, à òî è áîëüøå. Êîìáèíàöèÿ ADD ESP,8\TEST EAX, EAX òàêæå âðÿä ëè áóäåò
óíèêàëüíà, ïîñêîëüêó âñòðå÷àåòñÿ âî ìíîãèõ òèïîâûõ êîíñòðóêöèÿõ ÿçûêà Ñ:
if (func(arg1,arg2))..., if (!func(arg1,arg2))..., while(func(arg1,arg2) è ò. ä.
À âîò àäðåñ ïåðåõîäà, ñêîðåå âñåãî, âî âñåõ âåòêàõ ïðîãðàììû ðàçëè÷åí è ïîäñòðîêà ADD ESP,8/TEST EAX,EAX/JE 00401069 èìååò õîðîøèå øàíñû íà óíèêàëüíîñòü. Ïîïðîáóåì íàéòè â ôàéëå ñîîòâåòñòâóþùèé åé êîä: 83 C4 08 85 C0 74 0F
(â HIEW äëÿ ýòîãî äîñòàòî÷íî íàæàòü êëàâèøó ).

28

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Îïï-ñ! Íàéäåíî òîëüêî îäíî âõîæäåíèå, ÷òî íàì, ñîáñòâåííî, è íóæíî. Äàâàéòå òåïåðü ïîïðîáóåì ìîäèôèöèðîâàòü ôàéë íåïîñðåäñòâåííî â hex-ðåæèìå, íå
ïåðåõîäÿ â àññåìáëåð. Ïîïóòíî âîçüìåì ñåáå íà çàìåòêó — èíâåðñèÿ ìëàäøåãî
áèòà êîäà êîìàíäû ïðèâîäèò ê èçìåíåíèþ óñëîâèÿ ïåðåõîäà íà ïðîòèâîïîëîæíîå,
ò. å. 74 JE → 75 JNE.
Ðàáîòàåò? ( ñìûñëå çàùèòà ñâèõíóëàñü îêîí÷àòåëüíî — íå ïðèçíàåò èñòèííûå ïàðîëè, çàòî ðàäîñòíî ïðèâåòñòâóåò îñòàëüíûå.) Çàìå÷àòåëüíî! Îñòàåòñÿ ðåøèòü, êàê ýòó âçëîìàííóþ ïðîãðàììó ðàñïðîñòðàíÿòü. Òî åñòü ðàñïðîñòðàíèòü-òî
åå äåëî íåõèòðîå — íà òî è ñóùåñòâóþò CDR-ïèñöû, BBS, ñåòü Èíòåðíåò, íàêîíåö!
Çàëèâàé, ïèøè, íàðåçàé — íå õî÷ó. Íå õîòèòå — è ïðàâèëüíî! Íåçàêîííîå ýòî
äåëî — ðàñïðîñòðàíÿòü ïðîãðàììíîå îáåñïå÷åíèå â îáõîä åãî âëàäåëüöà. Ýäàê è
çàñàäèòü ìîãóò (ïðè÷åì ïðåöåäåíòû óæå èìåþòñÿ). Êóäà áåçîïàñíåå âîçëîæèòü
ðàñïðîñòðàíåíèå ïðîãðàììû íà åå äèñòðèáüþòîðîâ, íî äî êàæäîãî ïîëüçîâàòåëÿ
äîíåñòè, êàê ýòó ïðîãðàììó âçëîìàòü. Êîâûðÿòüñÿ â çàêîííûì îáðàçîì ïðèîáðåòåííîì ïðèëîæåíèè ïîòðåáèòåëü âïðàâå, à ðàñïðîñòðàíåíèå èíôîðìàöèè î âçëîìå
íå çàïðåùåíî â ñèëó çàêîíà î ñâîáîäå èíôîðìàöèè. Ïðàâäà, ïðè áëèæàéøåì ðàññìîòðåíèè âûÿñíÿåòñÿ, ÷òî ýòîò çàêîí è ó íàñ, è çà îêåàíîì äåéñòâóåò ëèøü ôîðìàëüíî, è åñëè íå ïîñàäèòü, òî ïî êðàéíåé ìåðå ïîïûòàòüñÿ ýòî ñäåëàòü, ïðàâîîõðàíèòåëüíûå îðãàíû âïîëíå ìîãóò (è íå òîëüêî ìîãóò, íî è äåëàþò). Êîãäà äåëî êàñàåòñÿ ÷üèõ-òî ôèíàíñîâûõ èíòåðåñîâ, ïðàâîñóäèå àâòîìàòè÷åñêè ñòàíîâèòñÿ íà
èõ çàùèòó. Íàèâíî äóìàòü, ÷òî ñîáëþäåíèå çàêîíà ñàìî ïî ñåáå äàåò íåêèå ãàðàíòèè. Íåò è åùå ðàç íåò! ×óâñòâîâàòü ñåáÿ â îòíîñèòåëüíîé áåçîïàñíîñòè ìîæíî
ëèøü ïðè óñëîâèè ñîáëþäåíèÿ êîäåêñà «äà íå íàâðåäè ñèëüíûì ìèðà ñåãî».
 ëþáîì ñëó÷àå èíôîðìàöèÿ î âçëîìå — ýòî íå ñîâñåì òî æå, ÷òî ñàì âçëîì,
è çà ýòî òðóäíåå ïðèâëå÷ü ê îòâåòñòâåííîñòè. Åäèíñòâåííàÿ ïðîáëåìà — ïîïðîáóé-êà îáúÿñíè ýòèì ïîëüçîâàòåëÿì, êàê ïîëüçîâàòüñÿ hex-ðåäàêòîðîì è èñêàòü â
íåì òàêèå-òî áàéòèêè. Çàïîðþò æå âåäü ôàéë çà ìèëóþ äóøó! Âîò äëÿ ýòîé öåëè è
ñóùåñòâóþò àâòîìàòè÷åñêèå âçëîìùèêè.
Äëÿ íà÷àëà íóæíî óñòàíîâèòü, êàêèå èìåííî áàéòû áûëè èçìåíåíû. Äëÿ ýòîãî íàì âíîâü ïîòðåáóåòñÿ îðèãèíàëüíàÿ êîïèÿ ìîäèôèöèðîâàííîãî ôàéëà, ïðåäóñìîòðèòåëüíî ñîõðàíåííàÿ ïåðåä åãî ïðàâêîé, è êàêîé-íèáóäü «ñðàâíèâàòåëü»
ôàéëîâ. Íàèáîëåå ïîïóëÿðíûìè íà ñåãîäíÿøíèé äåíü ÿâëÿþòñÿ c2u by Professor
Nimnul è MakeCrk by Doctor Stein's labs. Ïåðâûé ãîðàçäî ïðåäïî÷òèòåëüíåå, òàê
êàê îí íå òîëüêî áîëåå òî÷íî ïðèäåðæèâàåòñÿ íàèáîëåå ïîïóëÿðíîãî «ñòàíäàðòà»,
íî è óìååò ãåíåðèðîâàòü ðàñøèðåííûé xck-ôîðìàò. Íà õóäîé êîíåö ìîæíî âîñïîëüçîâàòüñÿ è øòàòíîé óòèëèòîé, âõîäÿùåé â ïîñòàâêó MS-DOS\Windows —
fc.exe (ñîêðàùåíèå îò FileCompare).
Çàïóñòèì ñâîé ëþáèìûé êîìïàðàòîð (ýòî óæ êàêîé êîìó áîëüøå ïî äóøå) è
ïîñìîòðèì íà ðåçóëüòàò åãî ðàáîòû:

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

29

> type simple.dif
Ñðàâíåíèå ôàéëîâ simple.exe è SIMPLE.EX_
00001058: 74 75

Ïåðâàÿ ñëåâà êîëîíêà óêàçûâàåò ñìåùåíèå áàéòà îò íà÷àëà ôàéëà, âòîðàÿ —
ñîäåðæèìîå áàéòà îðèãèíàëüíîãî ôàéëà, à òðåòüÿ — åãî çíà÷åíèå ïîñëå ìîäèôèêàöèè. Òåïåðü ñðàâíèì ýòî ñ îò÷åòîì óòèëèòû c2u:
>c2u simple.exe simple.ex_

Âñå èñïðàâëåíèÿ çàíîñÿòñÿ â ôàéë *.crx, ãäå «*» — èìÿ îðèãèíàëüíîãî ôàéëà.
Ðàññìîòðèì ðåçóëüòàò ñðàâíåíèÿ ïîáëèæå:

Ñîáñòâåííî, ñàì ðåçóëüòàò ñðàâíåíèé íè÷óòü íå èçìåíèëñÿ, ðàçâå ÷òî ê ôàéëó äîáàâèëñÿ òåêñòîâûé çàãîëîâîê, ïîÿñíÿþùèé, ÷òî ýòî çà ñåâåðíûé îëåíü òàêîé. Âñå ïîëÿ íå ñòàíäàðòèçèðîâàíû, è èõ íàáîð ñèëüíî ðàçíèòñÿ îò îäíîãî âçëîìùèêà ê äðóãîìó — ïðè æåëàíèè âû ìîæåòå ñíàáäèòü çàãîëîâîê ñâîèìè ñîáñòâåííûìè ïîëÿìè èëè æå, íàïðîòèâ, âûêèíóòü èç íåãî ÷óæèå. Îäíàêî íå ñòîèò
çëîóïîòðåáëÿòü ýòèì áåç ñåðüåçíîé íåîáõîäèìîñòè, óæ ëó÷øå ïðèäåðæèâàòüñÿ
êàêîãî-òî îäíîãî øàáëîíà.
Èòàê. Description — ïîÿñíåíèå ê âçëîìó, çàïîëíÿåìîå â ìåðó áóéñòâà ôàíòàçèè è óðîâíÿ ðàñïóùåííîñòè.  íàøåì ñëó÷àå îíî ìîæåò âûãëÿäåòü, íàïðèìåð,
òàê: «Òåñòîâûé âçëîì ¹ 1».
Crack subject — ïðåäìåò êðàêà, — ò. å. òî, ÷òî, ñîáñòâåííî ãîâîðÿ, ìû òîëüêî
÷òî ñëîìàëè. Ïèøåì: «Ïàðîëüíàÿ çàùèòà simple.exe».
Used packer — èñïîëüçóåìûé óïàêîâùèê. Åùå âî âðåìåíà ñòàðóøêè MS-DOS
ñóùåñòâîâàëè è áûëè øèðîêî ðàñïðîñòðàíåíû óïàêîâùèêè èñïîëíÿåìûõ ôàéëîâ,
àâòîìàòè÷åñêè ðàçæèìàþùèå ôàéë â ïàìÿòè ïðè åãî çàïóñêå. Ýòèì äîñòèãàëàñü
ýêîíîìèÿ äèñêîâîãî ïðîñòðàíñòâà (ïîìíèòå, êàêèìè ñìåõîòâîðíûìè ïî íûíåøíèì
âðåìåíàì áûëè ðàçìåðû âèí÷åñòåðîâ êîíöà âîñüìèäåñÿòûõ — íà÷àëà äåâÿíî-

30

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

ñòûõ!) è ïàðàëëåëüíî ñ ýòèì óñèëèâàëàñü çàùèòà — âåäü óïàêîâàííûé ôàéë íåäîñòóïåí äëÿ íåïîñðåäñòâåííîãî èçó÷åíèÿ, à òåì áîëåå — ïðàâêè. Ïðåæäå ÷åì íà÷àòü ÷òî-òî äåëàòü, ôàéë íåîáõîäèìî ðàñïàêîâàòü, ïðè÷åì ýòî äåëàòü ïðèõîäèòñÿ è
ñàìîìó ëîìàòåëþ, è âñåì ïîëüçîâàòåëÿì ýòîãî crk-ôàéëà. Ïîñêîëüêó íàø ôàéë íå
áûë óïàêîâàí, îñòàâèì ýòî ïîëå ïóñòûì èëè çàïèøåì â íåãî None.
Used unpacker — ðåêîìåíäóåìûé ðàñïàêîâùèê (åñëè îí íåîáõîäèì). Äåëî â
òîì, ÷òî íå âñå ðàñïàêîâùèêè îäèíàêîâû, ìíîãèå óïàêîâùèêè âåñüìà èñêóøåíû â
òåõíèêå çàùèòû è óìåëî ñîïðîòèâëÿþòñÿ ïîïûòêàì èõ «ñíÿòü». Ïîíÿòíîå äåëî,
ðàñïàêîâùèêè òîæå íå ëûêîì øèòû è äåðæàò ñâîèõ òóçîâ â ðóêàâàõ, íî... àâòîìàòè÷åñêàÿ ðàñïàêîâêà — øòóêà êàïðèçíàÿ. Áûâàåò, «èíòåëëåêòóàëüíûé» unpacker
ëåãêî ðàñïðàâëÿåòñÿ ñî âñåìè «êðóòûìè» packer'àìè, íî òèõî ñäûõàåò íà ïðîñòûõ
çàùèòàõ, è ñîîòâåòñòâåííî ñëó÷àåòñÿ è íàîáîðîò. Äàáû íå ìó÷èòü ïîëüçîâàòåëåé
óòîìèòåëüíûì ïåðåáîðîì âñåõ èìåþùèõñÿ ó íèõ ðàñïàêîâùèêîâ (ïîëüçîâàòåëü —
îí âåäü òîæå ÷åëîâåê!), ïðàâèëà õîðîøåãî òîíà îáÿçûâàþò óêàçûâàòü ïî êðàéíåé
ìåðå îäèí çàâåäîìî ïîäõîäÿùèé unpacker, à ëó÷øå — äâà èëè òðè ñðàçó (âäðóã êàêîãî-òî èç íèõ ó ïîëüçîâàòåëÿ è íå áóäåò). Åñëè æå ðàñïàêîâùèê íå òðåáóåòñÿ —
îñòàâëÿéòå ýòî ïîëå ïóñòûì èëè None.
Comments — êîììåíòàðèè. Âîîáùå-òî ýòî ïîëå çàäóìàíî äëÿ ïåðå÷èñëåíèÿ
äîïîëíèòåëüíûõ äåéñòâèé, êîòîðûå ïîëüçîâàòåëü äîëæåí âûïîëíèòü ïåðåä âçëîìîì, íó, íàïðèìåð, ñíÿòü ñ ôàéëà àòðèáóò «ñèñòåìíûé» èëè, íàïðîòèâ, óñòàíîâèòü åãî. Íî ïîñêîëüêó êàêèå-ëèáî äîïîëíèòåëüíûå äåéñòâèÿ òðåáóþòñÿ òîëüêî â
ýêçîòè÷åñêèõ ñëó÷àÿõ, â ýòî ïîëå îáû÷íî ïîìåùàþò ðàçíîîáðàçíûå ëîçóíãè è
êîììåíòàðèè (äà, ïðàâèëüíî, áûâàåò, ÷òî è íåöåíçóðíóþ áðàíü ïî ïîâîäó óìñòâåííûõ ñïîñîáíîñòåé ðàçðàáîò÷èêà çàùèòû).
Target OS — îïåðàöèîííàÿ ñèñòåìà, äëÿ êîòîðîé ïðåäíàçíà÷åí è (âíèìàíèå!) â êîòîðîé õàêåð òåñòèðîâàë ñëîìàííûé ïðîäóêò. Âîâñå íå ôàêò, ÷òî ïðîãðàììà ñîõðàíèò ïîñëå âçëîìà ÷åðòû ñâîåé ïðåæíåé ñîâìåñòèìîñòè. Òàê, íàïðèìåð, ïîëå êîíòðîëüíîé ñóììû Win 9x âñåãäà èãíîðèðóåò, à Win NT — íåò è, åñëè
åãî íå ñêîððåêòèðîâàòü, ôàéë çàïóñêàòüñÿ íå áóäåò!  íàøåì ñëó÷àå êîíòðîëüíàÿ
ñóììà çàãîëîâêà PE-ôàéëà ðàâíà íóëþ (òàê âåäåò ñåáÿ êîìïèëÿòîð), ÷òî îçíà÷àåò — öåëîñòíîñòü ôàéëà íå ïðîâåðÿåòñÿ è îí ïîñëå õàêà áóäåò óñïåøíî ðàáîòàòü
êàê ïîä Win 9x, òàê è ïîä Win NT.
Protection — ñòåïåíü «êðóòèçíû» çàùèòû, âûðàæàåìîé â ïðîöåíòàõ. 100%,
ïî èäåå, ñîîòâåòñòâóþò ïðåäåëó èíòåëëåêòóàëüíûõ âîçìîæíîñòåé õàêåðà. Íî êòî
æå â ýòîì çàõî÷åò ïðèçíàâàòüñÿ? Íåóäèâèòåëüíî, ÷òî «êðóòèçíó» çàùèòû îáû÷íî
çàíèæàþò, ïîðîé äàæå áîëüøå, ÷åì íà ïîðÿäîê (ñìîòðèòå âñå, âîò ÿ êàêîé êðóòîé
õàêåð, äëÿ ìåíÿ ÷òî óãîäíî âçëîìàòü íå ñëîæíåå, ÷åì êîí÷èê õâîñòà îáìî÷èòü!).
Íå÷åñòíîñòü — íå ïîðîê, íî...
Type of hack — òèï õàêà — ïîëå, ïîëåçíîå ñêîðåå äëÿ äðóãèõ õàêåðîâ, ÷åì
äëÿ ïîëüçîâàòåëåé, íè÷åãî íå ñìûñëÿùèõ â çàùèòàõ è òèïàõ èõ âçëîìà. Âïðî÷åì,
ñ òèïàìè âçëîìîâ íå âñå ãëàäêî è ó ñàìèõ õàêåðîâ — îáùåïðèçíàííûõ êëàññèôèêàöèé íåò. Íàèáîëåå óïîòðåáëÿåìûé òåðìèí bit-hack, êàê è ñëåäóåò èç åãî íàçâà-

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

31

íèÿ, îáîçíà÷àåò âçëîì ïîñðåäñòâîì èçìåíåíèÿ îäíîãî èëè íåñêîëüêèõ áèòîâ â îäíîì èëè íåñêîëüêèõ áàéòàõ. ×àñòíûé ñëó÷àé bit-hack'à — JMP correction (jumping) — ìîäèôèêàöèÿ àäðåñà èëè óñëîâèÿ ïåðåõîäà (òî, ÷òî ìû òîëüêî ÷òî è ïðîäåëàëè). NOPing — ýòî bit-hack ñ çàìåíîé ïðåæíèõ èíñòðóêöèé íà êîìàíäó NOP
èëè âñòàâêó íåçíà÷àùèõ êîìàíä, íàïðèìåð, äëÿ çàòèðàíèÿ äâóõáàéòîâîãî JZ xxx
ìîæíî ïðèìåíèòü ñî÷åòàíèå îäíîáàéòîâûõ INC EAX/DEC EAX.
Language — ÿçûê, à òî÷íåå, êîìïèëÿòîð, íà êîòîðîì íàïèñàíà ïðîãðàììà.
 íàøåì ñëó÷àå — Microsoft Visual C++ (ìû ýòî çíàåì, ïîñêîëüêó òîëüêî ÷òî åå
êîìïèëèðîâàëè), à âîò êàê áûòü ñ ÷óæèìè ïðîãðàììàìè? Ïåðâîå, ÷òî ïðèõîäèò íà
óì, — ïîèñêàòü â ôàéëå êîïèðàéòû — èõ îñòàâëÿþò î÷åíü ìíîãèå êîìïèëÿòîðû, â
òîì ÷èñëå è Visual C++, — ê ïðèìåðó: 000053d9:Microsoft Visual C++ Runtime
Library. Åñëè æå êîìïèëÿòîðîâ íåò, òî ïðîáóåì ïðîãíàòü ôàéë ÷åðåç IDA — îíà
àâòîìàòè÷åñêè ðàñïîçíàåò áîëüøèíñòâî ñòàíäàðòíûõ áèáëèîòåê äàæå ñ óêàçàíèåì êîíêðåòíîé âåðñèè, â êðàéíåì ñëó÷àå ïðîáóåò îïðåäåëèòü ÿçûê ïî ñàìîìó
êîäó, âñïîìèíàÿ î ñîãëàøåíèÿõ Ñè è Ïàñêàëü è ïûòàÿñü íàéòè çíàêîìûå ÷åðòû
èçâåñòíûõ âàì êîìïèëÿòîðîâ (ó êàæäîãî êîìïèëÿòîðà ñâîé «ïî÷åðê», è îïûòíûé
õàêåð ñïîñîáåí óçíàòü íå òîëüêî, ÷åì êîìïèëèðîâàëàñü ïðîãðàììà, íî äàæå è
îïðåäåëèòü êëþ÷è îïòèìèçàöèè).
Size — ðàçìåð ëîìàåìîé ïðîãðàììû, ñëóæàùèé äëÿ êîíòðîëÿ âåðñèè (÷àùå
âñåãî, õîòÿ è íå âñåãäà, êàæäàÿ âåðñèÿ ïðîãðàììû èìååò ñâîé ðàçìåð). Ðàçìåð àâòîìàòè÷åñêè îïðåäåëÿåòñÿ óòèëèòîé c2u, è ñàìîñòîÿòåëüíî âñòàâëÿòü åãî íåò íèêàêîé íóæäû.
Price — ñòîèìîñòü ëèöåíçèîííîé êîïèè ïðîãðàììû (äîëæåí æå ïîëüçîâàòü
çíàòü, ñêîëüêî äåíåã åìó ñýêîíîìèë ýòîò êðàê!).
Used tools — èñïîëüçóåìûå èíñòðóìåíòû. Íåçàïîëíåíèå ýòîãî ïîëÿ ñ÷èòàåòñÿ äóðíûì òîíîì — äåéñòâèòåëüíî æå èíòåðåñíî, ÷åì èìåííî áûëà õàêíóòà ïðîãðàììà! Îñîáåííî ýòèì èíòåðåñóþòñÿ ïîëüçîâàòåëè, íàèâíî ïîëàãàþùèå, ÷òî,
åñëè îíè ðàçäîáóäóò òîò æå DUMPBIN è HIEW, çàùèòà ñàìà ñîáîé ñëîìàåòñÿ.
Time for hack — âðåìÿ, çàòðà÷åííîå íà õàê, âêëþ÷àÿ ïåðåðûâû íà «ïåðåêóðèòü» è «ñõîäèòü âîäè÷êè ïîïèòü». Èíòåðåñíî, êàêîé ïðîöåíò ëþäåé ÷åñòíî çàïîëíÿåò ýòî ïîëå, íå ïûòàÿñü ïîêàçàòüñÿ «êðó÷å» â ÷óæèõ ãëàçàõ? Òàê ÷òî îñîáåííî
äîâåðÿòü åìó íå ñëåäóåò...
Crack made at — äàòà çàâåðøåíèÿ êðàêà. Ïîäñòàâëÿåòñÿ àâòîìàòè÷åñêè, è
ïðàâèòü åå íåò íåîáõîäèìîñòè (ðàçâå ÷òî âû «æàâîðîíîê» è õîòèòå âûäàòü ñåáÿ çà
«ñîâó», ïðîñòàâëÿÿ âðåìÿ îêîí÷àíèÿ âçëîìà 3 ÷àñàìè íî÷è 31 äåêàáðÿ).
Under Music — ìóçûêà, ïðîñëóøèâàåìàÿ âî âðåìÿ õàêà (åùå íå õâàòàåò ïîëÿ
«Èìÿ ëþáèìîãî õîìÿ÷êà»). Âû ñëóøàëè ìóçûêó âî âðåìÿ õàêà? Åñëè äà, òî ïèøèòå — ïóñòü âñå çíàþò âàøè âêóñû (çàîäíî íå çàáóäüòå öâåò ìàéêè è òåìïåðàòóðó
âîçäóõà çà áîðòîì âûøå íóëÿ).
 ðåçóëüòàòå âñåõ ìó÷åíèé ó íàñ äîëæíî ïîëó÷èòüñÿ ïðèáëèçèòåëüíî ñëåäóþùåå:

32

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Òåïåðü íàì ïîòðåáóåòñÿ äðóãàÿ óòèëèòà, öåëü êîòîðîé ïðÿìî ïðîòèâîïîëîæíàÿ: èñïîëüçóÿ crk (xcrk)-ôàéë, èçìåíèòü ýòè ñàìûå áàéòû â îðèãèíàëüíîé ïðîãðàììå. Òàêèõ óòèëèò íà ñåãîäíÿøíèé äåíü î÷åíü ìíîãî, ÷òî íå ëó÷øèì îáðàçîì
ñêàçûâàåòñÿ íà èõ ñîâìåñòèìîñòè ñ ðàçëè÷íûìè crk-ôîðìàòàìè. Ñàìûå èçâåñòíûå
èç íèõ — cra386 by Professor è pcracker by Doctor Stein's labs.
Èç ñîâðåìåííûõ Windows-ðàçðàáîòîê ìîæíî îòìåòèòü Patch maker ñ óñîâåðøåíñòâîâàííûì ïîëüçîâàòåëüñêèì èíòåðôåéñîì (ðèñ. 2). Îí âêëþ÷àåò â ñåáÿ
ñðàâíèâàòåëü ôàéëîâ, crk-ðåäàêòîð, hex-ðåäàêòîð (äëÿ ðó÷íîé çàìåíû?) è êîìïèëÿòîð crk â èñïîëíÿåìûå ôàéëû, ÷òîáû ïîëüçîâàòåëÿì íå ïðèõîäèëîñü ëîìàòü ãîëîâó, ÷òî ýòî çà êðàê òàêîé è êàê èì ëîìàòü.
Ìîæåò áûòü, êîìó-òî òàêîé èíòåðôåéñ è ïîíðàâèòñÿ, à âîò õàêåðû â ñâîåé
ìàññå ìûøü îðãàíè÷åñêè íå ïåðåíîñÿò è ëþáÿò òåêñòîâûå (êîíñîëüíûå) ïðèëîæåíèÿ è «òåòþ Êëàâó».

Ðèñ. 2. Patch Maker çà ðàáîòîé

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

33

Øàã ÷åòâåðòûé.
Çíàêîìñòâî ñ îòëàä÷èêîì
Îñòàâü ñâîè ìîçãè çà äâåðüþ è âíåñè
ñþäà òîëüêî òåëî.
Ô. Òåéëîð

Ïîìèìî äèçàññåìáëèðîâàíèÿ ñóùåñòâóåò è äðóãîé ñïîñîá èññëåäîâàíèÿ ïðîãðàìì — îòëàäêà. Èçíà÷àëüíî ïîä îòëàäêîé ïîíèìàëîñü ïîøàãîâîå èñïîëíåíèå
êîäà, òàêæå íàçûâàåìîå òðàññèðîâêîé. Ñåãîäíÿ æå ïðîãðàììû ðàñïóõëè íàñòîëüêî, ÷òî òðàññèðîâàòü èõ áåññìûñëåííî — âû ìîìåíòàëüíî óòîíåòå â îìóòå
âëîæåííûõ ïðîöåäóð, òàê è íå ïîíÿâ, ÷òî îíè, ñîáñòâåííî, äåëàþò. Îòëàä÷èê íå
ëó÷øåå ñðåäñòâî èçó÷åíèÿ àëãîðèòìà ïðîãðàììû — ñ ýòèì ýôôåêòíåå ñïðàâëÿåòñÿ èíòåðàêòèâíûé äèçàññåìáëåð (íàïðèìåð, IDA).
Ïîäðîáíûé ðàçãîâîð îá óñòðîéñòâå îòëàä÷èêà ìû îòëîæèì íà ïîòîì (ñì. ãëàâó «Ïðèåìû ïðîòèâ îòëàä÷èêîâ»), à çäåñü îãðàíè÷èìñÿ ëèøü ïåðå÷íåì îñíîâíûõ ôóíêöèîíàëüíûõ âîçìîæíîñòåé òèïîâûõ îòëàä÷èêîâ (áåç ýòîãî íåâîçìîæíî
èõ îñìûñëåííîå ïðèìåíåíèå):
• îòñëåæèâàíèå îáðàùåíèé íà çàïèñü/÷òåíèå/èñïîëíåíèå ê çàäàííîé ÿ÷åé-

êå (ðåãèîíó) ïàìÿòè, äàëåå ïî òåêñòó èìåíóåìîå áðÿêîì (áðåéêîì);
• îòñëåæèâàíèå îáðàùåíèé íà çàïèñü/÷òåíèå ê ïîðòàì ââîäà-âûâîäà (óæå







íåàêòóàëüíî äëÿ ñîâðåìåííûõ îïåðàöèîííûõ ñèñòåì, çàïðåùàþùèõ ïîëüçîâàòåëüñêèì ïðèëîæåíèÿì ïðîäåëûâàòü òàêèå òðþêè, — ýòî òåïåðü ïðåðîãàòèâà äðàéâåðîâ, à íà óðîâíå äðàéâåðîâ ðåàëèçîâàíû î÷åíü íåìíîãèå
çàùèòû);
îòñëåæèâàíèå çàãðóçêè DLL è âûçîâà èç íèõ òàêèõ-òî ôóíêöèé, âêëþ÷àÿ ñèñòåìíûå êîìïîíåíòû (êàê ìû óâèäèì äàëåå, ýòî îñíîâíîå îðóæèå ñîâðåìåííîãî âçëîìùèêà);
îòñëåæèâàíèå âûçîâà ïðîãðàììíûõ/àïïàðàòíûõ ïðåðûâàíèé (áîëüøåé ÷àñòüþ óæå íå àêòóàëüíî — íå òàê ìíîãî çàùèò áàëóåòñÿ ñ ïðåðûâàíèÿìè);
îòñëåæèâàíèå ñîîáùåíèé, ïîñûëàåìûõ ïðèëîæåíèåì îêíó;
è, ðàçóìååòñÿ, êîíòåêñòíûé ïîèñê â ïàìÿòè.

Êàê èìåííî ýòî äåëàåò îòëàä÷èê, ïîêà çíàòü íåîáÿçàòåëüíî, äîñòàòî÷íî çíàòü,
÷òî îí ýòî óìååò, è âñå. Êóäà àêòóàëüíåå âîïðîñ: êàêîé îòëàä÷èê óìååò ýòî äåëàòü? Øèðîêî èçâåñòíûé â ïîëüçîâàòåëüñêèõ êðóãàõ Turbo Debugger íà ñàìîì
äåëå î÷åíü ïðèìèòèâíûé è íèê÷åìíûé îòëàä÷èê — î÷åíü ìàëî õàêåðîâ èì ÷òî-òî
ëîìàåò.
Ñàìîå ìîùíîå è óíèâåðñàëüíîå ñðåäñòâî — Soft-Ice, ñåé÷àñ äîñòóïíûé äëÿ
âñåõ Windows-ïëàòôîðì (à êîãäà-òî îí ïîääåðæèâàë ëèøü îäíó Windows 95, íî íå
Windows NT). Ïîñëåäíÿÿ íà ìîìåíò íàïèñàíèÿ êíèãè, ÷åòâåðòàÿ âåðñèÿ, íå
î÷åíü-òî ñòàáèëüíî ðàáîòàåò ñ âèäåîàäàïòåðîì àâòîðà, ïîýòîìó ïðèõîäèòñÿ îãðàíè÷èâàòüñÿ áîëåå ðàííåé, íî çàòî óñòîé÷èâîé âåðñèåé 3.25.

34

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Ñïîñîá 0. Áðÿê íà îðèãèíàëüíûé ïàðîëü
Èñïîëüçóÿ ïîñòàâëÿåìóþ âìåñòå ñ Àéñîì óòèëèòó wldr, çàãðóçèì ëîìàåìûé
íàìè ôàéë, óêàçàâ åãî èìÿ â êîìàíäíîé ñòðîêå, íàïðèìåð, òàê:
>wldr simple.exe

Äà, àâòîð çíàåò, ÷òî wldr — 16-ðàçðÿäíûé çàãðóç÷èê, è NuMega ðåêîìåíäóåò
èñïîëüçîâàòü åãî 32-ðàçðÿäíóþ âåðñèþ loader32, ñïåöèàëüíî ðàçðàáîòàííóþ äëÿ
Win 9x\NT. Ýòî òàê, íî loader32 ÷àñòåíüêî ñáîèò (â ÷àñòíîñòè, íå âñåãäà îñòàíàâëèâàåòñÿ íà ïåðâîé ñòðî÷êå çàïóñêàåìîé ïðîãðàììû), à wldr óñïåøíî ðàáîòàåò è
ñ 32-ðàçðÿäíûìè ïðèëîæåíèÿìè; åäèíñòâåííûé ïðèñóùèé åìó íåäîñòàòîê — îòñóòñòâèå ïîääåðæêè äëèííûõ èìåí ôàéëîâ.
Åñëè îòëàä÷èê íàñòðîåí êîððåêòíî, íà ýêðàíå ïîÿâèòñÿ ÷åðíîå òåêñòîâîå
îêíî, îáû÷íî âûçûâàþùåå áîëüøîå óäèâëåíèå ó íà÷èíàþùèõ, — ýòî â íàøó-òî
ýïîõó âèçóàëüùèíû ñåðûé òåêñò è êîìàíäíûé ÿçûê a la command.com! À ïî÷åìó
áû è íåò? Íàáðàòü íà êëàâèàòóðå íóæíóþ êîìàíäó êóäà áûñòðåå, ÷åì îòûñêàòü åå
â äëèííîé âåðåíèöå âëîæåííûõ ìåíþ, ìó÷èòåëüíî âñïîìèíàÿ, ãäå æå âû åå â ïîñëåäíèé ðàç âèäåëè. Ê òîìó æå ÿçûê — ýòî åñòåñòâåííîå ñðåäñòâî âûðàæåíèÿ
ìûñëåé, à ìåíþ — îíî ãîäèòñÿ ðàçâå ÷òî äëÿ âûáîðà áëþä â ðåñòîðàíå. Âîò õîðîøèé ïðèìåð — ïîïðîáóéòå ñ ïîìîùüþ ïðîâîäíèêà Windows âûâåñòè íà ïå÷àòü
ñïèñîê ôàéëîâ òàêîé-òî äèðåêòîðèè. Íå ïîëó÷àåòñÿ? À â MS-DOS ýòî áûëî òàê
ïðîñòî: dir >PRN, è íèêàêèõ ëàïòåé!
Åñëè â îêíå êîäà âèäíû îäíè ëèøü èíñòðóêöèè INVALID (à îíî òàê è áóäåò), íå
ïóãàéòåñü — ïðîñòî Windows åùå íå óñïåëà ñïðîåöèðîâàòü èñïîëíÿåìûé ôàéë â
ïàìÿòü è âûäåëèòü åìó ñòðàíèöû. Ñòîèò íàæàòü êëàâèøó (àíàëîã êîìàíäû
P — òðàññèðîâêà áåç çàõîäîâ â ôóíêöèþ) èëè êëàâèøó (àíàëîã êîìàíäû
T — òðàññèðîâêà ñ çàõîäàìè â ôóíêöèè), êàê âñå ñðàçó æå ñòàíåò íà ñâîè ìåñòà.
001B:00401277
001B:00401279
001B:0040127B
001B:0040127D
:P

INVALID
INVALID
INVALID
INVALID

001B:00401285
001B:00401286
001B:00401287
001B:00401288
001B:0040128B
001B:00401291
001B:00401293
001B:00401295

PUSH
PUSH
PUSH
MOV
CALL
XOR
MOV
MOV

EBX
ESI
EDI
[EBP-18],ESP
[KERNEL32!GetVersion]
EDX,EDX
DL,AH
[0040692C],EDX

Îáðàòèòå âíèìàíèå: â îòëè÷èå îò äèçàññåìáëåðà DUMPBIN, Àéñ ðàñïîçíàåò
èìåíà ñèñòåìíûõ ôóíêöèé, ÷åì ñóùåñòâåííî óïðîùàåò àíàëèç. Âïðî÷åì, àíàëèçèðîâàòü âñþ ïðîãðàììó öåëèêîì íåò íèêàêîé íóæäû. Äàâàéòå ïîïðîáóåì íàñêîðî íàéòè çàùèòíûé ìåõàíèçì è, íå âíèêàÿ â ïîäðîáíîñòè åãî ôóíêöèîíèðîâàíèÿ,
íàïðî÷ü îòðóáèòü çàùèòó. Ëåãêî ñêàçàòü, íî ñäåëàòü åùå ïðîùå! Âñïîìíèì, ïî êà-

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

35

êîìó àäðåñó ðàñïîëîæåí â ïàìÿòè îðèãèíàëüíûé ïàðîëü. Ý... ÷òî-òî ïëîõî ó íàñ ñ
ýòèì ïîëó÷àåòñÿ — òî ëè ïàìÿòü áèòàÿ, òî ëè ìåäâåäü íà ëàïîòü íàñòóïèë, íî òî÷íûé àäðåñ íèêàê íå õî÷åò âñïîìèíàòüñÿ. Íå õî÷åò — íå íàäî. Íàéäåì-êà ìû åãî
ñàìîñòîÿòåëüíî!
 ýòîì íàì ïîìîæåò êîìàíäà map32, âûäàþùàÿ êàðòó ïàìÿòè âûáðàííîãî ìîäóëÿ (íàø ìîäóëü íàçûâàåòñÿ simple — ïî èìåíè èñïîëíÿåìîãî ôàéëà çà âû÷åòîì
ðàñøèðåíèÿ).
:map32 simple
Owner
Obj Name
simple
.text
simple
.rdata
simple
.data
^^^^

Obj#
0001
0002
0003

Address
001B:00401000
0023:00405000
0023:00406000
^^^^^^^^^^^^^

Size
00003F66
0000081E
00001E44

Type
CODE RO
IDATA RO
IDATA RW

Âîò îí, àäðåñ íà÷àëà ñåêöèè: .data. Òî, ÷òî ïàðîëü íàõîäèòñÿ â ñåêöèè .data,
íàäåþñü, ÷èòàòåëü âñå åùå ïîìíèò. Äàåì êîìàíäó d 23:406000 (âîçìîæíî, ïðåäâàðèòåëüíî ïðèäåòñÿ ñîçäàòü îêíî êîìàíäîé wc — åñëè îêíà äàííûõ íåò) è, íàæàâ
ñî÷åòàíèå êëàâèø äëÿ ïåðåõîäà â ýòî îêíî, ïðîêðóòèì åãî ñîäåðæèìîå
êëàâèøåé èëè êèðïè÷îì íà êëàâèøå . Âïðî÷åì,
êèðïè÷ èçëèøåí, äîëãî èñêàòü íå ïðèäåòñÿ:
0023:00406040
0023:00406050
0023:00406060
0023:00406070
0023:00406080
0023:00406090
0023:004060A0
0023:004060B0

6D
57
50
47
00
00
01
00

79
72
61
6E
00
00
00
00

47
6F
73
40
00
00
00
00

4F
6E
73
00
00
00
00
00

4F
67
77
00
00
00
00
00

44
20
6F
00
00
00
00
00

70
70
72
00
00
00
00
00

61-73
61-73
64-20
00-40
00-00
00-00
00-00
00-00

73
73
4F
6E
10
00
00
00

77
77
4B
40
00
00
00
00

6F
6F
0A
00
00
00
00
00

72
72
00
01
00
02
00
02

64
64
00
01
00
00
00
00

0A
0A
00
00
00
00
00
00

00
00
00
00
00
00
00
00

myGOODpassword..
Wrong password..
Password OK.....
Gn@.....@n@.....
................
................
................
................

Åñòü êîíòàêò! Çàäóìàåìñÿ åùå ðàç (âòîðîé ðàç çà ýòîò äåíü), ÷òîáû ïðîâåðèòü
êîððåêòíîñòü ââåäåííîãî ïîëüçîâàòåëåì ïàðîëÿ, çàùèòà, î÷åâèäíî, äîëæíà ñðàâíèòü åãî ñ îðèãèíàëüíûì. À ðàç òàê, óñòàíîâèâ òî÷êó îñòàíîâà íà ÷òåíèè ïàìÿòè
ïî àäðåñó 0x406040, ìû ïîéìàåì çà õâîñò ñðàâíèâàþùèé ìåõàíèçì. Ñêàçàíî —
ñäåëàíî.
:bpm 406040

Òåïåðü íàæèìàåì ñî÷åòàíèåêëàâèø äëÿ âûõîäà èç îòëàä÷èêà
(èëè îòäàåì êîìàíäó «x») è ââîäèì ëþáîé ïðèøåäøèé íà óì ïàðîëü, íàïðèìåð
KPNC++. Îòëàä÷èê «âñïëûâàåò» íåçàìåäëèòåëüíî:
001B:004010B0
001B:004010B2
001B:004010B4
001B:004010B6
001B:004010B8
001B:004010BA
001B:004010BD
001B:004010BF

MOV
CMP
JNZ
OR
JZ
CMP
JNZ
OR

EAX,[EDX]
AL,[ECX]
004010E4
AL,AL
004010E0
AH,[ECX+01]
004010E4
AH,AH

Break due to BPMB #0023:00406040 RW DR3 (ET=752.27 milliseconds)

(JUMP ↑)

36

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

MSR LastBranchFromIp=0040104E
MSR LastBranchToIp=004010A0

 ñèëó àðõèòåêòóðíûõ îñîáåííîñòåé ïðîöåññîðîâ Intel áðÿê ñðàáàòûâàåò ïîñëå èíñòðóêöèè, âûïîëíèâøåé «ïîïîëçíîâåíèå», ò. å. CS:EIP óêàçûâàþò íà ñëåäóþùóþ âûïîëíÿåìóþ êîìàíäó.  íàøåì ñëó÷àå — JNZ 004010E4, à ê ïàìÿòè, ñòàëî áûòü, îáðàòèëàñü èíñòðóêöèÿ CMP AL, [ECX]. À ÷òî íàõîäèòñÿ â AL? Ïîäíèìàåì âçãëÿä åùå ñòðîêîé âûøå — MOV EAX, [EDX]. Ìîæíî ïðåäïîëîæèòü, ÷òî
EÑX ñîäåðæèò óêàçàòåëü íà ñòðîêó îðèãèíàëüíîãî ïàðîëÿ (ïîñêîëüêó îí âûçâàë
âñïëûòèå îòëàä÷èêà), à EDX â òàêîì ñëó÷àå — óêàçàòåëü íà ââåäåííûé ïîëüçîâàòåëåì ïàðîëü. Ïðîâåðèì íàøå ïðåäïîëîæåíèå.
:d edx
0023:00406040 6D 79 47 4F 4F 44 70 61-73 73 77 6F 72 64 0A 00 myGOODpassword..
:d edx
0023:0012FF18 4B 50 4E 43 2B 2B 0A 00-00 00 00 00 00 00 00 00 KPNC++..........

È ïðàâäà — äîãàäêà îêàçàëàñü âåðíà. Òåïåðü âîïðîñ: à êàê ýòî çàëîìèòü? Âîò,
ñêàæåì, JNZ ìîæíî ïîìåíÿòü íà JZ èëè, åùå îðèãèíàëüíåå, çàìåíèòü EDX íà
ECX. Òîãäà îðèãèíàëüíûé ïàðîëü áóäåò ñðàâíèâàòüñÿ ñàì ñ ñîáîé! Ïîãîäèòå, ïîãîäèòå, íå ñòîèò òàê ñïåøèòü! À ÷òî, åñëè ìû íàõîäèìñÿ íå â òåëå çàùèòû, à â áèáëèîòå÷íîé ôóíêöèè (äåéñòâèòåëüíî, ìû íàõîäèìñÿ â òåëå strcmp), åå èçìåíåíèå
ïðèâåäåò ê òîìó, ÷òî ïðîãðàììà áóäåò âîñïðèíèìàòü ëþáûå ñòðîêè êàê èäåíòè÷íûå. Ëþáûå — à íå òîëüêî ñòðîêè ïàðîëÿ. Ýòî íå ïîâðåäèò íàøåìó ïðèìåðó, ãäå
strcmp âûçûâàëàñü ëèøü îäíàæäû, íî çàâàëèò íîðìàëüíîå ïîëíîôóíêöèîíàëüíîå
ïðèëîæåíèå. ×òî æå äåëàòü?
Âûéòè èç strcmp è ïîäêîððåêòèðîâàòü òîò ñàìûé IF, êîòîðûé àíàëèçèðóåò
ïðàâèëüíûé — íåïðàâèëüíûé ïàðîëü. Äëÿ ýòîãî ñëóæèò êîìàíäà P RET (òðàññèðîâàòü, ïîêà íå âñòðåòèòñÿ ret — èíñòðóêöèÿ âîçâðàòà èç ôóíêöèè).
:P RET
001B:0040104E
001B:00401053
001B:00401056
001B:00401058
001B:0040105A
001B:0040105F
001B:00401064
001B:00401067

CALL
ADD
TEST
JZ
PUSH
CALL
ADD
JMP

004010A0
ESP,08
EAX,EAX
00401069
00406050
00401234
ESP,04
0040106B

Çíàêîìûå ìåñòà! Ïîìíèòå, ìû èõ ïîñåùàëè äèçàññåìáëåðîì? Àëãîðèòì äåéñòâèé ïðåæíèé — çàïîìèíàåì àäðåñ êîìàíäû TEST äëÿ ïîñëåäóþùåé çàìåíû åå
íà XOR èëè çàïèñûâàåì ïîñëåäîâàòåëüíîñòü áàéòîâ, èäåíòèôèöèðóþùóþ... ýé,
ïîñòîéòå, à ãäå æå íàøè áàéòû — øåñòíàäöàòåðè÷íîå ïðåäñòàâëåíèå êîìàíä? Êîâàðíûé Àéñ ïî óìîë÷àíèþ èõ íå âûâîäèò, è çàñòàâèòü åãî ýòî ñäåëàòü ïîìîãàåò
êîìàíäà CODE ON.
code on
001B:0040104E E84D000000
001B:00401053 83C408
001B:00401056 85C0

CALL
ADD
TEST

004010A0
ESP,08
EAX,EAX

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
001B:00401058
001B:0040105A
001B:0040105F
001B:00401064
001B:00401067

740F
6850604000
E8D0010000
83C404
EB02

JZ
PUSH
CALL
ADD
JMP

37

00401069
00406050
00401234
ESP,04
0040106B

Âîò òåïåðü ñîâñåì äðóãîå äåëî! Íî ìîæíî ëè áûòü óâåðåííûì, ÷òî ýòè áàéòèêè ïî ýòèì ñàìûì àäðåñàì áóäóò íàõîäèòüñÿ â èñïîëíÿåìîì ôàéëå? Âîïðîñ
íå òàê ãëóï, êàê êàæåòñÿ íà ïåðâûé âçãëÿä. Ïîïðîáóéòå ñëîìàòü îïèñàííûì
âûøå ìåòîäîì ïðèìåð crackme0x03. Íà ïåðâûé âçãëÿä îí î÷åíü ïîõîæ íà simple.exe, äàæå îðèãèíàëüíûé ïàðîëü ðàñïîëàãàåòñÿ ïî òîìó æå ñàìîìó àäðåñó.
Ñòàâèì íà íåãî áðÿê, äîæèäàåìñÿ âñïëûòèÿ îòëàä÷èêà, âûõîäèì èç ñðàâíèâàþùåé ïðîöåäóðû è ïîïàäàåì íà òî÷íî òàêîé æå êîä, êîòîðûé óæå âñòðå÷àëñÿ
íàì ðàíåå:
001B:0042104E
001B:00421053
001B:00421056
001B:00421058

E87D000000
83C408
85C0
740F

CALL
ADD
TEST
JZ

004210D0
ESP,08
EAX,EAX
00421069

Ñåé÷àñ ìû çàïóñòèì HIEW, ïåðåéäåì ïî àäðåñó 0x421053 è... Ýé, ïîñòîé,
HIEW ðóãàåòñÿ è ãîâîðèò, ÷òî â ôàéëå íåò òàêîãî àäðåñà! Ïîñëåäíèé áàéò çàêàí÷èâàåòñÿ íà 0x407FFF. Áûòü ìîæåò, ìû íàõîäèìñÿ â òåëå ñèñòåìíîé ôóíêöèè
Windows? Íî íåò, ñèñòåìíûå ôóíêöèè Windows ðàñïîëîæåíû çíà÷èòåëüíî âûøå,
íà÷èíàÿ ñ àäðåñà 0x80000000.
Ôîêóñ ñîñòîèò â òîì, ÷òî PE-ôàéë ìîæåò áûòü çàãðóæåí ïî àäðåñó, îòëè÷íîìó îò òîãî, äëÿ êîòîðîãî îí áûë ñîçäàí (ýòî ñâîéñòâî íàçûâàåòñÿ ïåðåìåùàåìîñòüþ), ïðè ýòîì ñèñòåìà àâòîìàòè÷åñêè êîððåêòèðóåò âñå ññûëêè íà àáñîëþòíûå
àäðåñà, çàìåíÿÿ èõ íîâûìè çíà÷åíèÿìè.  ðåçóëüòàòå — îáðàç ôàéëà â ïàìÿòè íå
áóäåò ñîîòâåòñòâîâàòü òîìó, ÷òî çàïèñàíî íà äèñêå. Õîðîøåíüêîå íà÷àëî! Êàê æå
òåïåðü íàéòè ìåñòî, êîòîðîå íóæíî ïðàâèòü?
Çàäà÷ó íåñêîëüêî îáëåã÷àåò òîò ôàêò, ÷òî ñèñòåìíûé çàãðóç÷èê óìååò ïåðåìåùàòü òîëüêî DLL, à èñïîëíÿåìûå ôàéëû âñåãäà ïûòàåòñÿ çàãðóçèòü ïî «ðîäíîìó» äëÿ íèõ àäðåñó. Åñëè æå ýòî íåâîçìîæíî — çàãðóçêà ïðåðûâàåòñÿ ñ âûäà÷åé
ñîîáùåíèÿ îá îøèáêå. Âûõîäèò, ìû èìååì äåëî ñ DLL, çàãðóæåííîé èññëåäóåìîé
íàìè çàùèòîé. Õì, âðîäå áû íå äîëæíî çäåñü áûòü íèêàêèõ DLL, äà è îòêóäà áû
èì âçÿòüñÿ?
×òî æ, èçó÷èì ëèñòèíã 2 íà ïðåäìåò âûÿñíåíèÿ, êàê æå îí ðàáîòàåò.
Ëèñòèíã 2. Èñõîäíûé òåêñò çàùèòû crackme0x3

#include
#include
__declspec(dllexport) void Demo()
^^^^^^^^^^^^^^^^^^^^^
{
#define PASSWORD_SIZE 100
#define PASSWORD "myGOODpassword\n"
int count=0;

38

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
char buff[PASSWORD_SIZE]="";
for(;;)
{
printf("Enter password:");
fgets(&buff[0],PASSWORD_SIZE-1,stdin);
if (strcmp(&buff[0],PASSWORD))
printf("Wrong password\n");
else break;
if (++count>2) return -1;
}
printf("Password OK\n");

}
main()
{
HMODULE hmod;
void (*zzz)();
if ((hmod=LoadLibrary("crack0~1.exe"))
&& (zzz=(void (*)())GetProcAddress(h,"Demo")))
zzz();
}

Êàêîé, îäíàêî, èçâðàùåííûé ñïîñîá âûçîâà ôóíêöèè! Çàùèòà ýêñïîðòèðóåò
åå íåïîñðåäñòâåííî èç ñàìîãî èñïîëíÿåìîãî ôàéëà è ýòîò æå ôàéë çàãðóæàåò êàê
DLL (äà, îäèí è òîò æå ôàéë ìîæåò áûòü îäíîâðåìåííî è èñïîëíÿåìûì ïðèëîæåíèåì, è äèíàìè÷åñêîé áèáëèîòåêîé!)
«Âñå ðàâíî íè÷åãî íå ñõîäèòñÿ, — âîçðàçèò ïðîãðàììèñò ñðåäíåé êâàëèôèêàöèè, — âñåì æå èçâåñòíî, ÷òî Windows íå íàñòîëüêî ãëóïà, ÷òîáû äâàæäû ãðóçèòü îäèí è òîò æå ôàéë, — LoadLibrary âñåãî ëèøü âîçâðàòèò áàçîâûé àäðåñ ìîäóëÿ crackme0x03, íî íå ñòàíåò âûäåëÿòü äëÿ íåãî ïàìÿòü». À âîò êàê áû íå òàê!
Õèòðàÿ çàùèòà îáðàùàåòñÿ ê ôàéëó ïî åãî àëüòåðíàòèâíîìó êîðîòêîìó èìåíè,
ââîäÿ ñèñòåìíûé çàãðóç÷èê â ãëóáîêîå çàáëóæäåíèå!
Ñèñòåìà âûäåëÿåò ïàìÿòü è âîçâðàùàåò áàçîâûé àäðåñ çàãðóæàåìîãî ìîäóëÿ
â ïåðåìåííîé hmod. Î÷åâèäíî, êîä è äàííûå ýòîãî ìîäóëÿ ñìåùåíû íà ðàññòîÿíèå hmod — base, ãäå base — áàçîâûé àäðåñ ìîäóëÿ — òîò, ñ êîòîðûì ðàáîòàþò
HIEW è äèçàññåìáëåð. Áàçîâûé àäðåñ óçíàòü íåòðóäíî, äîñòàòî÷íî âûçâàòü òîò
æå DUMPBIN ñ êëþ÷îì /HEADERS (åãî îòâåò ïðèâåäåí â ñîêðàùåííîì âèäå):
>dumpbin /HEADERS crack0x03
OPTIONAL HEADER VALUES
...
400000 image base
^^^^^^^^^^^^^^^^^
...

Çíà÷èò, áàçîâûé àäðåñ — 0x400000 (â áàéòàõ). À îïðåäåëèòü àäðåñ çàãðóçêè
ìîæíî êîìàíäîé mod -u îòëàä÷èêà (êëþ÷ u ðàçðåøàåò âûâîäèòü òîëüêî ïðèêëàäíûå, ò. å. íå ñèñòåìíûå, ìîäóëè).

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

39

:mod -u
hMod Base PEHeader Module Name File Name
00400000 004000D8 crack0x0 \.PHCK\src\crack0x03.exe
00420000 004200D8 crack0x0 \.PHCK\src\crack0x03.exe
^^^^^^^^
77E80000 77E800D0 kernel32 \WINNT\system32\kernel32.dll
77F80000 77F800C0 ntdll \WINNT\system32\ntdll.dll

Ñìîòðèòå, çàãðóæåíî ñðàçó äâå êîïèè crack0x03, ïðè÷åì ïîñëåäíÿÿ ðàñïîëîæåíà ïî àäðåñó 0x420000, êàê ðàç òî, ÷òî íàì íàäî! Òåïåðü íåòðóäíî ïîñ÷èòàòü,
÷òî àäðåñ 0x421056 (òîò, ÷òî ìû ïûòàëèñü ïîñëåäíèé ðàç íàéòè â ëîìàåìîì ôàéëå) «íà äèñêå» áóäåò ñîîòâåòñòâîâàòü àäðåñó 0x421056 – (0x42000 - 0x400000) ==
0x421056 – 0x20000 == 0x401056. Ñìîòðèì:
00401056: 85C0
00401058: 740F

test
je

eax,eax
.000401069

———————— (1)

Âñå âåðíî, ïîñìîòðèòå, êàê õîðîøî ýòî ñîâïàäàåò ñ äàìïîì îòëàä÷èêà:
001B:00421056 85C0
001B:00421058 740F

TEST
JZ

EAX,EAX
00421069

Ðàçóìååòñÿ, îïèñàííàÿ ìåòîäèêà âû÷èñëåíèé ïðèìåíèìà ê ëþáûì DLL, à íå
òîëüêî ê òåì, ÷òî ïðåäñòàâëÿþò ñîáîé èñïîëíÿåìûé ôàéë.
À âîò åñëè áû ìû ïîøëè íå ïóòåì àäðåñîâ, à ïîïûòàëèñü íàéòè â ëîìàåìîé
ïðîãðàììå ñðèñîâàííóþ ñ îòëàä÷èêà ïîñëåäîâàòåëüíîñòü áàéòîâ, âêëþ÷àÿ è òó
÷àñòü, êîòîðàÿ âõîäèò â CALL 00422040, — èíòåðåñíî, íàøëè áû ìû åå èëè íåò?
001B:0042104E
001B:00421053
001B:00421056
001B:00421058
:Îáðàç ôàéëà â

E87D000000
83C408
85C0
740F
ïàìÿòè.

.0040104E: E87D000000
.00401053: 83C408
.00401056: 85C0
.00401058: 740F
:Îáðàç ôàéëà íà äèñêå.

CALL
ADD
TEST
JZ
call
add
test
je

004210D0
ESP,08
EAX,EAX
00421069
.0004010D0 ———————— (1)
esp,008 ;" "
eax,eax
.000401069 ———————— (2)

Âîò ýòî íîâîñòü — êîìàíäàì CALL 0x4210D0 è CALL 0x4010D0 ñîîòâåòñòâóåò
îäèí è òîò æå ìàøèííûé êîä — E8 7D 00 00 00! Êàê æå òàêîå ìîæåò áûòü?! À âîò
êàê — îïåðàíä ïðîöåññîðíîé èíñòðóêöèè 0xE8 ïðåäñòàâëÿåò ñîáîé íå ñìåùåíèå
ïîäïðîãðàììû, à ðàçíèöó ñìåùåíèé ïîäïðîãðàììû è èíñòðóêöèè, ñëåäóþùåé çà êîìàíäîé call. Òî åñòü â ïåðâîì ñëó÷àå: 0x421053 (ñìåùåíèå èíñòðóêöèè, ñëåäóþùåé çà CALL) + 0x0000007D (íå çàáûâàåì îá îáðàòíîì ïîðÿäêå áàéòîâ
â äâîéíîì ñëîâå) == 0x4210D0 — âîò îí, èñêîìûé àäðåñ. Òàêèì îáðàçîì, ïðè èçìåíåíèè àäðåñà çàãðóçêè êîððåêöèÿ êîäîâ êîìàíä CALL íå òðåáóåòñÿ.
Îöåíêà ïî àíàëîãèè îñíîâûâàåòñÿ íà ïðåäïîëîæåíèè, ÷òî åñëè äâà èëè
áîëåå îáúåêòà ñîãëàñóþòñÿ äðóã ñ äðóãîì â íåêîòîðûõ îòíîøåíèÿõ, òî îíè,
âåðîÿòíî, ñîãëàñóþòñÿ è â äðóãèõ îòíîøåíèÿõ.
Ã. Ñåëüå. Îò ìå÷òû ê îòêðûòèþ

40

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Ðàññóæäåíèÿ ïî àíàëîãèè — îïàñíàÿ øòóêà. Óâëå÷åííûå ñòðîéíîñòüþ àíàëîãèè, ìû ïîä÷àñ äàæå íå çàäóìûâàåìñÿ î ïðîâåðêå. Ìåæäó òåì àíàëîãèè ëãóò
÷àùå, ÷åì ýòîãî õîòåëîñü áû.
 ïðèìåðå crack0x03, ñðåäè ïðî÷åãî êîäà, åñòü è òàêàÿ ñòðîêà (íàéäèòå åå ñ
ïîìîùüþ hiew):
004012C5: 89154C694000

mov

[00040694C],edx

Ëåãêî âèäåòü, ÷òî êîìàíäà MOV îáðàùàåòñÿ ê ÿ÷åéêå íå ïî îòíîñèòåëüíîìó,
à ïî àáñîëþòíîìó àäðåñó. Âîïðîñ: à) âûÿñíèòå, ÷òî ïðîèçîéäåò ïðè èçìåíåíèè àäðåñà çàãðóçêè ìîäóëÿ; á) êàê âû äóìàåòå, áóäåò ëè òåïåðü ñîâïàäàòü îáðàç ôàéëà
íà äèñêå è â ïàìÿòè?
Çàãëÿíóâ îòëàä÷èêîì ïî àäðåñó 0x4212C5 (0x4012C5 + 0x2000), ìû óâèäèì, ÷òî
îáðàùåíèå èäåò ñîâñåì íå ê ÿ÷åéêå 0x42694C, à ê ÿ÷åéêå 0x40694C! Íàø ìîäóëü ñàìûì áåññîâåñòíûì îáðàçîì âòîðãàåòñÿ â ÷óæèå âëàäåíèÿ, ìîäèôèöèðóÿ èõ ïî
ñâîåìó óñìîòðåíèþ. Òàê è äî êðàõà ñèñòåìû äîêàòèòüñÿ íåäîëãî!  äàííîì ñëó÷àå
ýòî íå ïðîèñõîäèò òîëüêî ïîòîìó, ÷òî èñêîìàÿ ñòðîêà ðàñïîëîæåíà â Startup-ïðîöåäóðå (ñòàðòîâîì êîäå) è âûïîëíÿåòñÿ ëèøü îäíàæäû — ïðè çàïóñêå ïðèëîæåíèÿ, à èç çàãðóæåííîãî ìîäóëÿ íå âûçûâàåòñÿ.
Äðóãîå äåëî, åñëè áû ôóíêöèÿ Demo() îáðàùàëàñü ê êàêîé-íèáóäü ñòàòè÷åñêîé ïåðåìåííîé — êîìïèëÿòîð, ïîäñòàâèâ åå íåïîñðåäñòâåííîå ñìåùåíèå, ñäåëàë áû ìîäóëü íåïåðåìåùàåìûì! Ïîñëå ñêàçàííîãî ñòàíîâèòñÿ íåïîíÿòíî: êàê æå
òîãäà óõèòðÿþòñÿ ðàáîòàòü äèíàìè÷åñêè ïîäêëþ÷àåìûå áèáëèîòåêè (DLL), àäðåñ
çàãðóçêè êîòîðûõ çàðàíåå íåèçâåñòåí? Ïîðàçìûñëèâ íåêîòîðîå âðåìÿ, ìû íàéäåì, ïî êðàéíåé ìåðå, äâà ðåøåíèÿ ïðîáëåìû:
Ïåðâîå — âìåñòî íåïîñðåäñòâåííîé àäðåñàöèè èñïîëüçîâàòü îòíîñèòåëüíóþ,
íàïðèìåð [reg+offset_val], ãäå reg — ðåãèñòð, ñîäåðæàùèé áàçîâûé àäðåñ çàãðóçêè, à offset_val — ñìåùåíèå ÿ÷åéêè îò íà÷àëà ìîäóëÿ. Ýòî ïîçâîëèò ìîäóëþ
ãðóçèòüñÿ ïî ëþáîìó àäðåñó, íî çàìåòíî ñíèçèò ïðîèçâîäèòåëüíîñòü ïðîãðàììû
óæå õîòÿ áû çà ñ÷åò ïîòåðè îäíîãî ðåãèñòðà...
Âòîðîå — íàó÷èòü çàãðóç÷èê êîððåêòèðîâàòü íåïîñðåäñòâåííûå ñìåùåíèÿ â
ñîîòâåòñòâèè ñ âûáðàííûì áàçîâûì àäðåñîì çàãðóçêè. Ýòî, êîíå÷íî, íåñêîëüêî
çàìåäëèò çàãðóçêó, íî çàòî íå óõóäøèò áûñòðîäåéñòâèå ñàìîé ïðîãðàììû. Íå
ôàêò, ÷òî âðåìåíåì çàãðóçêè ìîæíî ñâîáîäíî ïðåíåáðå÷ü, íî ñïåöèàëèñòû èç Microsoft âûáðàëè èìåííî ýòîò ñïîñîá.
Åäèíñòâåííàÿ ïðîáëåìà — êàê îòëè÷èòü äåéñòâèòåëüíûå íåïîñðåäñòâåííûå
ñìåùåíèÿ îò êîíñòàíò, ñîâïàäàþùèõ ñ íèìè ïî çíà÷åíèþ? Íå äèçàññåìáëèðîâàòü
æå â ñàìîì äåëå DLL, ÷òîáû ðàçîáðàòüñÿ, êàêèå èìåííî ÿ÷åéêè â íåé íåîáõîäèìî
«ïîäêðóòèòü»? Âåðíî, êóäà ïðîùå ïåðå÷èñëèòü èõ àäðåñà â ñïåöèàëüíîé òàáëèöå,
ðàñïîëîæåííîé íåïîñðåäñòâåííî â çàãðóæàåìîì ôàéëå è íîñÿùåé ãîðäîå èìÿ
«Òàáëèöû ïåðåìåùàåìûõ ýëåìåíòîâ» èëè (Relocation [Fix Up] table —
ïî-àíãëèéñêè). Çà åå ôîðìèðîâàíèå îòâå÷àåò ëèíêåð (îí æå êîìïîíîâùèê), è òàêàÿ òàáëèöà ïðèñóòñòâóåò â êàæäîé DLL.
×òîáû ïîçíàêîìèòüñÿ ñ íåé ïîáëèæå, îòêîìïèëèðóåì è èçó÷èì ñëåäóþùèé
ïðèìåð:

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

41

Ëèñòèíã 3. Èñõîäíûé òåêñò fixupdemo.c

::fixupdemo.c
__declspec(dllexport) void meme(int x)
{
static int a=0x666;
a=x;
}
> cl fixupdemo.c /LD

Îòêîìïèëèðóåì è òóò æå äèçàññåìáëèðóåì åãî: DUMPBIN /DISASM fixupdemo.dll è DUMPBIN /SECTION:.data /RAWDATA.
10001000:
10001001:
10001003:
10001006:

55
8B EC
8B 45 08
A3 30 50 00 10
^^^^^^^^^^^
1000100B: 5D
1000100C: C3
RAW DATA #3
10005000: 00 00
10005010: 00 00
10005020: 00 00
10005030: 66 06
^^^^^

00
00
00
00

00
00
00
00

00
00
00
E3

push
mov
mov
mov

ebp
ebp,esp
eax,dword ptr [ebp+8]
[10005030],eax
^^^^^^^^
ebp

pop
ret
00
00
00
11

00
00
00
00

00
00
00
10

00
00
00
FF

00
00
00
FF

00
00
00
FF

00
00
00
FF

33
00
00
00

24
00
00
00

00
00
00
00

10
00
00
00

............3$..
................
................
f...ó... ....

Ñóäÿ ïî êîäó, çàïèñü ñîäåðæèìîãî EAX âñåãäà ïðîèñõîäèò â ÿ÷åéêó
0x10005030. Íî íå òîðîïèòåñü ñ âûâîäàìè! DUMPBIN /RELOCATIONS fixupdemo.dll:
BASE RELOCATIONS #4
1000 RVA, 154 SizeOfBlock
7 HIGHLOW
^
1C HIGHLOW
23 HIGHLOW
32 HIGHLOW
3A HIGHLOW

Òàáëèöà ïåðåìåùàåìûõ ýëåìåíòîâ-òî íå ïóñòà! È ïåðâàÿ æå åå çàïèñü óêàçûâàåò íà ÿ÷åéêó 0x100001007, ïîëó÷åííóþ àëãåáðàè÷åñêèì ñëîæåíèåì ñìåùåíèÿ
0x7 ñ RVA-àäðåñîì 0x1000 è áàçîâûì àäðåñîì çàãðóçêè 0x10000000 (ïîëó÷èòå åãî ñ
ïîìîùüþ DUMPBIN ñàìîñòîÿòåëüíî). Ñìîòðèì — ÿ÷åéêà 0x100001007 ïðèíàäëåæèò èíñòðóêöèè MOV [0x10005030],EAX è óêàçûâàåò íà ñàìûé ñòàðøèé áàéò íåïîñðåäñòâåííîãî ñìåùåíèÿ. Âîò ýòî ñàìîå ñìåùåíèå è êîððåêòèðóåò çàãðóç÷èê â
õîäå ïîäêëþ÷åíèÿ äèíàìè÷åñêîé áèáëèîòåêè (ðàçóìååòñÿ, åñëè â ýòîì åñòü íåîáõîäèìîñòü).
Õîòèòå ïðîâåðèòü? Ïîæàëóéñòà, ñîçäàäèì äâå êîïèè îäíîé DLL (íàïðèìåð,
copy fixupdemo.dll fixupdemo2.dll) è çàãðóçèì èõ ïîî÷åðåäíî ñëåäóþùåé ïðîãðàììîé:

42

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Ëèñòèíã 4. Èñõîäíûé òåêñò fixupload

::fixupload.c
#include
main()
{
void (*demo) (int a);
HMODULE h;
if ((h=LoadLibrary("fixupdemo.dll")) &&
(h=LoadLibrary("fixupdemo2.dll")) &&
(demo=(void (*)(int a))GetProcAddress(h,"meme")))
demo(0x777);
}
> cl fixupload

Ïîñêîëüêó ïî îäíîìó è òîìó æå àäðåñó äâå ðàçëè÷íûå DLL íå çàãðóçèøü
(îòêóäà æå ñèñòåìå çíàòü, ÷òî ýòî îäíà è òà æå DLL!), çàãðóç÷èêó ïðèõîäèòñÿ
ïðèáåãàòü ê åå ïåðåìåùåíèþ. Çàãðóçèì îòêîìïèëèðîâàííóþ ïðîãðàììó â îòëàä÷èê è óñòàíîâèì òî÷êó îñòàíîâà íà ôóíêöèþ LoadLibraryA. Ýòî, ïîíÿòíîå äåëî,
íåîáõîäèìî, ÷òîáû ïðîïóñòèòü Startup-êîä è ïîïàñòü â òåëî ôóíêöèè main. (Êàê
ëåãêî óáåäèòüñÿ, èñïîëíåíèå ïðîãðàììû íà÷èíàåòñÿ îòíþäü íå ñ main, à ñî ñëóæåáíîãî êîäà, â êîòîðîì î÷åíü ëåãêî óòîíóòü.) Íî îòêóäà âçÿëàñü çàãàäî÷íàÿ
áóêâà «A», íà êîíöå èìåíè ôóíêöèè? Åå ïðîèñõîæäåíèå òåñíî ñâÿçàíî ñ ââåäåíèåì â Windows ïîääåðæêè óíèêîäà — ñïåöèàëüíîé êîäèðîâêè, êàæäûé ñèìâîë
â êîòîðîé êîäèðóåòñÿ äâóìÿ áàéòàìè, áëàãîäàðÿ ÷åìó ïðèîáðåòàåò ñïîñîáíîñòü
âûðàæàòü ëþáîé èç 216 = 65536 çíàêîâ, — êîëè÷åñòâî, äîñòàòî÷íîå äëÿ âìåùåíèÿ ïðàêòè÷åñêè âñåõ àëôàâèòîâ íàøåãî ìèðà. Ïðèìåíèòåëüíî ê LoadLibrary —
òåïåðü èìÿ áèáëèîòåêè ìîæåò áûòü íàïèñàíî íà ëþáîì ÿçûêå, à ïðè æåëàíèè è
íà ëþáîì êîëè÷åñòâå ëþáûõ ÿçûêîâ îäíîâðåìåííî, íàïðèìåð íà ðóññêî-ôðàíöóçñêî-êèòàéñêîì. Çâó÷èò çàìàí÷èâî, íî íå óõóäøàåò ëè ýòî ïðîèçâîäèòåëüíîñòü? Ðàçóìååòñÿ, óõóäøàåò, åùå êàê — óíèêîä òðåáóåò æåðòâ! Ñàìîå îáèäíîå — â ïîäàâëÿþùåì áîëüøèíñòâå ñëó÷àåâ âïîëíå äîñòàòî÷íî ñòàðîé äîáðîé
êîäèðîâêè ASCII (âî âñÿêîì ñëó÷àå, íàì, ðóññêèì è àìåðèêàíöàì). Òàê êàêîé
æå ñìûñë áðîñàòü äðàãîöåííûå òàêòû ïðîöåññîðà íà âåòåð? Ðàäè ïðîèçâîäèòåëüíîñòè áûëî ðåøåíî ïîñòóïèòüñÿ ðàçìåðîì, ñîçäàâ îòäåëüíûå âàðèàíòû ôóíêöèé
äëÿ ðàáîòû ñ óíèêîäîì è ASCII-ñèìâîëàìè. Ïåðâûå ïîëó÷èëè ñóôôèêñ «W» (îò
Wide — øèðîêèé), à âòîðûå — «A» (îò ASCII). Ýòà òîíêîñòü ñêðûòà îò ïðèêëàäíûõ ïðîãðàììèñòîâ. Êàêóþ èìåííî ôóíêöèþ âûçûâàòü — «W» èëè «A» —
ðåøàåò êîìïèëÿòîð, íî ïðè ðàáîòå ñ îòëàä÷èêîì íåîáõîäèìî óêàçûâàòü òî÷íîå
èìÿ ôóíêöèè — ñàìîñòîÿòåëüíî îïðåäåëèòü ñóôôèêñ îí íå â ñîñòîÿíèè. Êàìåíü
ïðåòêíîâåíèÿ â òîì, ÷òî íåêîòîðûå ôóíêöèè, íàïðèìåð ShowWindows, âîîáùå
íå èìåþò ñóôôèêñîâ — íè «A», íè «W», è èõ áèáëèîòå÷íîå èìÿ ñîâïàäàåò ñ êàíîíè÷åñêèì. Êàê æå áûòü?
Ñàìîå ïðîñòîå — çàãëÿíóòü â òàáëèöó èìïîðòà ïðåïàðèðóåìîãî ôàéëà è îòûñêàòü òàì âàøó ôóíêöèþ. Íàïðèìåð, ïðèìåíèòåëüíî ê íàøåìó ñëó÷àþ:
> DUMPBIN /IMPORTS fixupload.exe > filename
> type filename

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

43

19D HeapDestroy
1C2 LoadLibraryA
CA GetCommandLineA
174 GetVersion
7D ExitProcess
29E TerminateProcess
...

Èç ïðèâåäåííîãî âûøå ôðàãìåíòà âèäíî, ÷òî LoadLibrary âñå-òàêè «A», à âîò
ôóíêöèè ExitProcess è TerminateProcess íå èìåþò ñóôôèêñîâ, ïîñêîëüêó âîîáùå
íå ðàáîòàþò ñî ñòðîêàìè.
Äðóãîé ïóòü — çàãëÿíóòü â SDK. Êîíå÷íî, áèáëèîòå÷íîå èìÿ ôóíêöèé â íåì
îòñóòñòâóåò, íî â Quick Info ìèìîõîäîì ïðèâîäèòñÿ èíôîðìàöèÿ î ïîääåðæêå
óíèêîäà (åñëè òàêîâàÿ ïðèñóòñòâóåò). À ðàç åñòü óíèêîä — åñòü ñóôôèêñû «W» è
«A», ñîîòâåòñòâåííî íàîáîðîò — ãäå íåò óíèêîäà, íåò è ñóôôèêñîâ. Ïðîâåðèì?
Âîò òàê âûãëÿäèò Quick Info îò LoadLibrary:
QuickInfo
Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

Íà ÷èñòåéøåì àíãëèéñêîì ÿçûêå çäåñü ñêàçàíî — «Ðåàëèçîâàíî êàê Unicode è ANSI âåðñèè íà Windows NT». Ñòîï! Ñ NT âñå ïîíÿòíî, à êàê íàñ÷åò «íàðîäíîé» äåâÿíîñòî âîñüìîé (ïÿòîé)? Áåãëûé âçãëÿä íà òàáëèöó ýêñïîðòà KERNEL32.DLL ïîêàçûâàåò: òàêàÿ ôóíêöèÿ òàì åñòü, íî, ïðèñìîòðåâøèñü ïîâíèìàòåëüíåå, ìû ñ óäèâëåíèåì îáíàðóæèì, ÷òî åå òî÷êà âõîäà ñîâïàäàåò ñ òî÷êàìè
âõîäà äåñÿòêà äðóãèõ ôóíêöèé!
ordinal hint RVA
name
556 1B3 00039031 LoadLibraryW

Òðåòüÿ êîëîíêà â îò÷åòå DUMPBIN — ýòî RVA-àäðåñ — âèðòóàëüíûé àäðåñ
íà÷àëà ôóíêöèè çà âû÷åòîì áàçîâîãî àäðåñà çàãðóçêè ôàéëà. Ïðîñòîé êîíòåêñòíûé ïîèñê ïîêàçûâàåò, ÷òî îí âñòðå÷àåòñÿ íå åäèíîæäû. Âîñïîëüçîâàâøèñü ïðîãðàììîé-ôèëüòðîì srcln äëÿ ïîëó÷åíèÿ ñâÿçíîãî ïðîòîêîëà, ìû óâèäèì ñëåäóþùåå:
21:
116:
119:
178:
204:
260:
297:
341:
377:
384:
389:

118
217
220
279
305
361
398
442
478
485
490

1
60
63
9E
B8
F0
115
141
165
16C
171

00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031

AddAtomW
DeleteFileW
DisconnectNamedPipe
FindAtomW
FreeEnvironmentStringsW
GetDriveTypeW
GetModuleHandleW
GetStartupInfoW
GetVersionExW
GlobalAddAtomW
GlobalFindAtomW

44
413:
417:
440:
455:
508:
547:
590:
592:
597:
601:
605:
645:
678:

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
514
518
541
556
611
648
691
693
698
702
706
746
779

189
18D
1A4
1B3
1E8
20F
23A
23C
241
245
249
271
292

00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031
00039031

HeapLock
HeapUnlock
IsProcessorFeaturePresent
LoadLibraryW
OutputDebugStringW
RemoveDirectoryW
SetComputerNameW
SetConsoleCP
SetConsoleOutputCP
SetConsoleTitleW
SetCurrentDirectoryW
SetThreadLocale
TryEnterCriticalSection

Âîò ýòî ñþðïðèç! Âñå óíèêîäîâûå ôóíêöèè ïîä îäíîé êðûøåé! Ïîñêîëüêó
òðóäíî ïîâåðèòü â èäåíòè÷íîñòü ðåàëèçàöèé LoadLibraryW è, ñêàæåì, DeleteFileW, îñòàåòñÿ ïðåäïîëîæèòü, ÷òî ìû èìååì äåëî ñ «çàãëóøêîé», êîòîðàÿ íè÷åãî
íå äåëàåò, à òîëüêî âîçâðàùàåò îøèáêó. Ñëåäîâàòåëüíî, â 9x ôóíêöèÿ LoadLibraryW äåéñòâèòåëüíî íå ðåàëèçîâàíà.
Íî âåðíåìñÿ ê íàøèì áàðàíàì, îò êîòîðûõ íàì ïðèøëîñü òàê äàëåêî îòîéòè.
Èòàê, âûçûâàåì îòëàä÷èê, ñòàâèì áðÿê íà LoadLibraryA, âûõîäèì èç îòëàä÷èêà è
òåðïåëèâî äîæèäàåìñÿ åãî âñïëûòèÿ. Äîëãî æäàòü, ê ñ÷àñòüþ, íå ïðèõîäèòñÿ...
KERNEL32!LoadLibraryA
001B:77E98023 PUSH
001B:77E98024 MOV
001B:77E98026 PUSH
001B:77E98027 PUSH
001B:77E98028 PUSH
001B:77E98029 PUSH
001B:77E9802E PUSH

EBP
EBP,ESP
EBX
ESI
EDI
77E98054
DWORD PTR [EBP+08]

Îòäàåì êîìàíäó P RET äëÿ âûõîäà èç LoadLibraryA (àíàëèçèðîâàòü åå, â ñàìîì äåëå, íè ê ÷åìó), è îêàçûâàåìñÿ â ëåãêî óçíàâàåìîì òåëå ôóíêöèè main:
001B:0040100B
001B:00401011
001B:00401014
001B:00401018
001B:0040101A
001B:0040101F
001B:00401025
001B:00401028

CALL
MOV
CMP
JZ
PUSH
CALL
MOV
CMP

[KERNEL32!LoadLibraryA]
[EBP-08],EAX
DWORD PTR [EBP-08],00
00401051
00405040
[KERNEL32!LoadLibraryA]
[EBP-08],EAX
DWORD PTR [EBP-08],00

Îáðàòèòå âíèìàíèå íà ñîäåðæèìîå ðåãèñòðà EAX — ôóíêöèÿ âîçâðàòèëà â
íåì àäðåñ çàãðóçêè (íà ìîåì êîìïüþòåðå ðàâíûé 0x10000000). Ïðîäîëæàÿ òðàññèðîâêó (êëàâèøà ), äîæäèòåñü âûïîëíåíèÿ âòîðîãî âûçîâà LoadLibraryA.
Íå ïðàâäà ëè, íà ýòîò ðàç àäðåñ çàãðóçêè èçìåíèëñÿ? (Íà êîìïüþòåðå àâòîðà îí
ðàâåí 0x0530000.)
Ïðèáëèçèâøèñü ê âûçîâó ôóíêöèè demo (â îòëàä÷èêå ýòî âûãëÿäèò êàê
PUSH 00000777\ CALL [EBP-04], EBP-04 íè î ÷åì íàì íå ãîâîðèò, íî âîò àðãóìåíò 0x777 îïðåäåëåííî ÷òî-òî íàì íàïîìèíàåò. Ñì. èñõîäíûé òåêñò fixupload.c),

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

45

íå çàáóäüòå ïåðåñòàâèòü ïàëåö ñ êëàâèøè íà êëàâèøó , ÷òîáû âîéòè
âíóòðü ôóíêöèè.
001B:00531000
001B:00531001
001B:00531003
001B:00531006
001B:0053100B
001B:0053100C

55
8BEC
8B4508
A330505300
5D
C3

PUSH
MOV
MOV
MOV
POP
RET

EBP
EBP,ESP
EAX,[EBP+08]
[00535030],EAX
EBP

Âîò îíî! Ñèñòåìíûé çàãðóç÷èê ñêîððåêòèðîâàë àäðåñ ÿ÷åéêè ñîãëàñíî áàçîâîìó àäðåñó çàãðóçêè ñàìîé DLL. Ýòî, êîíå÷íî, õîðîøî, äà âîò ïðîáëåìà — â
îðèãèíàëüíîé DLL íåò íè òàêîé ÿ÷åéêè, íè äàæå ïîñëåäîâàòåëüíîñòè A3 30 50 53
00, â ÷åì ëåãêî óáåäèòüñÿ, ïðîèçâåäÿ êîíòåêñòíûé ïîèñê. Äîïóñòèì, âîçíàìåðèëèñü áû ìû çàòåðåòü ýòó êîìàíäó NOP-àìè. Êàê íàéòè ýòî ìåñòî â îðèãèíàëüíîé
DLL?
Îáðàòèì ñâîé âçîð âûøå, íà êîìàíäû, çàâåäîìî íå ñîäåðæàùèå ïåðåìåùàåìûõ ýëåìåíòîâ, — PUSH EBP/MOV EBP, ESP/MOV EAX,[EBP+08]. Îò÷åãî áû íå ïîèñêàòü ïîñëåäîâàòåëüíîñòü 55 8B EC xxx A3?  äàííîì ñëó÷àå ýòî ñðàáîòàåò, íî, åñëè
áû ïåðåìåùàåìûå ýëåìåíòû áûëè ãóñòî ïåðåìåøàíû ñ «íîðìàëüíûìè», íè÷åãî áû
íå âûøëî. Îïîðíàÿ ïîñëåäîâàòåëüíîñòü îêàçàëàñü áû ñëèøêîì êîðîòêîé äëÿ ïîèñêà è âûäàëà áû ìíîæåñòâî ëîæíûõ ñðàáàòûâàíèé.
Áîëåå èçÿùíî è íàäåæíî âû÷èñëèòü èñòèííîå ñîäåðæèìîå ïåðåìåùàåìûõ
ýëåìåíòîâ, âû÷òÿ èç íèõ ðàçíèöó ìåæäó äåéñòâèòåëüíûì è ðåêîìåíäóåìûì àäðåñîì çàãðóçêè.  äàííîì ñëó÷àå: 0x535030 /ìîäèôèöèðîâàííûé çàãðóç÷èêîì àäðåñ/ – (0x530000 /áàçîâûé àäðåñ çàãðóçêè/ – 0x10000000 /ðåêîìåíäóåìûé àäðåñ
çàãðóçêè/) == 0x10005030. Ó÷èòûâàÿ îáðàòíûé ïîðÿäîê ñëåäîâàíèÿ áàéòîâ, ïîëó÷àåì, ÷òî èíñòðóêöèÿ MOV [10005030], EAX â ìàøèííîì êîäå äîëæíà âûãëÿäåòü
òàê: A3 30 50 00 10. Èùåì åå HIEW'îì, è ÷óäî — îíà åñòü!

Ñïîñîá 1. Ïðÿìîé ïîèñê ââåäåííîãî ïàðîëÿ â ïàìÿòè
Áûë áû îìóò, à ÷åðòè áóäóò.
Íàðîäíàÿ ïîãîâîðêà

Ïàðîëü, õðàíÿùèéñÿ â òåëå ïðîãðàììû îòêðûòûì òåêñòîì, — ñêîðåå èç ðÿäà
âîí âûõîäÿùåå èñêëþ÷åíèå, ÷åì ïðàâèëî. Ê ÷åìó óñëóãè õàêåðà, åñëè ïàðîëü è
áåç òîãî âèäåí íåâîîðóæåííûì âçãëÿäîì? Ïîýòîìó ðàçðàáîò÷èêè çàùèòû âñÿ÷åñêè ïûòàþòñÿ ñêðûòü åãî îò ïîñòîðîííèõ ãëàç (î òîì, êàê èìåííî îíè ýòî äåëàþò,
ìû ïîãîâîðèì ïîçæå). Âïðî÷åì, ó÷èòûâàÿ ðàçìåð ñîâðåìåííûõ ïàêåòîâ, ïðîãðàììèñò ìîæåò áåç îñîáîãî òðóäà ïîìåñòèòü ïàðîëü â êàêîì-íèáóäü çàâàëÿâøåìñÿ
ôàéëå, ïîïóòíî ñíàáäèâ åãî «êðÿêóøàìè» — ñòðîêàìè, âûãëÿäÿùèìè êàê ïàðîëü,
íî ïàðîëåì íå ÿâëÿþùèìèñÿ. Ïîïðîáóé ðàçáåðèñü, ãäå òóò ëèïà, à ãäå íåò, òåì
ïà÷å ÷òî ïîäõîäÿùèõ íà ýòó ðîëü ñòðîê â ïðîåêòå ñðåäíåé âåëè÷èíû ìîæåò áûòü
íåñêîëüêî ñîòåí, à òî è òûñÿ÷!

46

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Äàâàéòå ïîäîéäåì ê ðåøåíèþ ïðîáëåìû îò îáðàòíîãî — áóäåì èñêàòü íå îðèãèíàëüíûé ïàðîëü, êîòîðûé íàì íåèçâåñòåí, à òó ñòðîêó, êîòîðóþ ìû ñêîðìèëè
ïðîãðàììå â êà÷åñòâå ïàðîëÿ. À íàéäÿ, óñòàíîâèì íà íåå áðÿê, è äàëüøå âñå òî÷íî
òàê æå, êàê è ðàíüøå. Áðÿê âñïëûâàåò íà îáðàùåíèå ïî ñðàâíåíèþ, ìû âûõîäèì
èç ñðàâíèâàþùåé ïðîöåäóðû, êîððåêòèðóåì JMP, è...
Âçãëÿíåì åùå ðàç íà èñõîäíûé òåêñò ëîìàåìîãî íàìè ïðèìåðà simple.c:
for(;;)
{
printf("Enter password:");
fgets(&buff[0],PASSWORD_SIZE,stdin);
if (strcmp(&buff[0],PASSWORD))
printf("Wrong password\n");
else break;
if (++count>2) return -1;
}

Îáðàòèòå âíèìàíèå — â buff ÷èòàåòñÿ ââåäåííûé ïîëüçîâàòåëåì ïàðîëü,
ñðàâíèâàåòñÿ ñ îðèãèíàëîì, çàòåì (ïðè íåóäà÷íîì ñðàâíåíèè) çàïðàøèâàåòñÿ
åùå ðàç, íî (!) ïðè ýòîì buff íå î÷èùàåòñÿ! Îòñþäà ñëåäóåò, ÷òî, åñëè ïîñëå âûäà÷è ðóãàòåëüñòâà Wrong password âûçâàòü îòëàä÷èê è ïðîéòèñü ïî ïàìÿòè êîíòåêñòíûì ïîèñêîì, ìîæíî îáíàðóæèòü òîò çàâåòíûé buff, à îñòàëüíîå óæå — äåëî
òåõíèêè!
Èòàê, ïðèñòóïèì (ìû åùå íå çíàåì, âî ÷òî ìû ââÿçûâàåìñÿ, — íî, óâû, â æèçíè âñå ñëîæíåå, ÷åì â òåîðèè). Çàïóñêàåì SIMPLE.EXE, ââîäèì ëþáîé ïðèøåäøèé íà óì ïàðîëü (íàïðèìåð, KPNC Kaspersky++), ïðîïóñêàåì âîçìóùåííûé
âîïëü Wrong ìèìî óøåé è íàæèìàåì — «ãîðÿ÷óþ» êîìáèíàöèþ êëàâèø äëÿ âûçîâà Àéñà. Òàê, òåïåðü áóäåì èñêàòü? Ïîäîæäèòå, íå íàäî áåæàòü âïåðåäè ëîøàäåé: Windows 9x\NT — ýòî íå Windows 3.x è òåì áîëåå íå MS-DOS ñ
åäèíûì àäðåñíûì ïðîñòðàíñòâîì äëÿ âñåõ ïðîöåññîðîâ. Òåïåðü, ïî ñîîáðàæåíèÿì
áåçîïàñíîñòè, äàáû îäèí ïðîöåññ íåíàðîêîì íå çàëåç âî âëàäåíèÿ äðóãîãî, êàæäîìó èç íèõ ïðåäîñòàâëÿåòñÿ ñîáñòâåííîå àäðåñíîå ïðîñòðàíñòâî. Íàïðèìåð, ó ïðîöåññà A ïî àäðåñó 23:0146660 ìîæåò áûòü çàïèñàíî ÷èñëî 0x66, ó ïðîöåññà B ïî
òîìó æå ñàìîìó àäðåñó 23:0146660 ìîæåò íàõîäèòüñÿ 0x0, à ó ïðîöåññà C è
âîâñå òðåòüå çíà÷åíèå. Ïðè ýòîì ïðîöåññû À, B è C íå áóäóò äàæå ïîäîçðåâàòü î
ñóùåñòâîâàíèè äðóã äðóãà (íó, ðàçâå ÷òî âîñïîëüçóþòñÿ ñïåöèàëüíûìè ñðåäñòâàìè ìåæïðîöåññîðíîãî âçàèìîäåéñòâèÿ).
Ïîäðîáíåå îáî âñåì ýòîì ÷èòàéòå ó Õåëåí èëè Ðèõòåðà, çäåñü æå íàñ áîëüøå
çàáîòèò äðóãîå — âûçâàííûé ïî íàæàòèþ êîìáèíàöèè êëàâèø îòëàä÷èê âñïëûâàåò â ïðîèçâîëüíîì ïðîöåññå (ñêîðåå âñåãî, Idle) è êîíòåêñòíûé ïîèñê
â ïàìÿòè íè÷åãî íå äàñò. Íåîáõîäèìî íàñèëüíî ïåðåêëþ÷èòü îòëàä÷èê â íåîáõîäèìûé êîíòåêñò àäðåñíîãî ïðîñòðàíñòâà è ëèøü çàòåì ÷òî-òî ïðåäïðèíèìàòü.
Èç ïðèëàãàåìîé ê Àéñó äîêóìåíòàöèè ìîæíî óçíàòü, ÷òî ïåðåêëþ÷åíèå êîíòåêñòîâ îñóùåñòâëÿåòñÿ êîìàíäîé ADDR, çà êîòîðîé ñëåäóåò ëèáî èìÿ ïðîöåññà,
óðåçàííîå äî âîñüìè ñèìâîëîâ, ëèáî åãî PID. Óçíàòü è òî, è äðóãîå ìîæíî ñ ïîìîùüþ äðóãîé êîìàíäû — PROC (â òîì ñëó÷àå, åñëè èìÿ ïðîöåññà ñèíòàêñè÷åñêè

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

47

íåîòëè÷èìî îò PID, íàïðèìåð 123, ïðèõîäèòñÿ èñïîëüçîâàòü PID ïðîöåññà — âòîðàÿ êîëîíêà öèôð ñëåâà â îò÷åòå PROC).
:addr simple

Îòäàåì êîìàíäó addr simple, è... íè÷åãî íå ïðîèñõîäèò, äàæå çíà÷åíèÿ ðåãèñòðîâ îñòàþòñÿ íåèçìåííûìè! Íå âîëíóéòåñü, âñå î'êåé, ÷òî è ïîäòâåðæäàåò íàäïèñü «simple» â ïðàâîì íèæíåì óãëó, èäåíòèôèöèðóþùàÿ òåêóùèé ïðîöåññ. À ðåãèñòðû... ýòî íåáîëüøîé ãëþê Àéñà. Îí èõ èãíîðèðóåò, ïåðåêëþ÷àÿ òîëüêî àäðåñà.
 ÷àñòíîñòè, ïîýòîìó òðàññèðîâêà ïåðåêëþ÷åííîé ïðîãðàììû íåâîçìîæíà. Âîò
ïîèñê — äðóãîå äåëî. Ýòî — ïîæàëóéñòà!
:s 23:0 L -1 "KPNC Kaspersky"

Ïîÿñíåíèÿ: ïåðâûé ñëåâà àðãóìåíò ïîñëå s — àäðåñ, çàïèñàííûé â âèäå «ñåëåêòîð: ñìåùåíèå». Ïîä Windows 2000 äëÿ àäðåñàöèè äàííûõ è ñòåêà èñïîëüçóåòñÿ
ñåëåêòîð íîìåð 23, â äðóãèõ îïåðàöèîííûõ ñèñòåìàõ îí ìîæåò îòëè÷àòüñÿ (è îòëè÷àåòñÿ!). Óçíàòü åãî ìîæíî, çàãðóçèâ ëþáóþ ïðîãðàììó è ñïèñàâ ñîäåðæèìîå ðåãèñòðà DS. Ñìåùåíèå — âîîáùå-òî íà÷èíàòü ïîèñê ñ íóëåâîãî ñìåùåíèÿ — èäåÿ ãëóïàÿ. Ñóäÿ ïî êàðòå ïàìÿòè, çäåñü ðàñïîëîæåí ñëóæåáíûé êîä è èñêîìîãî ïàðîëÿ
áûòü íå ìîæåò. Âïðî÷åì, ýòî íè÷åìó íå âðåäèò, è òàê ãîðàçäî áûñòðåå, ÷åì ðàçáèðàòüñÿ, ñ êàêîãî àäðåñà çàãðóæåíà ïðîãðàììà è îòêóäà èìåííî íà÷èíàòü ïîèñê. Òðåòèé àðãóìåíò — L–1 — äëèíà ðåãèîíà äëÿ ïîèñêà. –1, êàê íåòðóäíî äîãàäàòüñÿ, —
ïîèñê «äî ïîáåäû». Äàëåå, îáðàòèòå âíèìàíèå, ÷òî ìû èùåì íå âñþ ñòðîêó, à òîëüêî åå ÷àñòü (KPNC Kaspersky++ ïðîòèâ KPNC Kaspersky) . Ýòî ïîçâîëÿåò èçáàâèòüñÿ îò ëîæíûõ ñðàáàòûâàíèé — Àéñ ëþáèò âûäàâàòü ññûëêè íà ñâîè âíóòðåííèå áóôåðà, ñîäåðæàùèå øàáëîí ïîèñêà. Âîîáùå-òî îíè âñåãäà ðàñïîëîæåíû âûøå
0õ80000000, òàì, ãäå íèêàêîé íîðìàëüíûé ïàðîëü íå æèâåò, íî âñå æå áóäåò íàãëÿäíåå, åñëè íà íåïîëíîé ïîäñòðîêå áóäåò íàõîäèòüñÿ èìåííî íàøà ñòðîêà.
Pattern found at 0023:00016E40 (00016E40)

Òàê, ïî êðàéíåé ìåðå, îäíî âõîæäåíèå óæå íàéäåíî. Íî âäðóã â ïàìÿòè åñòü
åùå íåñêîëüêî? Ïðîâåðèì ýòî, ïîñëåäîâàòåëüíî îòäàâàÿ êîìàíäû s âïëîòü äî âûäà÷è ñîîáùåíèÿ Pattern not found èëè ïðåâûøåíèÿ àäðåñà ïîèñêà 0x80000000.
:s
Pattern found at 0023:0013FF18 (0013FF18)
:s
Pattern found at 0023:0024069C (0024069C)
:s
Pattern found at 0023:80B83F18 (80B83F18)

Öåëûõ äâà âõîæäåíèÿ, äà åùå îäíî «â óìå» — èòîãî òðè! Íå ìíîãî ëè äëÿ
íàñ, íà÷èíàþùèõ? Âî-ïåðâûõ, íåÿñíî — ââîäèìûå ïàðîëè, îíè ÷òî, ïëîäÿòñÿ àêè
êðîëèêè? Âî-âòîðûõ, íó íå ñòàâèòü æå âñå òðè òî÷êè îñòàíîâà.  äàííîì ñëó÷àå
÷åòûðåõ îòëàäî÷íûõ ðåãèñòðîâ ïðîöåññîðà õâàòèò, à êàê áûòü, åñëè áû ìû íàøëè
äåñÿòîê âõîæäåíèé? Äà è â òðåõ áðÿêàõ íåìóäðåíî çàáëóäèòüñÿ ñ íåïðèâû÷êè!
Èòàê, íà÷èíàåì ðàáîòàòü ãîëîâîé. Âõîæäåíèé ìíîãî, âåðîÿòíåå âñåãî, ïîòîìó, ÷òî ïðè ÷òåíèè ââîäà ñ êëàâèàòóðû ñèìâîëû ñïåðâà ïîïàäàþò â ñèñòåìíûå áó-

48

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

ôåðû, êîòîðûå è äàþò ëîæíûå ñðàáàòûâàíèÿ. Çâó÷èò âïîëíå ïðàâäîïîäîáíî, íî
âîò êàê îòôèëüòðîâàòü ïîìåõè?
Íà ïîìîùü ïðèõîäèò êàðòà ïàìÿòè — çíàÿ âëàäåëüöà ðåãèîíà, êîòîðîìó ïðèíàäëåæèò áóôåð, ìîæíî î÷åíü ìíîãîå ñêàçàòü îá ýòîì áóôåðå. Íàñêîðî íàáèâ
êîìàíäó map32 simple, ìû ïîëó÷èì ïðèáëèçèòåëüíî ñëåäóþùåå:
:map32 simple
Owner
Obj Name Obj# Address
Size
simple
.text
0001 001B:00011000 00003F66
simple
.rdata
0002 0023:00015000 0000081E
simple
.data
0003 0023:00016000 00001E44

Type
CODE RO
IDATA RO
IDATA RW

Óðà, äåðæè Òèãðó çà õâîñò, åñòü îäíî îòîæäåñòâëåíèå! Áóôåð íà 0x16E40 ïðèíàäëåæèò ñåãìåíòó äàííûõ, è, âèäèìî, ýòî è åñòü òî, ÷òî íàì íóæíî. Íî íå ñòîèò
ñïåøèòü! Âñå íå òàê ïðîñòî. Ïîèùåì-êà àäðåñ 0x16E40 â ñàìîì ôàéëå simple.exe
(ó÷èòûâàÿ îáðàòíûé ïîðÿäîê áàéòîâ, ýòî áóäåò 40 E6 01 00):
> dumpbin /SECTION:.data /RAWDATA simple.exe
RAW DATA #3
00016030: 45 6E 74 65 72 20 70 61 73 73 77
00016040: 6D 79 47 4F 4F 44 70 61 73 73 77
00016050: 57 72 6F 6E 67 20 70 61 73 73 77
00016060: 50 61 73 73 77 6F 72 64 20 4F 4B
00016070: 40 6E 01 00 00 00 00 00 40 6E 01
00016080: 00 00 00 00 00 00 00 00 00 10 00

6F
6F
6F
0A
00
00

72
72
72
00
01
00

64
64
64
00
01
00

3A
0A
0A
00
00
00

00
00
00
00
00
00

Enter password:.
myGOODpassword..
Wrong password..
Password OK.....
@n......@n......
................

Åñòü, äà? Äàæå äâà ðàçà! Ïîñìîòðèì òåïåðü, êòî íà íåãî ññûëàåòñÿ, ïîïðîáóåì íàéòè â äèçàññåìáëèðîâàííîì òåêñòå ïîäñòðîêó «16070» — àäðåñ ïåðâîãî
äâîéíîãî ñëîâà, óêàçûâàþùåãî íà íàø áóôåð.
00011032: 68 70 60 01 00
00011037: 6A 64
00011039: 8D 4D 98

0001103C: 51
0001103D: E8 E2 00 00 00
00011042: 83 C4 0C

push
16070h
; 0
;*
;* No entry point to code

68
7E5B:114
7E5B:116
7E5B:119
7E5B:11F
7E5B:125
7E5B:12B
7E5B:131
7E5B:137

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
18
D2
6E
03
07
6B
59
2B

00
6F
67
0A
0F
6C
5E
CE

DC
AB
0A
0A
42
BF
F3

Crypt

47
09
09
E8
00
A4

A5
4A
14
00
01
C3

2E
35
47
00
57

sbb
shr
db 6Eh,
db 03h,
db 07h,
db 6Bh,
db 59h,
db 2Bh,

[bx+si],al
byte ptr [bx-24h],cl ; Shift w/zeros fill
67h,0ABh, 47h,0A5h, 2Eh
0Ah, 0Ah, 09h, 4Ah, 35h
0Fh, 0Ah, 09h, 14h, 47h
6Ch, 42h, E8h, 00h, 00h
5Eh, BFh, 00h, 01h, 57h
CEh, F3h, A4h, C3h

endp

SOURCER ïîëîâèíó êîäà âîîáùå íå ñìîã äèçàññåìáëèðîâàòü, îñòàâèâ åãî â
âèäå äàìïà, à äðóãóþ ïîëîâèíó äèçàññåìáëèðîâàë íåïðàâèëüíî! Êîìàíäà JMP SI â
ñòðîêå :0x103 îñóùåñòâëÿåò ïåðåõîä ïî àäðåñó :0x106 (çíà÷åíèå ðåãèñòðà SI ïîñëå çàãðóçêè com-ôàéëà ðàâíî 0x100, ïîýòîìó ïîñëå êîìàíäû ADD SI,6 ðåãèñòð SI
ðàâåí 0x106). Íî ñëåäóþùàÿ çà JMP êîìàíäà ðàñïîëîæåíà ïî àäðåñó 0x105! Â èñõîäíîì òåêñòå â ýòî ìåñòî âñòàâëåí áàéò-ïóñòûøêà, ñáèâàþùèé äèçàññåìáëåð ñ
òîëêó.
Start:
ADD SI,6
JMP SI
DB 0B9h
LEA SI,_end

;
; Íà íà÷àëî çàøèôðîâàííîãî ôðàãìåíòà

SOURCER íå îáëàäàåò ñïîñîáíîñòüþ ïðåäñêàçûâàòü ðåãèñòðîâûå ïåðåõîäû è,
âñòðåòèâ êîìàíäó JMP SI, ïðîäîëæàåò äèçàññåìáëèðîâàíèå, ìîë÷àëèâî ïðåäïîëàãàÿ, ÷òî êîìàíäû ïîñëåäîâàòåëüíî ðàñïîëîæåíû âïëîòíóþ äðóã ê äðóãó. Ñóùåñòâóåò âîçìîæíîñòü ñîçäàòü ôàéë îïðåäåëåíèé, óêàçûâàþùèé, ÷òî ïî àäðåñó: 0x105
ðàñïîëîæåí áàéò äàííûõ, íî ïîäîáíîå âçàèìîäåéñòâèå ñ ïîëüçîâàòåëåì î÷åíü íåóäîáíî.
Íàïðîòèâ, IDA èçíà÷àëüíî ïðîåêòèðîâàëàñü êàê äðóæåñòâåííàÿ ê ïîëüçîâàòåëþ èíòåðàêòèâíàÿ ñðåäà.  îòëè÷èå îò SURCER-ïîäîáíûõ äèçàññåìáëåðîâ, IDA
íå äåëàåò íèêàêèõ ìîë÷àëèâûõ ïðåäïîëîæåíèé, è ïðè âîçíèêíîâåíèè çàòðóäíåíèé îáðàùàåòñÿ çà ïîìîùüþ ê ÷åëîâåêó. Ïîýòîìó, âñòðåòèâ ðåãèñòðîâûé ïåðåõîä
ïî íåèçâåñòíîìó àäðåñó, îíà ïðåêðàùàåò äàëüíåéøèé àíàëèç, è ðåçóëüòàò àíàëèçà ôàéëà Crypt.com âûãëÿäèò òàê:
seg000:0100 start
proc near
seg000:0100
add
si, 6
seg000:0103
jmp
si
seg000:0103 start
endp
seg000:0103
seg000:0103 ; ———————————————————————————————————————————————————————————————————————————
seg000:0105
db 0B9h ; ø
seg000:0106
db 0BEh ; seg000:0107
db 14h ;
seg000:0108
db
1 ;
seg000:0109
db 0ADh ; i
seg000:010A
db 91h ; N
...

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

69

Íåîáõîäèìî ïîìî÷ü äèçàññåìáëåðó, óêàçàâ àäðåñ ïåðåõîäà. Íà÷èíàþùèå
ïîëüçîâàòåëè â ýòîé ñèòóàöèè îáû÷íî ïîäâîäÿò êóðñîð ê ñîîòâåòñòâóþùåé ñòðîêå
è íàæèìàþò êëàâèøó , çàñòàâëÿÿ IDA äèçàññåìáëèðîâàòü êîä ñ òåêóùåé ïîçèöèè äî êîíöà ôóíêöèè. Íåñìîòðÿ íà êàæóùóþñÿ î÷åâèäíîñòü, òàêîå ðåøåíèå
îøèáî÷íî, èáî ïî-ïðåæíåìó îñòàåòñÿ íåèçâåñòíûì, êóäà óêàçûâàåò óñëîâíûé ïåðåõîä â ñòðîêå :0x103 è îòêóäà êîä, ðàñïîëîæåííûé ïî àäðåñó :0x106, ïîëó÷àåò
óïðàâëåíèå.
Ïðàâèëüíîå ðåøåíèå — äîáàâèòü ïåðåêðåñòíóþ ññûëêó, ñâÿçûâàþùóþ ñòðîêó: 0x103 ñî ñòðîêîé: 0x106. Äëÿ ýòîãî íåîáõîäèìî â ìåíþ View âûáðàòü ïóíêò
Cross references è â ïîÿâèâøåìñÿ îêíå äèàëîãà çàïîëíèòü ïîëÿ from è to çíà÷åíèÿìè seg000:0103 è seg000:0106 ñîîòâåòñòâåííî.
Ïîñëå ýòîãî ýêðàí äèçàññåìáëåðà äîëæåí âûãëÿäåòü ñëåäóþùèì îáðàçîì (â
IDA âåðñèè 4.01.300 ñîäåðæèòñÿ îøèáêà, è äîáàâëåíèå íîâîé ïåðåêðåñòíîé ññûëêè íå âñåãäà ïðèâîäèò ê àâòîìàòè÷åñêîìó äèçàññåìáëèðîâàíèþ):
seg000:0100
seg000:0100
seg000:0100
seg000:0103
seg000:0103
seg000:0103
seg000:0103
seg000:0105
seg000:0106
seg000:0106
seg000:0106
seg000:0106
seg000:0109
seg000:010A
seg000:010B
seg000:010C
seg000:010C
seg000:010C
seg000:010F
seg000:0110
seg000:0112
seg000:0112
seg000:0114
seg000:0115
seg000:0116
seg000:0117
...

start

start

public start
proc near
add
si, 6
jmp
si
endp

; —————————————————————————————————————————————————————————————————————————db 0B9h ; ø
; —————————————————————————————————————————————————————————————————————————loc_0_106:

; CODE XREF: start+3↑u
mov
lodsw
xchg
push

si, 114h
ax, cx
si

loc_0_10C:

; CODE XREF: seg000:0110(j
xor
byte ptr [si], 66h
inc
si
loop
loc_0_10C
jmp
si
; ——————————————————————————————————————————————————————————————————————————
db 18h ;
db
0 ;
db 0D2h ; T
db 6Fh ; o

Ïîñêîëüêó IDA Pro íå îòîáðàæàåò àäðåñà-ïðèåìíèêà ïåðåêðåñòíîé ññûëêè,
òî ðåêîìåíäóåòñÿ âûïîëíèòü ýòî ñàìîñòîÿòåëüíî. Òàêîé ïðèåì óëó÷øèò íàãëÿäíîñòü òåêñòà è óïðîñòèò íàâèãàöèþ. Åñëè ïîâåñòè êóðñîð ê ñòðîêå :0x103, íàæàòü
êëàâèøó , ââåäÿ â ïîÿâèâøåìñÿ äèàëîãîâîì îêíå ëþáîé îñìûñëåííûé êîììåíòàðèé (íàïðèìåð, «ïåðåõîä ïî àäðåñó 0106»), òî ýêðàí ïðèìåò ñëåäóþùèé âèä:
seg000:0103

jmp

si

; Ïåðåõîä ïî àäðåñó 0106

70

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Öåííîñòü òàêîãî ïðèåìà çàêëþ÷àåòñÿ â âîçìîæíîñòè áûñòðîãî ïåðåõîäà ïî
àäðåñó, íà êîòîðûé ññûëàåòñÿ JMP SI, äîñòàòî÷íî ëèøü ïîäâåñòè êóðñîð ê ÷èñëó
0106 è íàæàòü êëàâèøó . Âàæíî ñîáëþäàòü ïðàâèëüíîñòü íàïèñàíèÿ —
IDA Pro íå ðàñïîçíàåò øåñòíàäöàòåðè÷íûé ôîðìàò íè â ñòèëå Ñ (0x106), íè â ñòèëå MASM\TASM (0106h).
×òî ïðåäñòàâëÿåò ñîáîé ÷èñëî 114h â ñòðîêå :0x106 — êîíñòàíòó èëè ñìåùåíèå? ×òîáû óçíàòü ýòî, íåîáõîäèìî ïðîàíàëèçèðîâàòü êîìàíäó LODSW, ïîñêîëüêó åå âûïîëíåíèå ïðèâîäèò ê çàãðóçêå â ðåãèñòð AX ñëîâà, ðàñïîëîæåííîãî ïî àäðåñó DS:SI, î÷åâèäíî, â ðåãèñòð SI çàíîñèòñÿ ñìåùåíèå.
seg000:0106
seg000:0109

mov
lodsw

si, 114h

Îäíîêðàòíîå íàæàòèå êëàâèøè ïðåîáðàçóåò êîíñòàíòó â ñìåùåíèå, è
äèçàññåìáëèðóåìûé òåêñò ñòàíåò âûãëÿäåòü òàê:
seg000:0106
seg000:0109
...
seg000:0114 unk_0_114
seg000:0115
seg000:0116
seg000:0117
...

mov
lodsw

si, offset unk_0_114

db 18h ;
db
0 ;
db 0D2h ; T
db 6Fh ; o

; DATA XREF: seg000:0106↑o

IDA Pro àâòîìàòè÷åñêè ñîçäàëà íîâîå èìÿ unk_0_114, ññûëàþùååñÿ íà ïåðåìåííóþ íåîïðåäåëåííîãî òèïà ðàçìåðîì â áàéò, íî êîìàíäà LODSW çàãðóæàåò â
ðåãèñòð AX ñëîâî, ïîýòîìó íåîáõîäèìî ïåðåéòè ê ñòðîêå :0144 è äâàæäû íàæàòü
êëàâèøó .  ýòîì ñëó÷àå ýêðàí ñòàíåò âûãëÿäåòü òàê:
seg000:0114 word_0_114
seg000:0116

dw 18h
db 0D2h ; T

; DATA XREF: seg000:0106↑o

Íî ÷òî èìåííî ñîäåðæèòñÿ â ÿ÷åéêå word_0_144? Ïîíÿòü ýòî ïîçâîëèò èçó÷åíèå ñëåäóþùåãî êîäà:
seg000:0106
seg000:0109
seg000:010A
seg000:010B
seg000:010C
seg000:010C loc_0_10C:
seg000:010C
seg000:010F
seg000:0110

mov
lodsw
xchg
push

si, offset word_0_114
ax, cx
si

xor
inc
loop

; CODE XREF: seg000:0110↓j
byte ptr [si], 66h
si
loc_0_10C

 ñòðîêå :0x10A çíà÷åíèå ðåãèñòðà AX ïîìåùàåòñÿ â ðåãèñòð CX, è çàòåì îí
èñïîëüçóåòñÿ êîìàíäîé LOOP LOC_010C êàê ñ÷åò÷èê öèêëà. Òåëî öèêëà ïðåäñòàâëÿåò ñîáîé ïðîñòåéøèé ðàñøèôðîâùèê — êîìàíäà XOR ðàñøèôðîâûâàåò
îäèí áàéò, íà êîòîðûé óêàçûâàåò ðåãèñòð SI, à êîìàíäà INC SI ïåðåìåùàåò óêàçàòåëü íà ñëåäóþùèé áàéò. Ñëåäîâàòåëüíî, â ÿ÷åéêå word_0_144 ñîäåðæèòñÿ êîëè-

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

71

÷åñòâî áàéòîâ, êîòîðûå íåîáõîäèìî ðàñøèôðîâàòü. Ïîäâåäÿ ê íåé êóðñîð, íàæàòèåì êëàâèøè ìîæíî äàòü åé îñìûñëåííîå èìÿ, íàïðèìåð BytesToDecrypt.
Ïîñëå çàâåðøåíèÿ öèêëà ðàñøèôðîâùèêà âñòðå÷àåòñÿ åùå îäèí áåçóñëîâíûé
ðåãèñòðîâûé ïåðåõîä:
seg000:0112

jmp

si

×òîáû óçíàòü, êóäà èìåííî îí ïåðåäàåò óïðàâëåíèå, íåîáõîäèìî ïðîàíàëèçèðîâàòü êîä è îïðåäåëèòü ñîäåðæèìîå ðåãèñòðà SI. Äëÿ ýòîé öåëè ÷àñòî ïðèáåãàþò
ê ïîìîùè îòëàä÷èêà — óñòàíàâëèâàþò òî÷êó îñòàíîâà â ñòðîêå 0x112 è, äîæäàâøèñü åãî âñïëûòèÿ, ïðîñìàòðèâàþò çíà÷åíèÿ ðåãèñòðîâ. Ñïåöèàëüíî äëÿ ýòîé
öåëè IDA Pro ïîääåðæèâàåò ãåíåðàöèþ map-ôàéëîâ, ñîäåðæàùèõ ñèìâîëüíóþ èíôîðìàöèþ äëÿ îòëàä÷èêà.  ÷àñòíîñòè, ÷òîáû íå çàó÷èâàòü ÷èñëåííûå çíà÷åíèÿ
âñåõ ïîäîïûòíûõ àäðåñîâ, êàæäîìó èç íèõ ìîæíî ïðèñâîèòü ëåãêî çàïîìèíàåìîå
ñèìâîëüíîå èìÿ. Íàïðèìåð, åñëè ïîäâåñòè êóðñîð ê ñòðîêå seg000:0112, íàæàòü
êëàâèøó è ââåñòè êîìàíäó BreakHere, îòëàä÷èê ñìîæåò àâòîìàòè÷åñêè âû÷èñëèòü îáðàòíûé àäðåñ ïî åãî èìåíè.
Äëÿ ñîçäàíèÿ map-ôàéëà â ìåíþ File íåîáõîäèìî ùåëêíóòü ìûøüþ ïî êîìàíäå
Produce output file è â ðàçâåðíóâøåìñÿ ïîäìåíþ âûáðàòü êîìàíäó Produce MAP
file èëè âìåñòî âñåãî ýòîãî íàæàòü íà êëàâèàòóðå «ãîðÿ÷óþ» êîìáèíàöèþ . Íåçàâèñèìî îò ñïîñîáà âûçîâà íà ýêðàíå äîëæíî ïîÿâèòüñÿ äèàëîãîâîå îêíî,
ïîçâîëÿþùåå âûáðàòü, êàêîãî ðîäà äàííûå áóäóò âêëþ÷åíû â map-ôàéë — èíôîðìàöèÿ î ñåãìåíòàõ, èìåíà, àâòîìàòè÷åñêè ñãåíåðèðîâàííûå IDA Pro (òàêèå, êàê, íàïðèìåð, loc_0_106, sub_0x110 è ò. ä.), è «ðàçìàíãëåííûå» (ò. å. ïðèâåäåííûå â ÷èòàáåëüíûé âèä) èìåíà. Ñîäåðæèìîå ïîëó÷åííîãî map-ôàéëà äîëæíî áûòü ñëåäóþùèì:
Start Stop Length Name
00100H 0013BH 0003CH seg000
Address
Publics by Value
0000:0100
start
0000:0112
BreakHere
0000:0114
BytesToDecrypt
Program entry point at 0000:0100

Class
CODE

Òàêîé ôîðìàò ïîääåðæèâàåò áîëüøèíñòâî îòëàä÷èêîâ, â òîì ÷èñëå è ïîïóëÿðíåéøèé Soft-Ice, â ïîñòàâêó êîòîðîãî âõîäèò óòèëèòà msym, çàïóñêàåìàÿ ñ
óêàçàíèåì èìåíè êîíâåðòèðóåìîãî map-ôàéëà â êîìàíäíîé ñòðîêå. Ïîëó÷åííûé
sym-ôàéë íåîáõîäèìî ðàçìåñòèòü â îäíîé äèðåêòîðèè ñ îòëàæèâàåìîé ïðîãðàììîé, çàãðóæàåìîé â çàãðóç÷èê áåç óêàçàíèÿ ðàñøèðåíèÿ, ò. å., íàïðèìåð, òàê:
WLDR Crypt.  ïðîòèâíîì ñëó÷àå ñèìâîëüíàÿ èíôîðìàöèÿ íå áóäåò çàãðóæåíà!
Çàòåì íåîáõîäèìî óñòàíîâèòü òî÷êó îñòàíîâà êîìàíäîé bpx BreakHere è ïîêèíóòü îòëàä÷èê êîìàíäîé x. Ñïóñòÿ ñåêóíäó åãî îêíî âíîâü ïîÿâèòñÿ íà ýêðàíå,
èçâåùàÿ î äîñòèæåíèè ïðîöåññîðîì êîíòðîëüíîé òî÷êè. Ïîñìîòðåâ íà çíà÷åíèÿ
ðåãèñòðîâ, îòîáðàæàåìûõ ïî óìîë÷àíèþ ââåðõó ýêðàíà, ìîæíî âûÿñíèòü, ÷òî ñîäåðæèìîå SI ðàâíî 0x12E.
Ñ äðóãîé ñòîðîíû, ýòî æå çíà÷åíèå ìîæíî âû÷èñëèòü â óìå, íå ïðèáåãàÿ ê îòëàä÷èêó. Êîìàíäà MOV â ñòðîêå 0x106 çàãðóæàåò â ðåãèñòð SI ñìåùåíèå 0x114,
îòêóäà êîìàíäîé LODSW ñ÷èòûâàåòñÿ êîëè÷åñòâî ðàñøèôðîâûâàåìûõ áàéòîâ —

72

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

0x18, ïðè ýòîì ñîäåðæèìîå SI óâåëè÷èâàåòñÿ íà ðàçìåð ñëîâà — äâà áàéòà. Îòñþäà â ìîìåíò çàâåðøåíèÿ öèêëà ðàñøèôðîâêè çíà÷åíèå SI áóäåò ðàâíî 0x114 +
+ 0x18 + 0x2 = 0x12E.
Âû÷èñëèâ àäðåñ ïåðåõîäà â ñòðîêå 0x112, ðåêîìåíäóåòñÿ ñîçäàòü ñîîòâåòñòâóþùóþ ïåðåêðåñòíóþ ññûëêó (from: 0x122; to: 0x12E) è äîáàâèòü êîììåíòàðèé ê
ñòðîêå 0x112 («Ïåðåõîä ïî àäðåñó 012E»). Ñîçäàíèå ïåðåêðåñòíîé ññûëêè àâòîìàòè÷åñêè äèçàññåìáëèðóåò êîä, íà÷èíàÿ ñ àäðåñà seg000:012E è äî êîíöà ôàéëà.
seg000:012E loc_0_12E:
; CODE XREF: seg000:0112u
seg000:012E
call $+3
seg000:0131
pop cx
seg000:0132
pop si
seg000:0133
mov di, 100h
seg000:0136
push di
seg000:0137
sub cx, si
seg000:0139
repe movsb
seg000:013B
retn

Íàçíà÷åíèå êîìàíäû CALL $ + 3 (ãäå $ îáîçíà÷àåò òåêóùåå çíà÷åíèå ðåãèñòðà óêàçàòåëÿ êîìàíä IP) ñîñòîèò â çàòàëêèâàíèè â ñòåê ñîäåðæèìîãî ðåãèñòðà IP,
îòêóäà âïîñëåäñòâèè îíî ìîæåò áûòü èçâëå÷åíî â ëþáîé ðåãèñòð îáùåãî íàçíà÷åíèÿ. Íåîáõîäèìîñòü ïîäîáíîãî òðþêà îáúÿñíÿåòñÿ òåì, ÷òî â ìèêðîïðîöåññîðàõ
ñåðèè Intel 80x86 ðåãèñòð IP íå âõîäèò â ñïèñîê íåïîñðåäñòâåííî àäðåñóåìûõ è
÷èòàòü åãî çíà÷åíèå ìîãóò ëèøü êîìàíäû, èçìåíÿþùèå õîä âûïîëíåíèÿ ïðîãðàììû, â òîì ÷èñëå è call.
Äëÿ îáëåã÷åíèÿ àíàëèçà ëèñòèíãà ìîæíî äîáàâèòü ê ñòðîêàì 0x12E è 0x131
êîììåíòàðèé MOV CX, IP èëè, åùå ëó÷øå, ñðàçó âû÷èñëèòü è ïîäñòàâèòü íåïîñðåäñòâåííîå çíà÷åíèå MOV CX,0x131.
Êîìàíäà POP SI â ñòðîêå 0x132 ñíèìàåò ñëîâî èç ñòåêà è ïîìåùàåò åãî â ðåãèñòð SI. Ïðîêðó÷èâàÿ ýêðàí äèçàññåìáëåðà ââåðõ, â ñòðîêå 0x10B ìîæíî îáíàðóæèòü ïàðíóþ åé èíñòðóêöèþ PUSH SI, çàíîñÿùóþ â ñòåê ñìåùåíèå ïåðâîãî ðàñøèôðîâûâàåìîãî áàéòà. Ïîñëå ýòîãî ñòàíîâèòñÿ ïîíÿòíûì ñìûñë ïîñëåäóþùèõ
êîìàíä MOV DI, 0x100\SUB CX,SI\REPE MOVSB. Îíè ïåðåìåùàþò íà÷àëî
ðàñøèôðîâàííîãî ôðàãìåíòà ïî àäðåñó, íà÷èíàþùåãîñÿ ñî ñìåùåíèÿ 0x100. Òàêàÿ îïåðàöèÿ õàðàêòåðíà äëÿ êîíâåðòíûõ çàùèò, íàêëàäûâàþùèõñÿ íà óæå îòêîìïèëèðîâàííûé ôàéë, êîòîðûé ïåðåä çàïóñêîì äîëæåí áûòü ðàçìåùåí ïî ñâîèì
ðîäíûì àäðåñàì.
Ïåðåä íà÷àëîì ïåðåìåùåíèÿ â ðåãèñòð CX çàíîñèòñÿ äëèíà êîïèðóåìîãî áëîêà, âû÷èñëÿåìàÿ ïóòåì âû÷èòàíèÿ ñìåùåíèÿ ïåðâîãî ðàñøèôðîâàííîãî áàéòà îò
ñìåùåíèÿ âòîðîé êîìàíäû ïåðåìåùàþùåãî êîäà. Â äåéñòâèòåëüíîñòè èñòèííàÿ
äëèíà áëîêà íà òðè áàéòà êîðî÷å âû÷èñëåííîé, è ïî èäåå, îò ïîëó÷åííîãî çíà÷åíèÿ íåîáõîäèìî âû÷åñòü òðè. Îäíàêî òàêîå íåñîãëàñîâàíèå íå íàðóøàåò ðàáîòîñïîñîáíîñòè, ïîñêîëüêó ñîäåðæèìîå ÿ÷ååê ïàìÿòè, ëåæàùèõ çà êîíöîì ðàñøèôðîâàííîãî ôðàãìåíòà, íå îïðåäåëåíî è ìîæåò áûòü ëþáûì.
Ïàðà êîìàíä 0x136:PUSH DI è 0x13B:RETN îáðàçóåò àíàëîã èíñòðóêöèè
CALL DI — PUSH çàòàëêèâàåò àäðåñ âîçâðàòà â ñòåê, à RETN èçâëåêàåò åãî îòòóäà è ïåðåäàåò óïðàâëåíèå ïî ñîîòâåòñòâóþùåìó àäðåñó. Çíàÿ çíà÷åíèå DI (îíî

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

73

ðàâíî 0x100), ìîæíî áûëî áû äîáàâèòü åùå îäíó ïåðåêðåñòíóþ ññûëêó
(from:0x13B; to:0x100) è êîììåíòàðèé ê ñòðîêå :0x13B — «Ïåðåõîä ïî àäðåñó
0x100», íî âåäü ê ýòîìó ìîìåíòó ïî óêàçàííûì àäðåñàì ðàñïîëîæåí ñîâñåì äðóãîé êîä! Ïîýòîìó ëîãè÷åñêè ïðàâèëüíåå äîáàâèòü ïåðåêðåñòíóþ ññûëêó
from:0x13B; to:0x116 è êîììåíòàðèé «Ïåðåõîä ïî àäðåñó 0x116».
Ñðàçó æå ïîñëå ñîçäàíèÿ íîâîé ïåðåêðåñòíîé ññûëêè IDA ïîïûòàåòñÿ äèçàññåìáëèðîâàòü çàøèôðîâàííûé êîä, â ðåçóëüòàòå ÷åãî ïîëó÷èòñÿ ñëåäóþùåå:
seg000:0116 loc_0_116:
; CODE XREF: seg000:013Bu
seg000:0116
shr
byte ptr [bx-24h], cl
seg000:0119
outsb
seg000:011A
stos
word ptr es:[edi]
seg000:011C
inc
di
seg000:011D
movsw
seg000:011E
add
cx, cs:[bp+si]
seg000:0121
or
cl, [bx+di]
seg000:0123
dec
dx
seg000:0124
xor
ax, 0F07h
seg000:0127
or
cl, [bx+di]
seg000:0129
adc
al, 47h
seg000:0129;—————————————————————————————————————————————————————————————————————————————
seg000:012B
db
6Bh ; k
seg000:012C
db
6Ch ; l
seg000:012D
db
42h ; B
seg000:012E;—————————————————————————————————————————————————————————————————————————————

Íåïîñðåäñòâåííîå äèçàññåìáëèðîâàíèå çàøèôðîâàííîãî êîäà íåâîçìîæíî —
ïðåäâàðèòåëüíî åãî íåîáõîäèìî ðàñøèôðîâàòü. Ïîäàâëÿþùåå áîëüøèíñòâî äèçàññåìáëåðîâ íå ìîãóò ìîäèôèöèðîâàòü àíàëèçèðóåìûé òåêñò íà ëåòó, è äî çàãðóçêè â äèçàññåìáëåð èññëåäóåìûé ôàéë äîëæåí áûòü ïîëíîñòüþ ðàñøèôðîâàí.
Íà ïðàêòèêå, îäíàêî, ýòî âûãëÿäèò íåñêîëüêî èíà÷å. Ïðåæäå ÷åì ðàñøèôðîâûâàòü, íåîáõîäèìî âûÿñíèòü àëãîðèòì ðàñøèôðîâêè, ïðîàíàëèçèðîâàâ äîñòóïíóþ
÷àñòü ôàéëà. Çàòåì íóæíî âûéòè èç äèçàññåìáëåðà, òåì èëè èíûì ñïîñîáîì ðàñøèôðîâàòü «ñåêðåòíûé» ôðàãìåíò, âíîâü çàãðóçèòü ôàéë â äèçàññåìáëåð (ïðè÷åì
ïðåäûäóùèå ðåçóëüòàòû äèçàññåìáëèðîâàíèÿ îêàæóòñÿ óòåðÿííûìè) è ïðîäîëæèòü åãî àíàëèç äî òåõ ïîð, ïîêà íå âñòðåòèòñÿ åùå îäèí çàøèôðîâàííûé ôðàãìåíò, ïîñëå ÷åãî îïèñàííûé öèêë «âûõîä èç äèçàññåìáëåðà — ðàñøèôðîâêà — çàãðóçêà — àíàëèç» ïîâòîðÿåòñÿ âíîâü.
Äîñòîèíñòâî IDA çàêëþ÷àåòñÿ â òîì, ÷òî îíà ïîçâîëÿåò âûïîëíèòü òó æå çàäà÷ó çíà÷èòåëüíî ìåíüøèìè óñèëèÿìè, íèêóäà íå âûõîäÿ èç äèçàññåìáëåðà. Ýòî
äîñòèãàåòñÿ çà ñ÷åò íàëè÷èÿ ìåõàíèçìà âèðòóàëüíîé ïàìÿòè. Åñëè íå âäàâàòüñÿ â
òåõíè÷åñêèå òîíêîñòè, ìîæíî óïðîùåííî èçîáðàçèòü IDA â âèäå ïðîçðà÷íîéâèðòóàëüíîé ìàøèíû, îïåðèðóþùåé ñ ôèçè÷åñêîé ïàìÿòüþ êîìïüþòåðà. Äëÿ ìîäèôèêàöèè ÿ÷ååê ïàìÿòè íåîáõîäèìî çíàòü èõ àäðåñ, ñîñòîÿùèé èç ïàðû ÷èñåë —
ñåãìåíòà è ñìåùåíèÿ.
Ñëåâà êàæäîé ñòðîêè óêàçûâàåòñÿ åå ñìåùåíèå è èìÿ ñåãìåíòà, íàïðèìåð
seg000:0116. Óçíàòü áàçîâûé àäðåñ ñåãìåíòà ïî åãî èìåíè ìîæíî, îòêðûâ îêíî
«Ñåãìåíòû» è âûáðàâ â ìåíþ View ïóíêò Segments.

74

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Ðèñ. 8. Îêíî «Ñåãìåíòû»

Èñêîìûé àäðåñ íàõîäèòñÿ â ñòîëáöå Base; äëÿ íàãëÿäíîñòè íà ïðèâåäåííîé
êîïèè ýêðàíà îí âûäåëåí æèðíûì øðèôòîì. Îáðàòèòüñÿ ê ëþáîé ÿ÷åéêå ñåãìåíòà
ïîìîæåò êîíñòðóêöèÿ [segment:offset], à äëÿ ÷òåíèÿ è ìîäèôèêàöèè ÿ÷ååê ïðåäóñìîòðåíû ôóíêöèè Byte è PatchByte ñîîòâåòñòâåííî. Èõ âûçîâ ìîæåò âûãëÿäåòü,
íàïðèìåð, òàê: a=Byte([0x1000,0x100]) — ÷èòàåò ÿ÷åéêó, ðàñïîëîæåííóþ ïî ñìåùåíèþ 0x100 â ñåãìåíòå ñ áàçîâûì àäðåñîì 0x1000; PatchByte([0x1000,0x100],0x27) — ïðèñâàèâàåò çíà÷åíèå 0x27 ÿ÷åéêå ïàìÿòè, ðàñïîëîæåííîé ïî ñìåùåíèþ 0x100 â ñåãìåíòå ñ áàçîâûì àäðåñîì 0x1000. Êàê ñëåäóåò èç
íàçâàíèÿ ôóíêöèé, îíè ìàíèïóëèðóþò ñ ÿ÷åéêàìè ðàçìåðîì â îäèí áàéò.
Çíàíèÿ ýòèõ äâóõ ôóíêöèé âïîëíå äîñòàòî÷íî äëÿ íàïèñàíèÿ ñêðèïòà-ðàñøèôðîâùèêà ïðè óñëîâèè, ÷òî ÷èòàòåëü çíàêîì ñ ÿçûêîì Ñ.
Ðåàëèçàöèÿ IDA-Ñ íå ïîëíîñòüþ ïðèäåðæèâàåòñÿ ñòàíäàðòà, â ÷àñòíîñòè,
IDA íå ïîçâîëÿåò ðàçðàáîò÷èêó çàäàâàòü òèï ïåðåìåííîé è îïðåäåëÿåò åãî àâòîìàòè÷åñêè ïî åå ïåðâîìó èñïîëüçîâàíèþ, à îáúÿâëåíèå îñóùåñòâëÿåòñÿ êëþ÷åâûì ñëîâîì auto. Íàïðèìåð, auto MyVar, s0 îáúÿâëÿåò äâå ïåðåìåííûõ —
MyVar è s0.
Äëÿ ñîçäàíèÿ ñêðèïòà íåîáõîäèìî íàæàòü êîìáèíàöèþ êëàâèø
èëè âûáðàòü â ìåíþ File ïóíêò IDC Command è â ïîÿâèâøåìñÿ îêíå äèàëîãà ââåñòè èñõîäíûé òåêñò ïðîãðàììû:

Ðèñ. 9. Âñòðîåííûé ðåäàêòîð ñêðèïòîâ
auto a;
for (a=0x116;a string terminated by "$"

retn
; ——————————————————————————————————————————————————————————————————————————aHelloSailor db 'Hello,Sailor!',0Dh,0Ah,'$'
; ——————————————————————————————————————————————————————————————————————————-

Êîìàíäà MOV AH,9 â ñòðîêå :0116 ïîäãîòàâëèâàåò ðåãèñòð AH ïåðåä âûçîâîì ïðåðûâàíèÿ 0x21, âûáèðàÿ ôóíêöèþ âûâîäà ñòðîêè íà ýêðàí, ñìåùåíèå êîòîðîé çàíîñèòñÿ ñëåäóþùåé êîìàíäîé â ðåãèñòð DX. Èíûìè ñëîâàìè, äëÿ óñïåøíîãî àññåìáëèðîâàíèÿ ëèñòèíãà íåîáõîäèìî çàìåíèòü êîíñòàíòó 0x108 ñîîòâåòñòâóþùèì ñìåùåíèåì. Íî âåäü âûâîäèìàÿ ñòðîêà íà ýòàïå àññåìáëèðîâàíèÿ (äî ïåðåìåùåíèÿ êîäà) ðàñïîëîæåíà ñîâñåì â äðóãîì ìåñòå! Îäíî èç âîçìîæíûõ ðåøåíèé
ýòîé ïðîáëåìû çàêëþ÷àåòñÿ â ñîçäàíèè íîâîãî ñåãìåíòà ñ ïîñëåäóþùèì êîïèðîâàíèåì â íåãî ðàñøèôðîâàííîãî êîäà, â ðåçóëüòàòå ÷åãî äîñòèãàåòñÿ ýìóëÿöèÿ ïåðåìåùåíèÿ êîäà ðàáîòàþùåé ïðîãðàììû.
Äëÿ ñîçäàíèÿ íîâîãî ñåãìåíòà ìîæíî âûáðàòü â ìåíþ View ïóíêò Segments è
â ðàñêðûâøåìñÿ îêíå íàæàòü êëàâèøó . Ïîÿâèòñÿ äèàëîã ñëåäóþùåãî
âèäà (ðèñ. 10):

Ðèñ. 10. IDAC: cîçäàíèå íîâîãî ñåãìåíòà
Ïîÿñíåíèå
Áàçîâûé àäðåñ ñåãìåíòà ìîæåò áûòü ëþáûì, åñëè ïðè ýòîì íå ïðîèñõîäÿò ïåðåêðûòèÿ ñåãìåíòîâ seg000 è MySeg; íà÷àëüíûé àäðåñ ñåãìåíòà çàäàåòñÿ òàê,
÷òîáû ñìåùåíèå ïåðâîãî áàéòà áûëî ðàâíî 0x100; ðàçíèöà ìåæäó êîíå÷íûì è

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

77

íà÷àëüíûì àäðåñîì ðàâíà äëèíå ñåãìåíòà, âû÷èñëèòü êîòîðóþ ìîæíî âû÷èòàíèåì ñìåùåíèÿ íà÷àëà ðàñøèôðîâàííîãî ôðàãìåíòà îò ñìåùåíèÿ åãî êîíöà —
0x13B – 0x116 = 0x25.

Ñêîïèðîâàòü òðåáóåìûé ôðàãìåíò â òîëüêî ÷òî ñîçäàííûé ñåãìåíò ìîæíî
ñêðèïòîì ñëåäóþùåãî ñîäåðæàíèÿ:
auto a;
for (a=0x0;a string terminated by "$"
MySeg:0107
retn
MySeg:0107 ; ———————————————————————————————————————————————————————————————————————————MySeg:0108 aHelloSailorS db 'Hello,Sailor!',0Dh,0Ah
MySeg:0108
db '$'
MySeg:0118 MySeg
ends

Ðåçóëüòàòîì âñåõ ýòèõ îïåðàöèé ñòàëî ñîâïàäåíèå ñìåùåíèÿ ñòðîêè ñî çíà÷åíèåì, çàãðóæàåìûì â ðåãèñòð DX (â òåêñòå îíè âûäåëåíû æèðíûì øðèôòîì).
Åñëè ïîäâåñòè êóðñîð ê êîíñòàíòå 108h è íàæàòü ñî÷åòàíèå êëàâèø ,
îíà áóäåò ïðåîáðàçîâàíà â ñìåùåíèå:
MySeg:0102
mov dx, offset aHelloSailorS ; "Hello,Sailor!\r\n$ø"
MySeg:0105
int 21h
; DOS - PRINT STRING
MySeg:0105
; DS:DX -> string terminated by "$"
MySeg:0107
retn
MySeg:0107 ; ———————————————————————————————————————————————————————————————————————————MySeg:0108 aHelloSailorS db 'Hello,Sailor!',0Dh,0Ah ; DATA XREF: MySeg:0102o

Ïîëó÷åííûé ëèñòèíã óäîáåí äëÿ àíàëèçà, íî âñå åùå íå ãîòîâ ê àññåìáëèðîâàíèþ õîòÿ áû ïîòîìó, ÷òî íèêàêîé àññåìáëåð íå â ñîñòîÿíèè çàøèôðîâàòü òðåáóåìûé êîä. Êîíå÷íî, ýòó îïåðàöèþ ìîæíî âûïîëíèòü âðó÷íóþ ïîñëå êîìïèëÿöèè, íî IDA ïîçâîëèò ïðîäåëàòü òî æå ñàìîå, íå âûõîäÿ èç íåå è íå ïðèáåãàÿ ê ïîìîùè ñòîðîííåãî èíñòðóìåíòàðèÿ.
Äåìîíñòðàöèÿ ïîëó÷èòñÿ íàìíîãî íàãëÿäíåå, åñëè â èññëåäóåìûé ôàéë âíåñòè íåêîòîðûå èçìåíåíèÿ, íàïðèìåð, äîáàâèòü îæèäàíèå êëàâèøè íà âûõîäå. Äëÿ
ýòîãî ìîæíî ïðèáåãíóòü ê èíòåãðèðîâàííîìó â IDA àññåìáëåðó, íî ïðåæäå, ðàçóìååòñÿ, íåîáõîäèìî íåñêîëüêî «ðàçäâèíóòü» ãðàíèöû ñåãìåíòà MySeg, äàáû áûëî
ê ÷åìó äîïèñûâàòü íîâûé êîä.
Âûáåðèòå â ìåíþ View ïóíêò Segments è â îòêðûâøåìñÿ îêíå ïîäâåäèòå êóðñîð ê ñòðîêå MySeg. Íàæàòèå êîìáèíàöèè êëàâèø îòêðûâàåò äèàëîã
ñâîéñòâ ñåãìåíòà, ñîäåðæàùèé ñðåäè ïðî÷èõ ïîëåé êîíå÷íûé àäðåñ, êîòîðûé è
òðåáóåòñÿ èçìåíèòü. Íå îáÿçàòåëüíî óêàçûâàòü òî÷íîå çíà÷åíèå, ìîæíî «ðàñòÿíóòü» ñåãìåíò ñ íåáîëüøèì çàïàñîì îò ïðåäïîëàãàåìûõ èçìåíåíèé.
Åñëè ïîïûòàòüñÿ äîáàâèòü ê ïðîãðàììå êîä XOR AX,AX; INT 16h, îí
íåìèíóåìî çàòðåò íà÷àëî ñòðîêè «Hello, Sailor!» — ïîýòîìó åå íåîáõîäèìî
çàáëàãîâðåìåííî ïåðåäâèíóòü íåìíîãî «âíèç» (ò. å. â îáëàñòü áîëåå ñòàðøèõ àäðåñîâ), íàïðèìåð, ñ ïîìîùüþ ñêðèïòà ñëåäóþùåãî ñîäåðæàíèÿ:
«for(a=0x108;a string terminated by "$"
seg000:011D
retn
seg000:011D ; ——————————————————————————————————————————————————————————————————————————seg000:011E aHelloSailor
db 'Hello,Sailor!',0Dh,0Ah,'$' ; DATA XREF: seg000:0118o
seg000:012E ; ——————————————————————————————————————————————————————————————————————————seg000:012E
seg000:012E loc_0_12E:
; CODE XREF: seg000:0112u
seg000:012E
call
$+3
seg000:0131
pop
cx
seg000:0132
pop
si
seg000:0133
mov
di, 100h
seg000:0136
push
di
seg000:0137
sub
cx, si
seg000:0139
repe
movsb
seg000:013B
retn
seg000:013B seg000
ends
seg000:013B
MySeg:0100 ; ——————————————————————————————————————————————————————————————————————————MySeg:0100 ; ===========================================================================
MySeg:0100
MySeg:0100 ; Segment type: Regular
MySeg:0100 MySeg
segment byte public '' use16
MySeg:0100
assume cs:MySeg
MySeg:0100
;org 100h
MySeg:0100
assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
MySeg:0100
MySeg:0100 loc_1000_100:
; CODE XREF: seg000:013Bu
MySeg:0100
mov
ah, 9
MySeg:0102
mov
dx, offset aHelloSailor_0 ; "Hello,Sailor!\r\n$"
MySeg:0105
int
21h
; DOS - PRINT STRING
MySeg:0105
; DS:DX -> string terminated by "$"
MySeg:0107
xor
ax, ax
MySeg:0109
int
16h ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY
MySeg:0109
; Return: AH = scan code, AL = character
MySeg:010B
retn
MySeg:010B ; ———————————————————————————————————————————————————————————————————————————MySeg:010C aHelloSailor_0 db 'Hello,Sailor!',0Dh,0Ah,'$' ; DATA XREF: MySeg:0102o
MySeg:010C MySeg
ends
MySeg:010C
MySeg:010C
MySeg:010C end
start

Ñòðóêòóðíî ïðîãðàììà ñîñòîèò èç ñëåäóþùèõ ÷àñòåé: ðàñøèôðîâùèêà, çàíèìàþùåãî àäðåñà seg000:0x100 — seg000:0x113, ïåðåìåííîé ðàçìåðîì â ñëîâî, ñî-

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

81

äåðæàùåé êîëè÷åñòâî ðàñøèôðîâûâàåìûõ áàéòîâ, çàíèìàþùåé àäðåñà
seg000:0x114 — seg000:0x116, èñïîëíÿåìîãî êîäà ïðîãðàììû, çàíèìàþùåãî öåëèêîì ñåãìåíò MySeg, è çàãðóç÷èêà, çàíèìàþùåãî àäðåñà seg000:0x12E —
seg000:0x13B. Âñå ýòè ÷àñòè äîëæíû áûòü â ïåðå÷èñëåííîì ïîðÿäêå ñêîïèðîâàíû
â öåëåâîé ôàéë, ïðè÷åì èñïîëíÿåìûé êîä ïðîãðàììû íåîáõîäèìî ïðåäâàðèòåëüíî
çàøèôðîâàòü, ïðîèçâåäÿ íàä êàæäûì åãî áàéòîì îïåðàöèþ XOR 0x66.
Íèæå ïðèâåäåí ïðèìåð ñêðèïòà, àâòîìàòè÷åñêè âûïîëíÿþùåãî óêàçàííûå
äåéñòâèÿ. Äëÿ åãî çàãðóçêè äîñòàòî÷íî íàæàòü íà êëàâèøó èëè âûáðàòü â
ìåíþ File ïóíêò Load file, IDC file.
// Êîìïèëÿòîð äëÿ ôàéëà Crypt
//
static main()
{
auto a,f;
// Îòêðûâàåòñÿ ôàéë Crtypt2.com äëÿ çàïèñè â äâîè÷íîì ðåæèìå
f=fopen("crypt2.com","wb");
// Â ôàéë Crypt2 êîïèðóåòñÿ ðàñøèôðîâùèê
for (a=0x100;a 0"
mov
[ebp+var_b], 1
; Çàïèñûâàåì â ïåðåìåííóþ var_b çíà÷åíèå 1
jmp
short continue
; Ïåðåõîä ê ìåòêå continue.
; Âåòêà "var_b > 0"
else:

; CODE XREF: _main+1Dj

323

324

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
mov
[ebp+var_b], 0FFFFFFFFh
; Çàïèñûâàåì â ïåðåìåííóþ var_b çíà÷åíèå -1

continue:
; CODE XREF: _main+26j
; Êîíåö âåòâëåíèÿ IF-THEN-ELSE.
; Îáðàòèòå âíèìàíèå - ïðåäñòàâëåíèå âåòâëåíèÿ IF-THEN-ELSE íàìíîãî êîìïàêòíåå
; óñëîâíîãî îïåðàòîðà "?", îäíàêî ñîäåðæèò â ñåáå óñëîâíûå ïåðåõîäû, îùóòèìî
; ñíèæàþùèå áûñòðîäåéñòâèå ïðîãðàììû
mov
eax, [ebp+var_a]
; Çàãðóæàåì â EAX çíà÷åíèå ïåðåìåííîé var_a
add
eax, [ebp+var_b]
; Ñêëàäûâàåì çíà÷åíèå ïåðåìåííîé var_a ñî çíà÷åíèåì ïåðåìåííîé var_b
; è ïîìåùàåì ðåçóëüòàò â EAX
mov
esp, ebp
pop
ebp
; Çàêðûâàåì êàäð ñòåêà
retn

Òàêèì îáðàçîì, ìû âèäèì, ÷òî íåëüçÿ àïðèîðè óòâåðæäàòü, áóäòî áû ðåçóëüòàò òðàíñëÿöèè óñëîâíîãî îïåðàòîðà «?» âñåãäà ýêâèâàëåíòåí ðåçóëüòàòó òðàíñëÿöèè êîíñòðóêöèè IF-THEN-ELSE. Îäíàêî òîò æå Microsoft Visual C++ â ðåæèìå
àãðåññèâíîé îïòèìèçàöèè â îáîèõ ñëó÷àÿõ ãåíåðèðóåò èäåíòè÷íûé êîä. Ñìîòðèòå:
Ëèñòèíã 155

_main

proc near
push
ecx
; Ðåçåðâèðóåì ìåñòî äëÿ ëîêàëüíûõ ïåðåìåííûõ a è b.
; Ïîñêîëüêó îíè íèêîãäà íå èñïîëüçóþòñÿ âìåñòå, à òîëüêî ïîî÷åðåäíî,
; êîìïèëÿòîð ïîìåùàåò èõ â îäíó ÿ÷åéêó ïàìÿòè
mov
edx, [esp+0]; êîìàíäà ¹ 1 îïåðàòîðà "?"
; Çàãðóçêà â EDX çíà÷åíèÿ ïåðåìåííîé a
xor
eax, eax; êîìàíäà ¹ 2 îïåðàòîðà ?
; Îáíóëÿåì EAX
; Ïîñêîëüêó êîìàíäà setle al èçìåíÿåò ñîäåðæèìîå îäíîãî ëèøü al è íå òðîãàåò
; îñòàëüíóþ ÷àñòü ðåãèñòðà, íàì ïðèõîäèòñÿ î÷èùàòü åãî ñàìîñòîÿòåëüíî
test
edx, edx; êîìàíäà ¹ 3 îïåðàòîðà "?"
; Ïðîâåðêà ïåðåìåííîé a íà ðàâåíñòâî íóëþ
mov
edx, [esp+0]; êîìàíäà ¹ 1 âåòâëåíèÿ IF
; Çàãðóçêà â EDX çíà÷åíèÿ ïåðåìåííîé b
setle al; êîìàíäà ¹ 4 îïåðàòîðà "?"
; Ïîìåñòèòü â al çíà÷åíèå 0x1, åñëè a 0
dec
eax; êîìàíäà ¹ 5 îïåðàòîðà "?"
; Óìåíüøèòü EAX íà åäèíèöó
; Òåïåðü,
åñëè a > 0, òî EAX := -1,
;
åñëè a 0, òî EAX := 2,
;
åñëè a 0, òî EAX := 1,
;
åñëè a 0, òî ECX := -1,
;
åñëè b 0, òî ECX := 2
;
åñëè b 0, òî ECX := -1,
;
åñëè b 0)?"Sailor":"World!");
}

326

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Ïîïðîáóéòå òàêæå êîìïàêòíî ðåàëèçîâàòü ýòî ñ ïîìîùüþ âåòâëåíèé! Íî íà
ñàìîì äåëå ýòî óäîáñòâî ëèøü âíåøíåå, à êîìïèëÿòîð òðàíñëèðóåò ïðèâåäåííûé
ïðèìåð òàê:
Ëèñòèíã 157

main()
{
int a;
char *p;
static char s0[]="Sailor";
static char s1[]="World";
if (a>0) p=s0; else p=s1;
printf("Hello, %s\n", p);
}

Îòêîìïèëèðóéòå îáà ëèñòèíãà è äèçàññåìáëèðóéòå ïîëó÷åííûå ôàéëû,
îíè äîëæíû áûòü èäåíòè÷íû. Òàêèì îáðàçîì, ïðè äåêîìïèëÿöèè Ñè/Ñè++
ïðîãðàìì â îáùåì ñëó÷àå íåâîçìîæíî ñêàçàòü, èñïîëüçîâàëîñü ëè â íèõ âåòâëåíèå èëè óñëîâíûé îïåðàòîð, îäíàêî âñå æå åñòü íåêîòîðûå çàöåïêè, ïîìîãàþùèå âîññòàíîâèòü èñòèííûé âèä èñõîäíîãî òåêñòà â íåêîòîðûõ ÷àñòíûõ
ñëó÷àÿõ.
Íàïðèìåð, ìàëîâåðîÿòíî, ÷òîáû ïðîãðàììèñò ñòðîèë ñâîé ëèñòèíã, êàê ïîêàçàíî â ïîñëåäíåì ïðèìåðå. Çà÷åì ââîäèòü ñòàòè÷åñêèå ïåðåìåííûå è ñëîæíûì îáðàçîì ìàíèïóëèðîâàòü ñ óêàçàòåëåì, êîãäà ïðîùå èñïîëüçîâàòü óñëîâíûé îïåðàòîð âìåñòî âåòâëåíèÿ?
Òàêèì îáðàçîì, åñëè óñëîâíûé îïåðàòîð ãëàäêî ëîæèòñÿ â äåêîìïèëèðóåìóþ
ïðîãðàììó, à âåòâëåíèå íå ëåçåò â íåå íèêàêèì áîêîì, òî, î÷åâèäíî, ÷òî â èñõîäíîì òåêñòå èñïîëüçîâàëñÿ èìåííî óñëîâíûé îïåðàòîð, à íå âåòâëåíèå.
Èäåíòèôèêàöèÿ òèïîâ. Óñëîâíûå êîìàíäû — êëþ÷ ê èäåíòèôèêàöèè òèïîâ. Ïîñêîëüêó àíàëèç ðåçóëüòàòà ñðàâíåíèÿ çíàêîâûõ è áåççíàêîâûõ ïåðåìåííûõ îñóùåñòâëÿåòñÿ ðàçëè÷íûìè ãðóïïàìè èíñòðóêöèé, ìîæíî óâåðåííî è îäíîçíà÷íî îòëè÷èòü signed int îò unsigned int.
Âïðî÷åì, èäåíòèôèêàöèÿ òèïîâ — òåìà îòäåëüíîãî ðàçãîâîðà, ïîýòîìó íå
áóäåò îòêëîíÿòüñÿ â ñòîðîíó, à ðàññìîòðèì åå ÷óòî÷êó ïîçæå â îäíîèìåííîé
ãëàâå.
16-ðàçðÿäíûé ðåæèì. Îäíà èç íåïðèÿòíûõ îñîáåííîñòåé 16-ðàçðÿäíîãî ðåæèìà — îãðàíè÷åííàÿ «äàëüíîáîéíîñòü» êîìàíä óñëîâíîãî ïåðåõîäà. Ðàçðàáîò÷èêè ìèêðîïðîöåññîðà â ñòðåìëåíèè äîáèòüñÿ âûñîêîé
êîìïàêòíîñòè êîäà îòâåëè íà öåëåâîé àäðåñ âñåãî îäèí áàéò, îãðàíè÷èâ òåì ñàìûì äëèíó ïðûæêà èíòåðâàëîì â 255 áàéòîâ. Ýòî òàê íàçûâàåìûé êîðîòêèé
(short) ïåðåõîä, àäðåñóåìûé îòíîñèòåëüíûì çíàêîâûì ñìåùåíèåì, îòñ÷èòûâàåìûì îò íà÷àëà ñëåäóþùåé çà èíñòðóêöèåé ïåðåõîäà êîìàíäîé (ðèñ. 26). Òàêàÿ
ñõåìà àäðåñàöèè îãðàíè÷èâàåò äëèíó ïðûæêà «âïåðåä» (ò. å. «âíèç») âñåãî 128
áàéòàìè, à «íàçàä» (ò. å. «ââåðõ») è òîãî ìåíüøå — 127! (Ïðûæîê âïåðåä êîðî÷å

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

327

ïîòîìó, ÷òî åìó òðåáóåòñÿ «ïåðåñå÷ü» è ñàìó êîìàíäó ïåðåõîäà.) Ýòèõ îãðàíè÷åíèé ëèøåí áëèæíèé (near) áåçóñëîâíûé ïåðåõîä, àäðåñóåìûé äâóìÿ áàéòàìè è
äåéñòâóþùèé â ïðåäåëàõ âñåãî ñåãìåíòà.

Ðèñ. 26. Âíóòðåííåå ïðåäñòàâëåíèå êîðîòêîãî (short) ïåðåõîäà

Êîðîòêèå ïåðåõîäû óñëîæíÿþò òðàíñëÿöèþ âåòâëåíèé — âåäü íå âñÿêèé öåëåâîé àäðåñ íàõîäèòñÿ â ïðåäåëàõ 128 áàéòîâ! Ñóùåñòâóåò ìíîæåñòâî ñïîñîáîâ
îáõîäà ýòîãî îãðàíè÷åíèÿ. Íàèáîëåå ïîïóëÿðåí ñëåäóþùèé ïðèåì: åñëè òðàíñëÿòîð âèäèò, ÷òî öåëåâîé àäðåñ âûõîäèò çà ïðåäåëû äîñÿãàåìîñòè óñëîâíîãî ïåðåõîäà, îí èíâåðòèðóåò óñëîâèå ñðàáàòûâàíèÿ è ñîâåðøàåò êîðîòêèé (short) ïåðåõîä
íà ìåòêó continue, à íà do_it ïåðåäàåò óïðàâëåíèå áëèæíèì (near) ïåðåõîäîì,
äåéñòâóþùèì â ïðåäåëàõ îäíîãî ñåãìåíòà (ðèñ. 27).

Ðèñ. 27. Òðàíñëÿöèÿ êîðîòêèõ ïåðåõîäîâ

Àíàëîãè÷íûì îáðàçîì ìîæíî âûêðóòèòüñÿ è â òåõ ñèòóàöèÿõ, êîãäà öåëåâîé
àäðåñ ðàñïîëîæåí ñîâñåì â äðóãîì ñåãìåíòå, äîñòàòî÷íî ëèøü çàìåíèòü áëèæíèé
áåçóñëîâíûé ïåðåõîä íà äàëüíèé. Âîò, ñîáñòâåííî, è âñå.
Ê âåëèêîìó ñ÷àñòüþ ðàçðàáîò÷èêîâ êîìïèëÿòîðîâ è íå ìåíüøåé ðàäîñòè
õàêåðîâ, äèçàññåìáëèðóþùèõ ïðîãðàììû, â 32-ðàçðÿäíîì ðåæèìå óñëîâíûé
ïåðåõîä «áüåò» â ïðåäåëàõ âñåãî ÷åòûðåõãèãàáàéòîâîãî àäðåñíîãî ïðîñòðàíñòâà, è âñå ýòè ïðîáëåìû èñ÷åçàþò, êàê áîðîäàâêè ïîñëå ñåàíñà Êàøïèðîâñêîãî.
Ëèñòèíãè ïðèìåðîâ. À òåïåðü äëÿ ëó÷øåãî óÿñíåíèÿ ìàòåðèàëà, ðàññìîòðåííîãî â ýòîé ãëàâå, äàâàéòå ðàññìîòðèì íåñêîëüêî æèâûõ ïðèìåðîâ, îòêîìïèëèðîâàííûõ ðàçëè÷íûìè êîìïèëÿòîðàìè. Íà÷íåì ñ èññëåäîâàíèÿ ýëåìåíòàðíûõ
öåëî÷èñëåííûõ îòíîøåíèé:

328

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

Ëèñòèíã 158

#include
main()
{
int a; int b;
if (ab) printf("a>b");
if (a==b) printf("a==b");
if (a!=b) printf("a!=b");
if (a>=b) printf("a>=b");
if (a= var_b, òî ïåðåõîä íà continue èíà÷å - ïå÷àòü ñòðîêè.
; Îáðàòèòå âíèìàíèå, ÷òî îðèãèíàëüíûé êîä âûãëÿäåë òàê:
; if (a=b) printf("a>=b");

329

330

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
push
call
add

offset aAB_1 ; "a>=b"
_printf
esp, 4

loc_40106F:
; CODE XREF: main+60j
mov
edx, [ebp+var_a]
; Çàãðóæàåì â EDX çíà÷åíèå ïåðåìåííîé var_a
cmp
edx, [ebp+var_b]
; Ñðàâíèâàåì çíà÷åíèå ïåðåìåííîé var_a ñ ïåðåìåííîé var_b
jg
short loc_401084
; Ïåðåõîä, åñëè var_a>var_b, èíà÷å ïå÷àòü ñòðîêè
; Ñëåäîâàòåëüíî, îðèãèíàëüíûé êîä ïðîãðàììû âûãëÿäåë òàê:
; if (a 0; a—) áîëåå ïðèâû÷íî, ÷åì for (a = 0; a < 10; a++)?

pop
retn

esi

main

endp

À ÷òî ñêàæåò íàì òîâàðèù Borland C++ 5.0? Êîìïèëèðóåì è ñìîòðèì:
Ëèñòèíã 195

_main proc near

; DATA XREF: DATA:00407044o

push
ebp
mov
ebp, esp
; Îòêðûâàåì êàäð ñòåêà
push
ebx
; Ñîõðàíÿåì EBX â ñòåêå
xor
ebx, ebx
; Ïðèñâàèâàåì ðåãèñòðîâîé ïåðåìåííîé EBX çíà÷åíèå 0
loc_401082:

; CODE XREF: _main+15j
; ^^^^^^^^^^^^^^^^^^^^^^

; Íà÷àëî öèêëà
push
offset aOperatorCiklaF ; format
call
_printf
pop
ecx
; Íà÷èíàåì öèêë ñ âûïîëíåíèÿ åãî òåëà.
; OK, Borland ïîíÿë, ÷òî öèêë âûïîëíÿåòñÿ ïî êðàéíåé ìåðå ðàç
inc
ebx
; Óâåëè÷èâàåì ïàðàìåòð öèêëà
cmp
ebx, 0Ah
; Ñðàâíèâàåì EBX ñî çíà÷åíèåì 0xA
jl
short loc_401082
; Ïåðåõîä â íà÷àëî öèêëà, ïîêà EBX < 0xA
xor
pop
pop
retn

eax, eax
ebx
ebp

373

374

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

_main

endp

Âèäíî, ÷òî Borland C++ 5.0 íå äîòÿãèâàåò äî Microsoft Visual C++ 6.0, ïîíÿòü, ÷òî öèêë âûïîëíÿåòñÿ îäèí ðàç, îí ïîíÿë, à âîò ðåâåðñ ñ÷åò÷èêà óìà óæå íå
õâàòèëî. Àíàëîãè÷íûì îáðàçîì ïîñòóïàåò è áîëüøèíñòâî äðóãèõ êîìïèëÿòîðîâ, â
÷àñòíîñòè WATCOM C.
Òåïåðü íàñòàëà î÷åðåäü öèêëîâ ñ óñëîâèåì â ñåðåäèíå èëè öèêëîâ, çàâåðøàåìûõ âðó÷íóþ îïåðàòîðîì break. Ðàññìîòðèì ñëåäóþùèé ïðèìåð:
Ëèñòèíã 196. Äåìîíñòðàöèÿ èäåíòèôèêàöèè break

#include
main()
{
int a=0;
while(1)
{
printf("1é îïåðàòîð\n");
if (++a>10) break;
printf("2é îïåðàòîð\n");
}
do
{
printf("1é îïåðàòîð\n");
if (—a 0xA) break;
printf("2-é îïåðàòîð\n");
}

loc_401041:

; CODE XREF: main+12j main+30j ...
; ^^^^^^^^^^
; Ïåðåêðåñòíàÿ ññûëêà, íàïðàâëåííàÿ âíèç, ãîâîðèò, ÷òî ýòî íà÷àëî öèêëà
push
offset a1iOperator_0 ; "1-é îïåðàòîð\n"
call
_printf
add
esp, 4
; printf("1-é îïåðàòîð\n")
mov
edx, [ebp+var_a]
sub
edx, 1
mov
[ebp+var_a], edx
; —var_a
cmp
[ebp+var_a], 0
; Ñðàâíèâàåì var_a ñî çíà÷åíèåì 0x0
jge
short loc_40105F
; Ïåðåõîä âíèç, åñëè var_a >= 0.
; Ñìîòðèòå, îïåðàòîð break öèêëà do íè÷åì íå îòëè÷àåòñÿ îò break öèêëà while!
; Ïîýòîìó íå áóäåì ðàçãëàãîëüñòâîâàòü, à ñðàçó åãî äåêîìïèëèðóåì!
; if (var_a < 0) ...
jmp
short loc_401075
; ..break

loc_40105F:
; CODE XREF: main+5Bj
push
offset a2iOperator_0 ; "2-é îïåðàòîð\n"
call
_printf
add
esp, 4
;printf("2é îïåðàòîð\n")
mov
test
jnz
; À ýòî

eax, 1
eax, eax
short loc_401041
- ïðîâåðêà ïðîäîëæåíèÿ öèêëà

loc_401075:
mov
esp, ebp
pop
ebp
; Çàêðûâàåì êàäð ñòåêà

; CODE XREF: main+5Dj

retn
main

endp

×òî æ, îïåðàòîð break â îáîèõ öèêëàõ âûãëÿäèò îäèíàêîâî è ýëåìåíòàðíî ðàñïîçíàåòñÿ (ïðàâäà, íå ñ ïåðâîãî âçãëÿäà, íî ïðè îòñëåæèâàíèè íåñêîëüêèõ ïåðåõîäîâ — äà). À âîò ñ áåñêîíå÷íûìè öèêëàìè íå îïòèìèçèðóþùèé êîìïèëÿòîð

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

377

ïîäêà÷àë, òðàíñëèðîâàâ èõ â êîä, ïðîâåðÿþùèé óñëîâèå, èñòèííîñòü (íå èñòèííîñòü) êîòîðîãî î÷åâèäíà. À êàê ïîâåäåò ñåáÿ îïòèìèçèðóþùèé êîìïèëÿòîð?
Äàâàéòå îòêîìïèëèðóåì òîò æå ñàìûé ïðèìåð êîìïèëÿòîðîì Microsoft Visual
C++ 6.0 ñ êëþ÷îì /Ox è ïîñìîòðèì:
Ëèñòèíã 198

main

proc near
push
esi
; Ñîõðàíÿåì ESI â ñòåêå

; CODE XREF: start+AFp

xor
esi, esi
; Ïðèñâàèâàåì ESI çíà÷åíèå 0
; var_ESI = 0;
loc_401003:

; CODE XREF: main+23j
; ^^^^^^^^^^^^^^^^^^^^^
; Ïåðåêðåñòíàÿ ññûëêà, íàïðàâëåííàÿ âïåðåä.
; Ýòî íà÷àëî öèêëà
push
offset a1iOperator ; "1-é îïåðàòîð\n"
call
_printf
add
esp, 4
; printf("1-é îïåðàòîð\n")
;
; Àãà! Ïðîâåðêè íà äîðîãàõ íåò, çíà÷èò, ýòî öèêë ñ ïîñòóñëîâèåì
; (èëè óñëîâèåì â ñåðåäèíå)
inc
esi
; ++var_ESI
cmp
esi, 0Ah
; Ñðàâíèâàåì var_ESI ñî çíà÷åíèåì 0xA
jg
short loc_401025
; Âûõîä èç öèêëà, åñëè var_ESI > 0xA.
; Ïîñêîëüêó äàííàÿ êîìàíäà íå ïîñëåäíÿÿ â òåëå öèêëà,
; ýòî öèêë ñ óñëîâèåì â ñåðåäèíå
; if (var_ESI > 0xA) break
push
offset a2iOperator ; "2-é îïåðàòîð\n"
call
_printf
add
esp, 4
; printf("2-é îïåðàòîð\n")
jmp
short loc_401003
; Áåçóñëîâíûé ïåðåõîä â íà÷àëî öèêëà.
; Êàê âèäíî, îïòèìèçèðóþùèé êîìïèëÿòîð âûêèíóë íèêîìó íå íóæíóþ ïðîâåðêó
; óñëîâèÿ, óïðîñòèâ êîä è îáëåã÷èâ åãî ïîíèìàíèå:
; Èòàê:
; var_ESI = 0
; for (;;) ← âûðîæäåííûé for ïðåäñòàâëÿåò ñîáîé áåñêîíå÷íûé öèêë
; {
; printf("1-é îïåðàòîð\n");
; ++var_ESI;
; if (var_ESI > 0xA) break;

378

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
; printf("2-é îïåðàòîð\n");
; }

loc_401025:

; CODE XREF: main+14j
; ^^^^^^^^^^^^^^^^^^^^^

; Ýòî íå íà÷àëî öèêëà!
push
offset a1iOperator_0 ; "1-é îïåðàòîð\n"
call
_printf
add
esp, 4
; printf("1-é îïåðàòîð\n")
; Õì, êàê æå ýòî íå íà÷àëî öèêëà?! Î÷åíü ïîõîæå!
dec
esi
; —var_ESI
js
short loc_401050
; Âûõîä èç öèêëà, åñëè var_ESI < 0
inc
esi
; Óâåëè÷èâàåì var_ESI íà åäèíèöó.
; Ì-ì-ì... (çàäóì÷èâî)...
loc_401036:

; CODE XREF: main+4Ej
; ^^^^^^^^^^^^^^^^^^^^^^

; À âîò ýòî íà÷àëî öèêëà!
push
offset a2iOperator_0 ; "2-é îïåðàòîð\n"
call
_printf
; printf("2-é îïåðàòîð\n")
; Òîëüêî ñòðàííî, ÷òî íà÷àëî öèêëà íà÷èíàåòñÿ ñ åãî, ñ ïîçâîëåíèÿ ñêàçàòü,
; ñåðåäèíû...
push
offset a1iOperator_0 ; "1-é îïåðàòîð\n"
call
_printf
add
esp, 8
; printf("1-é îïåðàòîð\n")
;
; ???!!! ×òî çà ÷óäåñà òâîðÿòñÿ? Âî-ïåðâûõ, âûçîâ ïåðâîãî îïåðàòîðà âòîðîãî
; öèêëà óæå âñòðå÷àëñÿ ðàíåå, âî-âòîðûõ, íå ìîæåò æå ñëåäîì çà ñåðåäèíîé öèêëà
; ñëåäîâàòü åãî íà÷àëî?!
dec
esi
; —var_ESI
jnz
short loc_401036
; Ïðîäîëæåíèå öèêëà, ïîêà var_ESI != 0
loc_401050:
; CODE XREF: main+33j
; Êîíåö öèêëà.
; Äà... òóò åñòü íàä ÷åì ïîäóìàòü!
; Êîìïèëÿòîð íîðìàëüíî "ïåðåâàëèë" ïåðâóþ ñòðîêó öèêëà
; printf("1-é îïåðàòîð\n"),
; à çàòåì "íàïîðîëñÿ" íà âåòâëåíèå:
; if (—a= 0xA
cmp
[ebp+var_a], 2
; Ñðàâíèâàåì var_a ñî çíà÷åíèåì 0x2
jnz

short loc_401024

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
;
;
;
;
;
;
;

381

Åñëè var_a != 2, òî ïðûæîê íà êîìàíäó, ñëåäóþùóþ çà èíñòðóêöèåé
áåçóñëîâíîãî ïåðåõîäà, íàïðàâëåííîé ââåðõ - â íà÷àëî öèêëà.
Î÷åíü ïîõîæå íà óñëîâèå âûõîäà èç öèêëà, íî íå áóäåì ñïåøèòü ñ âûâîäàìè!
Âñïîìíèì, â íà÷àëå öèêëà íàì âñòðåòèëèñü äâå ïåðåêðåñòíûå ññûëêè.
Áåçóñëîâíûé ïåðåõîä jmp short loc_40100B êàê ðàç îáðàçóåò îäíó èç íèõ.
À êòî "îòâå÷àåò" çà äðóãóþ?
×òîáû îòâåòèòü íà ýòîò âîïðîñ, íåîáõîäèìî ïðîàíàëèçèðîâàòü îñòàëüíîé êîä öèêëà

jmp
short loc_40100B
; Áåçóñëîâíûé ïåðåõîä, íàïðàâëåííûé â íà÷àëî öèêëà, ýòî ëèáî êîíåö öèêëà,
; ëèáî continue.
; Ïðåäïîëîæèì, ÷òî ýòî êîíåö öèêëà. Òîãäà ÷òî æå ïðåäñòàâëÿåò ñîáîé
; jge short loc_401037? Ïðåäóñëîâèå âûõîäà èç öèêëà? Íå ïîõîæå, â òàêîì
; ñëó÷àå îíî ïðûãàëî áû ãîðàçäî "áëèæå" - íà ìåòêó loc_401024.
; À ìîæåò, jge short loc_401037 ïðåäóñëîâèå îäíîãî öèêëà, à
; jnz short loc_401024 - ïîñòóñëîâèå äðóãîãî, âëîæåííîãî â íåãî?
; Âïîëíå âîçìîæíî, íî ìàëîâåðîÿòíî - â ýòîì ñëó÷àå ïîñòóñëîâèå ïðåäñòàâëÿëî áû
; ñîáîé óñëîâèå ïðîäîëæåíèÿ, à íå çàâåðøåíèÿ öèêëà.
; Ïîýòîìó ñ íåêîòîðîé äîëåé íåóâåðåííîñòè ìû ìîæåì ïðèíÿòü êîíñòðóêöèþ
; CMP var_a, 2 \ JNZ loc_401024 \ JMP loc_40100B çà if (a==2) continue
loc_401024:
; CODE XREF: main+20j
mov
edx, [ebp+var_a]
push
edx
push
offset asc_406030 ; "%x\n"
call
_printf
add
esp, 8
; printf("%x\n",var_a)
jmp
short loc_40100B
; À âîò ýòî ÿâíî êîíåö öèêëà, òàê êàê jmp short loc_40100B - ñàìàÿ
; ïîñëåäíÿÿ ññûëêà íà íà÷àëî öèêëà.
; Èòàê, ïîäûòîæèì, ÷òî ìû èìååì.
; Óñëîâèå, ðàñïîëîæåííîå â íà÷àëå öèêëà, êðóòèò ýòîò öèêë äî òåõ ïîð, ïîêà
; var_a < 0xA, ïðè÷åì èíêðåìåíò ïàðàìåòðà öèêëà ïðîèñõîäèò äî åãî ñðàâíåíèÿ.
; Çàòåì ñëåäóåò åùå îäíî óñëîâèå, âîçâðàùàþùåå óïðàâëåíèå â íà÷àëî öèêëà, åñëè
; var_a == 2. Ñòðîé çàìûêàåò îïåðàòîð öèêëà printf è áåçóñëîâíûé ïåðåõîä â åãî
; íà÷àëî. Òî åñòü
;
; Íà÷àëî öèêëà:
; Èíêðåìåíò ïåðåìåííîé var_a
; óñëîâèå "äàëåêîãî" âûõîäà
; óñëîâèå "áëèæíåãî" ïðîäîëæåíèÿ
; òåëî öèêëà
; áåçóñëîâíûé ïåðåõîä â íà÷àëî
; êîíåö öèêëà
;
; Óñëîâèå "áëèæíåãî" ïðîäîëæåíèÿ íå ìîæåò áûòü êîíöîì öèêëà, òàê êàê òîãäà óñëîâèþ
; "äàëåêîãî" âûõîäà ïðèøëîñü âûéòè àæ èç íàäëåæàùåãî öèêëà, íà ÷òî íè break,
; íè äðóãèå îïåðàòîðû íå ñïîñîáíû. Òàêèì îáðàçîì, óñëîâèå "áëèæíåãî" ïðîäîëæåíèÿ
; ìîæåò áûòü òîëüêî îïåðàòîðîì continue è íà ÿçûêå Ñè âñþ ýòà êîíñòðóêöèÿ
; áóäåò âûãëÿäåòü òàê:
; while(a++ 1; a++, b —)
printf("%x %x\n", a, b);
}

Ðåçóëüòàò åãî êîìïèëÿöèè êîìïèëÿòîðîì Microsoft Visual C++ 6.0 äîëæåí
âûãëÿäåòü òàê:
Ëèñòèíã 203

main
var_b
var_a

proc near

; CODE XREF: start+AFp

= dword ptr -8
= dword ptr -4
push
ebp
mov
ebp, esp
; Îòêðûâàåì êàäð ñòåêà
sub
esp, 8
; Ðåçåðâèðóåì ïàìÿòü äëÿ äâóõ ëîêàëüíûõ ïåðåìåííûõ
mov
[ebp+var_a], 1
; Ïðèñâàèâàåì ïåðåìåííîé var_a çíà÷åíèå 0x1
mov
[ebp+var_b], 0Ah
; Ïðèñâàèâàåì ïåðåìåííîé var_b çíà÷åíèå 0xA

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

385

jmp
short loc_401028
; Ïðûæîê íà êîä ïðîâåðêè óñëîâèÿ âûõîäà èç öèêëà
; Ýòî õàðàêòåðíàÿ ÷åðòà íå îïòèìèçèðîâàííûõ öèêëîâ for
loc_401016:

; CODE XREF: main+43j
;
^^^^^^^^^
; Ïåðåêðåñòíàÿ ññûëêà, íàïðàâëåííàÿ âíèç, ãîâîðèò î òîì, ÷òî ýòî íà÷àëî öèêëà.
; À âûøå ìû óæå âûÿñíèëè, ÷òî òèï öèêëà - for.
mov
eax, [ebp+var_a]
add
eax, 1
mov
[ebp+var_a], eax
; var_a++
mov
ecx, [ebp+var_b]
sub
ecx, 1
mov
[ebp+var_b], ecx
; var_b—

loc_401028:
; CODE XREF: main+14j
cmp
[ebp+var_b], 1
jle
short loc_401045
; Âûõîä èç öèêëà, åñëè var_b 1), à (a < 10) èãíîðèðóåòñÿ!!!
mov
edx, [ebp+var_b]
push
edx
mov
eax, [ebp+var_a]
push
eax
push
offset aXX ; "%x %x\n"
call
_printf
add
esp, 0Ch
; printf("%x %x\n", var_a, var_b)
jmp
short loc_401016
; Êîíåö öèêëà.
; Èòàê, äàííûé öèêë ìîæíî ïðåäñòàâèòü êàê:
; while(1)
; {
; var_a++;
; var_b—;
; if (var_b 1;var_a++,var_b—) printf("%x %x\n",var_a,var_b);
;
loc_401045:
mov

; CODE XREF: main+2Cj
esp, ebp

386

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
pop
ebp
; Çàêðûâàåì êàäð ñòåêà
retn

main

endp

Îïòèìèçèðîâàííûé âàðèàíò ïðîãðàììû ðàññìàòðèâàòü íå áóäåì, òàê êàê ýòî
íå ïîêàæåò íàì íè÷åãî íîâîãî. Êàêîé áû êîìïèëÿòîð ìû íè âûáðàëè, âûðàæåíèÿ
èíèöèàëèçàöèè è ìîäèôèêàöèè ñ÷åò÷èêîâ áóäóò îáðàáàòûâàòüñÿ âïîëíå êîððåêòíî â ïîðÿäêå èõ îáúÿâëåíèÿ â òåêñòå ïðîãðàììû, à âîò ìíîæåñòâåííûå âûðàæåíèÿ ïðîäîëæåíèÿ öèêëà íå óìååò ïðàâèëüíî îáðàáàòûâàòü íè îäèí êîìïèëÿòîð!

Èäåíòèôèêàöèÿ ìàòåìàòè÷åñêèõ
îïåðàòîðîâ
...åñëè âû îáåññèëåíû, òî íå óäèâèòåëüíî, ÷òî
âñÿ âàøà æèçíü — íå ðàçâëå÷åíèå. Ó âàñ...
òàê ìíîãî âû÷èñëåíèé, ðàñ÷åòîâ, êîòîðûå íåîáõîäèìî ñäåëàòü â âàøåé æèçíè, ÷òî îíà
ïðîñòî íå ìîæåò áûòü ðàçâëå÷åíèåì.
Îøî. Ïóñòàÿ ëîäêà.
Áåñåäû ïî âûñêàçûâàíèÿì ×æóàíà Öçû

Èäåíòèôèêàöèÿ îïåðàòîðà «+».  îáùåì ñëó÷àå îïåðàòîð «+» òðàíñëèðóåòñÿ ëèáî â ìàøèííóþ èíñòðóêöèþ ADD, «ïåðåìàëûâàþùóþ» öåëî÷èñëåííûå
îïåðàíäû, ëèáî â èíñòðóêöèþ FADDx, îáðàáàòûâàþùóþ âåùåñòâåííûå çíà÷åíèÿ.
Îïòèìèçèðóþùèå êîìïèëÿòîðû ìîãóò çàìåíÿòü ADD xxx, 1 áîëåå êîìïàêòíîé
êîìàíäîé INC xxx, à êîíñòðóêöèþ c = a + b + const òðàíñëèðîâàòü â ìàøèííóþ
èíñòðóêöèþ LEA c, [a + b + const]. Òàêîé òðþê ïîçâîëÿåò îäíèì ìàõîì ñêëàäûâàòü íåñêîëüêî ïåðåìåííûõ, âîçâðàòèâ ïîëó÷åííóþ ñóììó â ëþáîì ðåãèñòðå îáùåãî íàçíà÷åíèÿ, — íåîáÿçàòåëüíî â ëåâîì ñëàãàåìîì, êàê ýòî òðåáóåò ìíåìîíèêà êîìàíäû ADD. Îäíàêî LEA íå ìîæåò áûòü íåïîñðåäñòâåííî äåêîìïèëèðîâàíà
â îïåðàòîð «+», ïîñêîëüêó îíà èñïîëüçóåòñÿ íå òîëüêî äëÿ îïòèìèçèðîâàííîãî
ñëîæåíèÿ (÷òî, â îáùåì-òî, ÿâëÿåòñÿ òîëüêî ïîáî÷íûì ïðîäóêòîì åå äåÿòåëüíîñòè), íî è ïî ñâîåìó íåïîñðåäñòâåííîìó íàçíà÷åíèþ — âû÷èñëåíèþ ýôôåêòèâíîãî ñìåùåíèÿ. (ïîäðîáíåå îá ýòîì ñì. ðàçäåëû «Èäåíòèôèêàöèÿ êîíñòàíò è
ñìåùåíèé», «Èäåíòèôèêàöèÿ òèïîâ»).
Ðàññìîòðèì ñëåäóþùèé ïðèìåð:
Ëèñòèíã 204. Äåìîíñòðàöèÿ îïåðàòîðà «+»

main()
{
int a, b,c;
c = a + b;
printf("%x\n",c);
c=c+1;
printf("%x\n",c);

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

387

}

Ðåçóëüòàò åãî êîìïèëÿöèè êîìïèëÿòîðîì Microsoft Visual C++ 6.0 ñ íàñòðîéêàìè ïî óìîë÷àíèþ äîëæåí âûãëÿäåòü òàê:
Ëèñòèíã 205

main

proc near

var_c
var_b
var_a

= dword ptr -0Ch
= dword ptr -8
= dword ptr -4

; CODE XREF: start+AFp

push
ebp
mov
ebp, esp
; Îòêðûâàåì êàäð ñòåêà
sub
esp, 0Ch
; Ðåçåðâèðóåì ïàìÿòü äëÿ ëîêàëüíûõ ïåðåìåííûõ
mov
eax, [ebp+var_a]
; Çàãðóæàåì â EAX çíà÷åíèå ïåðåìåííîé var_a
add
eax, [ebp+var_b]
; Ñêëàäûâàåì EAX ñî çíà÷åíèåì ïåðåìåííîé var_b è çàïèñûâàåì ðåçóëüòàò â EAX
mov
[ebp+var_c], eax
; Êîïèðóåì ñóììó var_a è var_b â ïåðåìåííóþ var_c, ñëåäîâàòåëüíî,
; var_c = var_a + var_b
mov
ecx, [ebp+var_c]
push
ecx
push
offset asc_406030 ; "%x\n"
call
_printf
add
esp, 8
; printf("%x\n", var_c)
mov
edx, [ebp+var_c]
; Çàãðóæàåì â EDX çíà÷åíèå ïåðåìåííîé var_c
add
edx, 1
; Ñêëàäûâàåì EDX ñî çíà÷åíèåì 0õ1, çàïèñûâàÿ ðåçóëüòàò â EDX
mov
[ebp+var_c], edx
; Îáíîâëÿåì var_c
; var_c = var_c +1
mov
eax, [ebp+var_c]
push
eax
push
offset asc_406034 ; "%x\n"
call
_printf
add
esp, 8
; printf("%\n",var_c)
mov
esp, ebp
pop
ebp
; Çàêðûâàåì êàäð ñòåêà

388

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
retn

main

endp

À òåïåðü ïîñìîòðèì, êàê áóäåò âûãëÿäåòü òîò æå ñàìûé ïðèìåð, ñêîìïèëèðîâàííûé ñ êëþ÷îì /Ox (ìàêñèìàëüíàÿ îïòèìèçàöèÿ):
Ëèñòèíã 206

main

proc near
; CODE XREF: start+AFp
push
ecx
; Ðåçåðâèðóåì ìåñòî äëÿ îäíîé ëîêàëüíîé ïåðåìåííîé
; (êîìïèëÿòîð ïîñ÷èòàë, ÷òî òðè ïåðåìåííûå ìîæíî óæàòü â îäíó, è ýòî äåéñòâèòåëüíî òàê)
mov
eax, [esp+0]
; Çàãðóæàåì â EAX çíà÷åíèå ïåðåìåííîé var_a
mov
ecx, [esp+0]
; Çàãðóæàåì â EAX çíà÷åíèå ïåðåìåííîé var_b
; (òàê êàê ïåðåìåííàÿ íå èíèöèàëèçèðîâàíà, çàãðóæàòü ìîæíî îòêóäà óãîäíî)
push
esi
; Ñîõðàíÿåì ðåãèñòð ESI â ñòåêå
lea
esi, [ecx+eax]
; Èñïîëüçóåì LEA äëÿ áûñòðîãî ñëîæåíèÿ ECX è EAX ñ ïîñëåäóþùåé çàïèñüþ ñóììû
; â ðåãèñòð ESI.
; "Áûñòðîå ñëîæåíèå" ñëåäóåò ïîíèìàòü íå â ñìûñëå, ÷òî êîìàíäà LEA âûïîëíÿåòñÿ
; áûñòðåå, ÷åì ADD, - êîëè÷åñòâî òàêòîâ òîé è äðóãîé îäèíàêîâî, - íî LEA
; ïîçâîëÿåò èçáàâèòüñÿ îò ñîçäàíèÿ âðåìåííîé ïåðåìåííîé äëÿ ñîõðàíåíèÿ
; ïðîìåæóòî÷íîãî ðåçóëüòàòà ñëîæåíèÿ, ñðàçó íàïðàâëÿÿ ðåçóëüòàò â ESI.
; Òàêèì îáðàçîì, ýòà êîìàíäà äåêîìïèëèðóåòñÿ êàê
; reg_ESI = var_a + var_b
push
esi
push
offset asc_406030 ; "%x\n"
call
_printf
; printf("%x\n", reg_ESI)
inc
esi
; Óâåëè÷èâàåì ESI íà åäèíèöó
; reg_ESI = reg_ESI + 1
push
esi
push
offset asc_406034 ; "%x\n"
call
_printf
add
esp, 10h
; printf("%x\n", reg_ESI)
pop
pop
retn

main

esi
ecx
endp

Îñòàëüíûå êîìïèëÿòîðû (Borland C++, WATCOM C) ãåíåðèðóþò ïðèáëèçèòåëüíî èäåíòè÷íûé êîä, ïîýòîìó ïðèâîäèòü ðåçóëüòàòû áåññìûñëåííî — íèêàêèõ
íîâûõ «èçþìèíîê» îíè â ñåáå íå íåñóò.

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

389

Èäåíòèôèêàöèÿ îïåðàòîðà «–».  îáùåì ñëó÷àå îïåðàòîð «–» òðàíñëèðóåòñÿ ëèáî â ìàøèííóþ èíñòðóêöèþ SUB (åñëè îïåðàíäû — öåëî÷èñëåííûå çíà÷åíèÿ), ëèáî â èíñòðóêöèþ FSUBx (åñëè îïåðàíäû — âåùåñòâåííûå çíà÷åíèÿ). Îïòèìèçèðóþùèå êîìïèëÿòîðû ìîãóò çàìåíÿòü SUB xxx, 1 áîëåå êîìïàêòíîé êîìàíäîé DEC xxx, à êîíñòðóêöèþ SUB a, const òðàíñëèðîâàòü â ADD a, -const, êîòîðàÿ
íè÷óòü íå êîìïàêòíåå è íèñêîëüêî íå áûñòðåé (è òà è äðóãàÿ óêëàäûâàåòñÿ â îäèí
òàê), îäíàêî õîçÿèí (êîìïèëÿòîð) — áàðèí. Ïîêàæåì ýòî íà ñëåäóþùåì ïðèìåðå:
Ëèñòèíã 207. Äåìîíñòðàöèÿ èäåíòèôèêàöèè îïåðàòîðà «–»

main()
{
int a,b,c;
c = a - b;
printf("%x\n",c);
c = c - 10;
printf("%x\n",c);
}

Íå îïòèìèçèðîâàííûé âàðèàíò áóäåò âûãëÿäåòü ïðèáëèçèòåëüíî òàê:
Ëèñòèíã 208

main

proc near

var_c
var_b
var_a

= dword ptr -0Ch
= dword ptr -8
= dword ptr -4

; CODE XREF: start+AFp

push
ebp
mov
ebp, esp
; Îòêðûâàåì êàäð ñòåêà
sub
esp, 0Ch
; Ðåçåðâèðóåì ïàìÿòü ïîä ëîêàëüíûå ïåðåìåííûå
mov
eax, [ebp+var_a]
; Çàãðóæàåì â EAX çíà÷åíèå ïåðåìåííîé var_a
sub
eax, [ebp+var_b]
; Âû÷èòàåì èç var_a çíà÷åíèå ïåðåìåííîé var_b, çàïèñûâàÿ ðåçóëüòàò â EAX.
mov
[ebp+var_c], eax
; Çàïèñûâàåì â var_c ðàçíîñòü var_a è var_b
; var_c = var_a - var_b
mov
ecx, [ebp+var_c]
push
ecx
push
offset asc_406030 ; "%x\n"
call
_printf
add
esp, 8
; printf("%x\n", var_c)
mov
edx, [ebp+var_c]
; Çàãðóæàåì â EDX çíà÷åíèå ïåðåìåííîé var_c

390

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
sub
edx, 0Ah
; Âû÷èòàåì èç var_c çíà÷åíèå 0xA, çàïèñûâàÿ ðåçóëüòàò â EDX:
mov
[ebp+var_c], edx
; Îáíîâëÿåì var_c
; var_c = var_c - 0xA
mov
eax, [ebp+var_c]
push
eax
push
offset asc_406034 ; "%x\n"
call
_printf
add
esp, 8
; printf("%x\n",var_c)

main

mov
esp, ebp
pop
ebp
; Çàêðûâàåì êàäð ñòåêà
retn
endp

À òåïåðü ðàññìîòðèì îïòèìèçèðîâàííûé âàðèàíò òîãî æå ïðèìåðà:
Ëèñòèíã 209

main

proc near
; CODE XREF: start+AFp
push
ecx
; Ðåçåðâèðóåì ìåñòî äëÿ ëîêàëüíîé ïåðåìåííîé var_a
mov
eax, [esp+var_a]
; Çàãðóæàåì â EAX çíà÷åíèå ëîêàëüíîé ïåðåìåííîé var_a
push
esi
; Ðåçåðâèðóåì ìåñòî äëÿ ëîêàëüíîé ïåðåìåííîé var_b
mov
esi, [esp+var_b]
; Çàãðóæàåì â ESI çíà÷åíèå ïåðåìåííîé var_b
sub
esi, eax
; Âû÷èòàåì èç var_a çíà÷åíèå var_b, çàïèñûâàÿ ðåçóëüòàò â ESI
push
esi
push
offset asc_406030 ; "%x\n"
call
_printf
; printf("%x\n", var_a - var_b)
add
esi, 0FFFFFFF6h
; Äîáàâëÿåì ê ESI (ðàçíîñòè var_a è var_b) çíà÷åíèå 0õFFFFFFF6
; Ïîñêîëüêó 0xFFFFFFF6 == -0xA, äàííàÿ ñòðîêà êîäà âûãëÿäèò òàê:
; ESI = (var_a - var_b) + (- 0xA) = (var_a - var_b) - 0xA
push
esi
push
offset asc_406034 ; "%x\n"
call
_printf
add
esp, 10h
; printf("%x\n", var_a - var_b - 0xA)
pop
pop

esi
ecx

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

391

; Çàêðûâàåì êàäð ñòåêà
retn
main

endp

Îñòàëüíûå êîìïèëÿòîðû (Borland, WATCOM) ãåíåðèðóþò ïðàêòè÷åñêè èäåíòè÷íûé êîä, ïîýòîìó çäåñü íå ðàññìàòðèâàþòñÿ.
Èäåíòèôèêàöèÿ îïåðàòîðà «/».  îáùåì ñëó÷àå îïåðàòîð «/» òðàíñëèðóåòñÿ ëèáî â ìàøèííóþ èíñòðóêöèþ DIV (áåççíàêîâîå öåëî÷èñëåííîå äåëåíèå),
ëèáî â IDIV (öåëî÷èñëåííîå äåëåíèå ñî çíàêîì), ëèáî â FDIVx (âåùåñòâåííîå äåëåíèå). Åñëè äåëèòåëü êðàòåí ñòåïåíè äâîéêè, òî DIV çàìåíÿåòñÿ íà áîëåå áûñòðîäåéñòâóþùóþ èíñòðóêöèþ áèòîâîãî ñäâèãà âïðàâî SHR a, N, ãäå a — äåëèìîå,
N — ïîêàçàòåëü ñòåïåíè ñ îñíîâàíèåì äâà.
Íåñêîëüêî ñëîæíåå ïðîèñõîäèò áûñòðîå äåëåíèå çíàêîâûõ ÷èñåë. Ñîâåðøåííî íåäîñòàòî÷íî âûïîëíèòü àðèôìåòè÷åñêèé ñäâèã âïðàâî (êîìàíäà àðèôìåòè÷åñêîãî ñäâèãà âïðàâî SAR çàïîëíÿåò ñòàðøèå áèòû ñ ó÷åòîì çíàêà ÷èñëà), âåäü
åñëè ìîäóëü äåëèìîãî ìåíüøå ìîäóëÿ äåëèòåëÿ, òî àðèôìåòè÷åñêèé ñäâèã âïðàâî
ñáðîñèò âñå çíà÷àùèå áèòû â «áèòîâóþ êîðçèíó», â ðåçóëüòàòå ÷åãî ïîëó÷èòñÿ
0xFFFFFFFF, ò. å. –1, â òî âðåìÿ êàê ïðàâèëüíûé îòâåò — íîëü. Âîîáùå æå äåëåíèå
çíàêîâûõ ÷èñåë àðèôìåòè÷åñêèì ñäâèãîì âïðàâî äàåò îêðóãëåíèå â áîëüøóþ
ñòîðîíó, ÷òî ñîâñåì íå âõîäèò â íàøè ïëàíû. Äëÿ îêðóãëåíèÿ çíàêîâûõ ÷èñåë â
ìåíüøóþ ñòîðîíó íåîáõîäèìî ïåðåä âûïîëíåíèåì ñäâèãà äîáàâèòü ê äåëèìîìó
÷èñëî 2N – 1, ãäå N — êîëè÷åñòâî áèòîâ, íà êîòîðûå ñäâèãàåòñÿ ÷èñëî ïðè äåëåíèè. Ëåãêî âèäåòü, ÷òî ýòî ïðèâîäèò ê óâåëè÷åíèþ âñåõ ñäâèãàåìûõ áèòîâ íà åäèíèöó è ïåðåíîñó â ñòàðøèé ðàçðÿä, åñëè õîòÿ áû îäèí èç íèõ íå ðàâåí íóëþ.
Ñëåäóåò îòìåòèòü: äåëåíèå — î÷åíü ìåäëåííàÿ îïåðàöèÿ, ãîðàçäî áîëåå ìåäëåííàÿ, ÷åì óìíîæåíèå (âûïîëíåíèå DIV ìîæåò çàíÿòü ñâûøå 40 òàêòîâ, â òî
âðåìÿ êàê MUL îáû÷íî óêëàäûâàåòñÿ â 4), ïîýòîìó ïðîäâèíóòûå îïòèìèçèðóþùèå êîìïèëÿòîðû çàìåíÿþò äåëåíèå óìíîæåíèåì. Ñóùåñòâóåò ìíîæåñòâî ôîðìóë ïîäîáíûõ ïðåîáðàçîâàíèé, âîò, íàïðèìåð, îíà (ñàìàÿ ïîïóëÿðíàÿ èç íèõ):
a
a
2N
=
+ N ,
b
b
2
ãäå N — ðàçðÿäíîñòü ÷èñëà. Âûõîäèò, ãðàíü ìåæäó óìíîæåíèåì è äåëåíèåì î÷åíü
òîíêàÿ, à èõ èäåíòèôèêàöèÿ äîâîëüíî ñëîæíàÿ. Ðàññìîòðèì ñëåäóþùèé ïðèìåð:
Ëèñòèíã 210. Èäåíòèôèêàöèÿ îïåðàòîðà «/»

main()
{
int a;
printf("%x %x\n",a / 32, a / 10);
}

Ðåçóëüòàò åãî êîìïèëÿöèè êîìïèëÿòîðîì Microsoft Visual C++ ñ íàñòðîéêàìè ïî óìîë÷àíèþ äîëæåí âûãëÿäåòü òàê:
Ëèñòèíã 211

main

proc near

; CODE XREF: start+AFp

392

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

var_a

= dword ptr -4
push
ebp
mov
ebp, esp
; Îòêðûâàåì êàäð ñòåêà
push
ecx
; Ðåçåðâèðóåì ïàìÿòü äëÿ ëîêàëüíîé ïåðåìåííîé
mov
eax, [ebp+var_a]
; Êîïèðóåì â EAX çíà÷åíèå ïåðåìåííîé var_a
cdq
; Ðàñøèðÿåì EAX äî ÷åòâåðíîãî ñëîâà EDX:EAX
mov
ecx, 0Ah
; Çàíîñèì â ECX çíà÷åíèå 0xA
idiv
ecx
; Äåëèì (ó÷èòûâàÿ çíàê) EDX:EAX íà 0xA, çàíîñÿ ÷àñòíîå â EAX
; EAX = var_a / 0xA
push
eax
; Ïåðåäàåì ðåçóëüòàò âû÷èñëåíèé ôóíêöèè printf
mov
eax, [ebp+var_a]
; Çàãðóæàåì â EAX çíà÷åíèå var_a
cdq
; Ðàñøèðÿåì EAX äî ÷åòâåðíîãî ñëîâà EDX:EAX
and
edx, 1Fh
; Âûäåëÿåì ïÿòü ìëàäøèõ áèò EDX
add
eax, edx
; Ñêëàäûâàåì çíàê ÷èñëà äëÿ âûïîëíåíèÿ
; îêðóãëåíèÿ îòðèöàòåëüíûõ çíà÷åíèé
; â ìåíüøóþ ñòîðîíó
sar
eax, 5
; Àðèôìåòè÷åñêèé ñäâèã âïðàâî íà 5 ïîçèöèé
; ýêâèâàëåíòåí äåëåíèþ ÷èñëà íà 25 = 32.
; Òàêèì îáðàçîì, ïîñëåäíèå ÷åòûðå èíñòðóêöèè ðàñøèôðîâûâàþòñÿ êàê:
; EAX = var_a / 32
; Îáðàòèòå âíèìàíèå,
; äàæå ïðè âûêëþ÷åííîì ðåæèìå îïòèìèçàöèè êîìïèëÿòîð
; îïòèìèçèðîâàë äåëåíèå
push
eax
push
offset aXX ; "%x %x\n"
call
_printf
add
esp, 0Ch
; printf("%x %x\n", var_a / 0xA, var_a / 32)

mov

esp, ebp
pop
ebp
; Çàêðûâàåì êàäð ñòåêà
retn

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
main

393

endp

À òåïåðü, çàñó÷èâ ðóêàâà è ãëîòíóâ ïóñòûðíèêà (èëè âàëåðüÿíêè), ðàññìîòðèì îïòèìèçèðîâàííûé âàðèàíò òîãî æå ïðèìåðà:
Ëèñòèíã 212

main

proc near
; CODE XREF: start+AFp
push
ecx
; Ðåçåðâèðóåì ïàìÿòü äëÿ ëîêàëüíîé ïåðåìåííîé var_a
mov
ecx, [esp+var_a]
; Çàãðóæàåì â ECX çíà÷åíèå ïåðåìåííîé var_a
mov
eax, 66666667h
; Òàê, ÷òî ýòî çà çâåðñêîå ÷èñëî?!
;  èñõîäíîì êîäå íè÷åãî ïîäîáíîãî è áëèçêî íå áûëî!
imul
ecx
; Óìíîæàåì ýòî çâåðñêîå ÷èñëî íà ïåðåìåííóþ var_a.
; Îáðàòèòå âíèìàíèå, èìåííî óìíîæàåì, à íå äåëèì.
; Îäíàêî ïðèòâîðèìñÿ íà âðåìÿ, ÷òî ó íàñ íåò èñõîäíîãî êîäà ïðèìåðà, ïîòîìó
; íè÷åãî ñòðàííîãî â îïåðàöèè óìíîæåíèÿ ìû íå âèäèì
sar
edx, 2
; Âûïîëíÿåì àðèôìåòè÷åñêèé ñäâèã âñåõ áèòîâ EDX íà äâå ïîçèöèè âïðàâî, ÷òî
; â ïåðâîì ïðèáëèæåíèè ýêâèâàëåíòíî åãî äåëåíèþ íà 4.
; Îäíàêî âåäü â EDX íàõîäèòñÿ ñòàðøåå äâîéíîå ñëîâî ðåçóëüòàòà óìíîæåíèÿ!
; Ïîýòîìó òðè ïðåäûäóùèõ êîìàíäû ôàêòè÷åñêè ðàñøèôðîâûâàþòñÿ òàê:
; EDX = (66666667h * var_a) >> (32 + 2) = (66666667h * var_a) / 0x400000000
;
; Ïîíþõàéòå ýòó ñòðî÷êó, íå ïàõíåò ëè ïàëåíûì? Êàê òàê íå ïàõíåò?! Ñìîòðèòå:
; (66666667h * var_a) / 0x400000000 = var_a * 66666667h / 0x400000000 =
; = var_a * 0,10000000003492459654808044433594
; Çàìåíÿÿ ïî âñåì ïðàâèëàì ìàòåìàòèêè óìíîæåíèå íà äåëåíèå è îäíîâðåìåííî
; âûïîëíÿÿ îêðóãëåíèå äî ìåíüøåãî öåëîãî, ïîëó÷àåì:
; var_a * 0,1000000000 = var_a * (1/0,1000000000) = var_a/10
;
; Ñîãëàñèòåñü, îò òàêîãî ïðåîáðàçîâàíèÿ êîä ñòàë íàìíîãî ïîíÿòíåå!
; Êàê ìîæíî ðàñïîçíàòü òàêóþ ñèòóàöèþ â ÷óæîé ïðîãðàììå, èñõîäíûé òåêñò êîòîðîé
; íåèçâåñòåí? Äà î÷åíü ïðîñòî: åñëè âñòðå÷àåòñÿ óìíîæåíèå, à ñëåäîì çà íèì
; ñäâèã âïðàâî, îáîçíà÷àþùèé äåëåíèå, òî êàæäûé íîðìàëüíûé ìàòåìàòèê ñî÷òåò
; ñâîèì äîëãîì ñîêðàòèòü òàêóþ êîíñòðóêöèþ ïî ìåòîäèêå, ïîêàçàííîé âûøå!
mov
eax, edx
; Êîïèðóåì ïîëó÷åííîå ÷àñòíîå â EAX
shr
eax, 1Fh
; Ñäâèãàåì íà 31 ïîçèöèþ âïðàâî
add
edx, eax
; Ñêëàäûâàåì: EDX = EDX + (EDX >> 31)
; ×òî áû ýòî çíà÷èëî? Íåòðóäíî ïîíÿòü, ÷òî ïîñëå ñäâèãà EDX íà 31 áèò âïðàâî
; â íåì îñòàíåòñÿ ëèøü çíàêîâûé áèò ÷èñëà.
; Òîãäà, åñëè ÷èñëî îòðèöàòåëüíî, ìû äîáàâëÿåì ê ðåçóëüòàòó äåëåíèÿ îäèí,
; îêðóãëÿÿ åãî â ìåíüøóþ ñòîðîíó. Òàêèì îáðàçîì, âåñü ýòîò õèòðûé êîä

394

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
;
;
;
;
;
;
;
;

îáîçíà÷àåò íå ÷òî èíîå, êàê òðèâèàëüíóþ îïåðàöèþ çíàêîâîãî äåëåíèÿ:
EDX = var_a / 10
Íå ñëèøêîì ëè ìíîãî êîäà äëÿ îäíîãî ëèøü äåëåíèÿ? Êîíå÷íî, ïðîãðàììà
çäîðîâî "ðàñïóõàåò", çàòî âåñü ýòîò êîä âûïîëíÿåòñÿ âñåãî ëèøü çà 9 òàêòîâ,
â òî âðåìÿ êàê â íå îïòèìèçèðîâàííîì âàðèàíòå àæ çà 28!
/* Èçìåðåíèÿ ïðîâîäèëèñü íà ïðîöåññîðå CLERION ñ ÿäðîì P6, íà äðóãèõ
ïðîöåññîðàõ êîëè÷åñòâî òàêòîâ ìîæåò îòëè÷àòüñÿ */
Òî åñòü îïòèìèçàöèÿ äàëà áîëåå ÷åì òðåõêðàòíûé âûèãðûø. Áðàâî, Microsoft!

mov
eax, ecx
; Âñïîìíèì, ÷òî íàõîäèòñÿ â ECX? Îõ, óæ ýòà íàøà äûðÿâàÿ ïàìÿòü, áîëåå äûðÿâàÿ,
; ÷åì äóðøëàã áåç äíà... Ïðîêðó÷èâàåì ýêðàí äèçàññåìáëåðà ââåðõ. Àãà, â ECX
; ïîñëåäíèé ðàç ðàçãðóæàëîñü çíà÷åíèå ïåðåìåííîé var_a
push
edx
; Ïåðåäàåì ôóíêöèè printf ðåçóëüòàò äåëåíèÿ var_a íà 10
cdq
; Ðàñøèðÿåì EAX (var_a) äî ÷åòâåðíîãî ñëîâà EDX:EAX
and
edx, 1Fh
; Âûáèðàåì ìëàäøèå 5 áèòîâ ðåãèñòðà EDX, ñîäåðæàùèå çíàê var_a
add
eax, edx
; Îêðóãëÿåì äî ìåíüøåãî
sar
eax, 5
; Àðèôìåòè÷åñêèé ñäâèã íà 5 ýêâèâàëåíòåí äåëåíèþ var_a íà 32
push
eax
push
offset aXX ; "%x %x\n"
call
_printf
add
esp, 10h
; printf("%x %x\n", var_a / 10, var_a / 32)
retn
main

endp

Íó à äðóãèå êîìïèëÿòîðû, íàñêîëüêî îíè ïðîäâèíóòû â ïëàíå îïòèìèçàöèè?
Óâû, íè Borland, íè WATCOM íå óìåþò çàìåíÿòü äåëåíèå áîëåå áûñòðûì óìíîæåíèåì äëÿ ÷èñåë, îòëè÷íûõ îò ñòåïåíè äâîéêè.  ïîäòâåðæäåíèå òîìó ðàññìîòðèì ðåçóëüòàò êîìïèëÿöèè òîãî æå ïðèìåðà êîìïèëÿòîðîì Borland C++:
Ëèñòèíã 213

_main

proc near

; DATA XREF: DATA:00407044o

push
ebp
mov
ebp, esp
; Îòêðûâàåì êàäð ñòåêà
push
ebx
; Ñîõðàíÿåì EBX
mov
eax, ecx
; Êîïèðóåì â EAX ñîäåðæèìîå íåèíèöèàëèçèðîâàííîé ðåãèñòðîâîé ïåðåìåííîé ECX
mov

ebx, 0Ah

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

395

; Çàíîñèì â EBX çíà÷åíèå 0xA
cdq
; Ðàñøèðÿåì EAX äî ÷åòâåðíîãî ñëîâà EDX:EAX
idiv
ebx
; Äåëèì ECX íà 0xA (äîëãî äåëèì - òàêòîâ 20, à òî è áîëüøå)
push
eax
; Ïåðåäàåì ïîëó÷åííîå çíà÷åíèå ôóíêöèè printf
test
ecx, ecx
jns
short loc_401092
; Åñëè äåëèìîå íå îòðèöàòåëüíî, òî ïåðåõîä íà loc_401092
add
ecx, 1Fh
; Åñëè äåëèìîå ïîëîæèòåëüíî, òî äîáàâëÿåì ê íåìó 0x1F äëÿ îêðóãëåíèÿ
loc_401092:
; CODE XREF: _main+11j
sar ecx, 5
; Ñäâèãîì íà 5 ïîçèöèé âïðàâî äåëèì ÷èñëî íà 32
push
ecx
push
offset aXX ; "%x %x\n"
call
_printf
add
esp, 0Ch
; printf("%x %x\n", var_a / 10, var_a / 32)
xor
eax, eax
; Âîçâðàùàåì íîëü
pop
ebx
pop
ebp
; Çàêðûâàåì êàäð ñòåêà
retn
_main

endp

Èäåíòèôèêàöèÿ îïåðàòîðà «%». Ñïåöèàëüíîé èíñòðóêöèè äëÿ âû÷èñëåíèÿ
îñòàòêà â íàáîðå êîìàíä ìèêðîïðîöåññîðîâ ñåðèè 80x86 íåò, âìåñòî ýòîãî îñòàòîê âìåñòå ñ ÷àñòíûì âîçâðàùàåòñÿ èíñòðóêöèÿìè äåëåíèÿ DIV, IDIV è FDIVx
(ñì. «Èäåíòèôèêàöèÿ îïåðàòîðà «/»).
Åñëè äåëèòåëü ïðåäñòàâëÿåò ñîáîé ñòåïåíü äâîéêè (2N = b), à äåëèìîå — áåççíàêîâîå ÷èñëî, òî îñòàòîê áóäåò ðàâåí N ìëàäøèì áèòàì äåëèìîãî ÷èñëà. Åñëè
æå äåëèìîå — çíàêîâîå, íåîáõîäèìî óñòàíîâèòü âñå áèòû, êðîìå ïåðâûõ N, ðàâíûìè çíàêîâîìó áèòó äëÿ ñîõðàíåíèÿ çíàêà ÷èñëà. Ïðè÷åì, åñëè N ïåðâûõ áèòîâ
ðàâíî íóëþ, âñå áèòû ðåçóëüòàòà äîëæíû áûòü ñáðîøåíû íåçàâèñèìî îò çíà÷åíèÿ
çíàêîâîãî áèòà.
Òàêèì îáðàçîì, åñëè äåëèìîå — áåççíàêîâîå ÷èñëî, òî âûðàæåíèå a % 2N
òðàíñëèðóåòñÿ â êîíñòðóêöèþ AND a, N, â ïðîòèâíîì ñëó÷àå òðàíñëÿöèÿ ñòàíîâèòñÿ íåîäíîçíà÷íà — êîìïèëÿòîð ìîæåò âñòàâëÿòü ÿâíóþ ïðîâåðêó íà ðàâåíñòâî íóëþ ñ âåòâëåíèåì, à ìîæåò èñïîëüçîâàòü õèòðûå ìàòåìàòè÷åñêèå àëãîðèòìû,
ñàìûé ïîïóëÿðíûé èç êîòîðûõ âûãëÿäèò òàê: DEC x\ OR x, -N\ INC x. Âåñü ôîêóñ â òîì, ÷òî åñëè ïåðâûå N áèòîâ ÷èñëà x ðàâíû íóëþ, òî âñå áèòû ðåçóëüòàòà,

396

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

êðîìå ñòàðøåãî, çíàêîâîãî áèòà, áóäóò ãàðàíòèðîâàííî ðàâíû îäíîìó, à OR x, -N
ïðèíóäèòåëüíî óñòàíîâèò â åäèíèöó è ñòàðøèé áèò, ò. å. ïîëó÷èòñÿ çíà÷åíèå, ðàâíîå –1. À INC –1 äàñò íîëü! Íàïðîòèâ, åñëè õîòÿ áû îäèí èç N ìëàäøèõ áèòîâ ðàâåí îäíîìó, çàåìà èç ñòàðøèõ áèòîâ íå ïðîèñõîäèò è INC x âîçâðàùàåò çíà÷åíèþ
ïåðâîíà÷àëüíûé ðåçóëüòàò.
Ïðîäâèíóòûå îïòèìèçèðóþùèå êîìïèëÿòîðû ìîãóò ïóòåì ñëîæíûõ ïðåîáðàçîâàíèé çàìåíÿòü äåëåíèå íà ðÿä äðóãèõ, áîëåå áûñòðîäåéñòâóþùèõ îïåðàöèé.
Ê ñîæàëåíèþ, àëãîðèòìîâ äëÿ áûñòðîãî âû÷èñëåíèÿ îñòàòêà äëÿ âñåõ äåëèòåëåé
íå ñóùåñòâóåò è äåëèòåëü äîëæåí áûòü êðàòåí k⋅2t, ãäå k è t — íåêîòîðûå öåëûå
÷èñëà. Òîãäà îñòàòîê ìîæíî âû÷èñëèòü ïî ñëåäóþùåé ôîðìóëå:
 2N

a
a % b = a % k ⋅ 2t = a − 
+ N & − 2 k  ⋅ k.
 k

2
Äà, ýòà ôîðìóëà î÷åíü ñëîæíà è èäåíòèôèêàöèÿ îïòèìèçèðîâàííîãî îïåðàòîðà «%» ìîæåò áûòü âåñüìà è âåñüìà íåïðîñòîé, îñîáåííî ó÷èòûâàÿ ïàòîëîãè÷åñêóþ ëþáîâü îïòèìèçàòîðîâ ê èçìåíåíèþ ïîðÿäêà êîìàíä.
Ðàññìîòðèì ñëåäóþùèé ïðèìåð:
Ëèñòèíã 214. Èäåíòèôèêàöèÿ îïåðàòîðà «%»

main()
{
int a;
printf("%x %x\n",a % 16, a % 10);
}

Ðåçóëüòàò åãî êîìïèëÿöèè êîìïèëÿòîðîì Microsoft Visual C++ ñ íàñòðîéêàìè ïî óìîë÷àíèþ äîëæåí âûãëÿäåòü òàê:
Ëèñòèíã 215

main
var_4

proc near

; CODE XREF: start+AFp

= dword ptr -4
push
ebp
mov
ebp, esp
; Îòêðûâàåì êàäð ñòåêà
push
ecx
; Ðåçåðâèðóåì ïàìÿòü äëÿ ëîêàëüíîé ïåðåìåííîé
mov
eax, [ebp+var_a]
; Çàíîñèì â EAX çíà÷åíèå ïåðåìåííîé var_a
cdq
; Ðàñøèðÿåì EAX äî ÷åòâåðíîãî ñëîâà EDX:EAX
mov
ecx, 0Ah
; Çàíîñèì â ECX çíà÷åíèå 0xA
idiv
ecx
; Äåëèì EDX:EAX (var_a) íà ECX (0xA)
push
edx
; Ïåðåäàåì îñòàòîê îò äåëåíèÿ var_a íà 0xA ôóíêöèè printf

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

397

mov
edx, [ebp+var_a]
; Çàíîñèì â EDX çíà÷åíèå ïåðåìåííîé var_a
and
edx, 8000000Fh
; "Âûðåçàåì" çíàêîâûé áèò è ÷åòûðå ìëàäøèõ áèòà ÷èñëà,
; â ÷åòûðåõ ìëàäøèõ áèòàõ ñîäåðæèòñÿ îñòàòîê îò äåëåíèÿ EDX íà 16
jns
short loc_401020
; Åñëè ÷èñëî íå îòðèöàòåëüíî, òî ïðûãàåì íà loc_401020
dec
edx
or
edx, 0FFFFFFF0h
inc
edx
; Ïîñëåäîâàòåëüíîñòü ñèÿ, êàê ãîâîðèëîñü âûøå, õàðàêòåðíà äëÿ áûñòðîãî
; ðàñ÷åòà îòñòàâêà çíàêîâîãî ÷èñëà
; Ñëåäîâàòåëüíî, ïîñëåäíèå øåñòü èíñòðóêöèé ðàñøèôðîâûâàþòñÿ êàê:
; EDX = var_a % 16
loc_401020:
; CODE XREF: main+19j
push
edx
push
offset aXX ; "%x %x\n"
call
_printf
add
esp, 0Ch
; printf("%x %x\n",var_a % 0xA, var_a % 16)

main

mov
esp, ebp
pop
ebp
; Çàêðûâàåì êàäð ñòåêà
retn
endp

Ëþáîïûòíî, ÷òî îïòèìèçàöèÿ íå âëèÿåò íà àëãîðèòì âû÷èñëåíèÿ îñòàòêà.
Óâû, íè Microsoft Visual C++, íè îñòàëüíûå èçâåñòíûå ìíå êîìïèëÿòîðû íå óìåþò âû÷èñëÿòü îñòàòîê óìíîæåíèåì.
Èäåíòèôèêàöèÿ îïåðàòîðà «*».  îáùåì ñëó÷àå îïåðàòîð «*» òðàíñëèðóåòñÿ ëèáî â ìàøèííóþ èíñòðóêöèþ MUL (áåççíàêîâîå öåëî÷èñëåííîå óìíîæåíèå), ëèáî â IMUL (öåëî÷èñëåííîå óìíîæåíèå ñî çíàêîì), ëèáî â FMULx (âåùåñòâåííîå óìíîæåíèå). Åñëè îäèí èç ìíîæèòåëåé êðàòåí ñòåïåíè äâîéêè, òî MUL
(IMUL) îáû÷íî çàìåíÿåòñÿ êîìàíäîé áèòîâîãî ñäâèãà âëåâî SHL èëè èíñòðóêöèåé LEA, ñïîñîáíîé óìíîæàòü ñîäåðæèìîå ðåãèñòðîâ íà 2, 4 è 8. Îáå ïîñëåäíèõ
êîìàíäû âûïîëíÿþòñÿ çà îäèí òàêò, â òî âðåìÿ êàê MUL òðåáóåò â çàâèñèìîñòè
îò ìîäåëè ïðîöåññîðà îò äâóõ äî äåâÿòè òàêòîâ. Ê òîìó æå LEA çà òîò æå òàêò
óñïåâàåò ñëîæèòü ðåçóëüòàò óìíîæåíèå ñ ñîäåðæèìûì ðåãèñòðà îáùåãî íàçíà÷åíèÿ è/èëè êîíñòàíòîé â ïðèäà÷ó. Ýòîïîçâîëÿåò óìíîæàòü íà 3, 5 è 9, ïðîñòî äîáàâëÿÿ ê óìíîæàåìîìó ðåãèñòðó åãî çíà÷åíèå. Íó ðàçâå ýòî íå ñêàçêà? Ïðàâäà, ó
LEA åñòü îäèí íåäî÷åò — îíà ìîæåò âûçûâàòü îñòàíîâêó AGI, â êîíå÷íîì ñ÷åòå
«ñúåäàþùóþ» âåñü âûèãðûø â áûñòðîäåéñòâèè íà íåò.
Ðàññìîòðèì ñëåäóþùèé ïðèìåð:
Ëèñòèíã 216. Èäåíòèôèêàöèÿ îïåðàòîðà «*»

main()

398

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

{
int a;
printf("%x %x %x\n",a * 16, a * 4 + 5, a * 13);
}

Ðåçóëüòàò åãî êîìïèëÿöèè êîìïèëÿòîðîì Microsoft Visual C++ ñ íàñòðîéêàìè ïî óìîë÷àíèþ äîëæåí âûãëÿäåòü òàê:
Ëèñòèíã 217

main

proc near

var_a

= dword ptr -4

; CODE XREF: start+AFp

push
ebp
mov
ebp, esp
; Îòêðûâàåì êàäð ñòåêà
push
ecx
; Ðåçåðâèðóåì ìåñòî äëÿ ëîêàëüíîé ïåðåìåííîé var_a
mov
eax, [ebp+var_a]
; Çàãðóæàåì â EAX çíà÷åíèå ïåðåìåííîé var_a
imul
eax, 0Dh
; Óìíîæàåì var_a íà 0xD, çàïèñûâàÿ ðåçóëüòàò â EAX
push
eax
; Ïåðåäàåì ôóíêöèè printf ïðîèçâåäåíèå var_a * 0xD
mov
ecx, [ebp+var_a]
; Çàãðóæàåì â ECX çíà÷åíèå var_a
lea
edx, ds:5[ecx*4]
; Óìíîæàåì ECX íà 4 è äîáàâëÿåì ê ïîëó÷åííîìó ðåçóëüòàòó 5, çàïèñûâàÿ åãî â EDX.
; È âñå ýòî âûïîëíÿåòñÿ çà îäèí òàêò!
push
edx
; Ïåðåäàåì ôóíêöèè printf ðåçóëüòàò var_a * 4 + 5
mov
eax, [ebp+var_a]
; Çàãðóæàåì â EAX çíà÷åíèå ïåðåìåííîé var_a
shl
eax, 4
; Óìíîæàåì var_a íà 16.
push
eax
; Ïåðåäàåì ôóíêöèè printf ïðîèçâåäåíèå var_a * 16
push
offset aXXX ; "%x %x %x\n"
call
_printf
add
esp, 10h
; printf("%x %x %x\n", var_a * 16, var_a * 4 + 5, var_a * 0xD)

main

mov
esp, ebp
pop
ebp
; Çàêðûâàåì êàäð ñòåêà
retn
endp

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

399

Çà âû÷åòîì âûçîâà ôóíêöèè printf è çàãðóçêè ïåðåìåííîé var_a èç ïàìÿòè íà
âñå ïðî âñå òðåáóåòñÿ ëèøü òðè òàêòà ïðîöåññîðà. À ÷òî áóäåò, åñëè ñêîìïèëèðîâàòü ýòîò ïðèìåð ñ êëþ÷èêîì /Ox? À áóäåò âîò ÷òî:
Ëèñòèíã 218

main

proc near
; CODE XREF: start+AFp
push
ecx
; Âûäåëÿåì ïàìÿòü äëÿ ëîêàëüíîé ïåðåìåííîé var_a
mov
eax, [esp+var_a]
; Çàãðóæàåì â EAX çíà÷åíèå ïåðåìåííîé var_a
lea
ecx, [eax+eax*2]
; ECX = var_a * 2 + var_a = var_a * 3
lea
edx, [eax+ecx*4]
; EDX = (var_a * 3)* 4 + var_a = var_a * 13!
; Âîò òàê êîìïèëÿòîð óõèòðèëñÿ óìíîæèòü var_a íà 13,
; ïðè÷åì âñåãî çà îäèí (!) òàêò. Äà, îáå èíñòðóêöèè LEA ïðåêðàñíî ñïàðèâàþòñÿ
; íà Pentium MMX è Pentium Pro!
lea
ecx, ds:5[eax*4]
; ECX = EAX*4 + 5
push
edx
push
ecx
; Ïåðåäàåì ôóíêöèè printf var_a * 13 è var_a * 4 +5
shl
eax, 4
; Óìíîæàåì var_a íà 16
push
eax
push
offset aXXX ; "%x %x %x\n"
call
_printf
add
esp, 14h
; printf("%x %x %x\n", var_a * 16, var_a * 4 + 5, var_a * 13)
retn

main

endp

Ýòîò êîä, ïðàâäà, âñå æå íå áûñòðåå ïðåäûäóùåãî, íå îïòèìèçèðîâàííîãî, è
óêëàäûâàåòñÿ â òå æå òðè òàêòà, íî â äðóãèõ ñëó÷àÿõ âûèãðûø ìîæåò îêàçàòüñÿ
âïîëíå îùóòèìûì.
Äðóãèå êîìïèëÿòîðû òàêæå èñïîëüçóþò LEA äëÿ áûñòðîãî óìíîæåíèÿ ÷èñåë.
Âîò, ê ïðèìåðó, Borland ïîñòóïàåò òàê:
Ëèñòèíã 219

_main

proc near
lea
edx, [eax+eax*2]
; EDX = var_a*3

; DATA XREF: DATA:00407044o

mov
ecx, eax
; Çàãðóæàåì â ECX íåèíèöèàëèçèðîâàííóþ ðåãèñòðîâóþ ïåðåìåííóþ var_a
shl

ecx, 2

400

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà
; ECX = var_a * 4
push
ebp
; Ñîõðàíÿåì EBP
add
ecx, 5
; Äîáàâëÿåì ê var_a * 4 çíà÷åíèå 5.
; Borland íå èñïîëüçóåò LEA äëÿ ñëîæåíèÿ. À æàëü...
lea
edx, [eax+edx*4]
; EDX = var_a + (var_a *3) *4 = var_a * 13
; À âîò â ýòîì Borland è MS åäèíîäóøíû :-)
mov
ebp, esp
; Îòêðûâàåì êàäð ñòåêà
; Äà, äà..., âîò òàê ïîñðåäè ôóíêöèè è îòêðûâàåì...
; Âûøå, êñòàòè, "ïîòåðÿííàÿ" êîìàíäà push EBP
push
edx
; Ïåðåäàåì printf ïðîèçâåäåíèå var_a * 13
shl
eax, 4
; Óìíîæàåì ((var_a *4) + 5) íà 16
; ×òî òàêîå?! Äà, ýòî ãëþê êîìïèëÿòîðà, ïîñ÷èòàâøåãî, ðàç ïåðåìåííàÿ var_a
; íåèíèöèàëèçèðîâàíà, òî åå ìîæíî è íå çàãðóæàòü...
push
push
push
call
add
xor
pop
retn

_main

ecx
eax
offset aXXX ; "%x %x %x\n"
printf
esp, 10h
eax, eax
ebp
endp

Õîòÿ âèçóàëüíî Borland ãåíåðèðóåò áîëåå òóïîé êîä, åãî âûïîëíåíèå óêëàäûâàåòñÿ â òå æå òðè òàêòà ïðîöåññîðà. Äðóãîå äåëî WATCOM, ïîêàçûâàþùèé óäðó÷àþùå îòñòàëûé ðåçóëüòàò íà ôîíå äâóõ ïðåäûäóùèõ êîìïèëÿòîðîâ:
Ëèñòèíã 220

main

proc near
push
ebx
; Ñîõðàíÿåì EBX â ñòåêå
mov
eax, ebx
; Çàãðóæàåì â EAX çíà÷åíèå íåèíèöèàëèçèðîâàííîé ðåãèñòðîâîé ïåðåìåííîé var_a
shl
eax, 2
; EAX = var_a * 4
sub
eax, ebx
; EAX = var_a * 4 - var_a = var_a * 3
; Âîò îí êàêîé, WATCOM! Ñíà÷àëà óìíîæàåò "ñ çàïàñîì", à ïîòîì ëèøíåå îòíèìàåò!
shl

eax, 2

Çíàêîìñòâî ñ áàçîâûìè ïðèåìàìè ðàáîòû õàêåðà

401

; EAX = var_a * 3 * 4 = var_a * 12
add
eax, ebx
; EAX = var_a * 12 + var_a = var_a * 13
; Âîò òàê, äà? ×åòûðå èíñòðóêöèè, â òî âðåìÿ êàê "íåíàâèñòíûé" ìíîãèì
; Microsoft Visual C++ âïîëíå îáõîäèòñÿ è äâóìÿ!
push
eax
; Ïåðåäàåì printf çíà÷åíèå var_a * 13
mov
eax, ebx
; Çàãðóæàåì â EAX çíà÷åíèå íåèíèöèàëèçèðîâàííîé ðåãèñòðîâîé ïåðåìåííîé var_a
shl
eax, 2
; EAX = var_a * 4
add
eax, 5
; EAX = var_a * 4 + 5
; Àãà! Ïîëüçîâàòüñÿ LEA WATCOM òîæå íå óìååò!
push
eax
; Ïåðåäàåì printf çíà÷åíèå var_a * 4 + 5
shl
ebx, 4
; EBX = var_a * 16
push
ebx
; Ïåðåäàåì printf çíà÷åíèå var_a * 16
push
offset aXXX ; "%x %x %x\n"
call
printf_
add
esp, 10h
; printf("%x %x %x\n",var_a * 16, var_a * 4 + 5, var_a*13)
pop

ebx

retn
main_

endp

 ðåçóëüòàòå êîä, ñãåíåðèðîâàííûé êîìïèëÿòîðîì WATCOM, òðåáóåò øåñòè
òàêòîâ, ò. å. âäâîå áîëüøå, ÷åì ó êîíêóðåíòîâ.
Êîìïëåêñíûå îïåðàòîðû. ßçûê Ñè\Ñè++ âûãîäíî îòëè÷àåòñÿ îò áîëüøèíñòâà ñâîèõ êîíêóðåíòîâ ïîääåðæêîé êîìïëåêñíûõ îïåðàòîðîâ: x= (ãäå x —
ëþáîé ýëåìåíòàðíûé îïåðàòîð), ++ è ––.
Êîìïëåêñíûå îïåðàòîðû ñåìåéñòâà a x= b òðàíñëèðóþòñÿ â a = a x b, è îíè
èäåíòèôèöèðóþòñÿ òàê æå, êàê è ýëåìåíòàðíûå îïåðàòîðû (ñì. «Ýëåìåíòàðíûå
îïåðàòîðû»).
Îïåðàòîðû «++» è «–»: â ïðåôèêñíîé ôîðìå îíè âûðàæàþòñÿ â òðèâèàëüíûå
êîíñòðóêöèè a = a +1 è a = a - 1, íå ïðåäñòàâëÿþùèå äëÿ íàñ íèêàêîãî èíòåðåñà,
íî âîò ïîñòôèêñíàÿ ôîðìà — äåëî äðóãîå.

Ñïîñîáû çàòðóäíåíèÿ àíàëèçà
ïðîãðàìì

Óñòîÿâøèåñÿ îáðàçöû ìîãóò áûòü ïóòåâîäíûìè, à ìîãóò ïðèâåñòè â ëîâóøêó. Íàäî ïîìíèòü, ÷òî äàæå óçîðû ñîçâåçäèé ìåíÿþòñÿ.
Ô. Õåðáåðò. Äåòè Äþíû

Òðè îñíîâíûõ ýòàïà âçëîìà çàùèòíûõ ìåõàíèçìîâ — ýòî ëîêàëèçàöèè êîäà
çàùèòû â ñîòíÿõ êèëîáàéòîâ (ìåãàáàéòîâ) êîäà ïðèëîæåíèÿ è àíàëèç àëãîðèòìà åå ðàáîòû. Ïîñëåäíÿÿ ñòàäèÿ — ñîáñòâåííî ñàì âçëîì. Âñå ýòàïû îäèíàêîâî âàæíû, åñëè, íàïðèìåð, íå áóäåò ïðîéäåí âòîðîé èç íèõ — çà âçëîì íå÷åãî è
áðàòüñÿ.
Ìîæíî êëàññèôèöèðîâàòü çàùèòû ïî òèïó «ýòàïà ïðåòêíîâåíèÿ». Íàïðèìåð,
øèôðû è êðèïòîçàùèòû îïèðàþòñÿ íà òðåòèé ýòàï — àëãîðèòì èõ ðàáîòû îáû÷íî
îáùåäîñòóïåí, õîðîøî äîêóìåíòèðîâàí è â îáùåì ñëó÷àå èçâåñòåí õàêåðó, — íî
ýòî íå ñèëüíî îáëåã÷àåò âçëîì (ðàçâå ÷òî óïðîùàåò íàïèñàíèå ëîáîâîãî ïåðåáîðùèêà). Ìåõàíèçìû ðåãèñòðàöèîííûõ íîìåðîâ, íàïðîòèâ, äåëàþò óïîð íà çàñåêðå÷èâàíèè àëãîðèòìà ãåíåðàöèè è çàòðóäíåíèè åãî ïîèñêà è àíàëèçà â êîäå ïðîãðàììû (åùå áû, çíàÿ àëãîðèòì, ìîæíî ëåãêî íàïèñàòü êåéãåí).
Îäíàêî äàæå åñëè çàùèòà ïîñòðîåíà ñ ïðèìåíåíèåì êðèïòîãðàôè÷åñêèõ ìåòîäîâ, ñêàæåì, øèôðóåò òåëî êðèòè÷åñêèâàæíûé ôóíêöèé êðèïòîñòîéêèì ìåòîäîì ïî íåïîìåðíî äëèííîìó êëþ÷ó, îíà ìîæåò áûòü «îòâÿçàíà» îò êëþ÷à, íàïðèìåð, êîïèðîâàíèåì äàìïà ïðîãðàììû ïîñëå ðàñøèôðîâêè. Åùå ïðîùå — ðàñïðîñòðàíÿòü ïðîãðàììó âìåñòå ñ êëþ÷îì (îáû÷íàÿ òàêòèêà ïèðàòîâ). Îäèí èç
ñïîñîáîâ âîñïðåïÿòñòâîâàíèÿ òàêîìó áåñïðåäåëó — çàëîæèòü â êëþ÷ çàøèôðîâàííóþ ïðèâÿçêó ê êîìïüþòåðó èëè ïðîâåðÿòü «÷èñòîòó» êîïèè ÷åðåç Èíòåðíåò
(ìîæíî äàæå è âòèõîìîëêó — ñêðûòî îò ïîëüçîâàòåëÿ, õîòÿ ýòî ñ÷èòàåòñÿ äóðíûì òîíîì). Íî ÷òî ïîìåøàåò õàêåðó, âëàäåþùåìó ëèöåíçèîííîé êîïèåé ïðîãðàììû, ðàñøèôðîâàòü åå ñâîèì êëþ÷îì è âûêóñèòü âñå-âñå ïðîâåðêè ÷åãî áû òàì
íè áûëî?
Òàêèì îáðàçîì, ëþáîé çàùèòå æåëàòåëüíî óìåòü ýôôåêòèâíî ïðåïÿòñòâîâàòü ñâîåìó îáíàðóæåíèþ, àíàëèçó, ïîïóòíî îòðàâëÿÿ æèçíü äèçàññåìáëåðó è
îòëàä÷èêó — îñíîâíûì èíñòðóìåíòàì âçëîìùèêà. Áåç ýòîãî çàùèòà — íå çàùèòà.
 ýïîõó öàðñòâîâàíèÿ MS-DOS çåìëåé áåçðàçäåëüíî âëàäåëè ïðîãðàììû ðåàëüíîãî ðåæèìà, ìîíîïîëüíî ðàñïîðÿæàþùèåñÿ ïðîöåññîðîì, ïàìÿòüþ è àïïàðàòóðîé, â ëþáîé ìîìåíò áåñïðåïÿòñòâåííî ïåðåõîäÿùèå â çàùèùåííûé ðåæèì è
âîçâðàùàþùèåñÿ îáðàòíî. Îòëàä÷èêè â òî âðåìÿ (åùå õëèïêèå, íåìîùíûå, íåæèçíåñïîñîáíûå) ëåãêî îáìàíûâàëèñü (ñðóáàëèñü, çàâåøèâàëèñü) òðèâèàëüíûìè

Ñïîñîáû çàòðóäíåíèÿ àíàëèçà ïðîãðàìì

403

ïðèåìàìè ïðîãðàììèðîâàíèÿ, àêòèâíî èñïîëüçóåìûìè çàùèòàìè. Äèçàññåìáëåðû
òîãäà áûëè î÷åíü ãëóïûìè è âïàäàëè â ñòóïîð îò îäíîãî òîëüêî âèäà çàøèôðîâàííîãî èëè ñàìîìîäèôèöèðóþùåãîñÿ êîäà. Ñëîâîì, íàñòîÿùèé ðàé äëÿ ðàçðàáîò÷èêîâ çàùèò.
Ñåãîäíÿ âñå èçìåíèëîñü. Ïðåæäå âñåãî, ïðèêëàäíîé ïðîãðàììå ïîä Windows
îñîáî âûïåíäðèâàòüñÿ íèêòî è íå äàñò. Ñ çàùèùåííûì ðåæèìîì òåïåðü îñîáî íå
ðàçãîíèøüñÿ — èñïîëüçóé ïðîçàè÷åñêèå íåïðèâèëåãèðîâàííûå èíñòðóêöèè, à î
ðàçíûõ «òèãðîñòÿõ» è íå ïîìûøëÿé. Òà æå íåáîëüøàÿ ÷àñòü çàùèòíûõ ïðèåìîâ,
÷òî ìîæåò ôóíêöèîíèðîâàòü äàæå â òàêîé «þçåðèçèðîâàííîé» ñðåäå, íàòàëêèâàåòñÿ íà ñèëüíî ïîóìíåâøèå îòëàä÷èêè è äèçàññåìáëåðû.
Àïïàðàòíàÿ ïîääåðæêà îòëàäêè â ïðîöåññîðàõ 386+ â ñîâîêóïíîñòè ñ âèðòóàëüíûì ðåæèìîì ðàáîòû, ïðèâèëåãèðîâàííûìè èíñòðóêöèÿìè è âèðòóàëüíîé ïàìÿòüþ ïîçâîëÿåò ñîçäàâàòü îòëàä÷èêè, êîòîðûå ïðàêòè÷åñêè íå ìîãóò áûòü îáíàðóæåíû ïðèêëàäíîé ïðîãðàììîé, è óæ òåì áîëåå äëÿ íåå íåâîçìîæíî ïîëó÷èòü
íàä íèìè êîíòðîëü.
Ñóùåñòâóþò è îòëàä÷èêè-ýìóëÿòîðû, ôàêòè÷åñêè íàñòîÿùèå âèðòóàëüíûå
ìàøèíû, ñàìîñòîÿòåëüíî èñïîëíÿþùèå êîä, âìåñòî òîãî ÷òîáû ïóñòèòü åãî íà
«æèâîé» ïðîöåññîð. Ïðè ýòîì ýìóëÿòîð âñåãäà èñïîëíÿåòñÿ â ðåæèìå ñóïåðâèçîðà äàæå ïî îòíîøåíèþ ê îòëàæèâàåìîìó êîäó íóëåâîãî êîëüöà. Ó çàùèòû î÷åíü
ìàëî øàíñîâ îáíàðóæèòü îòëàä÷èê èëè ïîìåøàòü åãî ðàáîòå (äà è òî, åñëè ýìóëÿòîð ðåàëèçîâàí ñ îøèáêàìè).
Ïîÿâèëèñü è èíòåðàêòèâíûå äèçàññåìáëåðû (òà æå IDA), êîòîðûå â ñèëó òåñíîãî âçàèìîäåéñòâèÿ ñ ïîëüçîâàòåëåì (â ñìûñëå õàêåðîì) ìîãóò îáõîäèòü ëþáûå
ìûñëèìûå è íåìûñëèìûå ëîâóøêè, îñòàâëåííûå ðàçðàáîò÷èêîì.
Äàæå åñëè ïðèëîæåíèå è óñòàíîâèò ñâîé vxd (vxd âûïîëíÿåòñÿ â íóëåâîì
êîëüöå è ìîæåò âûòâîðÿòü ÷òî óãîäíî), ýòî òîëüêî îáëåã÷èò çàäà÷ó âçëîìùèêà,
òàê êàê âçàèìîäåéñòâîâàòü ñ vxd çàùèòà ñìîæåò òîëüêî ÷åðåç ñïåöèàëüíûé API,
÷òî óïðîùàåò èçó÷åíèå àëãîðèòìà çàùèòû è ýìóëÿöèþ ðàáîòó vxd äëÿ «îòâÿçêè»
ïðèëîæåíèÿ îò ýëåêòðîííîãî êëþ÷à èëè êëþ÷åâîé äèñêåòû.
Íî äàæå íà óðîâíå íóëåâîãî êîëüöà â Windows î÷åíü òðóäíî ÷òî-ëèáî ñêðûòü,
äëÿ îáåñïå÷åíèÿ ñîâìåñòèìîñòè ñî âñåì ïàðêîì Windows-ïîäîáíûõ îïåðàöèîííûõ ñèñòåì ïðèõîäèòñÿ èñïîëüçîâàòü òîëüêî äîêóìåíòèðîâàííûå âîçìîæíîñòè.
Ñòðîèòü â «îêíàõ» çàùèòó — âñå ðàâíî ÷òî ïûòàòüñÿ çàáëóäèòüñÿ â ïàðêå. Áóäü
òàì õîòü ìèëëèîí äåðåâüåâ — âñå îíè ãåîìåòðè÷åñêè ïðàâèëüíî ðàñïîëîæåíû è
îáèëüíî óâåøàíû òàáëè÷êàìè «âûõîä — òàì».
Òàêèì îáðàçîì, íàäåæíî ïðîòèâîñòîÿòü èçó÷åíèþ ïðîãðàììû î÷åíü òðóäíî,
åñëè âîîáùå âîçìîæíî. Îäíàêî ìíîãèå ïðèåìû ïðîòèâ îòëàä÷èêîâ è äèçàññåìáëåðîâ ïðîñòî èíòåðåñíû ñàìè ïî ñåáå è äîñòîéíû òîãî, ÷òîáû èõ ðàññìîòðåòü â ýòîé
êíèãå.

404

Ñïîñîáû çàòðóäíåíèÿ àíàëèçà ïðîãðàìì

Ïðèåìû ïðîòèâ îòëàä÷èêîâ
Íåìíîãî èñòîðèè
Èñòîðè÷åñêàÿ ñèñòåìà âçàèìíûõ ãðàáåæåé è âûìîãàòåëüñòâ
îñòàíîâèòñÿ çäåñü, íà Àððàêè. Íåëüçÿ ñ ãîäàìè ïðåîäîëåòü
ðàñõèùåíèå òîãî, â ÷åì íóæäàåøüñÿ, íå ïðèíèìàÿ âî âíèìàíèå èíòåðåñû òåõ, êòî ïðèäåò ïîñëå òåáÿ.
Ô. Õåðáåðò. Äþíà

Ðàíüøå âñåõ ïîÿâèëñÿ debug.com — ïàðîäèÿ, îòäàëåííî íàïîìèíàþùàÿ îòëàä÷èê, çàòî âõîäÿùàÿ â øòàòíóþ ïîñòàâêó MS-DOS. Ñåãîäíÿ ýòîò èíñòðóìåíò
ãîäèòñÿ ðàçâå ÷òî äëÿ çàáàâû è èçó÷åíèÿ àññåìáëåðà. Âïðî÷åì, è òîãäà îò íåãî
ìàëî êòî áûë â âîñòîðãå, è íîâûå îòëàä÷èêè ðîñëè êàê ãðèáû ïîñëå äîæäÿ. Ïðàâäà, áîëüøèíñòâî èç íèõ íåäàëåêî óøëî îò ñâîåãî ïðîòîòèïà, îòëè÷àÿñü îò îðèãèíàëà ðàçâå ÷òî èíòåðôåéñîì.
Ýòî áûëî çîëîòîå âðåìÿ ðàçðàáîò÷èêîâ çàùèò. Ñòîèëî ëèøü «çàïåðåòü» êëàâèàòóðó, çàïðåòèòü ïðåðûâàíèÿ, ñáðîñèòü ôëàã òðàññèðîâêè, è îòëàäêà ïðîãðàììû
ñòàíîâèëàñü íåâîçìîæíîé.
Ïåðâûå ìàëî-ìàëüñêè ïðèãîäíûå äëÿ âçëîìà îòëàä÷èêè ïîÿâèëèñü òîëüêî ïîñëå îñíàùåíèÿ êîìïüþòåðîâ 80286 ïðîöåññîðîì.  ïàìÿòè õàêåðîâ íàâñåãäà îñòàíóòñÿ AFD PRO, íàïèñàííûé â 1987 ãîäó AdTec GmbH, çíàìåíèòûé Turbo Debugger, ñîçäàííûé ãîäîì ïîçæå äâóìÿ áðàòüÿìè Êðèñîì è Ðè÷åì Âèëüÿìñàìè,
ïåðâûé ýìóëèðóþùèé îòëàä÷èê Ñåðãåÿ Ïà÷êîâêè, íàïèñàííûé, ïðàâäà, ñ áîëüøèì îïîçäàíèåì: â 1991 ãîäó. Ðàçðàáîò÷èêè çàùèò êðÿêíóëè, íî âûäåðæàëè —
ýòè îòëàä÷èêè ïî-ïðåæíåìó ïîçâîëÿëè îòëàæèâàåìîé ïðîãðàììå çàõâàòèòü íàä
ñîáîé êîíòðîëü è î÷åíü ïëîõî ïåðåíîñèëè «èçâðàùåíèÿ» ñî ñòåêîì, ýêðàíîì, êëàâèàòóðîé...
Ñèòóàöèÿ èçìåíèëàñü ñ âûõîäîì 80386 ïðîöåññîðà — ðåçêîå óñëîæíåíèå
ïðîãðàììíîãî îáåñïå÷åíèÿ (è êàê ñëåäñòâèå — îãðîìíûå ñëîæíîñòè ñ åãî îòëàäêîé) äèêòîâàëî íåîáõîäèìîñòü íàëè÷èÿ ðàçâèòûõ îòëàäî÷íûõ ñðåäñòâ â ñàìîì
ïðîöåññîðå. È â 386 îíè ïîÿâèëèñü! Ñ ýòîãî ìîìåíòà ðàçðàáîò÷èêàì çàùèò ñòàëè
íàñòóïàòü íà ïÿòêè.
Ìàñëà â îãîíü ïîäëèëà NuMega, âûïóñòèâøàÿ â êîíöå âîñüìèäåñÿòûõ ãîäîâ
ñâîé çàìå÷àòåëüíûé Soft-Ice, ïîëüçîâàâøèéñÿ ó õàêåðîâ îãðîìíîé ïîïóëÿðíîñòüþ, à íûíå ïîðòèðîâàííûé íà Windows 9x è Window NT/2000 è äî ñèõ ïîð
îñòàþùèéñÿ áåññïîðíûì ôàâîðèòîì (õîòÿ íå áåç êîíêóðåíöèè). Âïðî÷åì, íåâåðíî áûëî áû ñ÷èòàòü, ÷òî NuMega — êðèìèíàëüíàÿ ôèðìà, à Soft-Ice èñêëþ÷èòåëüíî õàêåðñêèé ïðîäóêò. Ýòîò îòëàä÷èê ïðåäíàçíà÷åí â ïåðâóþ î÷åðåäü äëÿ ðàçðàáîò÷èêîâ äðàéâåðîâ è ëåãàëüíûõ èññëåäîâàòåëåé îïåðàöèîííîé ñèñòåìû (íå ðàçáèðàÿñü âî âíóòðåííîñòÿõ ÎÑ, ñ äðàéâåðàìè îñîáî íå ðàçãîíèøüñÿ).
Íî òàê èëè èíà÷å, Soft-Ice çàäàë êîïîòè âñåì çàùèòàì è èõ ðàçðàáîò÷èêàì.
Ïóñêàé îí íå áûë (äà è ñåãîäíÿ íå ñòàë) ïîëíîñòüþ Stealth-îòëàä÷èêîì, íåâèäèìûì äëÿ îòëàæèâàåìûõ ïðîãðàìì, èìåë è èìååò ðÿä îøèáîê, ïîçâîëÿþùèõ îáíà-

Ñïîñîáû çàòðóäíåíèÿ àíàëèçà ïðîãðàìì

405

ðóæèòü îòëàä÷èê, çàâåñèòü åãî è/èëè âûðâàòüñÿ çàùèòå èç-ïîä êîíòðîëÿ, íî... â
óìåëûõ ðóêàõ îòëàä÷èê ñïðàâëÿëñÿ ñî âñåìè ýòèìè îãðàíè÷åíèÿìè è îáõîäèë çàáîòëèâî ðàññòàâëåííûå «êàïêàíû». È ñ êàæäîé âåðñèåé Àéñà ïðîòèâîñòîÿòü åìó
ñòàíîâèëîñü âñå òðóäíåå è òðóäíåå (ñòàðûå îøèáêè óñòðàíÿëèñü áûñòðåå, ÷åì
âíîñèëèñü íîâûå).
Ïîñòåïåííî ìîäà íà àíòèîòëàäî÷íûå ïðèåìû ñîøëà íà íåò è óæ ñîâñåì çàãëîõëà ïîä ïîáåäíîå øåñòâèå Windows. Ðàñïðîñòðàíèëîñü ñîâåðøåííî íåëåïîå
óáåæäåíèå, ÷òî ïîä Windows íà ïðèêëàäíîì óðîâíå äåðíóòü õâîñò ÷åëîâåêó ñ îòëàä÷èêîì íåâîçìîæíî. Ýòî âûçûâàåò óõìûëêó ïðîôåññèîíàëîâ, ýïèçîäè÷åñêè
âñòðàèâàþùèõ ðàçíûå ëîâóøêè â ñâîè ïðîãðàììû — òàê, áîëüøå äëÿ ðàçìèíêè
(äàáû ìîçãè æèðîì íå çàïëûëè), ÷åì äëÿ ñåðüåçíîé áîðüáû ñ õàêåðàìè.
Áîðîòüñÿ ñ õàêåðàìè ïðè ñîâðåìåííîì óðîâíå ñðåäñòâ àíàëèçà ïðèëîæåíèé
íåñêîëüêî íàèâíî — òå è îò Òèãðà õâîñò îòîðâóò, íî ñåãîäíÿ, êðîìå õàêåðîâ,
ñåðüåçíóþ óãðîçó ïðåäñòàâëÿþò è â÷åðàøíèå æåëòîðîòûå ïîëüçîâàòåëè, íà÷èòàâøèåñÿ ðàçëè÷íûõ faq, «êàê ëîìàòü ïðîãðàììû» (áëàãî ñåé÷àñ îíè äîñòóïíû
âñåì, êîìó íè ïîïàäÿ), è òåïåðü òîëüêî è èùóùèå, íà ÷åì èñïûòàòü ñâîþ áîãàòûðñêóþ ñèëó.

Êàê ðàáîòàåò îòëàä÷èê
...äðåâíèì ñ èõ ìûñëÿùèìè ìàøèíàìè áûëî êóäà ëåã÷å.
Ô. Õåðáåðò. Äþíà

Áîðîòüñÿ ñ îòëàä÷èêîì, íå ïðåäñòàâëÿÿ ñåáå, êàê îí ðàáîòàåò, áûëî áû ïî ìåíüøåé ìåðå íåêóëüòóðíî, ïîýòîìó íèæå áóäóò ðàññìîòðåíû áàçîâûå ïðèíöèïû, ëåæàùèå â åãî îñíîâå. Ýòî èçëîæåíèå íå ÿâëÿåòñÿ âñåîáúåìëþùèì, íî, òåì íå ìåíåå,
ïîçâîëÿåò ÷èòàòåëþ ñîñòàâèòü îáùåå ïðåäñòàâëåíèå î âîïðîñå. Òåõíè÷åñêèå ïîäðîáíîñòè èñ÷åðïûâàþùå èçëîæåíû â ãëàâå «Debugging and Performance Monitoring» òåõíè÷åñêîãî ðóêîâîäñòâà «Intel Architecture Software Developer's Manual Volume 3: System Programming Guide», áåñïëàòíî ðàñïðîñòðàíÿåìîãî ôèðìîé Intel.
Âñå ñóùåñòâóþùèå îòëàä÷èêè ìîæíî ðàçäåëèòü íà äâå êàòåãîðèè — ïåðâûå
èñïîëüçóþò îòëàäî÷íûå ñðåäñòâà ïðîöåññîðà, à âòîðûå ñàìîñòîÿòåëüíî ýìóëèðóþò ïðîöåññîð, ïîëíîñòüþ êîíòðîëèðóÿ âûïîëíåíèå «ïîäîïûòíîé» ïðîãðàììû.
Êà÷åñòâåííûé ýìóëèðóþùèé îòëàä÷èê îòëàæèâàåìîìó êîäó íè îáíàðóæèòü,
íè îáîéòè íåâîçìîæíî, íî ïîëíîöåííûõ ýìóëÿòîðîâ Pentium-ïðîöåññîðîâ íà ñåãîäíÿøíèé äåíü íåò è âðÿä ëè îíè ïîÿâÿòñÿ â îáîçðèìîì áóäóùåì.
Äà è åñòü ëè ñìûñë èõ ñîçäàâàòü? Ìèêðîïðîöåññîðû Pentium ïðåäîñòàâëÿþò
â ðàñïîðÿæåíèå ðàçðàáîò÷èêà áîãàòåéøèå îòëàäî÷íûå âîçìîæíîñòè, ïîçâîëÿþùèå êîíòðîëèðîâàòü äàæå ïðèâèëåãèðîâàííûé êîä! Îíè ïîääåðæèâàþò ïîøàãîâîå èñïîëíåíèå ïðîãðàììû, îòñëåæèâàþò âûïîëíåíèÿ èíñòðóêöèè ïî çàäàííîìó àäðåñó, êîíòðîëèðóþò îáðàùåíèÿ ê çàäàííûì ÿ÷åéêàì ïàìÿòè
(èëè ïîðòàì ââîäà-âûâîäà), ñèãíàëèçèðóþò î ïåðåêëþ÷åíèÿõ çàäà÷ è ò. ä.
Åñëè áèò òðàññèðîâêè ðåãèñòðà ôëàãîâ óñòàíîâëåí, òî ïîñëå âûïîëíåíèÿ
êàæäîé ìàøèííîé èíñòðóêöèè àâòîìàòè÷åñêè ãåíåðèðóåòñÿ îòëàäî÷íîå èñêëþ÷å-

406

Ñïîñîáû çàòðóäíåíèÿ àíàëèçà ïðîãðàìì

íèå INT 1, ïåðåäàâàÿ óïðàâëåíèå îòëàä÷èêó. Îòëàæèâàåìûé êîä ìîæåò îáíàðóæèòü òðàññèðîâêó àíàëèçîì ðåãèñòðà ôëàãîâ, ïîýòîìó äëÿ îáåñïå÷åíèÿ ñîáñòâåííîé íåâèäèìîñòè îòëàä÷èê äîëæåí ðàñïîçíàâàòü êîìàíäû ÷òåíèÿ ðåãèñòðà ôëàãîâ
è ýìóëèðîâàòü èõ âûïîëíåíèå, âîçâðàùàÿ íóëåâîå çíà÷åíèå ôëàãà òðàññèðîâêè.
Ñëåäóåò îáðàòèòü âíèìàíèå íà îäíî âàæíîå îáñòîÿòåëüñòâî: ïîñëå âûïîëíåíèÿ êîìàíäû, ìîäèôèöèðóþùåé çíà÷åíèå ðåãèñòðà SS, îòëàäî÷íîå èñêëþ÷åíèå
íå ãåíåðèðóåòñÿ! Îòëàä÷èê äîëæåí óìåòü ðàñïîçíàâàòü òàêóþ ñèòóàöèþ è ñàìîñòîÿòåëüíî óñòàíàâëèâàòü òî÷êó îñòàíîâà íà ñëåäóþùóþ èíñòðóêöèþ.  ïðîòèâíîì ñëó÷àå âîéòè â ïðîöåäóðó, ïðåäâàðåííóþ èíñòðóêöèåé POP SS (íàïðèìåð,
òàê: PUSH SS; POP SS; CALL MySecretProc), àâòîìàòè÷åñêèé òðàññèðîâùèê íå
ñìîæåò. Íå âñå ñîâðåìåííûå îòëàä÷èêè ó÷èòûâàþò ýòó òîíêîñòü, è òàêîé ïðèåì,
íåñìîòðÿ íà ñâîþ àðõàè÷íîñòü, ìîæåò îêàçàòüñÿ äàëåêî íå áåñïîëåçíûì.
×åòûðå îòëàäî÷íûõ ðåãèñòðà DR0-DR3 õðàíÿò ëèíåéíûå àäðåñà ÷åòûðåõ êîíòðîëüíûõ òî÷åê, à óïðàâëÿþùèé ðåãèñòð DR7 ñîäåðæèò äëÿ êàæäîé èç íèõ óñëîâèå, ïðè âûïîëíåíèè êîòîðîãî ïðîöåññîð ãåíåðèðóåò èñêëþ÷åíèå INT 0x1, ïåðåäàâàÿ óïðàâëåíèå îòëàä÷èêó. Âñåãî ñóùåñòâóåò ÷åòûðå ðàçëè÷íûõ óñëîâèÿ: ïðåðûâàíèå ïðè âûïîëíåíèè êîìàíäû, ïðåðûâàíèå ïðè ìîäèôèêàöèè ÿ÷åéêè
ïàìÿòè, ïðåðûâàíèå ïðè ÷òåíèè èëè ìîäèôèêàöèè, íî íå èñïîëíåíèè ÿ÷åéêè ïàìÿòè è ïðåðûâàíèå ïðè îáðàùåíèè ê ïîðòó ââîäà-âûâîäà.
Óñòàíîâêîé ñïåöèàëüíîãî áèòà ìîæíî äîáèòüñÿ ãåíåðàöèè îòëàäî÷íîãî èñêëþ÷åíèÿ ïðè âñÿêîì îáðàùåíèè ê îòëàäî÷íûì ðåãèñòðàì, êîòîðîå âîçíèêàåò
äàæå â òîì ñëó÷àå, åñëè èõ ïûòàåòñÿ ïðî÷åñòü (ìîäèôèöèðîâàòü) ïðèâèëåãèðîâàííûé êîä. Ãðàìîòíî ñïðîåêòèðîâàííûé îòëàä÷èê ìîæåò ñêðûòü ôàêò ñâîåãî ïðèñóòñòâèÿ, íå ïîçâîëÿÿ îòëàæèâàåìîìó êîäó ñåáÿ îáíàðóæèòü, êàêèå áû íè áûëè ó
íåãî ïðèâèëåãèè (ïðàâäà, åñëè «ïîäîïûòíûé» êîä îòëàæèâàåò ñàì ñåáÿ, çàäåéñòâîâàâ âñå ÷åòûðå êîíòðîëüíûå òî÷êè, îòëàä÷èê íå ñìîæåò ðàáîòàòü).
Åñëè áèò Ò â TSS îòëàæèâàåìîé çàäà÷è óñòàíîâëåí, òî ïðè êàæäîì ïåðåêëþ÷åíèè íà íåå áóäåò ãåíåðèðîâàòüñÿ îòëàäî÷íîå èñêëþ÷åíèå äî âûïîëíåíèÿ ïåðâîé êîìàíäû çàäà÷è. ×òîáû ïðåäîòâðàòèòü ñîáñòâåííîå îáíàðóæåíèå, îòëàä÷èê
ìîæåò îòñëåæèâàòü âñÿêèå îáðàùåíèÿ ê TSS è âîçâðàùàòü ïðîãðàììå ïîäëîæíûå
äàííûå. Íåîáõîäèìî çàìåòèòü: Windows NT ïî ñîîáðàæåíèÿì ïðîèçâîäèòåëüíîñòè íå èñïîëüçóåò TSS (òî÷íåå, èñïîëüçóåò, íî âñåãî îäèí) è ýòà îòëàäî÷íàÿ âîçìîæíîñòü äëÿ íåå ñîâåðøåííî áåñïîëåçíà.
Ïðîãðàììíàÿ òî÷êà îñòàíîâà — åäèíñòâåííîå, ÷òî íåëüçÿ çàìàñêèðîâàòü, íå ïðèáåãàÿ ê íàïèñàíèþ ïîëíîöåííîãî ýìóëÿòîðà ïðîöåññîðà. Îíà ïðåäñòàâëÿåò ñîáîé îäíîáàéòîâûé êîä 0xCC, êîòîðûé, áóäó÷è ïîìåùåííûì â íà÷àëî
èíñòðóêöèè, âûçûâàåò èñêëþ÷åíèå INT 0x3 ïðè ïîïûòêå åå âûïîëíåíèÿ. Îòëàæèâàåìîé ïðîãðàììå äîñòàòî÷íî ïîäñ÷èòàòü ñâîþ êîíòðîëüíóþ ñóììó, ÷òîáû âûÿñíèòü, áûëà ëè óñòàíîâëåíà õîòü îäíà òî÷êà îñòàíîâà èëè íåò. Äëÿ äîñòèæåíèÿ
ýòîé öåëè îíà ìîæåò âîñïîëüçîâàòüñÿ êîìàíäàìè MOV, MOVS, LODS, POP,
CMP, CMPS èëè ëþáûìè äðóãèìè, íèêàêîìó îòëàä÷èêó íåâîçìîæíî èõ âñåõ îòñëåäèòü è ïðîýìóëèðîâàòü.
Íàñòîÿòåëüíî ðåêîìåíäóåòñÿ èñïîëüçîâàòü ïðîãðàììíûå òî÷êè îñòàíîâà â
òåõ è òîëüêî â òåõ ñëó÷àÿõ, êîãäà àïïàðàòíûõ óæå íå õâàòàåò. Îäíàêî ïðàêòè÷åñêè âñå ñîâðåìåííûå îòëàä÷èêè (â òîì ÷èñëå è Soft-Ice) âñåãäà óñòàíàâëèâàþò

Ñïîñîáû çàòðóäíåíèÿ àíàëèçà ïðîãðàìì

407

ïðîãðàììíûå, à íå àïïàðàòíûå òî÷êè îñòàíîâà. Ýòî îáñòîÿòåëüñòâî ìîæåò áûòü ñ
óñïåõîì èñïîëüçîâàíî â çàùèòíûõ ìåõàíèçìàõ, ïðèìåðû ðåàëèçàöèé êîòîðûõ
ïðèâåäåíû â ðàçäåëå «Êàê ïðîòèâîñòîÿòü òðàññèðîâêå».

Îáðàáîòêà èñêëþ÷åíèé â ðåàëüíîì
è çàùèùåííîì ðåæèìàõ
Êîãäà âîçíèêàåò îòëàäî÷íîå èñêëþ÷åíèå (êàê, âïðî÷åì, è ëþáîå äðóãîå èñêëþ÷åíèå âîîáùå), ïðîöåññîð çàíîñèò â ñòåê ðåãèñòð ôëàãîâ, àäðåñ ñëåäóþùåé
(èëè òåêóùåé — â çàâèñèìîñòè îò ðîäà èñêëþ÷åíèÿ) âûïîëíÿåìîé èíñòðóêöèè è
ëèøü çàòåì ïåðåäàåò óïðàâëåíèå îòëàä÷èêó.
 ðåàëüíîì ðåæèìå ôëàãè ñ àäðåñîì âîçâðàòà çàíîñÿòñÿ â ñòåê îòëàæèâàåìîé ïðîãðàììû, ïîýòîìó ôàêò îòëàäêè îáíàðóæèòü î÷åíü ïðîñòî — äîñòàòî÷íî êîíòðîëèðîâàòü öåëîñòíîñòü ñîäåðæèìîãî, ëåæàùåãî âûøå óêàçàòåëÿ ñòåêà.
Èëè, êàê âàðèàíò, óñòàíîâèòü óêàçàòåëü íà åãî âåðøèíó, òîãäà äîáàâëåíèå íîâûõ
äàííûõ â ñòåê îêàæåòñÿ íåâîçìîæíûì è îòëàä÷èê íå ñìîæåò ôóíêöèîíèðîâàòü.
Èíàÿ ñèòóàöèÿ ñêëàäûâàåòñÿ ïðè ðàáîòå â çàùèùåííîì ðåæèìå — îáðàáîò÷èê èñêëþ÷åíèÿ ìîæåò íàõîäèòüñÿ â ñâîåì ñîáñòâåííîì àäðåñíîì ïðîñòðàíñòâå è
íå èñïîëüçîâàòü íèêàêèõ ðåñóðñîâ îòëàæèâàåìîãî ïðèëîæåíèÿ, â òîì ÷èñëå è ñòåêà. Ãðàìîòíî ñïðîåêòèðîâàííûé îòëàä÷èê çàùèùåííîãî ðåæèìà íè îáíàðóæèòü,
íè áëîêèðîâàòü ïðèíöèïèàëüíî íåâîçìîæíî, äàæå ïðèâèëåãèðîâàííîìó êîäó, èñïîëíÿþùåìóñÿ â íóëåâîì êîëüöå.
Ñêàçàííîå ñïðàâåäëèâî äëÿ Windows NT, íî íåïðèìåíèìî ê Windows 9x —
ýòà îïåðàöèîííàÿ ñèñòåìà íå èñïîëüçóåò äîëæíûì îáðàçîì âñåõ ïðåèìóùåñòâ çàùèùåííîãî ðåæèìà è âñåãäà «çàìóñîðèâàåò» ñòåê îòëàæèâàåìîé çàäà÷è, íåçàâèñèìî îò òîãî, íàõîäèòñÿ ëè îíà ïîä îòëàäêîé èëè íåò.

Êàê õàêåðû ëîìàþò ïðîãðàììû
Âñêðûòü çàùèòíûé ìåõàíèçì âçëîìùèêó â îáùåì ñëó÷àå íå ïðîáëåìà. Êóäà
ñëîæíåå íàéòè åãî âî ìíîãèõ ìåãàáàéòàõ êîäà ëîìàåìîãî ïðèëîæåíèÿ. Ñåãîäíÿ
ìàëî êòî èñïîëüçóåò äëÿ ýòîé öåëè àâòîìàòè÷åñêóþ òðàññèðîâêó — íà ñìåíó åé
ïðèøëè àïïàðàòíûå êîíòðîëüíûå òî÷êè.
Íàïðèìåð, ïóñòü íåêàÿ çàùèòà çàïðàøèâàåò ïàðîëü è çàòåì êàêèì-òî îáðàçîì
óäîñòîâåðÿåòñÿ â åãî ïîäëèííîñòè (íàïðèìåð, ñðàâíèâàåò ñ îðèãèíàëîì) è â çàâèñèìîñòè îò ðåçóëüòàòîâ ïðîâåðêè ïåðåäàåò óïðàâëåíèå ñîîòâåòñòâóþùåé âåòêå
ïðîãðàììû. Âñêðûòü òàêóþ çàùèòó âçëîìùèê ìîæåò, äàæå íå âíèêàÿ â àëãîðèòì
àóòåíòèôèêàöèè! Îí ïðîñòî ââåäåò ïåðâûé ïðèøåäøèé åìó íà óì ïàðîëü (íå îáÿçàòåëüíî ñîâïàäàþùèé ñ ïðàâèëüíûì), íàéäåò åãî â ïàìÿòè, óñòàíîâèò êîíòðîëüíóþ òî÷êó íà ïåðâûé ñèìâîë ñòðîêè ñâîåãî ïàðîëÿ, äîæäåòñÿ «âñïëûòèÿ» îòëàä÷èêà, îòñëåäèâøåãî îáðàùåíèå ê ïàðîëþ, âûéäåò èç ñðàâíèâàþùåé ïðîöåäóðû è
«ïîäïðàâèò» óñëîâèå ïåðåõîäà òàê, ÷òîáû óïðàâëåíèå âñåãäà ïîëó÷àëà íóæíàÿ
âåòâü ïðîãðàììû.

408

Ñïîñîáû çàòðóäíåíèÿ àíàëèçà ïðîãðàìì

Âðåìÿ ñíÿòèÿ ïîäîáíûõ çàùèò èçìåðÿåòñÿ ñåêóíäàìè (!), è îáû÷íî òàêèå
ïðîãðàììû ëîìàþòñÿ ðàíüøå, ÷åì óñïåâàþò äîéòè äî ëåãàëüíîãî ïîòðåáèòåëÿ.
Ê ñ÷àñòüþ, ýòîìó ìîæíî ïðîòèâîñòîÿòü!

Êàê çàùèòèòü ñâîè ïðîãðàììû
Îòêóäà áû íè áðàëàñü êëþ÷åâàÿ èíôîðìàöèÿ — èç ðååñòðà, ôàéëà èëè êëàâèàòóðû, — âçëîìùèê ìîæåò ïðàêòè÷åñêè ìãíîâåííî ëîêàëèçîâàòü åå ìåñòîïîëîæåíèå â ïàìÿòè è óñòàíîâèòü íà íåãî êîíòðîëüíóþ òî÷êó. Ïîìåøàòü ýòîìó íåëüçÿ,
íî íå ñîñòàâèò òðóäà ïîäëîæèòü õàêåðó íåîæèäàííûé ñþðïðèç — ïóñòü êëþ÷åâàÿ
èíôîðìàöèÿ àíàëèçèðóåòñÿ íå ñðàçó æå ïîñëå ïîëó÷åíèÿ, à ïåðåäàåòñÿ â êà÷åñòâå
àðãóìåíòà ìíîæåñòâó ôóíêöèé, êîòîðûå ÷òî-òî ñ íåé äåëàþò è çàòåì ïåðåäàþò
äðóãèì ôóíêöèÿì, à òå, â ñâîþ î÷åðåäü, ñëåäóþùèì.
Çàùèòíûé ìåõàíèçì ìîæåò áûòü âñòðîåí âî ÷òî óãîäíî, õîòü â ïðîöåäóðó îòêðûòèÿ ôàéëà èëè ðàñ÷åòà çàðïëàòû. Íå ñòîèò äåëàòü ÿâíûõ ïðîâåðîê, ïóñòü ëó÷øå â ñëó÷àå âûçîâà ôóíêöèè ñ íåâåðíîé êëþ÷åâîé èíôîðìàöèåé îíà âîçâðàòèò
íåïðàâèëüíûé ðåçóëüòàò, íî íå ñèãíàëèçèðóåò îá îøèáêå. Âçëîìàííàÿ ïðîãðàììà
íà ïåðâûé âçãëÿä áóäåò èñïðàâíî ðàáîòàòü, è äàëåêî íå ñðàçó âûÿñíèòñÿ, ÷òî ðàáîòàåò îíà íåïðàâèëüíî (íàïðèìåð, âûâîäèò íà ýêðàí îäíè ÷èñëà, à íà ïðèíòåð — ñîâñåì äðóãèå). À ÷òîáû îáåçîïàñèòü ëåãàëüíîãî ïîëüçîâàòåëÿ îò îøèáî÷íîãî ââîäà ïàðîëÿ, äîñòàòî÷íî â îäíîì ìåñòå ÿâíî ïðîâåðèòü åãî êîíòðîëüíóþ ñóììó, êîòîðàÿ íå äàåò âçëîìùèêó íèêàêîé èíôîðìàöèè îá èñòèííîì
çíà÷åíèè ïàðîëÿ.
Òàêèì îáðàçîì, çàùèòà êàê áû «ðàçìàçûâàåòñÿ» ïî âñåé ïðîãðàììå, áóôåðà ñ
êëþ÷åâûìè äàííûìè ìíîãîêðàòíî äóáëèðóþòñÿ, è íà îòñëåæèâàíèå îáðàùåíèé ó
âçëîìùèêà íå õâàòèò íè êîíòðîëüíûõ òî÷åê, íè òåðïåíèÿ äëÿ àíàëèçà îãðîìíîãî
îáúåìà ìàíèïóëèðóþùèìè ñ íèìè êîäà. Áóäåò åùå ëó÷øå, åñëè ïîñëå âûïîëíåíèÿ ïðîâåðêè êëþ÷åâîé èíôîðìàöèè ýòè æå ñàìûå áóôåðà èñïîëüçîâàòü äëÿ õðàíåíèÿ ñëóæåáíûõ äàííûõ, îáðàùåíèå ê êîòîðûì ïðîèñõîäèò ïî âîçìîæíîñòè ìàêñèìàëüíîãî ÷àñòî. Ýòî íå ïîçâîëèò âçëîìùèêó áûñòðî îòäåëèòü çàùèòíûé ìåõàíèçì îò ïðî÷åãî ïðèêëàäíîãî êîäà.
Ïîïóòíî: ïîñêîëüêó áîëüøèíñòâî âçëîìùèêîâ ñòàâèò êîíòðîëüíóþ òî÷êó íà
íà÷àëî êîíòðîëüíîãî áóôåðà, èìååò ñìûñë ïîìåñòèòü â ïåðâûå ÷åòûðå áàéòà êëþ÷à «çàãëóøêó», îáðàùåíèå ê êîòîðîé ëèáî íå ïðîèñõîäèò âîâñå, ëèáî ñ íåé ìàíèïóëèðóåò èìèòàòîð çàùèòû, íàïðàâëÿÿ õàêåðà ïî ëîæíîìó ïóòè.
 òàêîé ñèòóàöèè âçëîìùèêó íè÷åãî íå îñòàíåòñÿ, êðîìå òîãî, êàê, çàòàðèâøèñü ïèâîì, ïëîòíî çàñåñòü çà êðîïîòëèâîå èçó÷åíèå âñåãî êîäà ïðîãðàììû, ïðÿìî èëè êîñâåííî ìàíèïóëèðóþùåãî ñ êëþ÷åâîé èíôîðìàöèåé (à ýòî
ìíîãèå ìåãàáàéòû äèçàññåìáëåðíîãî ëèñòèíãà!). Åñëè êðèòè÷åñêàÿ ÷àñòü êîäà
çàøèôðîâàíà, ïðè÷åì íè â êàêîé ìîìåíò ðàáîòû ïðîãðàììû íå ðàñøèôðîâûâàåòñÿ ïîëíîñòüþ (ïðè âûõîäå â êàæäóþ ôóíêöèþ îíà ðàñøèôðîâûâàåòñÿ, à ïðè
âûõîäå çàøèôðîâûâàåòñÿ âíîâü), õàêåð íå ñìîæåò ïîëó÷èòü ãîòîâûé ê äèçàññåìáëèðîâàíèþ äàìï è áóäåò âûíóæäåí ïðèáåãíóòü ê òðàññèðîâêå. À âîò òóò
åãî áóäåò æäàòü âòîðîé ñþðïðèç!

Ñïîñîáû çàòðóäíåíèÿ àíàëèçà ïðîãðàìì

409

Êàê ïðîòèâîñòîÿòü òðàññèðîâêå
Ïðèíöèïèàëüíàÿ âîçìîæíîñòü ñîçäàíèÿ ïîäëèííî «íåâèäèìûõ» îòëàä÷èêîâ
áîëüøåé ÷àñòüþ ïðîñòî âîçìîæíîñòüþ è îñòàåòñÿ — áîëüøèíñòâî èç íèõ ïîçâîëÿåò îáíàðóæèòü ñåáÿ äàæå íåïðèâèëåãèðîâàííîìó êîäó.
Íàèáîëüøèå íàðåêàíèÿ âûçûâàåò èñïîëüçîâàíèå îäíîáàéòîâîãî êîäà 0xCC
äëÿ ñîçäàíèÿ òî÷êè îñòàíîâà âìåñòî ïîðó÷åíèÿ òîé æå çàäà÷è ñïåöèàëüíî äëÿ
ýòîãî ïðåäíàçíà÷åííûì îòëàäî÷íûì ðåãèñòðàì. Òàê ïîñòóïàþò Soft-Ice, Turbo
Debugger, Code Viewer è îòëàä÷èê, èíòåãðèðîâàííûé â Microsoft Visual Studio.
Ïðè÷åì ïîñëåäíèé íåÿâíî èñïîëüçóåò òî÷êè îñòàíîâà ïðè ïîøàãîâîì ïðîãîíå
ïðîãðàììû, ïîìåùàÿ â íà÷àëî ñëåäóþùåé èíñòðóêöèè ýòîò ïðåñëîâóòûé áàéò
0xCC.
Òðèâèàëüíàÿ ïðîâåðêà ñîáñòâåííîé öåëîñòíîñòè ïîçâîëÿåò îáíàðóæèòü ôàêò
óñòàíîâêè òî÷åê îñòàíîâà, ñâèäåòåëüñòâóþùèé îá îòëàäêå. Íå ñòîèò èñïîëüçîâàòü
êîíñòðóêöèè íàïîäîáèå if (CalculateMyCRC()!=MyValidCRC) {printf("Hello,
Hacker!\n");return;}, èõ ñëèøêîì ëåãêî îáíàðóæèòü è íåéòðàëèçîâàòü, ïîäïðàâèâ óñëîâíûé ïåðåõîä òàê, ÷òîáû îí âñåãäà ïåðåäàâàë óïðàâëåíèå íóæíîé âåòêå
ïðîãðàììû. Ëó÷øå ðàñøèôðîâûâàòü ïîëó÷åííûì çíà÷åíèåì êîíòðîëüíîé ñóììû
êðèòè÷åñêèå äàííûå èëè íåêîòîðûé êîä.
Ïðîñòåéøàÿ çàùèòà ìîæåò âûãëÿäåòü, íàïðèìåð, òàê:
Ëèñòèíã 221

int main(int argc, char* argv[])
{
// çàøèôðîâàííàÿ ñòðîêà Hello, Free World!
char s0[]="\x0C\x21\x28\x28\x2B\x68\x64\x02\x36\
\x21\x21\x64\x13\x2B\x36\x28\x20\x65\x49\x4E";
__asm
{
BeginCode:
; //íà÷àëî êîíòðîëèðóåìîãî êîäà
pusha
; //ñîõðàíåíèå âñåõ ðåãèñòðîâ îáùåãî íàçíà÷åíèÿ
lea
ebx,s0
; // ebx=&s0[0]
GetNextChar:
; // do
XOR
eax,eax
; // eax = 0;
LEA
esi,BeginCode ; // esi = &BeginCode
LEA
ecx,EndCode
; // âû÷èñëåíèå äëèíû...
SUB
ecx,esi
; // ...êîíòðîëèðóåìîãî êîäà
HarvestCRC:
; // do
LODSB
; // çàãðóçêà î÷åðåäíîãî áàéòà â al
ADD
eax,eax
; // âû÷èñëåíèå êîíòðîëüíîé ñóììû
LOOP HarvestCRC
; // until(—cx>0)
xor
[ebx],ah
; // ðàñøèôðîâêà î÷åðåäíîãî ñèìâîëà s0
inc
ebx
; // óêàçàòåëü íà ñëåä. ñèìâîë
cmp
[ebx],0
; // until (ïîêà íå êîíåö ñòðîêè)
jnz
GetNextChar
; // ïðîäîëæèòü ðàñøèôðîâêó
popa
; // âîññòàíîâèòü âñå ðåãèñòðû
EndCode:
; // êîíåö êîíòðîëèðóåìîãî êîäà
NOP
; // Safe BreakPoint here
}

410

Ñïîñîáû çàòðóäíåíèÿ àíàëèçà ïðîãðàìì
printf(s0)
return 0;

; // âûâîä ñòðîêè íà ýêðàí

}

Ïðè íîðìàëüíîì çàïóñêå íà ýêðàíå äîëæíà ïîÿâèòüñÿ ñòðîêà «Hello, Free
World!», íî ïðè ïðîãîíå ïîä îòëàä÷èêîì ïðè íàëè÷èè õîòÿ áû îäíîé òî÷êè îñòàíîâà, óñòàíîâëåííîé â ïðåäåëàõ îò BeginCode äî EndCode, íà ýêðàíå ïîÿâèòñÿ
áåññìûñëåííûé ìóñîð íàïîäîáèå: «Jgnnm."Dpgg"Umpnf#0».
Çíà÷èòåëüíî óñèëèòü çàùèòó ìîæíî, ïîìåñòèâ ïðîöåäóðó ïîäñ÷åòà êîíòðîëüíîé ñóììû â îòäåëüíûé ïîòîê, çàíèìàþùèéñÿ (äëÿ ñîêðûòèÿ ñâîåé äåÿòåëüíîñòè)
åùå ÷åì-íèáóäü ïîëåçíûì, òàê ÷òîáû çàùèòíûé ìåõàíèçì ïî âîçìîæíîñòè íå áðîñàëñÿ â ãëàçà.
Ïîòîêè âîîáùå âåëèêàÿ âåùü, òðåáóþùàÿ ê ñåáå îñîáîãî ïîäõîäà. ×åëîâåêó
î÷åíü òðóäíî ñìèðèòüñÿ ñ òåì, ÷òî ïðîãðàììà ìîæåò èñïîëíÿòüñÿ âî ìíîæåñòâå
ìåñò îäíîâðåìåííî. Ðàñïðîñòðàíåííûå îòëàä÷èêè ãðåøàò òåì, ÷òî îòëàæèâàþò
êàæäûé ïîòîê ïî îòäåëüíîñòè, íî íèêîãäà äâà è áîëåå ñðàçó. Ïðèâåäåííûé íèæå
ïðèìåð ïîêàçûâàåò, êàê ýòî ìîæíî èñïîëüçîâàòü äëÿ çàùèòû.
Ëèñòèíã 222

// Ýòà ôóíêöèÿ áóäåò âûïîëíÿòüñÿ â îòäåëüíîì ïîòîêå
// åå íàçíà÷åíèå íåçàìåòíî èçìåíÿòü ðåãèñòð ñèìâîëîâ â ñòðîêå,
// ñîäåðæàùåé èìÿ ïîëüçîâàòåëÿ
void My(void *arg)
{
int p=1;
// Óêàçàòåëü íà øèôðóåìûé áàéò
// îáðàòèòå âíèìàíèå, øèôðîâêà âûïîëíÿåòñÿ
// íå ñ ïåðâîãî áàéòà, ýòî ïîçâîëÿåò îáîéòè
// êîíòðîëüíóþ òî÷êó, óñòàíîâëåííóþ íà íà÷àëî áóôåðà
// âûïîëíÿòü äî òåõ ïîð, ïîêà íå âñòðåòèòñÿ ïåðåíîñ ñòðîêè
while ( ((char *) arg)[p]!='\n')
{
// îæèäàòü, ïîêà î÷åðåäíîé ñèìâîë íå áóäåò èíèöèàëèçèðîâàí
while( ((char *) arg)[p]