Example #1
0
        public PE(string fileName)
        {
            this.FileName = Path.GetFullPath(fileName);
            this.Uri      = new Uri(this.FileName);
            this.IsPEFile = false;

            try
            {
                this.fs = File.OpenRead(this.FileName);

                if (!CheckPEMagicBytes(this.fs))
                {
                    return;
                }

                this.peReader  = new PEReader(this.fs);
                this.PEHeaders = this.peReader.PEHeaders;

                this.IsPEFile = true;

                this.pImage = new SafePointer(this.peReader.GetEntireImage().GetContent().ToBuilder().ToArray());

                if (this.IsManaged)
                {
                    this.metadataReader = this.peReader.GetMetadataReader();
                }
            }
            catch (IOException e) { this.LoadException = e; }
            catch (BadImageFormatException e) { this.LoadException = e; }
            catch (UnauthorizedAccessException e) { this.LoadException = e; }
        }
Example #2
0
        public SafePointer RVA2VA(SafePointer rva)
        {
            // find which section is our rva in
            SectionHeader ish = new SectionHeader();

            foreach (SectionHeader sectionHeader in PEHeaders.SectionHeaders)
            {
                if ((rva.Address >= sectionHeader.VirtualAddress) &&
                    (rva.Address < sectionHeader.VirtualAddress + sectionHeader.SizeOfRawData))
                {
                    ish = sectionHeader;
                    break;
                }
            }

            if (ish.VirtualAddress == 0)
            {
                throw new InvalidOperationException("RVA does not belong to any section");
            }

            // calculate the VA
            rva.Address = (rva.Address - ish.VirtualAddress + ish.PointerToRawData);

            return(rva);
        }
Example #3
0
        public static object SafePointerToType(this SafePointer sp, ImageFieldData fi)
        {
            object res = null;

            switch (fi.Type)
            {
                case Type.BYTE: res = (byte)sp; break;
                case Type.SBYTE: res = (sbyte)(byte)sp; break;
                case Type.UINT16: res = (UInt16)sp; break;
                case Type.INT16: res = (Int16)(UInt16)sp; break;
                case Type.UINT32: res = (UInt32)sp; break;
                case Type.UINT64: res = (UInt64)sp; break;
                case Type.INT32: res = (Int32)(UInt32)sp; break;
                case Type.INT64: res = (Int64)(UInt64)sp; break;
                case Type.POINTER: res = new SafePointer(sp._array, sp._stream, (Int32)(UInt32)sp); break;
                case Type.HEADER: res = fi.Header.Create(fi.ParentHeader, sp); break;
                case Type.NATIVEINT:
                    PEHeader ioh = fi.ParentHeader;
                    if ((ioh != null) && (ioh.Magic == PEMagic.PE32Plus))
                        res = (UInt64)sp;
                    else
                        res = (UInt32)sp;
                    break;
                default: throw new Exception("Unknown type");
            }
            return res;
        }
Example #4
0
        public PE(string fileName)
        {
            FileName = Path.GetFullPath(fileName);
            Uri      = new Uri(FileName);
            IsPEFile = false;
            try
            {
                _fs = File.OpenRead(FileName);

                if (!CheckPEMagicBytes(_fs))
                {
                    return;
                }

                _peReader = new PEReader(_fs);
                PEHeaders = _peReader.PEHeaders;
                IsPEFile  = true;

                m_pImage = new SafePointer(_peReader.GetEntireImage().GetContent().ToBuilder().ToArray());

                if (IsManaged)
                {
                    _metadataReader = _peReader.GetMetadataReader();
                }
            }
            catch (IOException e) { LoadException = e; }
            catch (BadImageFormatException e) { LoadException = e; }
            catch (UnauthorizedAccessException e) { LoadException = e; }
        }
Example #5
0
        public PE(string fileName)
        {
            FileName = Path.GetFullPath(fileName);
            Uri = new Uri(FileName);
            IsPEFile = false;
            try
            {
                _fs = File.OpenRead(FileName);

                byte byteRead = (byte)_fs.ReadByte();
                if (byteRead != 'M') { return; }

                byteRead = (byte)_fs.ReadByte();
                if (byteRead != 'Z') { return; }
                _fs.Seek(0, SeekOrigin.Begin);

                _peReader = new PEReader(_fs);
                PEHeaders = _peReader.PEHeaders;
                IsPEFile = true;
            }
            catch (IOException e) { LoadException = e; }
            catch (BadImageFormatException e) { LoadException = e; }
            catch (UnauthorizedAccessException e) { LoadException = e; }

            if (IsPEFile)
            {
                m_pImage = new SafePointer(_peReader.GetEntireImage().GetContent().ToBuilder().ToArray());

                if (IsManaged)
                {
                    _metadataReader = _peReader.GetMetadataReader();
                }
            }
        }
Example #6
0
        public object GetField(int n)
        {
            object         res;
            ImageFieldData fi     = GetFieldInfo(n);
            int            count  = fi.Count;
            int            offset = GetFieldOffset(n);;
            Object         o;
            int            len;

            SafePointer sp = m_pHeader + offset;

            if (fi.VarLen)
            {
                // this assumes we can not have varlen arrays of headers
                count = GetFieldSize(n) / fi.GetTypeLen();
            }

            if (count == 1)
            {
                return(sp.SafePointerToType(fi));
            }

            // if a negative count is provided we tread it as an offset of
            // the field where to find the real count
            if (count < 0)
            {
                count = Convert.ToInt32(GetField(n + count));
            }

            res = new object[count];
            for (int i = 0; i < count; i++)
            {
                o = sp.SafePointerToType(fi);
                ((object[])res)[i] = o;
                if (o is ImageHeader)
                {
                    len = ((ImageHeader)o).Size;
                }
                else
                {
                    len = fi.GetTypeLen();
                }
                sp = sp + len;
            }

            return(res);
        }
Example #7
0
        public static object SafePointerToType(this SafePointer sp, ImageFieldData fi)
        {
            object res = null;

            switch (fi.Type)
            {
            case Type.BYTE: res = (byte)sp; break;

            case Type.SBYTE: res = (sbyte)(byte)sp; break;

            case Type.UINT16: res = (UInt16)sp; break;

            case Type.INT16: res = (Int16)(UInt16)sp; break;

            case Type.UINT32: res = (UInt32)sp; break;

            case Type.UINT64: res = (UInt64)sp; break;

            case Type.INT32: res = (Int32)(UInt32)sp; break;

            case Type.INT64: res = (Int64)(UInt64)sp; break;

            case Type.POINTER: res = new SafePointer(sp._array, sp._stream, (Int32)(UInt32)sp); break;

            case Type.HEADER: res = fi.Header.Create(fi.ParentHeader, sp); break;

            case Type.NATIVEINT:
                PEHeader ioh = fi.ParentHeader;
                if ((ioh != null) && (ioh.Magic == PEMagic.PE32Plus))
                {
                    res = (UInt64)sp;
                }
                else
                {
                    res = (UInt32)sp;
                }
                break;

            default: throw new Exception("Unknown type");
            }
            return(res);
        }
Example #8
0
        public PE(string fileName)
        {
            FileName = Path.GetFullPath(fileName);
            Uri      = new Uri(FileName);
            IsPEFile = false;
            try
            {
                _fs = File.OpenRead(FileName);

                byte byteRead = (byte)_fs.ReadByte();
                if (byteRead != 'M')
                {
                    return;
                }

                byteRead = (byte)_fs.ReadByte();
                if (byteRead != 'Z')
                {
                    return;
                }
                _fs.Seek(0, SeekOrigin.Begin);

                _peReader = new PEReader(_fs);
                PEHeaders = _peReader.PEHeaders;
                IsPEFile  = true;
            }
            catch (IOException e) { LoadException = e; }
            catch (BadImageFormatException e) { LoadException = e; }
            catch (UnauthorizedAccessException e) { LoadException = e; }

            if (IsPEFile)
            {
                m_pImage = new SafePointer(_peReader.GetEntireImage().GetContent().ToBuilder().ToArray());

                if (IsManaged)
                {
                    _metadataReader = _peReader.GetMetadataReader();
                }
            }
        }
Example #9
0
        public static object SafePointerToType(this SafePointer sp, ImageFieldData fi)
        {
            object res;

            switch (fi.Type)
            {
            case Type.BYTE: res = (byte)sp; break;

            case Type.SBYTE: res = (sbyte)(byte)sp; break;

            case Type.UINT16: res = (ushort)sp; break;

            case Type.INT16: res = (short)(ushort)sp; break;

            case Type.UINT32: res = (uint)sp; break;

            case Type.UINT64: res = (ulong)sp; break;

            case Type.INT32: res = (int)(uint)sp; break;

            case Type.INT64: res = (long)(ulong)sp; break;

            case Type.POINTER: res = new SafePointer(sp.array, sp.stream, (int)(uint)sp); break;

            case Type.HEADER: res = fi.Header.Create(fi.ParentHeader, sp); break;

            case Type.NATIVEINT:
                PEHeader ioh = fi.ParentHeader;
                res = ((ioh != null) && (ioh.Magic == PEMagic.PE32Plus))
                        ? (ulong)sp
                        : (uint)sp;
                break;

            default: throw new InvalidOperationException("Unknown type");
            }
            return(res);
        }
        private bool CookieOffsetValid(BinaryAnalyzerContext context, SafePointer boundsCheck)
        {
            if (boundsCheck.IsValid) { return true; }

            if (context.PE.IsPacked)
            {
                LogInvalidCookieOffsetForKnownPackedFile(context);
            }
            else
            {
                LogInvalidCookieOffset(context);
            }
            return false;
        }
        private bool Validate64BitImage(BinaryAnalyzerContext context)
        {
            PEHeader peHeader = context.PE.PEHeaders.PEHeader;
            SafePointer sp = new SafePointer(context.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress);
            SafePointer loadConfigVA = context.PE.RVA2VA(sp);
            ImageLoadConfigDirectory64 loadConfig = new ImageLoadConfigDirectory64(peHeader, loadConfigVA);

            UInt64 cookieVA = (UInt64)loadConfig.GetField(ImageLoadConfigDirectory64.Fields.SecurityCookie);
            UInt64 baseAddress = peHeader.ImageBase;

            // we need to find the offset in the file based on the cookie's VA
            UInt64 sectionSize, sectionVA = 0;
            SectionHeader ish = new SectionHeader();
            bool foundCookieSection = false;
            foreach (SectionHeader t in context.PE.PEHeaders.SectionHeaders)
            {
                sectionVA = (UInt64)(UInt32)t.VirtualAddress + baseAddress;
                sectionSize = (UInt32)t.VirtualSize;
                if ((cookieVA >= sectionVA) &&
                    (cookieVA < sectionVA + sectionSize))
                {
                    ish = t;
                    foundCookieSection = true;
                    break;
                }
            }

            if (!foundCookieSection)
            {
                LogCouldNotLocateCookie(context);
                return false;
            }

            UInt64 fileCookieOffset = (cookieVA - baseAddress) - (sectionVA - baseAddress) + (UInt32)ish.PointerToRawData;
            SafePointer fileCookiePtr = loadConfigVA;
            fileCookiePtr.Address = (int)fileCookieOffset;

            SafePointer boundsCheck = fileCookiePtr + 8;
            if (!CookieOffsetValid(context, boundsCheck))
            {
                return false;
            }

            if (!boundsCheck.IsValid && context.PE.IsPacked)
            {
                LogInvalidCookieOffsetForKnownPackedFile(context);
                return false;
            }

            UInt64 cookie = BitConverter.ToUInt64(fileCookiePtr.GetBytes(8), 0);

            if (cookie != StackProtectionUtilities.DefaultCookieX64)
            {
                LogFailure(context, cookie.ToString("x"));
                return false;
            }
            return true;
        }
Example #12
0
 public abstract ImageHeader Create(PEHeader parentHeader, SafePointer sp);
Example #13
0
 public ImageHeader(PEHeader parentHeader, SafePointer sp)
 {
     ParentHeader = parentHeader;
     m_pHeader = sp;
 }
        private bool Validate32BitImage(BinaryAnalyzerContext context)
        {
            PEHeader peHeader = context.PE.PEHeaders.PEHeader;
            SafePointer sp = new SafePointer(context.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress);
            SafePointer loadConfigVA = context.PE.RVA2VA(sp);
            ImageLoadConfigDirectory32 loadConfig = new ImageLoadConfigDirectory32(peHeader, loadConfigVA);

            UInt32 cookieVA = (UInt32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.SecurityCookie);
            UInt32 baseAddress = (UInt32)peHeader.ImageBase;

            // we need to find the offset in the file based on the cookie's VA
            UInt32 sectionSize, sectionVA = 0;
            SectionHeader ish = new SectionHeader();
            bool foundCookieSection = false;
            foreach (SectionHeader t in context.PE.PEHeaders.SectionHeaders)
            {
                sectionVA = (UInt32)t.VirtualAddress + baseAddress;
                sectionSize = (UInt32)t.VirtualSize;
                if ((cookieVA >= sectionVA) &&
                    (cookieVA < sectionVA + sectionSize))
                {
                    ish = t;
                    foundCookieSection = true;
                    break;
                }
            }

            if (!foundCookieSection)
            {
                // '{0}' is a C or C++binary that enables the stack protection feature but the security cookie could not be located. The binary may be corrupted.
                context.Logger.Log(MessageKind.Fail, context,
                        RuleUtilities.BuildMessage(context,
                            RulesResources.DoNotModifyStackProtectionCookie_CouldNotLocateCookie_Fail));
                return false;
            }

            UInt64 fileCookieOffset = (cookieVA - baseAddress) - (sectionVA - baseAddress) + (UInt32)ish.PointerToRawData;
            SafePointer fileCookiePtr = loadConfigVA;
            fileCookiePtr.Address = (int)fileCookieOffset;
            UInt32 cookie = BitConverter.ToUInt32(fileCookiePtr.GetBytes(8), 0);

            if (!StackProtectionUtilities.DefaultCookiesX86.Contains(cookie) && context.PE.Machine == Machine.I386)
            {
                // '{0}' is a C or C++ binary that interferes with the stack protector. The
                // stack protector (/GS) is a security feature of the compiler which makes
                // it more difficult to exploit stack buffer overflow memory corruption
                // vulnerabilities. The stack protector relies on a random number, called
                // the "security cookie", to detect these buffer overflows. This 'cookie'
                // is statically linked with your binary from a Visual C++ library in the
                // form of the symbol __security_cookie. On recent Windows versions, the
                // loader looks for the magic statically linked value of this cookie, and
                // initializes the cookie with a far better source of entropy -- the system's
                // secure random number generator -- rather than the limited random number
                // generator available early in the C runtime startup code. When this symbol
                // is not the default value, the additional entropy is not injected by the
                // operating system, reducing the effectiveness of the stack protector. To
                // resolve this issue, ensure that your code does not reference or create a
                // symbol named __security_cookie or __security_cookie_complement. NOTE:
                // the modified cookie value detected was: {1}
                context.Logger.Log(MessageKind.Fail, context,
                    RuleUtilities.BuildMessage(context,
                    RulesResources.DoNotModifyStackProtectionCookie_Fail, cookie.ToString("x")));
                return false;
            }

            return true;
        }
 public override ImageHeader Create(PEHeader parentHeader, SafePointer sp)
 {
     return new ImageLoadConfigDirectory32(parentHeader, sp);
 }
Example #16
0
 public abstract ImageHeader Create(PEHeader parentHeader, SafePointer sp);
        private bool Validate32BitImage(BinaryAnalyzerContext context)
        {
            PEHeader peHeader = context.PE.PEHeaders.PEHeader;
            SafePointer sp = new SafePointer(context.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress);
            SafePointer loadConfigVA = context.PE.RVA2VA(sp);
            ImageLoadConfigDirectory32 loadConfig = new ImageLoadConfigDirectory32(peHeader, loadConfigVA);

            UInt32 cookieVA = (UInt32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.SecurityCookie);
            UInt32 baseAddress = (UInt32)peHeader.ImageBase;

            // we need to find the offset in the file based on the cookie's VA
            UInt32 sectionSize, sectionVA = 0;
            SectionHeader ish = new SectionHeader();
            bool foundCookieSection = false;
            foreach (SectionHeader t in context.PE.PEHeaders.SectionHeaders)
            {
                sectionVA = (UInt32)t.VirtualAddress + baseAddress;
                sectionSize = (UInt32)t.VirtualSize;
                if ((cookieVA >= sectionVA) &&
                    (cookieVA < sectionVA + sectionSize))
                {
                    ish = t;
                    foundCookieSection = true;
                    break;
                }
            }

            if (!foundCookieSection)
            {
                LogCouldNotLocateCookie(context);
                return false;
            }

            UInt64 fileCookieOffset = (cookieVA - baseAddress) - (sectionVA - baseAddress) + (UInt32)ish.PointerToRawData;
            SafePointer fileCookiePtr = loadConfigVA;
            fileCookiePtr.Address = (int)fileCookieOffset;
            UInt32 cookie = BitConverter.ToUInt32(fileCookiePtr.GetBytes(8), 0);

            if (!StackProtectionUtilities.DefaultCookiesX86.Contains(cookie) && context.PE.Machine == Machine.I386)
            {
                LogFailure(context, cookie.ToString("x"));
                return false;
            }

            return true;
        }
Example #18
0
 public ImageHeader(PEHeader parentHeader, SafePointer sp)
 {
     ParentHeader = parentHeader;
     m_pHeader    = sp;
 }
Example #19
0
        public void Analyze(BinaryAnalyzerContext context)
        {
            PEHeader peHeader = context.PE.PEHeaders.PEHeader;

            /* IMAGE_DLLCHARACTERISTICS_NO_SEH */
            if ((peHeader.DllCharacteristics & DllCharacteristics.NoSeh) == DllCharacteristics.NoSeh)
            {
                // '{0}' is an x86 binary that does not use SEH, making it an invalid
                // target for exploits that attempt to replace SEH jump targets with
                // attacker-controlled shellcode.
                context.Logger.Log(MessageKind.Pass, context,
                    RuleUtilities.BuildMessage(context,
                        RulesResources.EnableSafeSEH_NoSEH_Pass));
                return;
            }

            // This will not raise false positives for non-C and C++ code, because the above
            // check for IMAGE_DLLCHARACTERISTICS_NO_SEH excludes things that don't actually
            // handle SEH exceptions like .NET ngen'd code.
            if (peHeader.LoadConfigTableDirectory.RelativeVirtualAddress == 0)
            {
                // '{0}' is an x86 binary which does not contain a load configuration table,
                // indicating that it does not enable the SafeSEH mitigation. SafeSEH makes
                // it more difficult to exploit memory corruption vulnerabilities that can
                // overwrite SEH control blocks on the stack, by verifying that the location
                // to which a thrown SEH exception would jump is indeed defined as an
                // exception handler in the source program (and not shellcode). To resolve
                // this issue, supply the /SafeSEH flag on the linker command line. Note
                // that you will need to configure your build system to supply this flag for
                // x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64.
                context.Logger.Log(MessageKind.Fail, context,
                    RuleUtilities.BuildMessage(context,
                        RulesResources.EnableSafeSEH_NoLoadConfigurationTable_Fail));
                return;
            }

            SafePointer sp = new SafePointer(context.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress);
            SafePointer loadConfigVA = context.PE.RVA2VA(sp);
            ImageLoadConfigDirectory32 loadConfig = new ImageLoadConfigDirectory32(peHeader, loadConfigVA);

            Int32 seHandlerSize = (Int32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.Size);
            if (seHandlerSize < 72)
            {
                // contains an unexpectedly small load configuration table {size 0}
                string seHandlerSizeText = String.Format(RulesResources.EnableSafeSEH_LoadConfigurationIsTooSmall_Fail, seHandlerSize.ToString());

                context.Logger.Log(MessageKind.Fail, context,
                    RuleUtilities.BuildMessage(context,
                        RulesResources.EnableSafeSEH_Formatted_Fail,
                        RulesResources.EnableSafeSEH_LoadConfigurationIsTooSmall_Fail,
                        seHandlerSizeText));
                return;
            }

            UInt32 seHandlerTable = (UInt32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.SEHandlerTable);
            UInt32 seHandlerCount = (UInt32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.SEHandlerCount);

            if (seHandlerTable == 0 || seHandlerCount == 0)
            {
                string failureKind = null;
                if (seHandlerTable == 0)
                {
                    // has an empty SE handler table in the load configuration table
                    failureKind = RulesResources.EnableSafeSEH_EmptySEHandlerTable_Fail;
                }
                else if (seHandlerCount == 0)
                {
                    // has zero SE handlers in the load configuration table
                    failureKind = RulesResources.EnableSafeSEH_ZeroCountSEHandlers_Fail;
                }

                // '{0}' is an x86 binary which {1}, indicating that it does not enable the SafeSEH
                // mitigation. SafeSEH makes it more difficult to exploit memory corruption
                // vulnerabilities that can overwrite SEH control blocks on the stack, by verifying
                // that the location to which a thrown SEH exception would jump is indeed defined
                // as an exception handler in the source program (and not shellcode). To resolve
                // this issue, supply the /SafeSEH flag on the linker command line. Note that you
                // will need to configure your build system to supply this flag for x86 builds only,
                // as the /SafeSEH flag is invalid when linking for ARM and x64.
                context.Logger.Log(MessageKind.Fail, context,
                    RuleUtilities.BuildMessage(context,
                        RulesResources.EnableSafeSEH_Formatted_Fail, failureKind));
                return;
            }

            // ''{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception
            // jump targets are defined as exception handlers in the program (and not shellcode).
            context.Logger.Log(MessageKind.Pass, context,
                RuleUtilities.BuildMessage(context,
                    RulesResources.EnableSafeSEH_SafeSEHEnabled_Pass));
        }
Example #20
0
 public ImageHeader(PEHeader parentHeader, SafePointer sp)
 {
     this.ParentHeader = parentHeader;
     this.m_pHeader    = sp;
 }
Example #21
0
        public SafePointer RVA2VA(SafePointer rva)
        {
            // find which section is our rva in
            SectionHeader ish = new SectionHeader();
            foreach (SectionHeader sectionHeader in PEHeaders.SectionHeaders)
            {
                if ((rva.Address >= sectionHeader.VirtualAddress) &&
                    (rva.Address < sectionHeader.VirtualAddress + sectionHeader.SizeOfRawData))
                {
                    ish = sectionHeader;
                    break;
                }
            }

            if (ish.VirtualAddress == 0) throw new InvalidOperationException("RVA does not belong to any section");

            // calculate the VA
            rva.Address = (int)(rva.Address - ish.VirtualAddress + ish.PointerToRawData);

            return rva;
        }
Example #22
0
 public ImageLoadConfigDirectory32(PEHeader parentHeader, SafePointer sp) : base(parentHeader, sp)
 {
 }
Example #23
0
        public int GetFieldSize(int n)
        {
            ImageFieldData fi      = GetFieldInfo(n);
            int            count   = fi.Count;
            int            padding = fi.PadTo;
            int            size;
            int            len;


            if (fi.VarLen)
            {
                SafePointer field_start = m_pHeader + GetFieldOffset(n);
                SafePointer field_end   = field_start;
                while ((byte)field_end != fi.TrailingByte)
                {
                    field_end++;
                }
                // if we have a VarLen and a PadTo specified we will make sure
                // we only skip up to PadTo trailing bytes
                if (padding != 0)
                {
                    padding = padding - (field_end.Address - m_pHeader.Address) % padding;
                }
                else
                {
                    padding = -1;
                }
                while (((byte)field_end == fi.TrailingByte) && (padding-- != 0))
                {
                    field_end++;
                }

                return(field_end - field_start);
            }

            if (fi.Type == Type.HEADER)
            {
                object o = GetField(n);
                if (o is Array)
                {
                    len = ((ImageHeader)((object[])o)[0]).Size;
                }
                else
                {
                    len = ((ImageHeader)o).Size;
                }
            }
            else
            {
                len = fi.GetTypeLen();
            }

            if (count == 1)
            {
                return(len);
            }

            // if a negative count is provided we tread it as an offset of
            // the field where to find the real count
            if (count < 0)
            {
                count = Convert.ToInt32(GetField(n + count));
            }

            size = len * count;

            // We don't pad is the size is already a multiple of padding
            if ((padding != 0) && (size % padding != 0))
            {
                size += padding - (size % padding);
            }

            return(size);
        }
Example #24
0
 public override ImageHeader Create(PEHeader parentHeader, SafePointer sp)
 {
     return(new ImageLoadConfigDirectory32(parentHeader, sp));
 }
        private bool EnablesControlFlowGuard(BinaryAnalyzerContext context)
        {
            PEHeader peHeader = context.PE.PEHeaders.PEHeader;
            if (((uint)peHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_CONTROLFLOWGUARD) == 0)
            {
                return false;
            }

            SafePointer loadConfigRVA = new SafePointer(context.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress);
            if (loadConfigRVA.Address == 0)
            {
                return false;
            }

            SafePointer loadConfigVA = context.PE.RVA2VA(loadConfigRVA);

            if (context.PE.Is64Bit)
            {
                ImageLoadConfigDirectory64 loadConfig = new ImageLoadConfigDirectory64(peHeader, loadConfigVA);

                Int32 imageDirectorySize = (Int32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.Size);
                UInt64 guardCFCheckFunctionPointer = (UInt64)loadConfig.GetField(ImageLoadConfigDirectory64.Fields.GuardCFCheckFunctionPointer);
                UInt64 guardCFFunctionTable = (UInt64)loadConfig.GetField(ImageLoadConfigDirectory64.Fields.GuardCFFunctionTable);
                UInt32 guardFlags = (UInt32)loadConfig.GetField(ImageLoadConfigDirectory64.Fields.GuardFlags);

                if (imageDirectorySize >= IMAGE_LOAD_CONFIG_MINIMUM_SIZE_64 &&
                    guardCFCheckFunctionPointer != 0 &&
                    guardCFFunctionTable != 0 &&
                    (guardFlags & IMAGE_GUARD_CF_CHECKS) == IMAGE_GUARD_CF_CHECKS)
                {
                    return true;
                }
            }
            else
            {
                ImageLoadConfigDirectory32 loadConfig = new ImageLoadConfigDirectory32(peHeader, loadConfigVA);

                Int32 imageDirectorySize = (Int32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.Size);
                UInt32 guardCFCheckFunctionPointer = (UInt32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.GuardCFCheckFunctionPointer);
                UInt32 guardCFFunctionTable = (UInt32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.GuardCFFunctionTable);
                UInt32 guardFlags = (UInt32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.GuardFlags);

                if (imageDirectorySize >= IMAGE_LOAD_CONFIG_MINIMUM_SIZE_32 &&
                    guardCFCheckFunctionPointer != 0 &&
                    guardCFFunctionTable != 0 &&
                    (guardFlags & IMAGE_GUARD_CF_CHECKS) == IMAGE_GUARD_CF_CHECKS)
                {
                    return true;
                }
            }

            return false;
        }
 public ImageLoadConfigDirectory32(PEHeader parentHeader, SafePointer sp) : base(parentHeader, sp)
 {
 }