Главная Случайная страница


Полезное:

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


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Декомпиляторы VB





Изрядное количество программ во всем мире написано на Visual Basic (VB). Сюда относятся как зловредные программы, так и программы законопослушных программистов. VB бросает вызов всякому, кто отважится декомпилировать программу, написанную на этом языке. Последний свободно доступный декомпилятор мог работать только с программами VB3. Начиная с VB5, результат компиляции программы может быть представлен как во внутреннем коде исполняемого модуля («native code»), реализующем стандартное обращение к Windows, так и в p-code. P-код – это псевдокод, который похож на байт-код (или машинно-независимый код), генерируемый Java-компилятором. P-код распознает интерпретатор реального времени Visual Basic VBRUN300.DLL, VBRUN500.DLL или VBRUN600.DLL. Сложность заключается в том, что очень мало доступной документации, в которой описано соответствие конструкций исходного текста программы функциям VB в откомпилированной программе. Конечно, всегда можно декомпилировать интерпретатор VB DLL и восстановить соответствие, но это очень трудоемкое занятие.

 

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

 

Для удобства восприятия протокол трассировки дополнен комментариями:

 

 

[elliptic@ellipse]$ echo hello > test

 

[elliptic@ellipse]$ strace cat test

 

execve(“/bin/cat”, [“cat”, “test”], [/* 21 vars */]) = 0

 

 

Утилита strace не начинает вывод до тех пор, пока не будет вызвана команда cat. Поэтому нельзя отследить процесс ее поиска командным процессором shell. К моменту начала работы утилиты strace команда cat находилась в директории /bin. Из примера трассировки видно, что входными параметрами программы execve являются местонахождение cat, ее имя, аргумент (test) и список из 21 переменной окружения.

 

brk(0) = 0x804b160

 

old_mmap(NULL, 4096, PROT_READ|PROT_WRITE,

 

MAP_PRIVATE|MAP_ANONYMOUS, – 1, 0) = 0x40014000

 

open(“/etc/ld.so.preload”, O_RDONLY) = -1 ENOENT (No

 

such file or directory)

 

 

После вызова execve начинается обычный процесс загрузки: распределение памяти и т. д. Отметим свидетельствующий об ошибке код возврата, равный —1, при попытке открыть /etc/ld.so.preload. Ошибка поясняется диагностическим сообщением об отсутствии файла или директории. Действительно, такого файла нет. Из примера ясно, что если вместо файла указать параметры так, как это указано в примере open, execve самостоятельно найдет файл. Это было бы полезно для последующих действий привилегированного пользователя. Но для этого нужно поместить новый файл в директорию /etc, в которой запрещено что-либо делать до тех пор, пока кто-нибудь не откорректирует файл системных разрешений. В большинстве Unix-систем право записи в директорию /etc имеет только пользователь, получивший привилегированные права «root» тем или иным способом. Это еще одна причина, по которой обычные пользователи не могут писать в /etc. Если задаться целью спрятать Троянского коня, то лучшего места не найти (после того как будут получены права привилегированного пользователя root).

 

 

open(“/etc/ld.so.cache”, O_RDONLY) = 4

 

fstat(4, {st_mode=S_IFREG|0644, st_size=12431,...}) = 0

 

old_mmap(NULL, 12431, PROT_READ, MAP_PRIVATE, 4, 0) =

 

0x40015000

 

close(4) = 0

 

open(“/lib/libc.so.6”, O_RDONLY) = 4

 

fstat(4, {st_mode=S_IFREG|0755, st_size=4101324,...}) = 0

 

read(4,

 

“\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\210\212”...,

 

4096) = 4096

 

 

Прочитаны первые 4 Кб библиотеки libc. Libc – это стандартная библиотека коллективного доступа, в которой расположены функции, вызываемые из программ на языке C (такие как printf, scanf и т. д.).

 

 

old_mmap(NULL, 1001564, PROT_READ|PROT_EXEC, MAP_PRIVATE, 4,

 

0) = 0x40019000

 

mprotect(0x40106000, 30812, PROT_NONE) = 0

 

old_mmap(0x40106000, 16384, PROT_READ|PROT_WRITE,

 

MAP_PRIVATE|MAP_FIXED, 4, 0xec000) = 0x40106000

 

old_mmap(0x4010a000, 14428, PROT_READ|PROT_WRITE,

 

MAP_PRIVATE|MAP_FIXED| MAP_ANONYMOUS, -1, 0)

 

= 0x4010a000

 

close(4) = 0

 

mprotect(0x40019000, 970752, PROT_READ|PROT_WRITE) = 0

 

mprotect(0x40019000, 970752, PROT_READ|PROT_EXEC) = 0

 

munmap(0x40015000, 12431) = 0

 

personality(PER_LINUX) = 0

 

getpid() = 9271

 

brk(0) = 0x804b160

 

brk(0x804b198) = 0x804b198

 

brk(0x804c000) = 0x804c000

 

open(“/usr/share/locale/locale.alias”, O_RDONLY) = 4

 

fstat64(0x4, 0xbfffb79c) = -1 ENOSYS (Function not

 

implemented)

 

fstat(4, {st_mode=S_IFREG|0644, st_size=2265,...}) = 0

 

old_mmap(NULL, 4096, PROT_READ|PROT_WRITE,

 

MAP_PRIVATE|MAP_ANONYMOUS, – 1, 0) = 0x40015000

 

read(4, “# Locale name alias data base.\n#”..., 4096) = 2265

 

read(4, “”, 4096) = 0

 

close(4) = 0

 

munmap(0x40015000, 4096) = 0

 

 

Если в программе встречается вызов функции setlocale, то libc читает локализованную информацию (информацию о местной специфике) для определения формата отображения чисел, даты, времени и т.

 

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

 

open(“/usr/share/i18n/locale.alias”, O_RDONLY) = -1 ENOENT

 

(No such file or directory)

 

open(“/usr/share/locale/en_US/LC_MESSAGES”, O_RDONLY) = 4

 

fstat(4, {st_mode=S_IFDIR|0755, st_size=4096,...}) = 0

 

close(4) = 0

 

open(“/usr/share/locale/en_US/LC_MESSAGES/SYS_LC_MESSAGES”,

 

O_RDONLY) = 4

 

fstat(4, {st_mode=S_IFREG|0644, st_size=44,...}) = 0

 

old_mmap(NULL, 44, PROT_READ, MAP_PRIVATE, 4, 0)

 

= 0x40015000

 

close(4) = 0

 

open(“/usr/share/locale/en_US/LC_MONETARY”, O_RDONLY) = 4

 

fstat(4, {st_mode=S_IFREG|0644, st_size=93,...}) = 0

 

old_mmap(NULL, 93, PROT_READ, MAP_PRIVATE, 4, 0)

 

= 0x40016000

 

close(4) = 0

 

open(“/usr/share/locale/en_US/LC_COLLATE”, O_RDONLY) = 4

 

fstat(4, {st_mode=S_IFREG|0644, st_size=29970,...}) = 0

 

old_mmap(NULL, 29970, PROT_READ, MAP_PRIVATE, 4, 0)

 

= 0x4010e000

 

close(4) = 0

 

brk(0x804d000) = 0x804d000

 

open(“/usr/share/locale/en_US/LC_TIME”, O_RDONLY) = 4

 

fstat(4, {st_mode=S_IFREG|0644, st_size=508,...}) = 0

 

old_mmap(NULL, 508, PROT_READ, MAP_PRIVATE, 4, 0)

 

= 0x40017000

 

close(4) = 0

 

open(“/usr/share/locale/en_US/LC_NUMERIC”, O_RDONLY) = 4

 

fstat(4, {st_mode=S_IFREG|0644, st_size=27,...}) = 0

 

old_mmap(NULL, 27, PROT_READ, MAP_PRIVATE, 4, 0)

 

= 0x40018000

 

close(4) = 0

 

open(“/usr/share/locale/en_US/LC_CTYPE”, O_RDONLY) = 4

 

fstat(4, {st_mode=S_IFREG|0644, st_size=87756,...}) = 0

 

old_mmap(NULL, 87756, PROT_READ, MAP_PRIVATE, 4, 0)

 

= 0x40116000

 

close(4) = 0

 

fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4),

 

...}) = 0

 

open(“test”, O_RDONLY|O_LARGEFILE) = 4

 

fstat(4, {st_mode=S_IFREG|0664, st_size=6,...}) = 0

 

 

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

 

 

read(4, “hello\n”, 512) = 6

 

write(1, “hello\n”, 6) = 6

 

read(4, “”, 512) = 0

 

close(4) = 0

 

close(1) = 0

 

_exit(0) =?

 

 

В заключение cat пытается прочитать 512 байтов из файла (читает 6) и выводит их на экран (который описан STDOUT с дескриптором файла 1). При повторной попытке прочитать очередные 512 байтов файла читается 0 байт, что свидетельствует о достижении конца файла. В результате файл закрывается, дескриптор файла освобождается и выполняется нормальный выход (признаком нормального выхода является нулевой код завершения).

 

Для демонстрации читателю представляем очень простой пример. Логика работы команды cat очень проста и легко восстанавливается. На псевдокоде команду cat можно записать следующим образом:

 

 

int count, handle

 

string contents

 

handle = open (argv[1])

 

while (count = read (handle, contents, 512))

 

write (STDOUT, contents, count)

 

exit (0)

 

 

Для сравнения приведем результат выполнения утилиты truss для той же самой команды, выполненной в системе Solaris 7 на машине (x86):

 

 

execve(“/usr/bin/cat”, 0x08047E50, 0x08047E5C) argc = 2

 

open(“/dev/zero”, O_RDONLY) = 3

 

mmap(0x00000000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,

 

MAP_PRIVATE, 3, 0) = 0xDFBE1000

 

xstat(2, “/usr/bin/cat”, 0x08047BCC) = 0

 

sysconfig(_CONFIG_PAGESIZE) = 4096

 

open(“/usr/lib/libc.so.1”, O_RDONLY) = 4

 

fxstat(2, 4, 0x08047A0C) = 0

 

mmap(0x00000000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE, 4,

 

0) = 0xDFBDF000

 

mmap(0x00000000, 598016, PROT_READ|PROT_EXEC, MAP_PRIVATE,

 

4, 0) = 0xDFB4C000

 

mmap(0xDFBD6000, 24392, PROT_READ|PROT_WRITE|PROT_EXEC,

 

MAP_PRIVATE|MAP_FIXED, 4, 561152) = 0xDFBD6000

 

mmap(0xDFBDC000, 6356, PROT_READ|PROT_WRITE|PROT_EXEC,

 

MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xDFBDC000

 

close(4) = 0

 

open(“/usr/lib/libdl.so.1”, O_RDONLY) = 4

 

fxstat(2, 4, 0x08047A0C) = 0

 

mmap(0xDFBDF000, 4096, PROT_READ|PROT_EXEC,

 

MAP_PRIVATE|MAP_FIXED, 4, 0) = 0xDFBDF000

 

close(4) = 0

 

close(3) = 0

 

sysi86(SI86FPHW, 0xDFBDD8C0, 0x08047E0C, 0xDFBFCEA0)

 

= 0x00000000

 

fstat64(1, 0x08047D80) = 0

 

open64(“test”, O_RDONLY) = 3

 

fstat64(3, 0x08047CF0) = 0

 

llseek(3, 0, SEEK_CUR) = 0

 

mmap64(0x00000000, 6, PROT_READ, MAP_SHARED, 3, 0)

 

= 0xDFB4A000

 

read(3, “ h”, 1) = 1

 

memcntl(0xDFB4A000, 6, MC_ADVISE, 0x0002, 0, 0) = 0

 

write(1, “ h e l l o\n”, 6) = 6

 

llseek(3, 6, SEEK_SET) = 6

 

munmap(0xDFB4A000, 6) = 0

 

llseek(3, 0, SEEK_CUR) = 6

 

close(3) = 0

 

close(1) = 0

 

llseek(0, 0, SEEK_CUR) = 296569

 

_exit(0)

 

 

Проанализировав конец протокола, можно заметить, что в Solaris команда cat выполняется несколько по-другому. Различие проявляется в том, что в Solaris ош использует проецируемый в память файл для передачи диапазона адресов непосредственно вызову функции write. Эксперимент с большим файлом (результаты которого здесь не приведены) выявил цикл запросов между вызовами функций memorymap/write, причем за один раз обрабатывается 256 Кб.

 

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

 

Для углубления своих представлений об используемом инструментарии следует рассмотреть случаи применения файлов с предсказуемыми именами в директории временной памяти /tmp, чтения информации из файлов, доступных всем для записи, различных вариантов вызова функций и т. д.

 

Date: 2015-06-05; view: 640; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию