Once the dynamic-link library (DLL) is loaded in the memory, the address of an exported function is usually retrieved. The address is copied into a variable. Before the program executes the exported function, it retrieves its address from the variable. A potential vulnerability exists if the DLL is unloaded but the variable still contain the address of the exported function that was previously valid.
Here is one approach to get started the investigation into a potential vulnerability.
Let's assume the debugger executes the target application. We configure it to break-in when a DLL is unloaded. We know the base address and the size of the DLL as the debugger displays it. When the debugger breaks in we search for pointers that fall into this region. We set data access breakpoint for each pointer, and resume the execution to see if the pointers are accessed.
We may find that some of the pointers set to NULL when the breakpoint is triggered. This is most likely to prevent the access to invalid memory.
We may find that other expired pointers get copied into another memory location. This could be suspicious as we don't normally read expired pointers, albeit, often whole structures get copied even if they contain members that are no longer used.
We may find that some of the breakpoints are not triggered, and we need to analyze further if they can be reached from the execution flow.