Непереносимый, но основанный на API и правильно работающий подход заключается в использовании программ чтения программных баз данных - таких как dbghelp.dll в Windows или readelf в Linux. Их использование возможно только в том случае, если отладочная информация включена / присутствует вместе с программой. Вот пример того, как это работает в Windows:
SYMBOL_INFO symbol = { };
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
// Implies, that the module is loaded into _dbg_session_handle, see ::SymInitialize & ::SymLoadModule64
::SymFromAddr(_dbg_session_handle, address, 0, &symbol);
Вы получите размер функции в символе. Размер , но вам также может понадобиться дополнительная логика, определяющая, является ли данный адрес на самом деле функцией, прокладкой, размещенной там инкрементным компоновщиком или DLL вызов thunk (тоже самое).
Я полагаю, что нечто подобное можно сделать с помощью readelf в Linux, но, возможно, вам придется создать библиотеку поверх ее исходного кода ...
Вы должны иметь в виду, что, хотя подход, основанный на дизассемблировании, возможен, вам, в основном, придется анализировать ориентированный граф с конечными точками в ret, halt, jmp (ДОКАЗАНО, что включено инкрементное связывание и вы можете читать jmp -table для определения того, является ли jmp, с которым вы сталкиваетесь в функции, внутренним по отношению к этой функции (отсутствует в jmp-таблице изображения) или внешним (присутствует в этой таблице; такие jmp часто встречаются как часть оптимизации хвостового вызова на x64, так как я знать)) любые вызовы, которые должны быть нерегламентированными (например, помощник, генерирующий исключение) и т. д.