дизассемблерный листинг, демонстрирующий всю мощь косвенного вызова функций
IDA Pro не смогла распознать функции и хотя восстановила перекрестные ссылки на main, они еще ни о чем не говорят! Ведь функции sub_demo и sub_sub_demo вызываются совсем не оттуда. Возьмем "функцию" loc_401000. Она принимает указатель в качестве аргумента и тут же его вызывает. А что это за указатель? Да хвост его знает! Ведь перекрестной ссылки на материнскую функцию нет! Единственный способ установить истину — проанализировать все цепочку вызовов с самого начала программы — с функции main, но слишком трудоемко, так что даже не обсуждается (особенно, если ломать реальную программу), но даже в этом случае приходится постоянно следить за указателями, которые пляшут как кони и ни хрена не понятно, что находится в них в каждый конкретный момент!
Защиту можно значительно усилить, если реализовать модель Маркова — функцию, возвращающую указатель на функцию. Такой прием программирования не слишком популярен, поскольку непривычен и лишен языковой поддержки (язык Си вообще не позволяет объявлять функции, возвращающие указатели на функции, поскольку такие определения рекурсивны, и программисту приходится возиться с постоянным преобразованием типов, что не слишком украшает программу и является потенциальным рассадником ошибок). Тем не менее, на автоматическое дизассемблирование моделей Маркова не способен ни один дизассемблер, включая IDA PRO.