为什么idapython得到的函数和用IDA在函数window中显示的不一样?
Why the function got by idapython is not the same as displayed in function window using IDA?
我在 Linux 上尝试使用 IDA Pro 分析自己编写和编译的二进制文件。在函数 window 中,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()
)是None。我想获取所有函数的参数,但是如上所述,我无法获取函数的信息(_Z10experimentSsiSs),甚至找不到函数(实验)。为什么是这样?我该怎么办?
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 (i.e if you strip your binary you don't have access to this information anymore! except in the case of 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>
,您会发现该函数的名称将不再存在。
我在 Linux 上尝试使用 IDA Pro 分析自己编写和编译的二进制文件。在函数 window 中,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()
)是None。我想获取所有函数的参数,但是如上所述,我无法获取函数的信息(_Z10experimentSsiSs),甚至找不到函数(实验)。为什么是这样?我该怎么办?
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 (i.e if you strip your binary you don't have access to this information anymore! except in the case of 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>
,您会发现该函数的名称将不再存在。