Memory access violation occurs when attempting to reuse the ECX register after LoadLibrary is called.
call dword ptr[ebp + fn_LoadLibraryA]
When this function is called, it does not retain the ECX register. The ECX register is being used as an index for the hash location, but gets reused by the LoadLibraryA function, without pushing the ECX register onto the stack.
Any subsequent calls to find_function causes a memory access violation here...
mov [ebp + ecx], eax ; save the funtion address in our table