Security

While bypassing the Security Patch to allow for an unrestricted access to the Outlook objects, Redemption does provide several layers of security to help you minimize a change of a rogue code using taking advantage of Redemption.

Renaming the DLL

AuthKey property

Customizing the DLL

Registry-free COM

Directly loading Redemption

 

  • Similar to registry-free COM, you can explicitly load Redemption library and create instances of its creatable objects without registering the dll in the registry or even using an application manifest. On the low level, all in-proc COM libraries (dlls) export DllGetClassObject function that the COM system uses after looking up the dll location through the class name/CLSID in the registry. Since you know the Redemption dll location, there is no reason to create any registry entries for the COM system. You will still need to register Redemption in the registry on your development machine to be able to import the type library and/or create the interop dll (in case of .Net languages). At run-time however, you can simply copy Redemption.dll/Redemption64.dll to the target folder.

                //tell the app where the 32 and 64 bit dlls are located

                //by default, they are assumed to be in the same folder as the current assembly and be named

                //Redemption.dll and Redemption64.dll.

                //In that case, you do not need to set the two properties below

                RedemptionLoader.DllLocation64Bit = @"c:\SourceCode\Redemption\redemption64.dll";

                RedemptionLoader.DllLocation32Bit = @"c:\SourceCode\Redemption\redemption.dll";

                //Create a Redemption object and use it

                RDOSession session = RedemptionLoader.new_RDOSession();

                session.Logon(Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);

    RedemptionLoader class can be downloaded here. Its full source code is also given below:

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.IO;

    using System.Reflection;

    using System.Runtime.InteropServices;

    using System.Runtime.InteropServices.ComTypes;

     

    namespace Redemption

    {

        public static class RedemptionLoader

        {

            #region public methods

            //64 bit dll location - defaults to <assemblydir>\Redemption64.dll

            public static string DllLocation64Bit;

            //32 bit dll location - defaults to <assemblydir>\Redemption.dll

            public static string DllLocation32Bit;

     

     

            //The only creatable RDO object - RDOSession

            public static RDOSession new_RDOSession()

            {

                return (RDOSession)NewRedemptionObject(new Guid("29AB7A12-B531-450E-8F7A-EA94C2F3C05F"));

            }

     

            //Safe*Item objects

            public static SafeMailItem new_SafeMailItem()

            {

                return (SafeMailItem)NewRedemptionObject(new Guid("741BEEFD-AEC0-4AFF-84AF-4F61D15F5526"));

            }

     

            public static SafeContactItem new_SafeContactItem()

            {

                return (SafeContactItem)NewRedemptionObject(new Guid("4FD5C4D3-6C15-4EA0-9EB9-EEE8FC74A91B"));

            }

     

            public static SafeAppointmentItem new_SafeAppointmentItem()

            {

                return (SafeAppointmentItem)NewRedemptionObject(new Guid("620D55B0-F2FB-464E-A278-B4308DB1DB2B"));

            }

     

            public static SafeTaskItem new_SafeTaskItem()

            {

                return (SafeTaskItem)NewRedemptionObject(new Guid("7A41359E-0407-470F-B3F7-7C6A0F7C449A"));

            }

     

            public static SafeJournalItem new_SafeJournalItem()

            {

                return (SafeJournalItem)NewRedemptionObject(new Guid("C5AA36A1-8BD1-47E0-90F8-47E7239C6EA1"));

            }

     

            public static SafeMeetingItem new_SafeMeetingItem()

            {

                return (SafeMeetingItem)NewRedemptionObject(new Guid("FA2CBAFB-F7B1-4F41-9B7A-73329A6C1CB7"));

            }

     

            public static SafePostItem new_SafePostItem()

            {

                return (SafePostItem)NewRedemptionObject(new Guid("11E2BC0C-5D4F-4E0C-B438-501FFE05A382"));

            }

     

            public static SafeReportItem new_SafeReportItem()

            {

                return (SafeReportItem)NewRedemptionObject(new Guid("D46BA7B2-899F-4F60-85C7-4DF5713F6F18"));

            }

     

            public static MAPIFolder new_MAPIFolder()

            {

                return (MAPIFolder)NewRedemptionObject(new Guid("03C4C5F4-1893-444C-B8D8-002F0034DA92"));

            }

     

            public static SafeCurrentUser new_SafeCurrentUser()

            {

                return (SafeCurrentUser)NewRedemptionObject(new Guid("7ED1E9B1-CB57-4FA0-84E8-FAE653FE8E6B"));

            }

     

            public static SafeDistList new_SafeDistList()

            {

                return (SafeDistList)NewRedemptionObject(new Guid("7C4A630A-DE98-4E3E-8093-E8F5E159BB72"));

            }

     

            public static AddressLists newAddressLists()

            {

                return (AddressLists)NewRedemptionObject(new Guid("37587889-FC28-4507-B6D3-8557305F7511"));

            }

     

            public static MAPITable new_MAPITable()

            {

                return (MAPITable)NewRedemptionObject(new Guid("A6931B16-90FA-4D69-A49F-3ABFA2C04060"));

            }

     

            public static MAPIUtils new_MAPIUtils()

            {

                return (MAPIUtils)NewRedemptionObject(new Guid("4A5E947E-C407-4DCC-A0B5-5658E457153B"));

            }

     

            public static SafeInspector new_SafeInspector()

            {

                return (SafeInspector)NewRedemptionObject(new Guid("ED323630-B4FD-4628-BC6A-D4CC44AE3F00"));

            }

     

            #endregion

     

     

            #region private methods

     

            static RedemptionLoader()

            {

                //default locations of the dlls

                string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

                DllLocation64Bit = string.Concat(path, @"\Redemption64.dll");

                DllLocation32Bit = string.Concat(path, @"\Redemption.dll");

            }

     

            /*

            static ~Loader()

            {

                if (!_redemptionDllHandle.Equals(IntPtr.Zero))

                {

                    IntPtr dllCanUnloadNowPtr = Win32NativeMethods.GetProcAddress(_redemptionDllHandle, "DllCanUnloadNow");

                    if (!dllCanUnloadNowPtr.Equals(IntPtr.Zero))

                    {

                        DllCanUnloadNow dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(dllCanUnloadNowPtr, typeof(DllCanUnloadNow));

                        if (dllCanUnloadNow() != 0) return; //there are still live objects returned by the dll, so we shoudl not unload the dll

                    }

                    Win32NativeMethods.FreeLibrary(_redemptionDllHandle);

                    _redemptionDllHandle = IntPtr.Zero;

                }

            }

            */

     

     

            [ComVisible(false)]

            [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000001-0000-0000-C000-000000000046")]

            private interface IClassFactory

            {

                void CreateInstance([MarshalAs(UnmanagedType.Interface)] object pUnkOuter, ref Guid refiid, [MarshalAs(UnmanagedType.Interface)] out object ppunk);

                void LockServer(bool fLock);

            }

     

            [ComVisible(false)]

            [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000000-0000-0000-C000-000000000046")]

            private interface IUnknown

            {

            }

     

            private delegate int DllGetClassObject(ref Guid ClassId, ref Guid InterfaceId, [Out, MarshalAs(UnmanagedType.Interface)] out object ppunk);

            private delegate int DllCanUnloadNow();

     

            //COM GUIDs

            private static Guid IID_IClassFactory = new Guid("00000001-0000-0000-C000-000000000046");

            private static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");

     

            //win32 functions to load\unload dlls and get a function pointer

            private class Win32NativeMethods

            {

                 [DllImport("kernel32.dll", CharSet=CharSet.Ansi)]

                 public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

     

                 [DllImport("kernel32.dll")]

                 public static extern bool FreeLibrary(IntPtr hModule);

     

                 [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]

                 public static extern IntPtr LoadLibraryW(string lpFileName);

            }

     

            //private variables

            private static IntPtr _redemptionDllHandle = IntPtr.Zero;

            private static IntPtr _DllGetClassObject = IntPtr.Zero;

     

            private static IUnknown NewRedemptionObject(Guid guid)

            {

                object res = null;

                IClassFactory ClassFactory;

                if (_redemptionDllHandle.Equals(IntPtr.Zero))

                {

                    string dllPath;

                    if (IntPtr.Size == 8) dllPath = DllLocation64Bit; else dllPath = DllLocation32Bit;

                    _redemptionDllHandle = Win32NativeMethods.LoadLibraryW(dllPath);

                    if (_redemptionDllHandle.Equals(IntPtr.Zero)) throw new Exception(string.Format("Could not load '{0}'\nMake sure the dll exists.", dllPath));

                    _DllGetClassObject = Win32NativeMethods.GetProcAddress(_redemptionDllHandle, "DllGetClassObject");

                    if (_DllGetClassObject.Equals(IntPtr.Zero)) throw new Exception("Could not retrieve a pointer to the 'DllGetClassObject' function exported by the dll");

                }

                DllGetClassObject dllGetClassObject = (DllGetClassObject)Marshal.GetDelegateForFunctionPointer(_DllGetClassObject, typeof(DllGetClassObject));

     

                Object unk;

                int hr = dllGetClassObject(ref guid, ref IID_IClassFactory, out unk);

                if (hr != 0) throw new Exception("DllGetClassObject failed");

                ClassFactory = unk as IClassFactory;

                ClassFactory.CreateInstance(null, ref IID_IUnknown, out res);

     

                return (res as IUnknown);

     

     

            }

     

            #endregion

     

        }

     

        public class RedemptionException : Exception

        {

        }

    }

     

     

     

     

  •