На главную | Содержание | Назад | Вперёд
Наши друзья

 

 

Глобальный анализ с помощью IDA-Pro

Мы уже продемонстрировали, как создавать дополнительные модули для IDA. Программа IDA также поддерживает язык написания сценариев. Сценарии для IDA называются IDС-сценариями. Отметим, что иногда их создать гораздо проще, чем использовать дополнительный модуль. Используя следующую команду и IDC-сценарий, можно провести глобальный анализ с помощью IDA-Pro.
c:\ida\idaw  -Sbatch   hunt, idc   -А  -с c:\winnt\notepad.exe
Ниже приведен элементарный файл IDC-сценария.
#include <idc.idc>
/А----------------------------------------------------------------------------
static main(void) { Batch (1);
/*  will hang if  existing database   file */ WaitO ; Exit(0);

Для разнообразия проведем глобальный анализ для вызовов функции sprintf. В Perl-сценарии программа IDA вызывается с помощью командной строки.
open(FILENAMES,   "files.txt" ) ;
while (<FILENAMES>)
(
chop ($_) ;
my $filename = $_;
5command = "dumpbin /imports S_ > durrpfile.txt"; Sprint  "trying $command";
system($command);
open(DUMPFILE,   "dumpfile.txt");
while (<DUMPFILE>)
(
if(m/sprintf/gi) {
print "$fiiename: $_\n";
system ( "c : WidaWidaw -Sbul k_audi t_spr in t f. idc -A -c $filename");
)
)
close(DUMPFILE);
)
close(FILENAMES);
Мы используем сценарий bulk_audit_sprintf . idc,
//
//В этом примере показано,   как использовать функцию GetOperandValue().
//
Kinclude <idc.idc>
/* эта процедура жестко закодирована для обработки вызовов sprintf */
static hunt__address (      eb,   /* адрес этого вызова */
param_count,   /* число параметров для этого вызова */ ее,   /* максимальное число отслеживаемых инструкций */ output_file )
auto ер;   /* знакоместо */ auto k;
auto kill_frame_sz; auto comment_string;
k = GetMnem(eb);
if(strstr(k,   "call")   != 0) (
Message ("Invalid starting point\n"); return;

/* код трассировки */ while( eb=FindCode(eb,   0) ) {
auto j;
j  = GetMnem(eb);
/* выход на ранней стадии,  если мы попали в код retn */ if (strstr(j,   "retn")   == 0) return;
/* push - это аргумент для вызова функции sprintf */ if(strstr(j,   "push")   == 0)

{
fprintf(output_file,   "%s это аргумент,  который будет будет вызывать переполнение в буфере,  если будет больше %d байт!\п", my_src,   kill_frame_sz);
}
}
break;

}
max_backtrace--;
if(max_backtrace == 0)break;
)
eb = ер;  /* перейти в начальное состояние и продолжить
для следующего параметра */ param_count--; if(0 == param_count)
(
fprintf(output_file,   "Закончились все параметры\п") ; return;
I
}
if (ее-- == 0)break;
}
)
static main() (
auto ea; auto eb;
auto last_address; auto output_file; auto file_name;
/* отключить все диалоговые окна для глобальной обработки */ Batch(0) ;
/* подождать до завершения автоанализа */ Wait () ;
ea = MinEA(); eb = МахЕА () ;
output_file = fopenCreport_out.txt", "а"); file_name = GetldbPath();
fprintf (output_file, "----------------------------------------------
\nFilename: %s\n",  file_name);
fprintf(output_file,   "HUNTING FROM %x TO %x\n----------------------------
---------\n",  ea,  eb);
while (ea  != BADADDR) (
auto my_code;
last_address=ea;
//Message("checking %x\n",  ea);
my_code = GetMnem(ea);
if(0 == strstr(my_code, "call"))(
auto my_op;
my_op = GetOpnd(ea, 0);
if(-l  != strstr(my_op, "sprintf")))
fprintf(output_file,   "Найден вызов sprintf по адресу 0x%x -
\n",  ea);

I*  3 параметра,  max отслеживание 20 */ hunt_address(ea,   3,  20,   output_file); fprintf(output_file, "----------------
------\n");
)
)
ea = FindCode(ea, 1);
)
fprintf(output file,   "Завершено на адресе 0x%x\n--
-------------\n",   last_address);
fclose(output_file); Exit (0) ;
)
Результат выполнения этой глобальной проверки сохраняется в файле report_ out. txt для последующего анализа. Содержимое этого файла может выглядеть следующим образом.
Filename: C:\reversing\ofl.idb HUNTING FROM 401000 ТО 404000
Found sprintf call at 0x401012 - checking
push number 3, ecx
detected subroutine 0x401000
got frame ff00004f
got frame size 32
got frame lvar size 28
got frame args size 0
[esp+lCh+var_iC]   is the target buffer,   in frame size 32 bytes
push number 2,   offset unk_403010
push number i, eax
[esp+arg__0]   is the source buffer
[esp+arg_0] is an argument that will overflow if larger than 28 bytes! Exhausted all parameters
Found sprintf call at 0x401035 - checking
push number 3, ecx
detected subroutine 0x401020
got frame ff000052
got frame size 292
got frame lvar size 288
got frame args size 0
[esp+120h+var_120]   is the target buffer,   in frame size 292 bytes push number 2,  offset aSHh push number 1, eax
[esp+arg_0]   is the source buffer
[esp+arg_0] is an argument that will overflow if larger than 288 bytes! Exhausted all parameters
FINISHED at address 0x4011b6
Fi iename: С:\winnt\MSAGENT\AGENTCTL.idb HUNTING FROM 74c61000 TO 74c7a460
Found sprintf call at 0x74c6e3b6 - checking
push number 3, eax
detected subroutine 0x74c6e2f9
got frame ffOOOeca
got frame size 568
got frame lvar size 552
got frame args size 8
[ebp+v.ar_218]   is the target buffer,   in frame size 568 bytes

Восстановление исходного кода и структуры программы 117
push number 2,  offset aD_2d
push number 1, eax [ebp+var_21C]  is the source buffer Exhausted all parameters
При поиске вызовов функций мы обнаружили подозрительный вызов функции 1st г еру (). Автоматический анализ больших фрагментов кода широко использует­ся хакерами для поиска "интересных" для атаки точек и крайне полезен на практике.

 

На главную | Содержание | Назад | Вперёд
 
Яндекс.Метрика