Radare2's afl command returns function names with a specific syntax that I could not find documentation on:

For example:

radare2 -2 -A -q -c "aflj" C:/Windows/system32/advapi32.dll

0x77cce13c   22 280          sub.ntdll.dll_RtlNtStatusToDosError_13c
0x77cce259    7 62           fcn.77cce259
0x77cce29c   10 88           sub.KERNEL32.dll_lstrcmpiW_29c
0x77cce2f9   24 463          sub.KERNEL32.dll_lstrlenW_2f9
0x77c617b4    1 40           sym.imp.KERNEL32.dll_LocalAlloc
0x77c6abe5    5 92   -> 130  sub.KERNEL32.dll_LocalAlloc_be5
0x77c7edd5    1 20           sub.KERNEL32.dll_LocalAlloc_dd5
  • What is the meaning of the hexadecimal number after the function name ?
  • Why is the core difference between the prefixes "sym." and "sub." of DLL function names ?
  • What is the difference between library names in lower or uppercase ?

The DLL file names are all in lowercase:

  • C:\Windows\System32\ntdll.dll
  • C:\Windows\System32\kernel32.dll
  • The last 3 hex digits are taken from the address. As for the capitalization: did you compare this with the names of those DLL's? – usr2564301 Jan 13 at 18:20
  • So, the 3 hex digits are taken from the address of what ? How is it possible to point to a DLL "sub.*" function "sub.*" which is not an exported symbole "sym.*" ? Is there a relation between sym.imp.KERNEL32.dll_LocalAlloc and sub.KERNEL32.dll_LocalAlloc_be5 ? Here are the file names, they are in lowercase: - "C:\Windows\System32\ntdll.dll" - "C:\Windows\System32\kernel32.dll" – remi.chateauneu Jan 13 at 18:47

I will start by answering your specific three questions, and then will shed more light about the naming structure of functions in radare2.

What is the meaning of the hexadecimal number after the function name?

The meaning of the 3 hexadecimal digits at the end of function names like "sub.KERNEL32.dll_lstrlenW_2f9" are the last 3 digits of the function address. The confusion here is because this is not an imported function name, but a regular function. This naming caused by the aan command which you probably used when you executed aaa or opened a file with th -A flag: $ r2 -A <filename>.

As stated in the radare2 documentation:

aan                 autoname functions that either start with fcn.* or sym.func.*

The aan command will auto-generate a name, based on the flags being used in the function. This should ease the analysis for the user before analyzing the function.

So let's have a look at a function which is called sub.KERNEL32.dll_DisableThreadLibraryCalls_18002a860. You can see that an import function called "DisableThreadLibraryCalls" is being called. This is why the function was renamed by aan:

[0x18002a860]> pdf
╭ (fcn) sub.KERNEL32.dll_DisableThreadLibraryCalls_18002a860 35
│   sub.KERNEL32.dll_DisableThreadLibraryCalls_18002a860 ();
│           ; arg unsigned int arg3 @ rdx
│           0x18002a860      4883ec28       sub rsp, 0x28
│           0x18002a864      83fa01         cmp edx, 1
│       ╭─< 0x18002a867      7510           jne 0x18002a879
│       │   0x18002a869      48833dff1f00.  cmp qword [0x18002c870], 0 ; [0x18002c870:8]=0
│      ╭──< 0x18002a871      7506           jne 0x18002a879
│      ││   0x18002a873      ff159f170000   call qword sym.imp.KERNEL32.dll_DisableThreadLibraryCalls 
│      ╰╰─> 0x18002a879      b801000000     mov eax, 1
│           0x18002a87e      4883c428       add rsp, 0x28
╰           0x18002a882      c3             ret

Why is the core difference between the prefixes "sym." and "sub." of DLL function names?

sym stands for "Symbol". This is a symbol taken from the binary's Symbol Table. sub. stands for "Subroutine". This can by a standalone function but most likely a part of a function, like JMPTABLE blocks, addresses in pointer table, etc.

What is the difference between library names in lower or uppercase?

In general, radare2 keeps the case of the libraries as shown in the Import Address Tables. But I think sometimes it is being modified in favor of readability and to make it easier to differentiate between an import function, and a renamed function (aan).


I made some ASCII-arts for you, hope this would make things clearer.

Regular Function

|      |
|      |__ The function's address
|__ stands for "Function"

Imported function

 |   |     |            |
 |   |     |            |__ The imported function name, "LocalAlloc"
 |   |     |
 |   |     |__ the Library name. In this case, "kernel32.dll"
 |   |
 |   |
 |   |___ "Import", this is an imported function
 |___ "Symbol", taken from the Symbol Table

Auto-Generated Name

 |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 |                   |
 |                   |__ auto-generated name based on flags that being used
 |                       the 3 digits at the end are the function's address
 |__ "Subroutine"
  • If I have well understood, the function sub.KERNEL32.dll_DisableThreadLibraryCalls_18002a860 is not strictly related to the import sym.imp.KERNEL32.dll_DisableThreadLibraryCalls, except that the former might call the latter, along with possibly other imports. – remi.chateauneu yesterday
  • 1
    Yes, exactly! This is the auto generated name based on an one Imported function that was used in this function. – Megabeets yesterday

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.