Операционные системы - статьи


Поиск и анализ "троянских коней" под UNIX - часть 3


Сначала должна быть определена точка входа в программу. Это - адрес начала функции, которая будет выполнена при запуске программы и которая, если из программы не была модифицирована или из неё не были удалены символы, всегда называется main или _start. Следуя за этой функцией можно проследить процесс выполнения программы и увидеть, что может, а чего не может сделать программа. Особенно интересны вызовы инструкций (function calls) и инструкции jmp/int, если они используют небиблиотечные вызовы ядра или скомпилированы статически. Типичные точки входа для двоичных файлов архитектуры x86 выглядят примерно так:

0x8048f97 <_start+7>: call 0x8048eac <atexit> 0x8048f9d <_start+13>: call 0x8048dcc <__libc_init_first> 0x69662 <__open+18>: int $0x80

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

void do_something (char *y) {}; char *h = "hello world"; int main() { char *text = h; int x = getchar(); do_something(text); return 0; }

Это соответствует следующим командам ассемблера: 0x804847e <main+6>: movl 0x804950c,%eax 0x8048483 <main+11>: movl %eax,0xfffffffc(%ebp)

Сохранить указатель по относительному адресу. Указатель ссылается на статическую, жёстко запрограммированную строку "hello world" в коде. 0x8048486 <main+14>: call 0x80483cc <getchar> 0x804848b <main+19>: movl %eax,%eax 0x804848d <main+21>: movl %eax,0xfffffff8(%ebp)

Вызвать функцию getchar и поместить результат (видимо, целое. хранящееся в регистре EAX) в стек. EBP - базовый указатель, используемый для ссылки на адреса относительно текукщей функции в стеке. 0x8048490 <main+24>: movl 0xfffffffc(%ebp),%eax 0x8048493 <main+27>: pushl %eax 0x8048494 <main+28>: call 0x8048470 <do_something>

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

Теперь мы можем вручную разыменовать указатель при помощи команды x

: (gdb) x/a 0x804950c /* x option /a displays the memory content as an address, to see which address a pointer actually points to */ 0x804950c <h>: 0x80484fc <_fini+28> (gdb) x/s 0x80484fc /* x option /s displays the memory content as string up to the point where a terminating \0 is found */ 0x80484fc <_fini+28>: "hello world"

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

 




Начало  Назад  Вперед



Книжный магазин