Gallopsled / Gallopsled/pwntools
Parse __libc_ifunc_impl_list data to provide more symbols for libc
- Dominant language
- Python
- Stars
- 13.7k
- Forks
- 1.9k
- Avg merge
- 6d 23h
- Merged PRs (30d)
- 3
Description
Libc has a bunch of optimized implementations of many of its functions such as `__strlen_avx2`, etc. These are not exported as symbols but instead there is a function called `__libc_ifunc_impl_list` that can give you this information at runtime. If we can parse the info from that function, we can provide more entries in the symbols dict.
This is useful in cases where you leak the address of one of these functions and want to calculate the libc base without hardcoding the offset.
I intend to look at possible solutions but I'm starting by opening an issue here to get input and document my findings.
The function follows a format like this:
```
else if ( !strcmp(name, "memmove") )
{
array[7].usable = 1;
array[8].usable = 1;
array->name = "__memmove_avx_unaligned";
array->fn = (__int64)&loc_18EA70;
v16 = *((_DWORD *)&rtld_global_ro + 45);
array[1].name = "__memmove_avx_unaligned_erms";
array[1].fn = (__int64)&loc_18EAD0;
v17 = v16;
array[2].name = "__memmove_avx512_no_vzeroupper";
LOBYTE(v16) = (v16 >> 12) & 1;
array[2].fn = (__int64)&loc_192460;
array[2].usable = v16;
array[3].usable = v16;
array[4].usable = v16;
v18 = *((_DWORD *)&rtld_global_ro + 30);
array[3].name = "__memmove_avx512_unaligned";
array[3].fn = (__int64)&loc_192E50;
array[5].name = "__memmove_ssse3_back";
v19 = (v17 >> 6) & 1;
v20 = (v18 >> 9) & 1;
array[5].fn = (__int64)&loc_174790;
array[5].usable = v20;
array[6].usable = v20;
array[6].name = "__memmove_ssse3";
array->usable = v19;
array[7].name = "__memmove_erms";
array[1].usable = v19;
array[4].name = "__memmove_avx512_unaligned_erms";
array[4].fn = (__int64)&loc_192EC0;
array[7].fn = (__int64)&loc_BB4C0;
array[6].fn = (__int64)&loc_16F120;
array[8].name = "__memmove_sse2_unaligned";
array[8].fn = (__int64)memcpy_0;
array[9].name = "__memmove_sse2_unaligned_erms";
array[9].fn = (__int64)&loc_BB520;
array[9].usable = 1;
result = 10LL;
}
else if ( !strcmp(name, "memrchr") ) {
...
```
The "usable" flag is not that interesting but the name-function mapping is.
Contributor guide
Research direction
Start by locating the symbols dict and the runtime handling for __libc_ifunc_impl_list, then compare that path with the format shown in the issue. Done means the discovered name-function mappings, including optimized libc implementations, are available through the symbols dict without hardcoded offsets.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- reverse-engineering
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100