Example #1
0
            private IEnumerable <HarmonyImportLibrary> ResolveImports(Image image)
            {
                IMAGE_DATA_DIRECTORY directory = Environment.Is64BitProcess
                                        ? image.OptionalHeader64->ImportTable
                                        : image.OptionalHeader32->ImportTable;

                if (directory.Size == 0 || (_loadFlags & HarmonyLoadFlags.NoImports) != 0)
                {
                    return(Enumerable.Empty <HarmonyImportLibrary>());
                }

                Dictionary <string, HarmonyLibrary> otherLibraryLookup =
                    _otherLibraries.ToDictionary(l => (Path.GetFileName(l.Name) ?? l.Name).ToLowerInvariant());

                List <HarmonyImportLibrary> imports = new List <HarmonyImportLibrary>();

                IMAGE_IMPORT_DESCRIPTOR *importDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)(image.BasePtr + directory.VirtualAddress);

                for (; !Kernel32.IsBadReadPtr((UIntPtr)importDescriptor, (uint)sizeof(IMAGE_IMPORT_DESCRIPTOR)) &&
                     importDescriptor->Name != 0; importDescriptor++)
                {
                    HarmonyImportLibrary import = LoadImport(image.BasePtr, image.Size, importDescriptor, otherLibraryLookup, _loadFlags);

                    imports.Add(import);
                }

                return(imports);
            }
Example #2
0
        private void BuildImportTable()
        {
            IMAGE_DATA_DIRECTORY *directory = &this.headers->OptionalHeader.ImportTable;

            if (directory->Size > 0)
            {
                IMAGE_IMPORT_DESCRIPTOR *importDesc = (IMAGE_IMPORT_DESCRIPTOR *)(this.codeBase + directory->VirtualAddress);
                for (; !NativeDeclarations.IsBadReadPtr(new IntPtr(importDesc), (uint)Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR))) && importDesc->Name > 0; importDesc++)
                {
                    uint *thunkRef;
                    int * funcRef;

                    string funcName = Marshal.PtrToStringAnsi(new IntPtr(this.codeBase + importDesc->Name));
                    IntPtr handle   = NativeDeclarations.LoadLibrary(funcName);

                    if (handle == IntPtr.Zero)
                    {
                        throw new NativeDllLoadException("Can't load libary " + funcName);
                    }

                    this.modules.Add(handle);
                    if (importDesc->OriginalFirstThunk > 0)
                    {
                        thunkRef = (uint *)(codeBase + importDesc->OriginalFirstThunk);
                        funcRef  = (int *)(codeBase + importDesc->FirstThunk);
                    }
                    else
                    {
                        // no hint table
                        thunkRef = (uint *)(codeBase + importDesc->FirstThunk);
                        funcRef  = (int *)(codeBase + importDesc->FirstThunk);
                    }
                    for (; *thunkRef > 0; thunkRef++, funcRef++)
                    {
                        string procName;
                        if (NativeDeclarations.IMAGE_SNAP_BY_ORDINAL32(*thunkRef))
                        {
                            procName = Marshal.PtrToStringAnsi(new IntPtr(NativeDeclarations.IMAGE_ORDINAL32(*thunkRef)));
                            *funcRef = (int)NativeDeclarations.GetProcAddress(handle, procName);
                        }
                        else
                        {
                            IMAGE_IMPORT_BY_NAME *thunkData = (IMAGE_IMPORT_BY_NAME *)(codeBase + (*thunkRef));
                            procName = Marshal.PtrToStringAnsi(new IntPtr(thunkData->Name));
                            *funcRef = (int)NativeDeclarations.GetProcAddress(handle, procName);
                        }
                        if (*funcRef == 0)
                        {
                            throw new NativeDllLoadException("Can't get adress for " + procName);
                        }
                    }
                }
            }
        }
Example #3
0
        public computeImports(string path, DataTable table)
        {
            uint hLib = LoadLibraryEx(path, 0, 0);
            uint size = 0;
            IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)ImageDirectoryEntryToData((void *)hLib, true, 1, out size);

            if (hLib != 0 && pIID != null)
            {
                table.Columns.Add("import function", typeof(string));
                table.Columns.Add("address", typeof(string));
                table.Columns.Add("dll", typeof(string));
                table.Columns.Add("ordinal", typeof(string));
                while (pIID->OriginalFirstThunk != 0)
                {
                    char *      szName    = (char *)(hLib + pIID->Name);
                    string      name      = Marshal.PtrToStringAnsi((IntPtr)szName);
                    THUNK_DATA *pThunkOrg = (THUNK_DATA *)(hLib + pIID->OriginalFirstThunk);
                    while (pThunkOrg->AddressOfData != 0)
                    {
                        char *szImportName;
                        uint  Ord;
                        if ((pThunkOrg->Ordinal & 0x80000000) > 0)
                        {
                            Ord = pThunkOrg->Ordinal & 0xffff;
                            table.Rows.Add("", pThunkOrg->Function.ToString("X8"), name, Ord.ToString());
                        }
                        else
                        {
                            IMAGE_IMPORT_BY_NAME *pIBN = (IMAGE_IMPORT_BY_NAME *)(hLib + pThunkOrg->AddressOfData);
                            if (!IsBadReadPtr((void *)pIBN, (uint)sizeof(IMAGE_IMPORT_BY_NAME)))
                            {
                                Ord          = pIBN->Hint;
                                szImportName = (char *)pIBN->Name;
                                string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName);
                                table.Rows.Add(sImportName, pThunkOrg->Function.ToString("X8"), name, Ord.ToString());
                            }
                            else
                            {
                                break;
                            }
                        }
                        pThunkOrg++;
                    }
                    pIID++;
                }
                table.DefaultView.Sort = "import function";
            }
        }
Example #4
0
            private static HarmonyImportLibrary LoadImport(byte *basePtr, uint size, IMAGE_IMPORT_DESCRIPTOR *importDescriptor,
                                                           Dictionary <string, HarmonyLibrary> otherLibraryLookup, HarmonyLoadFlags loadFlags)
            {
                string moduleName = StringOperations.NulTerminatedBytesToString(basePtr + importDescriptor->Name, basePtr, size);

                HarmonyLibrary otherLibrary;

                if (otherLibraryLookup.TryGetValue(moduleName.ToLowerInvariant(), out otherLibrary))
                {
                    return(LoadHarmonyImport(basePtr, size, importDescriptor, otherLibrary));
                }

                if ((loadFlags & HarmonyLoadFlags.PrivateImports) == 0)
                {
                    return(LoadExternalDllImport(basePtr, size, importDescriptor, moduleName));
                }

                return(null);
            }
 public ImportsParser(string executable, List <string> errorMessages)
 {
     fixed(LOADED_IMAGE *fixedLoadedImage = &_loadedImage)
     {
         if (MapAndLoad(executable, null, fixedLoadedImage, true, true))
         {
             uint size = 0u;
             IMAGE_IMPORT_DESCRIPTOR *directoryEntryPtr = ImageDirectoryEntryToData(fixedLoadedImage->MappedAddress, 0, 1, &size);
             IMAGE_IMPORT_DESCRIPTOR  directoryEntry    = *directoryEntryPtr;
             while (directoryEntry.OriginalFirstThunk != 0u)
             {
                 Imports.Add(GetString(directoryEntry.Name));
                 directoryEntryPtr++;
                 directoryEntry = *directoryEntryPtr;
             }
             if (!UnMapAndLoad(ref _loadedImage))
             {
                 errorMessages.Add("UnMapAndLoad failed!");
             }
         }
     }
 }
Example #6
0
        public MyObject Load64Imports(MyObject myObject, string filePath, bool mappedAsImage)
        {
            var hLib = LoadLibrary(filePath);

            if (hLib == null)
            {
                var errorCode = GetLastError();
            }
            PeHeaderReader reader = new PeHeaderReader(filePath);

            List <ImportFunctionObject> objList = myObject.FunctionObjectList;

            Console.WriteLine("1st function list");
            unsafe
            {
                void *hMod = (void *)hLib;

                ulong size        = 0;
                ulong BaseAddress = (ulong)hMod;

                if (hMod != null)
                {
                    IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)Interop.ImageDirectoryEntryToData((void *)hMod, mappedAsImage, Interop.IMAGE_DIRECTORY_ENTRY_IMPORT, out size);

                    if (pIID != null)
                    {
                        // walk the array until find the end of the array
                        while (pIID->OriginalFirstThunk != 0)
                        {
                            try
                            {
                                //Name contains the RVA to the name of the dll.
                                //Thus convert it to a virtual address first.
                                char *szName = (char *)(BaseAddress + pIID->Name);

                                IntPtr result = new IntPtr(szName);
                                string name   = Marshal.PtrToStringAnsi(result);

                                if (!name.Contains("api-ms-win"))
                                {
                                    // value in OriginalFirstThunk is an RVA.
                                    // convert it to virtual address.
                                    THUNK_DATA64 *pThunkOrg = (THUNK_DATA64 *)(BaseAddress + pIID->OriginalFirstThunk);
                                    while (pThunkOrg->AddressOfData != 0)
                                    {
                                        char *szImportName;
                                        ulong Ord;

                                        if ((pThunkOrg->Ordinal & 0x8000000000000000) > 0)
                                        {
                                            Ord = pThunkOrg->Ordinal & 0xffffffff;
                                        }
                                        else
                                        {
                                            IMAGE_IMPORT_BY_NAME64 *pIBN = (IMAGE_IMPORT_BY_NAME64 *)(BaseAddress + pThunkOrg->AddressOfData);

                                            if (!Interop.IsBadReadPtr((void *)pIBN, (ulong)sizeof(IMAGE_IMPORT_BY_NAME64)))
                                            {
                                                Ord          = pIBN->Hint;
                                                szImportName = (char *)pIBN->Name;
                                                string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName);

                                                UInt64 Address = pThunkOrg->Function;

                                                objList.Add(new ImportFunctionObject(sImportName, Address, name));
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }
                                        pThunkOrg++;
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                System.Diagnostics.Debug.WriteLine("An Access violation occured\n" +
                                                                   "this seems to suggest the end of the imports section\n");
                                System.Diagnostics.Debug.WriteLine(e);
                            }
                            //pIID.size = 40;
                            pIID++;
                        }
                    }
                }
            }
            Console.WriteLine("2nd function list");

            return(myObject);
        }
Example #7
0
        // using mscoree.dll as an example as it doesnt export any thing
        // so nothing shows up when use the own module.
        // and the only none delayload in mscoree.dll is the Kernel32.dll
        private static void LoadImports(uint hLib, bool mappedAsImage)
        {
            unsafe
            {
                {
                    void *hMod = (void *)hLib;

                    uint size        = 0;
                    uint BaseAddress = (uint)hMod;

                    if (hMod != null)
                    {
                        IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)Interop.ImageDirectoryEntryToData((void *)hMod, mappedAsImage, Interop.IMAGE_DIRECTORY_ENTRY_IMPORT, out size);
                        if (pIID != null)
                        {
                            Console.WriteLine("Got Image Import Descriptor");
                            //walk the array until find the end of the array
                            while (pIID->OriginalFirstThunk != 0)
                            {
                                try
                                {
                                    //Name contains the RVA to the name of the dll.
                                    //Thus convert it to a virtual address first
                                    char * szName = (char *)(BaseAddress + pIID->Name);
                                    string name   = Marshal.PtrToStringAnsi((IntPtr)szName);
                                    Console.WriteLine("pIID->Name = {0} BaseAddress - {1}", name, (uint)BaseAddress);
                                    // value in OriginalFirstThunk is an RVA.
                                    // convert it to virtual address.
                                    THUNK_DATA *pThunkOrg = (THUNK_DATA *)(BaseAddress + pIID->OriginalFirstThunk);

                                    while (pThunkOrg->AddressOfData != 0)
                                    {
                                        char *szImportName;
                                        uint  Ord;

                                        if ((pThunkOrg->Ordinal & 0x80000000) > 0)
                                        {
                                            Ord = pThunkOrg->Ordinal & 0xffff;
                                            Console.WriteLine("imports ({0}).Ordinal{1} - Address: {2}", name, Ord, pThunkOrg->Function);
                                        }
                                        else
                                        {
                                            IMAGE_IMPORT_BY_NAME *pIBN = (IMAGE_IMPORT_BY_NAME *)(BaseAddress + pThunkOrg->AddressOfData);

                                            if (!Interop.IsBadReadPtr((void *)pIBN, (uint)sizeof(IMAGE_IMPORT_BY_NAME)))
                                            {
                                                Ord          = pIBN->Hint;
                                                szImportName = (char *)pIBN->Name;
                                                string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName); // yes i know i am a lazy ass
                                                Console.WriteLine("imports ({0}).{1}@{2} - Address: {3}", name, sImportName, Ord, pThunkOrg->Function);
                                            }
                                            else
                                            {
                                                Console.WriteLine("Bad ReadPtr Detected or EOF on Imports");
                                                break;
                                            }
                                        }

                                        pThunkOrg++;
                                    }
                                }
                                catch (AccessViolationException e)
                                {
                                    Console.WriteLine("An Access violation occured\n" +
                                                      "this seems to suggest the end of the imports section\n");
                                    Console.WriteLine(e);
                                }

                                pIID++;
                            }
                        }
                    }
                }
            }
        }
Example #8
0
        /// <summary>
        /// 填充导入表
        /// </summary>
        /// <param name="pPEHeader"></param>
        private unsafe void FillImportTable(IMAGE_NT_HEADERS *pPEHeader)
        {
#if _WIN64
            var iOffset = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).VirtualAddress;
            if (iOffset == 0)
            {
                return;
            }

            if (pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).Size == 0)
            {
                return;
            }

            IMAGE_IMPORT_DESCRIPTOR *pImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)((IntPtr)((Int64)this.mModuleHandle + (Int64)iOffset));
            while (pImportDescriptor->Name != 0)
            {
                UInt64 *pRealIAT     = (UInt64 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pImportDescriptor->FirstThunk));
                UInt64 *pOriginalIAT = (UInt64 *)((IntPtr)((Int64)this.mModuleHandle + (pImportDescriptor->OriginalFirstThunk == 0 ? (Int64)pImportDescriptor->FirstThunk : (Int64)pImportDescriptor->OriginalFirstThunk)));
                var     sDllName     = Marshal.PtrToStringAnsi((IntPtr)((Int64)this.mModuleHandle + (Int64)pImportDescriptor->Name));

                var hDll = Win32API.GetModuleHandle(sDllName);
                if (hDll == IntPtr.Zero)
                {
                    hDll = Win32API.LoadLibrary(sDllName);
                }

                if (hDll == IntPtr.Zero)
                {
                    throw new Exception(String.Format("load library({0}) fail", sDllName));
                }

                while (*pOriginalIAT != 0)
                {
                    IntPtr lpFunction = IntPtr.Zero;
                    if ((*pOriginalIAT & Win32API.IMAGE_ORDINAL_FLAG) == Win32API.IMAGE_ORDINAL_FLAG) // 最高位是1
                    {
                        var iFuncID = *pOriginalIAT & 0x0000FFFF;
                        lpFunction = Win32API.GetProcAddress(hDll, (IntPtr)((Int32)iFuncID));
                    }
                    else
                    {
                        //var sFuncName = Marshal.PtrToStringAnsi((IntPtr)((Int64)this.mModuleHandle + (Int64)(*pOriginalIAT) + 2));
                        lpFunction = Win32API.GetProcAddress(hDll, (IntPtr)((Int64)this.mModuleHandle + (Int64)(*pOriginalIAT) + 2));
                    }
                    if (lpFunction != IntPtr.Zero)
                    {
                        *pRealIAT = (UInt64)lpFunction;
                    }
                    pRealIAT++;
                    pOriginalIAT++;
                }
                pImportDescriptor++;
            }
#else
            var iOffset = pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).VirtualAddress;
            if (iOffset == 0)
            {
                return;
            }

            if (pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_IMPORT).Size == 0)
            {
                return;
            }

            IMAGE_IMPORT_DESCRIPTOR *pImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)(this.mModuleHandle + (Int32)iOffset);
            while (pImportDescriptor->Name != 0)
            {
                UInt32 *pRealIAT     = (UInt32 *)(this.mModuleHandle + (Int32)pImportDescriptor->FirstThunk);
                UInt32 *pOriginalIAT = (UInt32 *)(this.mModuleHandle + (pImportDescriptor->OriginalFirstThunk == 0 ? (Int32)pImportDescriptor->FirstThunk : (Int32)pImportDescriptor->OriginalFirstThunk));
                var     sDllName     = Marshal.PtrToStringAnsi(this.mModuleHandle + (Int32)pImportDescriptor->Name);

                var hDll = Win32API.GetModuleHandle(sDllName);
                if (hDll == IntPtr.Zero)
                {
                    hDll = Win32API.LoadLibrary(sDllName);
                }

                if (hDll == IntPtr.Zero)
                {
                    throw new Exception(String.Format("load library({0}) fail", sDllName));
                }

                while (*pOriginalIAT != 0)
                {
                    IntPtr lpFunction = IntPtr.Zero;
                    if ((*pOriginalIAT & Win32API.IMAGE_ORDINAL_FLAG) == Win32API.IMAGE_ORDINAL_FLAG) // 最高位是1
                    {
                        var iFuncID = *pOriginalIAT & 0x0000FFFF;
                        lpFunction = Win32API.GetProcAddress(hDll, (IntPtr)((Int32)iFuncID));
                    }
                    else
                    {
                        //var sFuncName = Marshal.PtrToStringAnsi(this.mModuleHandle + (Int32)(*pOriginalIAT) + 2);
                        lpFunction = Win32API.GetProcAddress(hDll, this.mModuleHandle + (Int32)(*pOriginalIAT) + 2);
                    }
                    if (lpFunction != IntPtr.Zero)
                    {
                        *pRealIAT = (UInt32)lpFunction;
                    }
                    pRealIAT++;
                    pOriginalIAT++;
                }
                pImportDescriptor++;
            }
#endif
        }
Example #9
0
        // using mscoree.dll as an example as it doesnt export any thing
        // so nothing shows up if you use your own module.
        // and the only none delayload in mscoree.dll is the Kernel32.dll
        private static void TestImports(uint hLib, bool mappedAsImage)
        {
            unsafe
            {
                //fixed (char* pszModule = "mscoree.dll")
                {
                    //void* hMod = Interop.GetModuleHandleW(pszModule);
                    void *hMod = (void *)hLib;

                    uint size        = 0;
                    uint BaseAddress = (uint)hMod;

                    if (hMod != null)
                    {
                        Console.WriteLine("Got handle");

                        IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)Interop.ImageDirectoryEntryToData((void *)hMod, mappedAsImage, Interop.IMAGE_DIRECTORY_ENTRY_IMPORT, out size);
                        if (pIID != null)
                        {
                            Console.WriteLine("Got Image Import Descriptor");
                            while (pIID->OriginalFirstThunk != 0)
                            {
                                try
                                {
                                    char * szName = (char *)(BaseAddress + pIID->Name);
                                    string name   = Marshal.PtrToStringAnsi((IntPtr)szName);
                                    Console.WriteLine("pIID->Name = {0} BaseAddress - {1}", name, (uint)BaseAddress);

                                    THUNK_DATA *pThunkOrg = (THUNK_DATA *)(BaseAddress + pIID->OriginalFirstThunk);

                                    while (pThunkOrg->AddressOfData != 0)
                                    {
                                        char *szImportName;
                                        uint  Ord;

                                        if ((pThunkOrg->Ordinal & 0x80000000) > 0)
                                        {
                                            Ord = pThunkOrg->Ordinal & 0xffff;
                                            Console.WriteLine("imports ({0}).Ordinal{1} - Address: {2}", name, Ord, pThunkOrg->Function);
                                        }
                                        else
                                        {
                                            IMAGE_IMPORT_BY_NAME *pIBN = (IMAGE_IMPORT_BY_NAME *)(BaseAddress + pThunkOrg->AddressOfData);

                                            if (!Interop.IsBadReadPtr((void *)pIBN, (uint)sizeof(IMAGE_IMPORT_BY_NAME)))
                                            {
                                                Ord          = pIBN->Hint;
                                                szImportName = (char *)pIBN->Name;
                                                string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName);     // yes i know i am a lazy ass
                                                Console.WriteLine("imports ({0}).{1}@{2} - Address: {3}", name, sImportName, Ord, pThunkOrg->Function);
                                            }
                                            else
                                            {
                                                Console.WriteLine("Bad ReadPtr Detected or EOF on Imports");
                                                break;
                                            }
                                        }

                                        pThunkOrg++;
                                    }
                                }
                                catch (AccessViolationException e)
                                {
                                    Console.WriteLine("An Access violation occured\n" +
                                                      "this seems to suggest the end of the imports section\n");
                                    Console.WriteLine(e);
                                }

                                pIID++;
                            }
                        }
                    }
                }
            }

            Console.WriteLine("Press Any Key To Continue......");
            Console.ReadKey();
        }
Example #10
0
            private static HarmonyImportLibrary ApplyImportLibrary(byte *basePtr, uint size, IMAGE_IMPORT_DESCRIPTOR *importDescriptor,
                                                                   string moduleName, HarmonyImportLibraryKind importLibraryKind,
                                                                   Func <string, IntPtr> getImportByName, Func <ushort, IntPtr> getImportByOrdinal)
            {
                const uint  ImageOrdinalFlag32 = 0x80000000U;
                const ulong ImageOrdinalFlag64 = 0x8000000000000000UL;

                List <HarmonyImport> importThunks = new List <HarmonyImport>();

                UIntPtr thunkRef;
                UIntPtr funcRef;

                if (importDescriptor->OriginalFirstThunk != 0)
                {
                    thunkRef = (UIntPtr)(basePtr + importDescriptor->OriginalFirstThunk);
                    funcRef  = (UIntPtr)(basePtr + importDescriptor->FirstThunk);
                }
                else
                {
                    // No hint table.
                    thunkRef = (UIntPtr)(basePtr + importDescriptor->FirstThunk);
                    funcRef  = (UIntPtr)(basePtr + importDescriptor->FirstThunk);
                }

                bool is64BitMode = Environment.Is64BitProcess;
                uint thunk;

                for (; (thunk = *(uint *)thunkRef) != 0; thunkRef += sizeof(UIntPtr), funcRef += sizeof(UIntPtr))
                {
                    IntPtr procAddress;
                    if (!is64BitMode && (thunk & ImageOrdinalFlag32) != 0 ||
                        is64BitMode && (thunk & ImageOrdinalFlag64) != 0)
                    {
                        procAddress = getImportByOrdinal((ushort)(thunk & 0xFFFF));

                        if (procAddress == IntPtr.Zero)
                        {
                            throw new LoadFailedException(string.Format("Unable to dependent library \"{0}\" is missing required import ordinal {1}.", moduleName, thunk & 0xFFFF));
                        }

                        *(IntPtr *)funcRef = procAddress;

                        importThunks.Add(new HarmonyImport((int)(thunk & 0xFFFF), null, procAddress));
                    }
                    else
                    {
                        IMAGE_IMPORT_BY_NAME *thunkData = (IMAGE_IMPORT_BY_NAME *)(basePtr + thunk);
                        string thunkName = StringOperations.NulTerminatedBytesToString((byte *)thunkData + 2, basePtr, size);
                        procAddress = getImportByName(thunkName);

                        if (procAddress == IntPtr.Zero)
                        {
                            throw new LoadFailedException(string.Format("Unable to dependent library \"{0}\" is missing required import \"{1}\".", moduleName, thunkName));
                        }

                        *(IntPtr *)funcRef = procAddress;

                        importThunks.Add(new HarmonyImport(null, thunkName, procAddress));
                    }
                }

                return(new HarmonyImportLibrary(importLibraryKind, moduleName, importThunks));
            }
Example #11
0
            private static HarmonyImportLibrary LoadExternalDllImport(byte *basePtr, uint size, IMAGE_IMPORT_DESCRIPTOR *importDescriptor, string moduleName)
            {
                IntPtr moduleHandle = Kernel32.LoadLibrary(moduleName);

                if (moduleHandle == IntPtr.Zero)
                {
                    int       lastError = Marshal.GetLastWin32Error();
                    Exception innerEx   = new Win32Exception(lastError);
                    innerEx.Data.Add("LastWin32Error", lastError);
                    throw new LoadFailedException(string.Format("Unable to load dependent library \"{0}\".", moduleName), innerEx);
                }

                HarmonyImportLibrary importLibrary = ApplyImportLibrary(
                    basePtr, size, importDescriptor, moduleName, HarmonyImportLibraryKind.ExternalDll,
                    name => Kernel32.GetProcAddress(moduleHandle, name),
                    ordinal => Kernel32.GetProcAddressOrdinal(moduleHandle, (IntPtr)ordinal)
                    );

                return(importLibrary);
            }
Example #12
0
            private static HarmonyImportLibrary LoadHarmonyImport(byte *basePtr, uint size, IMAGE_IMPORT_DESCRIPTOR *importDescriptor, HarmonyLibrary library)
            {
                HarmonyImportLibrary importLibrary = ApplyImportLibrary(
                    basePtr, size, importDescriptor, library.Name, HarmonyImportLibraryKind.HarmonyLibrary,
                    library.GetProcAddress, library.GetProcAddressByOrdinal
                    );

                return(importLibrary);
            }
Example #13
0
        // using mscoree.dll as an example as it doesnt export any thing
        // so nothing shows up when use the own module.
        // and the only none delayload in mscoree.dll is the Kernel32.dll
        /// <summary>
        /// return the imported dlls and functions from them
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="mappedAsImage"></param>
        /// <returns></returns>
        private void LoadImports(string filePath, bool mappedAsImage, List <ImportFunctionObject> ImportFunctions, List <String> ImportNames)
        {
            var hLib = LoadLibrary(filePath);

            if (hLib == null)
            {
                var errorCode = GetLastError();
            }
            //var hLib = LoadLibraryEx(filePath, 0,
            //                   DONT_RESOLVE_DLL_REFERENCES | LOAD_IGNORE_CODE_AUTHZ_LEVEL);

            unsafe
            {
                {
                    void *hMod        = (void *)hLib;
                    uint  size        = 0;
                    uint  BaseAddress = (uint)hMod;
                    if (hMod != null)
                    {
                        IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)Interop.ImageDirectoryEntryToData((void *)hMod, mappedAsImage, Interop.IMAGE_DIRECTORY_ENTRY_IMPORT, out size);
                        if (pIID != null)
                        {
                            //walk the array until find the end of the array
                            while (pIID->OriginalFirstThunk != 0)
                            {
                                try
                                {
                                    //Name contains the RVA to the name of the dll.
                                    //Thus convert it to a virtual address first.
                                    char * szName = (char *)(BaseAddress + pIID->Name);
                                    string name   = Marshal.PtrToStringAnsi((IntPtr)szName);
                                    if (!name.Contains("api-ms-win"))
                                    {
                                        ImportNames.Add(name);
                                        // value in OriginalFirstThunk is an RVA.
                                        // convert it to virtual address.
                                        THUNK_DATA *pThunkOrg = (THUNK_DATA *)(BaseAddress + pIID->OriginalFirstThunk);
                                        while (pThunkOrg->AddressOfData != 0)
                                        {
                                            char *szImportName;
                                            uint  Ord;

                                            if ((pThunkOrg->Ordinal & 0x80000000) > 0)
                                            {
                                                Ord = pThunkOrg->Ordinal & 0xffff;
                                            }
                                            else
                                            {
                                                IMAGE_IMPORT_BY_NAME *pIBN = (IMAGE_IMPORT_BY_NAME *)(BaseAddress + pThunkOrg->AddressOfData);

                                                if (!Interop.IsBadReadPtr((void *)pIBN, (uint)sizeof(IMAGE_IMPORT_BY_NAME)))
                                                {
                                                    Ord          = pIBN->Hint;
                                                    szImportName = (char *)pIBN->Name;
                                                    string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName);

                                                    UInt32 Address = pThunkOrg->Function;

                                                    ImportFunctions.Add(new ImportFunctionObject(sImportName, Address, name));
                                                }
                                                else
                                                {
                                                    break;
                                                }
                                            }
                                            pThunkOrg++;
                                        }
                                    }
                                    //else
                                    //{
                                    //    smartSuggestionEngine.readErrorCode(name, 7);
                                    //}
                                }
                                catch (Exception e)
                                {
                                    System.Diagnostics.Debug.WriteLine("An Access violation occured\n" +
                                                                       "this seems to suggest the end of the imports section\n");
                                    System.Diagnostics.Debug.WriteLine(e);
                                }
                                pIID++;
                            }
                        }
                    }
                }
            }
            return;
        }
        private void BuildImportTable()
        {
            IMAGE_DATA_DIRECTORY *directory = &_headers->OptionalHeader.ImportTable;

            if (directory->Size == 0)
            {
                throw new NativeDllLoadException("Invalid import table.");
            }


            IMAGE_IMPORT_DESCRIPTOR *importDesc = (IMAGE_IMPORT_DESCRIPTOR *)(_codeBase + directory->VirtualAddress);

            for (; !Win.IsBadReadPtr((importDesc), (UIntPtrT)Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR))) && importDesc->Name > 0; importDesc++)
            {
                UIntPtrT *thunkRef;
                Farproc * funcRef;

                HCoustomMudule handle = Win.LoadLibrary(_codeBase + importDesc->Name);

                if (InvalidHandle(handle))
                {
                    if (_modules.Any())
                    {
                        _modules.ForEach(m => Win.FreeLibrary(m));
                    }

                    throw new NativeDllLoadException("Can't load libary " + Marshal.PtrToStringAnsi(new IntPtr(_codeBase + importDesc->Name)));
                }

                _modules.Add(handle);
                if (importDesc->OriginalFirstThunk > 0)
                {
                    thunkRef = (UIntPtrT *)(_codeBase + importDesc->OriginalFirstThunk);
                    funcRef  = (Farproc *)(_codeBase + importDesc->FirstThunk);
                }
                else
                {
                    // no hint table
                    thunkRef = (UIntPtrT *)(_codeBase + importDesc->FirstThunk);
                    funcRef  = (Farproc *)(_codeBase + importDesc->FirstThunk);
                }
                for (; *thunkRef > 0; thunkRef++, funcRef++)
                {
                    string procName;
                    if (Win.IMAGE_SNAP_BY_ORDINAL(*thunkRef))
                    {
                        procName = Marshal.PtrToStringAnsi(new IntPtr());
                        *funcRef = (Farproc)Win.GetProcAddress(handle, (byte *)Win.IMAGE_ORDINAL(*thunkRef));
                    }
                    else
                    {
                        IMAGE_IMPORT_BY_NAME *thunkData = (IMAGE_IMPORT_BY_NAME *)(_codeBase + (*thunkRef));
                        *funcRef = (Farproc)Win.GetProcAddress(handle, thunkData->Name);
                    }
                    if (*funcRef == 0)
                    {
                        throw new NativeDllLoadException("Can't get adress for imported function.");
                    }
                }
            }
        }