We all know that in typical programs, there exist some references.

enter image description here

When compiling, linker will translate all the memory references into concrete memory addresses during the symbol relocation step. And by doing some quick experiments (IDA-Pro 6.4), I notice that IDA-Pro can help to lift these memory addresses back into symbols.

However, I found that the symbolization functionality of IDA-Pro can be mislead by some cases. So what I am interested is to calculate how many references have been recovered by IDA-Pro. I am asking that is there anyway to obtain the information of "how many memory references are recovered by IDA-Pro?"

Thanks @Jason a lot for his answer, but what I am trying to do is not collect all the labels. Here is an example:

enter image description here

Please pay attention to the symbol sub_80484AE in address 0x804a020. Note that the 4 byte data 0x08, 0x04, 0x84, 0xae in porocessed binary are considered as a symbol, as it is equal to the beginning address of function sub_80484AE. This is true. However, as no instruction refers to the address 0x804A020, so there is no name in address 0x804a020.

What I want to collect is all the symbols with its corresponding address, for example, in the above case, I need to collect this

0x804a018 : sub_804847b
0x804a01dc : _strchr
0x804a020 : sub_80484AE

Am I clear enough? I really appreciate if anyone can give me some help! Thank you a lot!!

----------------------------------------------- update ---------------------------------------

Am I still not clear enough?

Let me put it in this way. Can I obtain all the symbol information which used to be resolved by linker? Say, in the picture I updated, during compiling linker resolved three symbols, at memory address 0x804a018, 0x804a01dc, 0x804a020. IDA-Pro recovers some of these information. So I want to collect all the IDA recovered symbol information (this information could be function name, or it could be an entry of jump table, or it could be a jump destination, as I draw in the picture).

Note that I want to recover the information in a format that each resolved symbol together with the memory address. For example in the picture, it should be:

0x804a018 : sub_804847b
0x804a01dc : _strchr
0x804a020 : sub_80484AE

I am thinking to traverse all the memory address of a binary, and check each the oprend of instruction (or content if it is in the data section), to see whether it is a recovered symbol or not. If so, I will store this symbol together with this instruction (or data)'s memory address.

But basically how to check whether a oprend in a instruction is a symbol?

  • Sorry for the off topic, may I ask what did you use to create the function graph? – Dominik Antal Apr 2 '15 at 14:18
  • 1
    @DominikAntal, I use tiKz. – lllllllllllll Apr 2 '15 at 15:45

If I understand your question correctly, you're asking how many addresses have names.

For example, in the following snippet, two of the addresses in the snippet have names (loc_4385E4 and dword_4385F8), since both are cross-referenced from other addresses:

.text:004385E4 loc_4385E4:                             ; CODE XREF: sub_4254E0+1C0j
.text:004385E4                                         ; CODE XREF: sub_4254E0+1E6j
.text:004385E4                 push    ecx
.text:004385E5                 push    ecx
.text:004385E6                 push    0Eh
.text:004385E8                 pop     edx
.text:004385E9                 mov     ecx, offset dword_438618
.text:004385EE                 call    sub_4421A7
.text:004385F3                 jmp     loc_4256A6
.text:004385F3 ; END OF FUNCTION CHUNK FOR sub_4254E0
.text:004385F3 ; ---------------------------------------------------------------------------
.text:004385F8 dword_4385F8    dd 1000000Ah, 80204h, 10000h, 80010000h
.text:004385F8                                         ; DATA XREF: sub_4254E0+13092o

You can use the IDC script below to count all named addresses in your disassembly:

auto ea;
auto names = 0;

for (ea = BeginEA(); ea != BADADDR; ea = NextNotTail(ea))
{
    if (Name(ea) != "")
    {
        names++;
    }
}

Message("%d named addresses found.\n", names);

Edit

The change you made to your original question now makes it sounds like you want to capture all function names. To do this, open the Functions window (in the menubar: ViewOpen subviewsFunctions), right-click in the Functions window, and choose Copy all. You can now paste the list of function names into a text editor or spreadsheet.

  • Hello Jason, thank you for your answer. I haven't tested yet, but in the above case, what if dword_4385F8 is a function pointer array? I want to calculate, say, in the array, how many entries (memory addresses) have been symbolized by IDA-Pro. – lllllllllllll Mar 29 '15 at 17:07
  • Sum up the labels could be a subset of all the symbolized references, as there could be multiple references, say, data to code references, that points to the same function. – lllllllllllll Mar 29 '15 at 17:08
  • "how many entries (memory addresses) have been symbolized by IDA-Pro." -- If an entry is directly cross-referenced then IDA will give it a name and the script above will include it in the count. – Jason Geffner Mar 29 '15 at 20:16
  • Hello Jason, I updated my question. Would you mind to take a look? :-) Am I clear now? – lllllllllllll Apr 2 '15 at 15:58
  • Answer updated. – Jason Geffner Apr 2 '15 at 18:32

I write some scripts, and tested on some ELF binaries. It works.

#include <idc.idc>

static main()
{
auto ea, e1, e2;
auto t1, t2;
auto names = 0;

// needs to be set manually
auto b_text = 0x8048360;
auto e_text = 0x804867c;
auto b_data = 0x804a010;
auto e_data = 0x804a024;
auto b_rodata = 0x8048698;
auto e_rodata = 0x80486d0;

for (ea = BeginEA(); ea != BADADDR; ea = NextNotTail(ea))
{

    if (ea >= b_text && ea < e_text)
    {
        t1 = GetOpType(ea,0);
        t2 = GetOpType(ea,1);

        if (t1 == 2 || t1 == 6 || t1 == 7 || t1 == 5)
        {
            e1 = GetOpnd(ea, 0);

            if (t1 != 5) {
                Message("%x ---> %s\n", ea, e1);
            } else {
              if (strstr(e1, "_") != -1 || strstr(e1, "offset") != -1) {Message("%x ---> %s\n", ea, e1);
              }
            }
        }
        if (t2 == 2 || t2 == 6 || t2 == 7 || t2 == 5)
        {
             e2 = GetOpnd(ea, 1);

            if (t2 != 5) {
                Message("%x ---> %s\n", ea, e2);
            } else {
              if (strstr(e2, "_") != -1 || strstr(e2, "offset") != -1) {
              Message("%x ---> %s\n", ea, e2);
              }
            }
        }
     }
     else if ((ea >= b_data && ea < e_data) || (ea >=b_rodata && ea < e_rodata))
     {
            auto n_ea = NextNotTail(ea);
            if (n_ea - ea == 4) // 32-bit OS, 4-byte pointer
            {
                    auto data = Dword(ea);
                    if (Name(data)){
                       Message("%x ---> %s\n", ea, Name(data));
                    }
            }
     }
     else {}
}

return 0;
}

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.