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
$ r2 -A <filename>.
As stated in the radare2 documentation:
aan autoname functions that either start with fcn.* or sym.func.*
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
╭ (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 (
I made some ASCII-arts for you, hope this would make things clearer.
| |__ The function's address
|__ stands for "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 based on flags that being used
| the 3 digits at the end are the function's address