Reputation: 15
I was trying to use IDA Pro to analyse a binary writen and compiled by myself on Linux. In the function window, IDA displayed the function experiment(std::string,int,std::string) .text 00000000004181FB 0000082F 000004D8 00000000 R . . . B . .
But, when I tried to get the function by 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)
the result is
_Z10experimentSsiSs
None
no function is named as experiment
, and the type of function _Z10experimentSsiSs
(it seems that it is the function experiment()
) is None. I want to get the arguments of all functions, but as mentioned above, I can not get the function's infomation (_Z10experimentSsiSs), and even i can not find the function (experiment). Why is this? What should I do?
Upvotes: 0
Views: 1922
Reputation: 8166
AFAIK, idc.getType
only work with C functions. As you're using C++ the name is mangled.
Here's a quick test I did:
#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;
}
Compile, test:
neitsa@eagle:/mnt/temp/gpp$ g++ -o test test.cpp
neitsa@eagle:/mnt/temp/gpp$ ./test hello world
hello world
In IDA (I'm using 7.2), I have this (monstrosity) for the test
function:
.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
So, technically the (mangled) function name is: _Z4testRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_
As the type of the arguments is provided by the symbolic information (i.e if you strip your binary you don't have access to this information anymore! except in the case of RTTI which can also provide this type of information) the only way to get them is to demangle the name and then parse it:
Get the name:
Python>idaapi.get_func_name(0xcba)
_Z4testRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_
Demangle it:
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&)
Once you have that you can parse the function prototype and extract the parameters types (which might not be an easy fit with C++...).
You might want to try with INF_LONG_DN
which seems to add spaces after each argument. That might help when parsing:
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&)
Note: do try with strip <program> -o <program_stripped>
you'll see that the name of the function will simply not be here anymore.
Upvotes: 1