为什么idapython获得的功能与使用IDA在功能窗口中显示的功能不同?

时间:2018-11-21 04:12:29

标签: binary disassembly ida

我试图使用IDA Pro分析自己在Linux上编写和编译的二进制文件。在函数窗口中,IDA显示了函数export class AppComponent { constructor(private cssservice: CSSService, public http: Http) { // get css from server here and write into the http response } } ,但是,当我尝试通过ida python获取函数时。

experiment(std::string,int,std::string) .text 00000000004181FB 0000082F 000004D8 00000000 R . . . B . .

结果是

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)的类型为None。我想获取所有函数的参数,但是如上所述,我无法获取函数的信息(_Z10experimentSsiSs),甚至找不到函数(实验)。为什么是这样?我该怎么办?

1 个答案:

答案 0 :(得分:0)

AFAIK,idc.getType仅适用于C函数。使用C ++时,名称为mangled

这是我做的一个快速测试:

#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_

由于参数的类型由symbolic information提供(即,如果您剥离二进制文件,则您将无法再访问此信息!除了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>,您会发现该函数的名称不再存在。