Two parallel SMD capacitors with the left D72 capacitor confirmed internally shorted
Two SMD capacitors positioned vertically in parallel next to each other on the circuit board. The capacitor on the left, marked D72, appears visually normal but testing confirms that it has failed internally and is shorted. This repair image is an independent work sample and is not an illustration of the educational subject discussed below.

Understanding Control Flow Guard

A Program Is Supposed to Follow a Predictable Path

Software does not execute every instruction in one uninterrupted line.

Programs continually call functions, return from them, evaluate conditions, and transfer execution to different locations in memory. Those movements form the control flow of the program.

Under normal conditions, those destinations are determined by the software’s design.

Execution Has Intended Destinations

A legitimate application may contain thousands of possible code paths, but that does not mean every byte of executable memory is a valid destination for every indirect function call.

An Attacker Did Not Always Need to Inject an Entire New Program

Memory-corruption vulnerabilities can allow data to overwrite information the application depends on.

If the corrupted information includes a function pointer or another value controlling where execution continues, an attacker may attempt to redirect the program away from its intended destination.

The legitimate application can become the vehicle for the attack.

Changing Data Can Change Execution

A memory-safety flaw becomes especially dangerous when corrupted data influences an address the processor later uses to decide which code should execute next.

Writing Beyond a Boundary Could Damage Something More Important

A buffer is allocated a particular amount of memory for data.

If vulnerable software accepts more information than that area can safely contain, the excess data may overwrite neighboring memory. Depending on what resides there, the corruption can affect application state, pointers, or other structures involved in execution.

The overflow itself is only the beginning of the exploit.

Corruption Creates the Opportunity

The attacker’s objective is often not merely to crash the application but to manipulate corrupted memory in a way that changes what the program does next.

DEP Made Data Memory a Less Convenient Place to Execute Code

Data Execution Prevention helped separate memory intended to contain data from memory intended to contain executable instructions.

That made a traditional technique—placing malicious instructions into writable memory and executing them directly—more difficult on protected systems.

Attackers adapted rather than disappearing.

Mitigations Change the Attacker’s Options

A successful defense does not need to eliminate every vulnerability to be valuable. Making a common exploitation technique unreliable can force an attacker toward more complicated alternatives.

Known Addresses Could Stop Being Predictable

Address Space Layout Randomization changes where executable modules and other memory regions appear.

If an exploit depends on code existing at a predictable address, randomization can interfere with that assumption. Attackers may then need an additional vulnerability or information leak to discover useful addresses.

Again, exploitation became harder but not impossible.

Knowing What Code Exists Is Different From Knowing Where It Is

ASLR reduces the reliability of exploits that depend on fixed memory locations by changing the layout attackers expect to find when the program runs.

The Attacker Could Try to Redirect Execution Into Code Already Present

If injecting executable code becomes difficult, existing executable instructions can become useful to an attacker.

Code-reuse techniques attempt to manipulate control flow so the application executes legitimate pieces of code in an unintended sequence or from unintended entry points.

The code may be legitimate while the path through it is malicious.

Trusted Code Can Be Used in an Untrusted Way

Exploit mitigation must consider not only whether executable instructions are legitimate but also whether the program reached those instructions through a valid control-flow path.

Was This Jump Going Somewhere the Program Was Actually Allowed to Call?

Control Flow Guard introduced runtime validation for indirect function calls in software compiled to support it.

Rather than allowing an indirect call to transfer execution to any executable address supplied through the relevant pointer, CFG checks whether the destination belongs to the set of valid call targets.

The destination itself becomes part of the security decision.

Executable Did Not Automatically Mean Valid

Control Flow Guard distinguishes between memory containing executable code and locations that the application is legitimately expected to reach through protected indirect calls.

Valid Function Destinations Could Be Identified While the Program Was Built

The compiler analyzes the application as it creates the executable code.

When CFG is enabled, the build process identifies functions that can legitimately serve as indirect-call targets and adds information that Windows can use when the program later runs.

Security knowledge is therefore prepared before the attack occurs.

The Program Could Carry a Map of Legitimate Destinations

Compiler-generated CFG metadata helps the operating system distinguish expected indirect-call targets from arbitrary executable addresses an exploit might attempt to use.

The Program Could Question the Destination Before Taking the Jump

An indirect call obtains its destination through a pointer or another value rather than having one fixed destination encoded directly into the instruction.

That flexibility is useful in legitimate software, but it also makes corrupted pointers attractive to attackers. CFG-enabled code includes lightweight checks before protected indirect calls.

The destination must survive validation first.

Indirect Calls Needed Additional Scrutiny

Because the final destination of an indirect call can depend on runtime data, CFG checks whether that dynamically selected address is an approved target before allowing execution to continue there.

The Compiler and Operating System Worked Together

Control Flow Guard was not simply a compiler trick.

The compiler inserted the necessary checks and described valid destinations, while Windows maintained the runtime information used to determine whether an indirect call target was permitted.

The protection crossed the boundary between application and operating system.

Compiler

Adds CFG checks to protected code and identifies legitimate indirect-call targets when the application is built.

Windows

Maintains the runtime state describing valid targets and performs the validation used when CFG-protected indirect calls occur.

The Application Could Be Terminated Instead of Following the Corrupted Pointer

If CFG determines that an indirect call is attempting to reach an invalid destination, Windows does not need to guess what the program intended.

The process can be terminated immediately.

That may produce a crash, but from a security perspective a controlled termination is preferable to allowing an attacker to redirect execution successfully.

Crashing Can Be the Safe Outcome

When an application’s control flow has been manipulated toward an invalid destination, terminating the process can prevent the corrupted execution path from becoming a successful exploit.

CFG Was Designed to Break Exploitation Rather Than Repair the Bug

This distinction is important.

A buffer overflow does not disappear merely because the affected application uses Control Flow Guard. The underlying programming error may remain and still require a software update.

CFG attempts to make certain consequences of that error harder to weaponize.

Mitigation Is Not Remediation

Control Flow Guard can interfere with exploitation of memory corruption, but developers still need to correct the vulnerability that allowed memory to become corrupted in the first place.

The Protection Did Not Need the CVE Number First

Signature-based defenses often depend on recognizing a known threat or characteristic.

CFG operates on the behavior of the program’s control flow. If an unknown vulnerability is exploited in a way that attempts an invalid protected indirect-call destination, CFG can intervene without needing prior knowledge of the specific vulnerability.

The mitigation targets a technique rather than one malware sample.

A Zero-Day Can Still Break a Rule

An exploit may be completely new while still depending on a control-flow manipulation that violates the restrictions enforced by CFG.

Applications Could Be Built With CFG Without Being Rewritten From Scratch

Microsoft exposed Control Flow Guard through the Visual Studio 2015 toolchain.

For suitable C and C++ applications, developers could enable CFG through compiler and linker options rather than redesigning the application’s source architecture solely to obtain the mitigation.

The build system performed much of the work.

Security Could Become a Build Decision

Enabling CFG allowed the compiler and linker to instrument compatible software and generate the information Windows needed for runtime enforcement.

Windows 10 Components Were Compiled With Control Flow Guard

CFG was not presented only as an optional experiment for outside developers.

Microsoft incorporated the technology into Windows 10 binaries and other software, using the same mitigation to make exploitation of memory-corruption vulnerabilities more difficult across important system components.

The platform itself became an early deployment target.

The Operating System Could Benefit Before Every Application Did

Building Windows components with CFG provided protection in important parts of the platform even while third-party software adoption varied from one developer to another.

Microsoft’s Exploit-Mitigation Toolkit Was Compiled With the New Protection

In March 2015, Microsoft released EMET 5.2 with its native DLLs compiled using Control Flow Guard.

Microsoft also encouraged third-party developers to rebuild their applications to take advantage of the mitigation available through the newer toolchain.

The recommendation was moving beyond Microsoft’s own binaries.

The Technology Was Already Shipping in 2015

EMET 5.2 provides a clear historical example of Microsoft deploying CFG during 2015 while encouraging software developers to adopt the same protection.

The Compiler Needed to Participate

CFG depends on information created when compatible software is compiled.

An older application built without CFG instrumentation does not suddenly contain the compiler-generated checks and metadata simply because it runs on Windows 10.

Operating-system support alone cannot recreate information that was never built into the binary.

Running on a Newer Windows Version Is Not the Same as Being Built for Its Mitigations

Software vendors need to compile compatible applications with CFG support for those applications to receive the intended protection from CFG-instrumented indirect calls.

Adoption Did Not Require Every Module to Change at the Same Moment

Real applications often depend on multiple libraries created by different developers.

Microsoft designed CFG so protected code could operate alongside modules that were not compiled with the mitigation. This made gradual adoption possible instead of requiring an entire software ecosystem to migrate simultaneously.

Compatibility helped deployment.

Partial Adoption Is Possible but Leaves Gaps

An application can contain a mixture of CFG-enabled and non-CFG code, but unprotected portions do not receive the same control-flow checks and can leave additional exploitation opportunities.

A Security Check Used Constantly Could Not Be Expensive

Indirect calls occur frequently in modern software.

If every CFG validation introduced a large delay, developers would be reluctant to enable the feature and users would experience slower applications. Microsoft therefore designed the runtime validation to be highly optimized.

Security had to fit into ordinary execution.

A Mitigation Only Helps at Scale if Software Can Afford to Use It

Control Flow Guard was engineered to provide frequent runtime checks with sufficiently low overhead for broad use in normal applications and operating-system components.

Different Mitigations Blocked Different Parts of an Exploit

DEP focuses on whether code can execute from memory intended only for data.

CFG focuses on whether protected indirect calls are reaching valid destinations. An attacker who works around one restriction may still encounter the other.

The protections are complementary rather than interchangeable.

DEP

Restricts execution from memory regions that should contain data rather than executable instructions.

CFG

Restricts where protected indirect calls can transfer execution by validating their destinations against legitimate call targets.

Random Locations and Valid Destinations Solved Different Problems

ASLR attempts to make useful memory locations difficult for an attacker to predict.

CFG can still question whether a destination is legitimate even if the attacker has somehow discovered the address. The defenses therefore place different obstacles in the exploitation chain.

Layering makes one bypass less decisive.

Finding an Address Does Not Necessarily Make It a Valid Target

An information leak might weaken address randomization, while CFG can continue imposing restrictions on protected indirect calls that attempt to use discovered addresses improperly.

The Program Should Not Be Free to Jump Anywhere Merely Because Memory Was Corrupted

Control-flow integrity describes the broader goal of keeping execution within acceptable paths.

CFG provides a practical form of forward-edge protection by validating destinations of indirect calls. It does not enforce every possible relationship between every source and destination, but it substantially narrows the attacker’s freedom compared with unrestricted indirect branching.

The allowed execution surface becomes smaller.

Less Freedom for the Exploit Means More Work for the Attacker

By reducing the set of destinations available through corrupted indirect calls, CFG removes many execution paths that an attacker might otherwise use when constructing an exploit.

An Application Closing Suddenly Was Not Always Evidence That CFG Failed

When CFG detects an invalid control-flow destination, terminating the process is the intended defensive response.

From the user’s perspective, the application may simply disappear or report a crash. Diagnosing the event therefore requires distinguishing ordinary software instability from a mitigation intentionally stopping suspicious execution.

The symptom can look similar while the cause is very different.

Investigate Repeated Mitigation Failures

If a program repeatedly terminates because of exploit-protection enforcement, determine whether the cause is malicious activity, corrupted software, incompatible code, or another condition rather than simply disabling the mitigation.

Making Exploitation Harder Did Not Excuse Leaving Vulnerabilities Open

Exploit mitigations are defensive layers, not substitutes for secure software maintenance.

An attacker may discover a technique that avoids a particular CFG check, exploit an unprotected module, or use a vulnerability that does not depend on the control-flow behavior CFG restricts.

Patching removes opportunities that mitigation alone can only complicate.

Defense in Depth Does Not Mean Patch Later

CFG can provide valuable protection before and after a vulnerability becomes known, but installing the vendor’s security update remains important because the underlying defect may support attack paths outside CFG’s scope.

The Executable Carried Evidence of Its Protection

Microsoft’s development tools allowed programmers to inspect a compiled binary and determine whether CFG instrumentation and the required function information were present.

This made the mitigation something developers could verify rather than merely assume had been enabled correctly.

Security configuration could be tested in the finished executable.

Build Settings Should Be Verified in the Output

Development teams can inspect binary headers and load-configuration information to confirm that the expected Control Flow Guard instrumentation was actually produced during compilation and linking.

Different Exploits Could Fail for the Same Reason

Malware signatures generally identify characteristics associated with particular threats.

CFG operates at another level. Different vulnerabilities and different attackers may all depend on corrupting an indirect control-flow destination. If that destination violates CFG’s rules, the same mitigation can interfere with all of them.

One defensive rule can apply across many unrelated attacks.

Exploit Techniques Can Be More Stable Than Malware Names

Attack campaigns change constantly, but many still depend on recurring low-level exploitation techniques. Mitigating the technique can therefore provide protection across threats that otherwise have little in common.

The Security Came From Controlling Which Destination Was Accepted

CFG did not require a completely different programming model.

Applications continued using functions, pointers, libraries, and ordinary processor instructions. The additional protection appeared at critical control-flow decisions where an indirect destination needed validation.

A small decision point could disrupt an entire exploit chain.

The Check Happens Before the Dangerous Transfer

CFG’s value comes from validating the target while the program still has an opportunity to refuse the manipulated control-flow transition.

Corrupting a Pointer No Longer Guaranteed the Program Would Follow It

Before control-flow enforcement, a successful overwrite of a function pointer could give an attacker substantial influence over where execution moved.

CFG introduced another requirement. The corrupted pointer had to identify a destination Windows considered valid for the protected indirect call.

The memory corruption might succeed while the exploit still failed.

Owning the Pointer Did Not Mean Owning Every Destination

Control Flow Guard reduces the value of manipulating an indirect-call pointer by preventing many arbitrary executable addresses from becoming acceptable destinations.

The Compiler Could Help Defend Software Before Anyone Found the Vulnerability

One of CFG’s most important characteristics was that developers did not need to know which future vulnerability an attacker might discover.

The compiler could add the mitigation while the software was being built, and Windows could enforce the resulting restrictions whenever the application ran. The defense was already waiting if a compatible memory-corruption exploit appeared later.

Preparation happened before the attack was known.

The vulnerability may be unexpected, but the program still does not have to accept an unexpected destination.

Control Flow Guard Made a Corrupted Jump Easier to Refuse

Control Flow Guard added another obstacle between memory corruption and successful code execution.

Software compiled with CFG could identify legitimate indirect-call targets and perform lightweight checks before transferring execution. Windows supplied the runtime support needed to validate those destinations, and an invalid target could cause the process to terminate instead of following an attacker-controlled path.

CFG did not repair vulnerable code and did not replace DEP, ASLR, security updates, or antimalware protection. Its contribution was narrower and important: even after an attacker managed to corrupt memory, the program gained another opportunity to refuse to go where the attacker wanted it to go.