Пример #1
0
        internal static void* MemoryGetProcAddress(MEMORYMODULE mod, byte* name)
        {
            MEMORYMODULE module = mod;
            byte* codeBase = module.codeBase;
            uint idx = 0;
            IMAGE_EXPORT_DIRECTORY* exports;
            IMAGE_DATA_DIRECTORY* directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_EXPORT);
            if (directory->Size == 0)
                // no export table found
                return null;

            exports = (IMAGE_EXPORT_DIRECTORY*)(codeBase + directory->VirtualAddress);
            if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0)
                // DLL doesn't export anything
                return null;

            if (HIWORD(name) == 0)
            {
                // load function by ordinal value
                if (LOWORD(name) < exports->Base)
                    return null;

                idx = LOWORD(name) - exports->Base;
            }
            else if (exports->NumberOfNames == 0)
                return null;
            else
            {
                ExportNameEntry found;

                // Lazily build name table and sort it by names
                if (module.nameExportsTable == null)
                {
                    uint i;
                    uint* nameRef = (uint*)(codeBase + exports->AddressOfNames);
                    ushort* ordinal = (ushort*)(codeBase + exports->AddressOfNameOrdinals);
                    ExportNameEntry[] entry = new ExportNameEntry[exports->NumberOfNames];
                    module.nameExportsTable = entry;
                    for (i = 0; i < exports->NumberOfNames; i++, nameRef++, ordinal++)
                        entry[i] = new ExportNameEntry
                        {
                            name = codeBase + (*nameRef),
                            idx = *ordinal
                        };
                    Array.Sort(module.nameExportsTable, _compare);
                }

                // search function name in list of exported names with binary search
                ExportNameEntry tmp = new ExportNameEntry { name = name };
                int foundIndex = Array.BinarySearch(module.nameExportsTable, tmp, tmp);
                found = foundIndex < 0 ? null : module.nameExportsTable[foundIndex];
                if (found == null)
                    // exported symbol not found
                    return null;

                idx = found.idx;
            }

            if (idx > exports->NumberOfFunctions)
                // name <. ordinal number don't match
                return null;

            // AddressOfFunctions contains the RVAs to the "real" functions
            return (void*)(codeBase + (*(uint*)(codeBase + exports->AddressOfFunctions + (idx * 4))));
        }
Пример #2
0
 private static int _compare(ExportNameEntry a, ExportNameEntry b)
 {
     return strcmp(a.name, b.name);
 }