I found the reason why the plugin didn't work: the PLUGIN symbol wasn't exported from the dll (.plw).
In headers prior to version 5.1 the symbol isn't declared __declspec(dllexport), meaning it has to be exported via a .DEF file or a workaround has to be used so that the symbol definition can be made __declspec(dllexport) despite the wrong declaration in the header:
#define PLUGIN sCaPeGoAt_PLUGIN
#include "loader.hpp" // plugin_t, PLUGIN_KEEP etc.
#undef PLUGIN
extern "C"
__declspec(dllexport)
plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
...
};
With the scapegoat soaking up the wrong declaration, VC++ accepts the __declspec(dllexport) on the definition and compiles it. Now the plugin works perfectly fine in IDA 5.0 free... Without the fix, the build stops with the following message:
error C2370: 'PLUGIN' : redefinition; different storage class
The problem of obtaining a decent .DEF or .LIB still remains, though. Reversing the WLL to identify the functions behind the ordinals is a bit cumbersome and slow going... There are plugins for IDA free around, so the libs must be out there somewhere (unless they were got under a gag agreement).
UPDATE: for VC++ there's a much easier way to accomplish the same thing, without evil macro trickery:
#pragma comment (linker, "/export:PLUGIN=_PLUGIN")
or simply
#pragma comment (linker, "/export:_PLUGIN")
since the leading underscore seems to get stripped automatically.