Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
12
Добавлен:
20.04.2024
Размер:
13.11 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

>> codingto BUY

 

 

 

 

 

 

 

w Click

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

o

 

 

.

 

 

 

 

.c

 

 

 

p

 

 

 

g

 

 

 

 

 

df

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Наш крутой кодинг

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

Создаем объект «соединение»

Основное, что здесь нам потребуется, — это создать и получить хэндл устройства \\Device\\Tcp через ZwCreateFile, создать пустой объект FileObject и вызовом ObReferenceObjectByHan dle связать их вместе. Предварительно для получения хэндла устройства \\Device\\Tcp нужно заполнить структуру FILE_ FULL_EA_INFORMATION. И все! Смотрим нижеследующий код (объявление переменных и реализация общих для всех функций моментов намеренно опущено, потому что журнал не резиновый — смотри исходник на диске).

NTSTATUS CreateConnection(PHANDLE Handle, PFILE_OBJECT *FileObject)

{

Ea = (PFILE_FULL_EA_INFORMATION)&DataBlock; Ea->EaNameLength =

TDI_CONNECTION_CONTEXT_LENGTH; Ea->EaValueLength =

sizeof(CONNECTION_CONTEXT); memcpy(Ea->EaName,

TdiConnectionContext,

Ea->EaNameLength + 1); *(CONNECTION_CONTEXT*)(Ea->EaName +

(Ea->EaNameLength + 1)) = (CONNECTION_CONTEXT)conn_context;

Status = ZwCreateFile(Handle, FILE_READ_EA | FILE_WRITE_EA, &Attr,

 

 

warning

 

 

Осторожнее в работе

 

 

с ядром! Грубые

 

 

ошибки неминуемо

 

 

ведут к BSOD’у,

 

 

стрессу и смерти

 

 

нервных клеток!

 

 

&IoStatus, 0, FILE_ATTRIBUTE_NORMAL, 0,

 

FILE_OPEN, 0, Ea, sizeof(DataBlock));

 

return ObReferenceObjectByHandle(*Handle,

 

GENERIC_READ | GENERIC_WRITE, 0,

 

KernelMode, (PVOID *)FileObject, 0);

dvd

}

 

На диске лежит пол-

 

 

ный исходный код

Создаем локальный адрес

рассматриваемого

Фактически здесь происходит то же самое, что и при создании

драйвера. Для его

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

сборки тебе пона-

ру TA_IP_ADDRESS. Ее описание ты легко найдешь в DDK или

добится Microsoft’s

в Сети. Можно заполнять поля самостоятельно, как показано

Driver Development

ниже (например, поле sin_port — порт, который будет открыт на

Kit. Также добав-

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

лены INSTDRV для

системе возможность самой назначить номер порта. При

установки и исполь-

самостоятельном заполнении sin_port можно использовать

зования драйвера и

такой макрос:

Dbgview для kernel-

 

 

отладки.

HTONS(a) (((0xFF&a)<<8) + ((0xFF00&a)>>8))

 

 

 

 

Послевыполненияэтойфункциивсистеме будетсозданобъект«локальныйадрес»

NTSTATUS CreateAddress(PHANDLE Handle, PFILE_OBJECT *FileObject)

{

Ea = (PFILE_FULL_EA_INFORMATION) &DataBlock;

memcpy(Ea->EaName, TdiTransportAddress, Ea->EaNameLength + 1);

Ea->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;

Ea->EaValueLength = sizeof (TA_IP_ADDRESS); Sin = (PTA_IP_ADDRESS)(&Ea->EaName +

Ea->EaNameLength + 1);

xàêåð 02 /110/ 08

119

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

E

 

 

 

 

X

 

 

 

 

 

-

 

 

 

 

d

 

 

F

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

w Click

to BUY

 

>> coding

 

 

 

 

 

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

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Работает! Драйвер шлет то, что нужно

info

Для отладки драйвера обязательно нужен будет отладчик ядерного уровня типа SoftICE или

WinDBG, иначе на первых порах искать ошибки в коде будет сложновато.

И обязательно раздобудь продвинутый анализатор сетевых пакетов для контроля за устанавливаемыми соединениями и анализа содержимого пакетов.

Sin->TAAddressCount = 1; Sin->Address[0].AddressLength =

TDI_ADDRESS_LENGTH_IP; Sin->Address[0].AddressType =

TDI_ADDRESS_TYPE_IP; Sin->Address[0].Address[0].sin_port =

HTONS(номер_порта_на_локальной_машине); Sin->Address[0].Address[0].in_addr = 0; RtlZeroMemory(Sin->Address[0].Address[0].

sin_zero, sizeof(Sin->Address[0].Address[0]. sin_zero));

Status = ZwCreateFile(Handle, FILE_READ_EA | FILE_WRITE_EA, &Attr, &IoStatus, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, 0, Ea, sizeof(DataBlock));

return ObReferenceObjectByHandle(*Handle, GENERIC_READ | GENERIC_WRITE, 0, KernelMode, (PVOID *)FileObject, 0);

}

Узелок на память...

Теперь необходимо связать оба созданных файловых объекта вместе.

Первое — универсальная функция TdiBuildInternalDeviceCo ntrolIrp, в зависимости от переданных ей параметров (в чем убедимся далее) создающая IRP-пакет, который передается функции TdiBuildAssociateAddress. Все дальнейшее взаи-

модействие будет происходить именно через этот IRP-пакет, который затем вызовом IoCallDriver будет передан нижележащему драйверу в стеке.

Вообще, рекомендуется прикрутить ко всему этому эвент на тот случай, если обработка IRP-пакета попадет в очередь, поскольку Windows — очень занятая система и, для того чтобы попасть на прием к Его Величеству Ядру, приходится выстаивать в очередях :). О работе с IRP-пакетами можно почитать статьи Four-F на wasm.ru.

Связываемсозданныеобъектывместе

NTSTATUS Bind(PFILE_OBJECT FileObject,

HANDLE Address)

{

DeviceObject = IoGetRelatedDeviceObject (FileObject);

Irp = TdiBuildInternalDeviceControlIrp (TDI_ASSOCIATE_ADDRESS, DeviceObject, FileObject, &Event, &IoStatus);

TdiBuildAssociateAddress(Irp,

DeviceObject, FileObject, 0, 0, Address);

return IoCallDriver(DeviceObject, Irp);

}

Коннектимся...

Главное здесь — заполнить структуру TA_IP_ADDRESS, которая будет описывать тот удаленный хост, к которому нужно приконнектиться. При создании локального адреса мы это уже делали, только теперь поля sin_port и in_addr нужно заполнить вручную. При заполнении in_addr используй следующий макрос: INETADDR(a, b, c, d) (a + (b<<8) + (c<<16) + (d<<24)).

Кроме того, нужно заполнить структуру TDI_CONNECTION_ INFORMATION. Непосредственный коннект реализуется вызовом TdiBuildConnect и уже привычным IoCallDriver. В

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

Функциясоединениясудаленнымхостом

NTSTATUS Connect(PFILE_OBJECT FileObject)

{

DeviceObject = IoGetRelatedDeviceObject (FileObject);

Irp = TdiBuildInternalDeviceControlIrp (TDI_CONNECT, DeviceObject, FileObject, &Event, &IoStatus);

rem_adr.TAAddressCount = 1; rem_adr.Address[0].AddressLength =

TDI_ADDRESS_LENGTH_IP; rem_adr.Address[0].AddressType =

TDI_ADDRESS_TYPE_IP; rem_adr.Address[0].Address[0].sin_port =

HTONS(номер_порта); rem_adr.Address[0].Address[0].in_addr =

INETADDR(IP-адрес хоста);

120

xàêåð 02 /110/ 08

 

 

 

 

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

>> codingto BUY

 

 

 

 

 

 

 

w Click

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

o

 

 

.

 

 

 

 

.c

 

 

 

p

 

 

 

g

 

 

 

 

 

df

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Сетевая инфраструктура в ядре

RtlZeroMemory(rem_adr.Address[0]. Address[0].sin_zero, sizeof(rem_adr. Address[0].Address[0].sin_zero));

remote_node.UserDataLength = 0; remote_node.UserData = 0; remote_node.OptionsLength = 0; remote_node.Options = 0; remote_node.RemoteAddressLength =

sizeof(rem_adr); remote_node.RemoteAddress = &rem_adr; TdiBuildConnect(Irp, DeviceObject,

FileObject, 0, 0, 0, &remote_node, 0); return IoCallDriver(DeviceObject, Irp);

}

То, что мы рассмотрели, — это костяк TDI-клиента, который всего лишь устанавливает соединение с выбранным хостом. Но ведь необходимо еще и отправлять и получать данные! Для этого потребуется всего лишь предусмотреть отдельную реализацию функций TdiBuildSend TdiBildRecieve с переданными параметрами TDI_SEND и TDI_RECEIVE соответственно. Что и как они делают, смотри в DDK. Для совсем ленивых на диске лежит небольшой бонус, в котором можно найти вполне рабочий сорец драйвера с уже реализованными функциями посылки и получения данных (если все еще не ясно, пиши мне на мыло — объясню).

Чтобы по возможности избежать тех проблем, с которым сталкиваются начинающие, слушай мои советы.

Первое. При реализации функции получения данных через вызов TDI_RECEIVE нужно предусмотреть возможность получения ВСЕХ данных, которые нам отправит сервер. Если этого не сделать, размер полученных данных будет ограничен лишь размером ПРЕДВАРИТЕЛЬНО выделенного буфера. Иначе говоря, если ты захочешь скачать 2 Мб, а размер буфера равен 0xff байт, то свои 0xff ты и получишь. Остальное будет обрезано, и процедура может просто подвиснуть. На мой взгляд, неплохим вариантом будет динамическое выделение буфера в памяти под размер передаваемых данных, который можно выдрать из поля Content-Length, которое, в свою очередь, тебе вернет правильный веб-сервер (и то это при условии, что ты работаешь именно с веб-сервером). Решение этой проблемы будет твоим домашним заданием.

Второе. Полученный буфер будет ВРЕМЕННО храниться в ЯДРЕ. Не пытайся искать скачанное в кэше Internet Explorer или где-то на диске — это бесперспективно до тех пор, пока ты туда его насильно не сохранишь. При этом не забывай освобождать память из-под буфера в ядре, иначе... сам знаешь, чем это может грозить.

Ну и третье. При реализации функции приема данных через вызов TDI_RECEIVE нужно помнить, что, в случае если она не дождется данных от сервера (мало ли что с удаленным хостом может случиться: заддосят негодяи или просто админ будет где-то резаться в линейку, забыв о серваке), функция может вернуть вечный STATUS_PENDING, то есть IRP-пакет будет стоять в очереди до тех пор, пока он не будет обработан. А как следствие, зависший драйвер. Поэтому в коде обязательно надо учесть подобное развитие ситуации. Особо продвинутым

итем, кто хочет досконально разобраться в работе TDI, рекомендую скачать tdfw-файрвол. Он open source, и его можно свободно найти в Сети.

Итак, мы рассмотрели простейший вариант TDI-клиента, который ничего особенного не делает. Целью статьи была, дорогой читатель, демонстрация того, что работать с сетью в ядре Windows не так уж и сложно. А TDI на самом деле предоставляет для этого кучу возможностей: там и TDI_LISTEN,

иTDI_ACCEPT, и много прочих вкусностей... MSDN и журнал «Хакер» помогут тебе! И помни: дорогу осилит идущий...

Злоключение

«Зачем все это нужно, ведь можно спокойно юзать библиотеки WinSock в user mode и при минимальных затратах решать поставленные задачи по работе с сетью?» — спросит читатель. Как однажды сказал мой хороший друг, «то, что ты написал,

в C# можно уложить в 5 строк». Может быть. Но если обратить внимание, можно заметить, что разработчики сетевых решений безопасности (имеются в виду монстры типа Outpost Firewall) все настойчивее стремятся к контролю за действиями пользователя на уровне ядра. Реализовывать файрволы в user mode уже давно моветон. Работа с ядром, прямые манипуляции с объектами ядра — стандарт де-факто, и «Хакер» об этом писал уже неоднократно. А чем мы хуже? Тем более, почувствовав вкус ядра и пощупав его своими шаловливыми ручками, ты уже ни за что не захочешь возвращаться в user mode... Ring0

— суровая среда обитания, в которой выживают только самые настоящие брутальные падаваны, но... способных учеников ядро награждает щедрыми дарами! z

links

Крайне желателен для посещения tarasc0.blogspot. com, чувак нереально много знает о работе с сетью в ring0. Достойная для прочтения статья по кодингу TDI в

ядре «Kernel mode sockets library for the masses» лежит здесь: http://rootkit. com/newsread. php?newsid=416. Про wasm.ru, codeproject.com, ntkernel.com, MSDN, google.com/ codesearch и koders. com я уж промолчу :).

xàêåð 02 /110/ 08

121

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

E

 

 

 

 

X

 

 

 

 

 

-

 

 

 

 

d

 

 

F

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

w Click

to BUY

 

 

>> coding

 

 

 

 

 

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

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Сегодня мы займемся укрощением gets и подобных ей функций, возвращающих непредсказуемый объем данных: от десятка байт до целой сотни мегабайт. Ограничивать предельный объем (как это часто делается) негуманно, а в некоторых случаях — невозможно, или же это требует серьезного редизайна всего кода. Но если немножко схитрить, то ни ограничивать, ни редизайнить не потребуется, все будет работать и так!

01malloc(maxinuxmaximore)

ОК, возьмем функцию gets (название, естественно, условное, и на ее месте может оказаться любая функция, возвращающая непредсказуемый объем данных) и скалькулируем, сколько памяти она может затребовать в худшем случае. Для определенности остановимся на отметке в 100 Мб. Выделяем нужное количество памяти через malloc, а после воз-

вращения из gets определяем актуальный размер данных и тут же реаллоцируем блок памяти, усекая его вызовом realloc до нужного размера. Просто как дважды два, но, увы, ресурсоемко и не совсем безопасно (точнее, совсем не безопасно). Хотя Windows выделяет физическую память лишь при реальном обращении к страницам, Си-функция malloc (вызывающая API-функцию VirtualAlloc с атрибутом MEM_COMMIT) увеличивает Working Set процесса. И если виртуальной памяти не хватает, происходит неизбежный рост файла подкачки (даже при наличии свободной физической памяти!), что снижает производительность, не говоря уже о том, что на системах с квотированием такие программы просто не выживают.

К тому же в случае с gets выделение 100 Мб памяти проблемы не решает и риск переполнения буфера не исчезает, а всего лишь уменьшается. Чтобы программа не пошла вразнос и не стала жертвой атаки, последней странице буфера рекомендуется присвоить атрибут PAGE_NOACCESS вызовом API-функции VirtualProtect (а сам блок памяти выделять не через malloc, а

через VirtualAlloc).

Тогда при достижении конца буфера возникнет исключение, которое мы сможем перехватить, установив SEH-обработчик на EXCEPTION_ACCESS_ VIOLATION, и тем или иным образом обработать ситуацию.

Сделать это можно следующим образом (обработка ошибок для упрощения понимания сведена к минимуму).

простойспособукрощенияGets

#define XXL

(100*1024*1024)

#define PAGE_SIZE

0x1000

#define Is2power(x)

(!(x & (x 1)))

#define ALIGN_DOWN(x, align) (x & ~(align 1))

#define ALIGN_UP(x, align)

((x & (align 1))?ALIGN_DOWN(x,align)+align:x)

main(){ DWORD old; char *p;

int real_size=0;

p = VirtualAlloc(0,XXL,MEM_COMMIT,PAGE_READWRITE); VirtualProtect((p PAGE_SIZE), PAGE_SIZE,

PAGE_NOACCESS, &old); __try {

gets(p);

}

__except( GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)

{

printf("too much!\n"); real_size= 1;

}

if (real_size== 1)

VirtualFree(p, XXL, MEM_DECOMMIT); else

VirtualFree(p + ALIGN_UP((strlen(p)+1), PAGE_SIZE), XXL ALIGN_UP((strlen(p)+1), PAGE_SIZE), MEM_DECOMMIT);

}

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

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

вобиду не даст. Однако гарантий, что эта память не занята, у нас, увы, нет!

02virtualAlloc(,,MeM_reserve,)

Главным недостатком предыдущего способа была и остается его ресурсоемкость. Совершенно нецелесообразно отбирать у системы XXL байт памяти, не будучи при этом уверенным, что из них потребуется хотя бы половина.

Поступим умнее. Поменяв флаг MEM_COMMIT на MEM_RESERVE, мы заставим функцию VirtualAlloc не выделять, а всего лишь резервировать память без неизбежного роста Working Set’а и размера файла подкачки. Резервирование памяти осуществляется практически мгновенно. А вот при всяком доступе к зарезервированной странице возникает исключение типа EXCEPTION_ACCESS_VIOLATION, и нам остается всего лишь написать

122

xàêåð 02 /110/ 08

 

 

 

 

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

 

>> coding to BUY

 

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.

 

 

 

 

.c

 

 

 

 

 

p

 

 

 

g

 

 

 

 

 

 

 

df

 

n

e

 

 

 

 

 

 

 

-x cha

 

 

 

 

свой собственный SEH-фильтр, вызывающий VirtualAlloc с атрибутом MEM_COMMIT для выделения запрошенной страницы.

То есть память в натуре выделяется динамически по мере ее потребления, и потому, не жадничая особо, мы можем увеличить XXL хоть на порядок. Главное, чтобы адресного пространства хватило! А в распоряжении приложения, работающего под управлением 32-битных версий Windows, как правило, имеется по меньшей мере — 1 Гб.

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

динамическийспособукрощенияGets

souriz(struct _EXCEPTION_POINTERS *exception_pointers)

{

DWORD old;

if (exception_pointers >ExceptionRecord > ExceptionCode == EXCEPTION_ACCESS_VIOLATION)

{

VirtualAlloc((char*)(exception_pointers > ExceptionRecord >ExceptionInformation[1]), PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE);

return EXCEPTION_CONTINUE_EXECUTION;

}

return EXCEPTION_CONTINUE_SEARCH;

}

main()

{

char *p = VirtualAlloc(0, XXL, MEM_RESERVE, PAGE_READWRITE);

__try

{

gets(p);

}

__except ( souriz( GetExceptionInformation()))

{

}

VirtualFree(p + ALIGN_UP((strlen(p)+1),PAGE_SIZE), XXL ALIGN_UP((strlen(p)+1),PAGE_SIZE), MEM_DECOMMIT);

}

А вот производительность, по сравнению с предыдущим способом, не только не поднимется, но даже упадет. Конкретно так упадет, ведь обработка исключений — операция не из дешевых, а постраничная стратегия выделения памяти — кретинизм еще тот. ОК, меняем стратегию: изначально выделяем в буфере несколько страниц памяти, а затем при первом вызове обработчика исключения выделяем одну страницу, при втором — две, при следующем — четыре... И так вплоть до ~16 страниц, время обработки которых вызываемой функцией заметно превышает накладные расходы (оверхид) на отлов исключений, хотя точная цифра зависит как от мощности ЦП, так и от специфики поставленной задачи.

xàêåð 02 /110/ 08

На слабых машинах (типа P-III) мыщъх рекомендует выделять по 64 страницы за раз, однако в условиях дефицита памяти можно сойтись и на 32 страницах.

03доверяемсяавтоматике

Отслеживать исключения — довольно нудное и утомительное дело. А нет ли в Windows-системах готового механизма, поддерживающего динамическое выделение памяти, который бы все делал за нас?!

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

Возникает следующая идея. Создаем пустой поток со стеком размера XXL. Указатель на стек передаем основному потоку с функцией типа gets, которая начинает планомерно отъедать память. После ее завершения остается только определить реальный размер возвращенных данных и вызвать функцию VirtualAlloc, чтобы выделить обозначенные страницы еще один раз (первый раз их выделила система, второй — мы). Менеджер кучи увеличивает специальный счетчик, и теперь при завершении потока освобождаются все страницы, за исключением страниц, выделенных нами, и их может использовать любой другой поток этого процесса!

Это становится возможным благодаря одному очевидному, но малоизвестному обстоятельству: на низком уровне стек и куча управляются одним и тем же менеджером памяти! То есть мы используем стек потока как своеобразный динамический массив, а тело потока пустует. Теперь становится понятно, почему gets следует размещать именно в основном, а не во вспомогательном потоке — после того как gets вернет свои данные, все остальное стековое пространство вспомогательного потока автоматически освободится путем его завершения по return или TerminateThread. А вот если бы gets была расположена во вспомогательном потоке, то с завершением возникли бы проблемы.

Впрочем, проблемы возникнут и так. Поскольку стек растет вверх, то с функцией gets он не станет работать однозначно (она заполняет буфер сверху вниз, то есть в обратном порядке). Однако если у нас есть возможность переписать код gets (или другой функции, подобной ей), этот трюк может сработать. «Может», потому что: а) система выделяет стековое пространство постранично, вследствие чего мы имеем большой оверхид и тормоза; б) система рассчитывает, что стек заполняется последовательно, и не прощает прыжки через сторожевую страницу, генерируя при этом исключение, которое, конечно, нетрудно обработать и самостоятельно, но тогда исчезает все очарование простоты кода, за которое мы боролись. Таким образом, второй метод самый оптимальный. Он несложен в реализации, не отъедает лишнюю память, достаточно быстро работает и надежно страхует от переполняющихся буферов. Дело ведь не в самой gets, которая выбрана всего лишь в качестве наглядного примера. Хорошо, пускай нам необходимо читать данные со стандартного потока ввода и мы заранее не можем сказать, сколько их будет: десяток байт, мегабайт или целый

гигабайт. Конечно, можно читать блоками по несколько десятков килобайт, объединяя блоки в списки или занимаясь их реаллокацией, но… все это либо слишком сложно в реализации, либо непродуктивно. Так что исключения рулят (причем совершенно без руля). z

123

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

E

 

 

 

 

X

 

 

 

 

 

-

 

 

 

 

d

 

 

F

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

to BUY

 

 

w Click

 

 

>> phreaking

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

o

 

 

.

 

 

 

 

.c

 

 

 

p

 

 

 

g

 

 

 

 

 

df

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

Артемий «Di Halt» Исламов

/ di_halt@mail.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

 

 

 

 

Мобильное

зло

Электронный дьявол в мобильном телефоне

Это все, что нам потребуется

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

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

ак вот. Мобила посылала sms’ками на три буквы всех кого ни Т или, наоборот, сбрасывала звонки,

сама. Сбросы и перезагрузки продолжал чудить, попутно ехидно

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

, залил в телефон новую прошивку… Когда же после включения открылась записуха и в ней весело набралось: «Ну

, опять не вышло? ;))))» — у чувака задергался глаз, а телефон

.

What is the matrix?

Ты, наверное, уже допетрил, что за демона я подсадил корешу в мобильник? Конечно же, трояна. Собственно, почему бы нет? По идее, не такая уж сложная, казалось бы, задача, если бы не одна маленькая деталь — чувак перепрошил мобилу (по аналогии с компом — отформатировал винт на низком уровне), а нечисть осталась на месте и продолжила издеваться над несчастным. Чувствуешь нестыковочку? Тот, кто читал мои предыдущие

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

Как я сделал демона

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

124

xàêåð 02 /110/ 08

 

 

 

 

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

 

>> phreaking to BUY

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-x cha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

Вот так выглядит схемотехника виброзовнка. Красным помечен наш оптрон

вательно, обычный радиоприемник его случайно не поймает и не спалит всю контору. А если учесть, что в мобилах часто бывает еще и подобие фотокамеры, то можно ведь и наловчиться фоткать, а фотки сливать по mms куда-нибудь.

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

Техническое задание

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

1.Он должен уметь хорошо слышать все вокруг. А значит, мне потребуется режим громкой связи.

2.Должен выходить на связь по звонку.

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

4.Должен умело затирать в себе следы входящих звонков.

5.В случае обнаружения должен умело косить под обычную забытую мобилу.

6.Должен быть надежным.

Это техзадание уже подразумевает весьма сложный алгоритм, а значит, тупой релюшкой, подвешенной на подъем трубки, обойтись будет сложно. Поэтому буду юзать микроконтроллер.

Время собирать камни

Итак, для начала мне, конечно же, понадобится мобильный телефон. Первое требование к нему — чтобы внутрь можно было что-либо запихать. Поэтому всякие ультратонкие мобилы отпадают, там все

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

Сниферим

клавиатуру

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

— земли, что на раз прозванивается тестером. Перехватывается просто. Надо лишь припаять линии порта микроконтроллера на сигнальный вывод кнопки (па-

раллельно родному процессору телефона по сути) и отслеживать просадку этой линии на землю

замыкание кнопки. Второй вариант сложнее

матрица из строк и столбцов (часто встречается именно на сименсах). Кнопки замыкают строки на столбцы. Для того чтобы определить, какая именно из кнопок нажата, применяют сканирование клавиатуры. Работает это следующим образом. Например, на строки вешаем входящий порт (на схемах сименсов он зовется kb_in_xx, где хх — номер линии порта), а на столбцы заводим выходящий порт (у тех же сименсов это kb_out_xx). Далее выводим в выходящий порт число 11111110 и

начинаем гонять нолик по всем разрядам (11111110 11111101 11111011 и т.д.). В итоге, у

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

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

Hi-Z (для AVR это DDRxy=0 и PORTxy=0, где х и y — имя и бит порта контроллера).

xàêåð 02 /110/ 08

125

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

E

 

 

 

 

X

 

 

 

 

 

-

 

 

 

 

d

 

 

F

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

to BUY

 

 

w Click

 

 

>> phreaking

 

 

 

 

 

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

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

 

 

 

 

 

 

Прозвонка силовых линий виброзвонка — занятие легкое и непринужденное

 

 

 

Siemens, а потому опираться опять же буду на пример Siemens. В этот

бытьоченьтонким,таккакпридетсяпаятьTQFP-корпусаиподпаиватьсяв

 

раз подопытным кроликом у меня будет Siemens CX65. Почему именно

кишкикмобиле.Потомулибонуженспециализированныйпаяльник(СТ-96,

 

он? Да первый, что под руку подвернулся из сименсов. Под телефон

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

 

также неплохо было бы заполучить принципиальную схему, так как

са(уменявообщенапаяльникенаборсменныхжалподразныеситуации).

 

некоторые моменты я буду разъяснять по ней. По известным причинам

Из приборов мне хватит простого тестера, но владей я осциллографом,

 

причинам мы не можем выложить схему этого телефона на диск, но

множество крутых проблем я выловил бы значительно быстрее.

 

вот ключевое слово, по которому Яндекс легко найдет нужный файл:

Из инструментов очень не помешает пинцет. Я бы сказал, без него вообще

 

CX65_schematics.rar или просто СХ65 schematic. На первом же попав-

никуда.

 

шемся форуме ремонтников сотовых будет вагон и маленькая тележка

Также мне потребуются паяльные принадлежности: припой и флюс.

 

схем под сотовые телефоны.

 

 

 

Следующий важнейший компонент — микроконтроллер. Это, как и

 

Интерфейсы

 

 

 

в прошлый раз, будет Atmel AVR. В принципе, можно взять любой из

Для начала определимся, что мы будем делать. Поскольку журнальное

 

семейства, лишь бы там был UART (или USART, что почти то же самое,

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

 

но с прибамбасиками). Я заюзал старую проверенную ATMega8535L в

Итак, делаю из мобилы подслушивающее устройство, автоматом берущее

 

TQFP-корпусе. О корпусе стоит рассказать особо. Он должен быть самый

трубку после второго звонка (чтобы избежать ложных срабатываний из-за

 

маленький и плоский (TQFP,SOIC и т.д.) — его, может, и сложно запаять,

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

 

но пихать в мобилу какой-нибудь здоровенный PDIP или PLCC — еще

посредством которой происходит прослушка помещения.

 

сложнее. (Самый тонкий из семейства AVR — ATmega8 в TQFP-корпусе.

Для начала мне нужно узнать, что на телефон пришел звонок. Подумаем,

 

— Прим. dlinyj). Также стоит отметить наличие индекса L в маркиров-

что происходит при приходе звонка? Звенит звонок, дрожит вибра, горит

 

ке микросхемы, это важно! L означает, что этот контроллер способен

подсветка — до фига событий! Любой из этих сигналов можно завести

 

питаться от пониженного напряжения — от 2,5 до 5 вольт. А напряжение

в микроконтроллер, чтобы он дал сработку. Я предпочел пожертвовать

 

в мобиле у меня всего 3,3 вольта. Так что беру только низковольтные

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

 

контроллеры!

качестве простого телефона.

 

Еще потребуется оптореле, в данном случае я рекомендую KAQY214S — хо-

Второй важнейший интерфейс для меня — это терминальная сессия, по-

 

рошая штука, достаточно популярная, недорогая и в то же время отличается

этому мне надо будет припаяться изнутри к линиям Rx и Tx, чтобы заставить

 

миниатюрными размерами.

телефон плясать под нашу дудку. Собственно, уже этого достаточно, чтобы

 

Также необходим десяток резисторов в SMD-исполнении типоразмера

получить адекватный шпионский девайс. Ну и питание контроллера. Его я

 

1206, а лучше и того меньше — 0805, чтобы напаивать прямо на ножки мик-

возьму от штатного аккумулятора телефона.

 

росхем. Резисторы нужны на 10 кОм и 620 Ом или около того.

 

 

 

Все соединения буду осуществлять тонким проводом. Отлично подойдет

 

Схемотехника

 

тонюсенький провод типа МГТФ (белый такой, в скользкой фтороплас-

Так, шутки и пространные размышления закончились, приступаю к

 

товой изоляции) или тонкий обмоточный провод с любой катушки или

активным действиям. Для начала посмотрим на схему всего девайса

 

трансформатора.

в целом. Как видно, ничего страшного нет, все почти так же, как в про-

 

Паятьябудумаломощнымтонкимпаяльником.Повторюсь,паяльникдолжен

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

126

xàêåð 02 /110/ 08

 

 

 

 

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

>> phreaking

 

to BUY

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

o

 

 

.

 

 

 

 

.c

 

 

 

p

 

 

 

g

 

 

 

 

 

df

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

 

последовательном порту. Оно и понятно — мы работаем с мобилой

Теперь определимся с подключением питания. Питаться я буду от

 

на одном и том же напряжении. Теперь обрати внимание на то, что

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

 

тут кроме контроллера есть еще оптореле. Твердотельное (опти-

разъема. На фотографии видно, что на аккумуляторе четко обозначен

 

ческое) реле — это такой девайс, который позволяет замыкать свои

плюс и минус. Но не на всех мобилах это так. Поэтому лучше всего

 

контакты, когда внутри него зажигается светодиод. По сути дела, оно

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

 

работает как обычное реле, только отличается диким быстродейс-

красного провода тестера к плюсу, а черного — к минусу значение

 

твием, микропотреблением и фактически вечное, поскольку никаких

напряжения на табло должно быть положительным, без минуса.

 

изнашивающихся частей там нет. Управляющий вход реле я повесил

Тестер у нас показывает полярность напряжения, если тестер не

 

на выход виброзвонка, и теперь, когда придет звонок, телефон по-

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

 

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

к минусу (черному). Собственно, можно брать паяльник и припаи-

 

Остальная схема до смешного проста. Резистор в 620 Ом от плюса

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

 

питания на ножку RESET обеспечивает запуск контроллера, замыка-

немного повозиться и припаять их снизу. Во-первых, это куда неза-

 

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

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

 

микроконтроллером. Выходы Rx и Tx идут прямиком Tx и Rx теле-

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

 

фона соответственно. Также в порту телефона впаяна перемычка,

дальнейшем. Пока просто припаяю два тоненьких проводочка, потом

 

сигнализирующая о том, что в телефон якобы воткнут дата-кабель и

заведу их на Vcc и GND контроллера. Главное, не перепутать их,

 

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

запомнить или пометить как-нибудь.

 

то непонятно из схемы, я сделал ряд фотографий девайса, чтобы ты

Следующим номером у меня значится виброзвонок, а говоря точнее,

 

мог рассмотреть всю конструкцию вживую, в сборе.

подключение оптрона к его выводам. Сразу посмотрим, как он

 

 

 

 

подключается, — видно две здоровенные контактные площадки.

 

 

Монтаж

Вот туда мы и будем паять. Только сначала определим полярность

 

 

 

 

 

Теориязакончена,порабыприступатькпрактике.Дальнейшиеоперации

выходов. В 90% случаев вибра питается либо от ноги процессора,

 

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

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

 

руктожеобязательно.Крометого,ясобираюсьосуществитьгрубейшеевме-

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

 

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

питания телефона. Возьмем тестер и включим режим пикалки или

 

Разбираем мобилу. Для этого мне потребуются звездообразные

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

 

отверточки. Сразу же окидываю взглядом конструкцию на предмет

аккумуляторного разъема, а вторым — на контакты виброзвонка. Где

 

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

раздастся противный писк или покажется сопротивление 0,00, там и

 

проводков. В идеале все должно быть спрятано так, чтобы нельзя

есть GND, запомним его. Опять же пока выведем от вибры два прово-

 

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

дочка и пометим их, чтобы не забыть. Сам же моторчик виброзвонка

 

ронний аддон. К слову, у сименсов 65 й серии в голове возле антенны

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

 

есть неслабый «чердак», куда при желании можно засунуть полковую

Теперь обратим свой взор в сторону порта телефона. Нас в данном случае

 

радиостанцию, а также казино с блек-джеком и шлюхами.

интересуют контакты:

 

 

 

 

 

Пока мы собрали схему на большом проце. Отлаживаем

 

xàêåð 02 /110/ 08

127

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

E

 

 

 

 

X

 

 

 

 

 

-

 

 

 

 

d

 

 

F

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

to BUY

 

 

w Click

 

 

>> phreaking

 

 

 

 

 

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

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Закрепили проц на двусторонний скотч, чтобы не болтался. Прокинули проводки. Красота!

3 — Tx — загнать напрямую в порт Rx нашего микроконтрол лера.

4 — Rx — загнать напрямую в порт Tx нашего микроконтрол лера.

5, 7 — спаять их вместе и через резистор на 10 кОм припа ять на GND.

2 — GND

В принципе, в этом же сименсе есть здоровенный «чердак» и в нижней части, так что туда можно сунуть даже обычный резистор 0,125 Вт, но я все же предпочитаю напаивать SMD 1206 — он и в разы компактнее, и в случае чего не оторвет дорожки от платы, так как подпаивать я его буду мягким монтажным проводом. Запаяв схему разрешения порта (объединение

ножек 5 и 7 на землю), выведем провода с Rx и Tx, также пометив их какимнибудь образом, чтобы не забыть.

Теперь соберем процессорную часть. Тут все просто. Припаиваем проводки к выводам Vcc и GND. На PLCCили TQFP-корпусе несколько выводов питания и земли. Берем любой из них — они внутри все соединены, в чем можно убедиться, прозвонив их тестером.

Далее я припаиваю к ножке Reset тоненький проводок, к нему — резистор на 10 кОм, а второй конец резистора — проводком на Vcc. Также припаяю проводки к Rx и Tx контроллера.

На линию порта, которую мы будем считать входом реле, в данном случае PD2 (теоретически это может быть любая линия любого свободного порта, выбираем ту, которая удобнее, потом просто немного подправим исходник), мы припаиваем третий вывод нашего оптореле, четвертый же

Асвидупочти ничегоинезаметно

128

xàêåð 02 /110/ 08

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