Почему функция, полученная с помощью idapython, отличается от функции, отображаемой в окне функций с помощью IDA? - PullRequest
0 голосов
/ 21 ноября 2018

Я пытался использовать IDA Pro для анализа двоичного файла, написанного и скомпилированного мной в Linux.В окне функций IDA отображает функцию experiment(std::string,int,std::string) .text 00000000004181FB 0000082F 000004D8 00000000 R . . . B . . Но, когда я пытался получить функцию по ida python,

Python>for i in idautils.Functions():
Python>    name =  idaapi.get_func_name(i)
Python>    if name.startswith('_Z10experimentSsiSs') or name.startswith('experiment'):
Python>        print name
Python>        print idc.GetType(i)

результат равен

_Z10experimentSsiSs None

ни одна функция не названа experiment, а тип функции _Z10experimentSsiSs (кажется, что это функция experiment()) - Нет.Я хочу получить аргументы всех функций, но, как упоминалось выше, я не могу получить информацию о функции (_Z10experimentSsiSs), и даже я не могу найти функцию (эксперимент).Почему это?Что мне делать?

1 Ответ

0 голосов
/ 22 ноября 2018

AFAIK, idc.getType работают только с функциями C.Поскольку вы используете C ++, имя искажено .

Вот быстрый тест, который я сделал:

#include <iostream>
#include <string>


void test(const std::string& s1, const std::string& s2)
{
    std::cout << s1 << " " << s2 << std::endl;

    return;
}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        std::cerr << "2 args needed" << std::endl;
        return -1;
    }

    test(argv[1], argv[2]);

    return 0;    
}

Компиляция, тест:

neitsa@eagle:/mnt/temp/gpp$ g++ -o test test.cpp
neitsa@eagle:/mnt/temp/gpp$ ./test hello world
hello world

В IDA (я использую 7.2) у меня есть это (чудовище) для функции test:

.text:0000000000000CBA ; test(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
.text:0000000000000CBA                 public _Z4testRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_
.text:0000000000000CBA _Z4testRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_ proc near

Итак, технически (искаженное) имя функции: _Z4testRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_

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

Получить имя:

Python>idaapi.get_func_name(0xcba)
_Z4testRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_

Разобрать его:

Python>idc.Demangle(idaapi.get_func_name(0xcba), idc.GetLongPrm(idc.INF_SHORT_DN))
test(std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>> const&,std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>> const&)

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

Возможно, вы захотите попробоватьINF_LONG_DN, который, кажется, добавляет пробелы после каждого аргумента.Это может помочь при разборе:

Python>idc.Demangle(idaapi.get_func_name(0xcba), idc.GetLongPrm(idc.INF_LONG_DN))
test(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)

Примечание: попробуйте с strip <program> -o <program_stripped>, вы увидите, что имя функции просто не будет здесь больше.

...