private bool Validate32BitImage(BinaryAnalyzerContext context) { PEBinary target = context.PEBinary(); PEHeader peHeader = target.PE.PEHeaders.PEHeader; SafePointer sp = new SafePointer(target.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress); SafePointer loadConfigVA = target.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 target.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; SafePointer boundsCheck = fileCookiePtr + 4; if (!CookieOffsetValid(context, boundsCheck)) { return(false); } UInt32 cookie = BitConverter.ToUInt32(fileCookiePtr.GetBytes(4), 0); if (!StackProtectionUtilities.DefaultCookiesX86.Contains(cookie) && target.PE.Machine == Machine.I386) { LogFailure(context, cookie.ToString("x")); return(false); } return(true); }
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; UInt64 cookie = BitConverter.ToUInt64(fileCookiePtr.GetBytes(8), 0); if (cookie != StackProtectionUtilities.DefaultCookieX64) { LogFailure(context, cookie.ToString("x")); return(false); } return(true); }
private bool Validate64BitImage(BinaryAnalyzerContext context) { PEBinary target = context.PEBinary(); PEHeader peHeader = target.PE.PEHeaders.PEHeader; var sp = new SafePointer(target.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress); SafePointer loadConfigVA = target.PE.RVA2VA(sp); var loadConfig = new ImageLoadConfigDirectory64(peHeader, loadConfigVA); ulong cookieVA = (ulong)loadConfig.GetField(ImageLoadConfigDirectory64.Fields.SecurityCookie); ulong baseAddress = peHeader.ImageBase; // we need to find the offset in the file based on the cookie's VA ulong sectionSize, sectionVA = 0; var ish = new SectionHeader(); bool foundCookieSection = false; foreach (SectionHeader t in target.PE.PEHeaders.SectionHeaders) { sectionVA = (uint)t.VirtualAddress + baseAddress; sectionSize = (uint)t.VirtualSize; if ((cookieVA >= sectionVA) && (cookieVA < sectionVA + sectionSize)) { ish = t; foundCookieSection = true; break; } } if (!foundCookieSection) { this.LogCouldNotLocateCookie(context); return(false); } ulong fileCookieOffset = (cookieVA - baseAddress) - (sectionVA - baseAddress) + (uint)ish.PointerToRawData; SafePointer fileCookiePtr = loadConfigVA; fileCookiePtr.Address = (int)fileCookieOffset; SafePointer boundsCheck = fileCookiePtr + 8; if (!this.CookieOffsetValid(context, boundsCheck)) { return(false); } if (!boundsCheck.IsValid && target.PE.IsPacked) { this.LogInvalidCookieOffsetForKnownPackedFile(context); return(false); } ulong cookie = BitConverter.ToUInt64(fileCookiePtr.GetBytes(8), 0); if (cookie != StackProtectionUtilities.DefaultCookieX64) { this.LogFailure(context, cookie.ToString("x")); return(false); } return(true); }
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) { // '{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; UInt64 cookie = BitConverter.ToUInt64(fileCookiePtr.GetBytes(8), 0); if (cookie != StackProtectionUtilities.DefaultCookieX64) { // '{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); }