Вероятно, VirtualProtect вернул ошибку.Проверьте возвращаемое значение (BOOL) и, если false, используйте GetLastError, чтобы проверить причину.
Обратите внимание, что VirtualProtect должен быть совместим с доступом, предоставленным при вызове VirtualAlloc, который выделил память.Это то, что вы не можете контролировать, так как VirtualAlloc вызывается внутри LoadLibrary.
Другое дело, что указатель, предоставляемый VirtualProtect, должен быть начальным адресом этой страницы памяти, а указанный вами указатель на функцию, скорее всего, нет.Ваша функция может быть где угодно внутри страницы, вам придется настроить ее до ближайшего начала страницы раньше.
Интерес:
http://support.microsoft.com/kb/127904 (в основном то, что вы делаете, но требуется еще несколько шагов)
http://www.joachim -bauch.de / tutorials / loading-a-dll-from-memory / (может быть полезно для подробностей о механизме загрузки DLL)