Анимация
JavaScript


Главная  Библионтека 

0 [ 1 ] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140

С версии 3.8x2 в IDA появилась поддержка «сворачивания» (Collapsed) функций. Такой прием значительно упрощает навигацию по тексту, позволяя убрать с экрана не интересные в данный момент строки. По умолчанию все библиотечные функции сворачиваются автоматически.

Развернуть функцию можно подведя к ней курсор и нажав <+> на дополнительной цифровой клавиатуре, расположенной справа. Соответственно, клавиша <-> предназначена для сворачивания.

По окончании автоматического анализа файла "first.exe", IDA переместит курсор к строке ".text:00401B2C" - точке входа в программу. Среди начинающих программистов широко распространено заблуждение, якобы программы, написанные на Си, начинают выполняться с функции "main", но в действительности это не совсем так. На самом деле сразу после загрузки файла управление передается на функцию "Start", вставленную компилятором. Она подготавливает глобальные переменные osver (билд), winmajor (старшая версия операционной системы), winminor (младшая версия операционной

системы), winver (полная версия операционной системы), argc (количество аргументов

командной строки), argv (массив указателей на строки аргументов), environ (массив

указателей на строки переменных окружения); инициализирует кучи (heap); вызывает функцию main, а после возращения управления завершает процесс с помощью функции Exit.

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

#include <stdio.h>

#include <stdlib.h>

void main() {

int a;

printf(">Версия OS:\t\t\t%d.%d\n\ >Билд:\t\t\t%d\n\

>Количество агрументов:\t%d\n",\

winmajor, winminor, osver, argc);

for (a=0;a< argc;a++)

printf(">\tАгрумент %02d:\t\t%s\n",a+1, argv[a]);

a=!a-1;

while( environ[++a]) ;

printf(">Количество переменных окружения:%d\n",a);

while(a) printf(">\tПеременная %d:\t\t%s\n",a, environ[--a]);

a) исходный текст программы CRt0.demo.c

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

>Версия OS: 5.0

>Билд: 2195

>Количество агрументов: 1

> Агрумент 01: CRt0.demo >Количество переменных окружения: 30

> Переменная 29: windir=C:\WINNT >...

b) результат работы программы CRt0.demo.c

Очевидно, нет никакой необходимости анализировать стандартный стартовый код

2 А может и чуточку раньше



приложения, и первая задача исследователя - найти место передачи управления на функцию main. К сожалению, гарантированное решение это задачи требует полного анализа содержимого функции "Start". У исследователей существует множество хитростей, но все они базируются на особенностях реализации конкретных компиляторов3 и не могут считаться универсальными.

Рекомендуется изучить исходные тексты стартовых функций популярных компиляторов, находящиеся в файлах CRt0.c (Microsoft Visual C) и c0w.asm (Borland C) -это упросит анализ дизассемблерного листинга.

Ниже, в качестве иллюстрации, приводится содержимое стартового кода программы "first.exe", полученное в результате работы W32Dasm:

Program

00401B2C 55 00401B2D 8BEC

00401B2F 6AFF

00401B31 6870714000 00401B36 68A8374000

00401B3B 64A100000000 00401B41 50

00401B42 64892500000000 00401B49 83EC10 00401B4C 53 00401B4D 56 00401B4E 57 00401B4F 8965E8

Entry Point ******** push ebp mov ebp, esp push FFFFFFFF

push 00407170 push 004037A8

mov eax, dword ptr fs:[00000000] push eax

mov dword ptr fs:[00000000], esp sub esp, 00000010

push ebx push esi push edi

mov dword ptr [ebp-18], esp

Reference To: KERNEL32.GetVersion, Ord:0174h

00401B52 00401B58 00401B5A 00401B5C 00401B62 00401B64 00401B6A 00401B70 00401B73 00401B75 00401B7B 00401B7E 00401B83 00401B85 00401B8A 00401B8B 00401B8D 00401B8F 00401B91 00401B96

FF1504704000 33D2 8AD4

8915B0874000 8BC8

81E1FF000000 890DAC874000 C1E108 03CA

890DA8874000 C1E810 A3A4874000 6A00

E8D91B0000 59 85C0 7508 6A1C

E89A000000

Call dword ptr [00407004]

xor edx, edx mov dl, ah

mov dword ptr [004087B0], edx mov ecx, eax and ecx, 000000FF mov dword ptr [004087AC], ecx shl ecx, 08

add ecx, edx mov dword ptr shr eax, 10 mov dword ptr push 00000000 call 00403763

pop ecx test eax, eax

jne 00401B97 push 0000001C call 00401C30

pop ecx

[004087A8], ecx [004087A4], eax

Referenced by a (U)nconditional or (C)onditional Jump at Address:

3 Например, Microsoft Visual C всегда, независимо от прототипа функции main передает ей три аргумента - указатель на массив указателей переменных окружения, указатель на массив указателей аргументов командной строки и количество аргументов командной строки, а все остальные функции стартового кода принимают меньшее количество аргументов



:00401B8D(C)

00401B97 8365FC00 00401B9B E8D70C0000

and dword ptr

call 00402877

[ebp-04], 00000000

Reference To: KERNEL32.GetCommandLineA, Ord:00CAh

00401BA0 FF1560704000 00401BA6 A3E49C4000 00401BAB E8811A0000 00401BB0 A388874000 00401BB5 E82A180000 00401BBA E86C170000 00401BBF E8E1140000 00401BC4 A1C0874000 00401BC9 A3C4874000 00401BCE 50 00401BCF FF35B8874000 00401BD5 FF35B4874000

00401BDB E820F4FFFF

00401BE0 83C40C 00401BE3 8945E4 00401BE6 50 00401BE7 E8E6140000 00401BEC 8B45EC 00401BEF 8B08 00401BF1 8B09 00401BF3 894DE0 00401BF6 50 00401BF7 51 00401BF8 E8AA150000 00401BFD 59 00401BFE 59 00401BFF C3 a) стартовый код программы

Call dword ptr [00407060] mov dword ptr [00409CE4], eax call 00403631

mov dword ptr [00408788], eax call 004033E4 call 0040332B call 004030A5

mov eax, dword ptr [004087C0] mov dword ptr [004087C4], eax push eax

push dword ptr [004087B8]

push dword ptr [004087B4]

call 00401000

add esp, 0000000C

mov dword ptr [ebp-1C], eax

push eax

call 004030D2

mov eax, dword ptr [ebp-14] mov ecx, dword ptr [eax] mov ecx, dword ptr [ecx] mov dword ptr [ebp-20], ecx push eax push ecx

call 004031A7

pop ecx pop ecx

"first.exe", полученный дизассемблером W32Dasm

Иначе выглядит результат работы IDA, умеющей распознавать библиотечные функции по их сигнатурам (приблизительно по такому же алгоритму работает множество антивирусов). Поэтому, способности дизассемблера тесно связаны с его версией и полнотой комплекта поставки - далеко не все версии IDA Pro в состоянии работать с программами, сгенерированными современными компиляторами. (Перечень поддерживаемых компиляторов можно найти в файле "%IDA%/SIG/list").

00401B2C start

00401B2C

00401B2C var 20

00401B2C var 1C

00401B2C var 18

00401B2C var 14

00401B2C var 4

00401B2C

00401B2C

00401B2D

00401B2F

00401B31

00401B36

00401B3B

proc near

= dword

-20h

= dword

-1Ch

= dword

-18h

= dword

-14h

= dword

push ebp

mov ebp, esp

push 0FFFFFFFFh

push offset stru 407170

push offset except handler3

mov eax, large fs:0



0 [ 1 ] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140