diff --git a/core/logic/MemoryUtils.cpp b/core/logic/MemoryUtils.cpp
index adb54ba3..62a236be 100644
--- a/core/logic/MemoryUtils.cpp
+++ b/core/logic/MemoryUtils.cpp
@@ -49,6 +49,7 @@ MemoryUtils g_MemUtils;
 
 MemoryUtils::MemoryUtils()
 {
+	m_InfoMap.init();
 #ifdef PLATFORM_APPLE
 
 	task_dyld_info_data_t dyld_info;
@@ -77,20 +78,19 @@ void MemoryUtils::OnSourceModAllInitialized()
 
 void *MemoryUtils::FindPattern(const void *libPtr, const char *pattern, size_t len)
 {
-	DynLibInfo lib;
-	bool found;
-	char *ptr, *end;
+	const DynLibInfo* lib = nullptr;
 
-	memset(&lib, 0, sizeof(DynLibInfo));
-
-	if (!GetLibraryInfo(libPtr, lib))
+	if ((lib = GetLibraryInfo(libPtr)) == nullptr)
 	{
 		return NULL;
 	}
 
-	ptr = reinterpret_cast<char *>(lib.baseAddress);
-	end = ptr + lib.memorySize - len;
+	// Search in the original unaltered state of the binary.
+	char *start = lib->originalCopy.get();
+	char *ptr = start;
+	char *end = ptr + lib->memorySize - len;
 
+	bool found;
 	while (ptr < end)
 	{
 		found = true;
@@ -103,8 +103,9 @@ void *MemoryUtils::FindPattern(const void *libPtr, const char *pattern, size_t l
 			}
 		}
 
+		// Translate the found offset into the actual live binary memory space.
 		if (found)
-			return ptr;
+			return reinterpret_cast<char *>(lib->baseAddress) + (ptr - start);
 
 		ptr++;
 	}
@@ -116,6 +117,8 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
 {
 #ifdef PLATFORM_WINDOWS
 
+	/* Add this this library into the cache */
+	GetLibraryInfo(handle);
 	return GetProcAddress((HMODULE)handle, symbol);
 	
 #elif defined PLATFORM_LINUX
@@ -162,6 +165,9 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
 		}
 	}
 
+	/* Add this this library into the cache */
+	GetLibraryInfo((void *)dlmap->l_addr);
+
 	/* If we don't have a symbol table for this library, then create one */
 	if (table == NULL)
 	{
@@ -325,6 +331,9 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
 		/* Uh oh, we couldn't find a matching handle */
 		return NULL;
 	}
+
+	/* Add this this library into the cache */
+	GetLibraryInfo((void *)dlbase);
 	
 	/* See if we already have a symbol table for this library */
 	for (size_t i = 0; i < m_SymTables.size(); i++)
@@ -429,15 +438,17 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
 #endif
 }
 
-bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
+const DynLibInfo *MemoryUtils::GetLibraryInfo(const void *libPtr)
 {
 	uintptr_t baseAddr;
 
 	if (libPtr == NULL)
 	{
-		return false;
+		return nullptr;
 	}
 
+	DynLibInfo lib;
+
 #ifdef PLATFORM_WINDOWS
 
 #ifdef PLATFORM_X86
@@ -456,7 +467,7 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
 
 	if (!VirtualQuery(libPtr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
 	{
-		return false;
+		return nullptr;
 	}
 
 	baseAddr = reinterpret_cast<uintptr_t>(info.AllocationBase);
@@ -470,19 +481,19 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
 	/* Check PE magic and signature */
 	if (dos->e_magic != IMAGE_DOS_SIGNATURE || pe->Signature != IMAGE_NT_SIGNATURE || opt->Magic != PE_NT_OPTIONAL_HDR_MAGIC)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* Check architecture */
 	if (file->Machine != PE_FILE_MACHINE)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* For our purposes, this must be a dynamic library */
 	if ((file->Characteristics & IMAGE_FILE_DLL) == 0)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* Finally, we can do this */
@@ -509,12 +520,12 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
 
 	if (!dladdr(libPtr, &info))
 	{
-		return false;
+		return nullptr;
 	}
 
 	if (!info.dli_fbase || !info.dli_fname)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* This is for our insane sanity checks :o */
@@ -524,31 +535,31 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
 	/* Check ELF magic */
 	if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* Check ELF version */
 	if (file->e_ident[EI_VERSION] != EV_CURRENT)
 	{
-		return false;
+		return nullptr;
 	}
 	
 	/* Check ELF endianness */
 	if (file->e_ident[EI_DATA] != ELFDATA2LSB)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* Check ELF architecture */
 	if (file->e_ident[EI_CLASS] != ELF_CLASS || file->e_machine != ELF_MACHINE)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* For our purposes, this must be a dynamic library/shared object */
 	if (file->e_type != ET_DYN)
 	{
-		return false;
+		return nullptr;
 	}
 
 	phdrCount = file->e_phnum;
@@ -598,12 +609,12 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
 
 	if (!dladdr(libPtr, &info))
 	{
-		return false;
+		return nullptr;
 	}
 
 	if (!info.dli_fbase || !info.dli_fname)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* This is for our insane sanity checks :o */
@@ -613,19 +624,19 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
 	/* Check Mach-O magic */
 	if (file->magic != MACH_MAGIC)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* Check architecture */
 	if (file->cputype != MACH_CPU_TYPE || file->cpusubtype != MACH_CPU_SUBTYPE)
 	{
-		return false;
+		return nullptr;
 	}
 
 	/* For our purposes, this must be a dynamic library */
 	if (file->filetype != MH_DYLIB)
 	{
-		return false;
+		return nullptr;
 	}
 
 	cmd_count = file->ncmds;
@@ -646,5 +657,17 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
 
 	lib.baseAddress = reinterpret_cast<void *>(baseAddr);
 
-	return true;
+	LibraryInfoMap::Insert i = m_InfoMap.findForAdd(lib.baseAddress);
+	if (i.found())
+	{
+		// We already loaded this binary before.
+		return &i->value;
+	}
+	
+	// Keep a copy of the binary in its initial unpatched state for lookup.
+	lib.originalCopy = std::make_unique<char[]>(lib.memorySize);
+	memcpy(lib.originalCopy.get(), lib.baseAddress, lib.memorySize);
+	m_InfoMap.add(i, lib.baseAddress, std::move(lib));
+
+	return &i->value;
 }
diff --git a/core/logic/MemoryUtils.h b/core/logic/MemoryUtils.h
index 49a20fb2..f7eeaafd 100644
--- a/core/logic/MemoryUtils.h
+++ b/core/logic/MemoryUtils.h
@@ -32,6 +32,8 @@
 
 #include "common_logic.h"
 #include <IMemoryUtils.h>
+#include <am-hashmap.h>
+#include <memory>
 #if defined PLATFORM_LINUX || defined PLATFORM_APPLE
 #include <sh_vector.h>
 #include "sm_symtable.h"
@@ -49,6 +51,7 @@ struct DynLibInfo
 {
 	void *baseAddress;
 	size_t memorySize;
+	std::unique_ptr<char[]> originalCopy;
 };
 
 #if defined PLATFORM_LINUX || defined PLATFORM_APPLE
@@ -73,7 +76,7 @@ public: // IMemoryUtils
 	void *FindPattern(const void *libPtr, const char *pattern, size_t len);
 	void *ResolveSymbol(void *handle, const char *symbol);
 public:
-	bool GetLibraryInfo(const void *libPtr, DynLibInfo &lib);
+	const DynLibInfo *GetLibraryInfo(const void *libPtr);
 #if defined PLATFORM_LINUX || defined PLATFORM_APPLE
 private:
 	CVector<LibSymbolTable *> m_SymTables;
@@ -83,6 +86,8 @@ private:
 	SInt32 m_OSXMinor;
 #endif
 #endif
+	typedef ke::HashMap<void *, DynLibInfo, ke::PointerPolicy<void> > LibraryInfoMap;
+	LibraryInfoMap m_InfoMap;
 };
 
 extern MemoryUtils g_MemUtils;