B&R PLC Program Reverse Engineering: Technical Analysis
A comprehensive technical reference for analyzing, disassembling, and recovering information from compiled B&R (Bernecker + Rainer) IEC 61131-3 programs.
1. B&R Object Code File Formats
B&R Automation Studio uses several proprietary file formats throughout the development, compilation, and deployment lifecycle. Understanding each is essential to any analysis of compiled B&R code.
1.1 .br Files — Compiled Binary Modules
The .br extension is the primary B&R compiled object format. The Automation Studio compiler produces executable program modules (“B&R modules”) in machine code as .br files. These are transferred to the controller as “system objects” during project download.
Contents:
- Native machine code (x86 or ARM depending on target CPU)
- Compiled library references and dependency information
- Configuration parameters for the module
- Symbolic variable names (if symbol export is enabled at compile time)
- Module metadata: name, version, size in bytes, target architecture
The .br format is proprietary and undocumented. B&R has not publicly released format specifications. The compiled binary cannot be decompiled back to source code using any B&R-provided tool.
Source: B&R Automation Studio Quick Start guide states: “The compiler provides an executable program module (B&R module) in machine code. B&R modules (*.BR files) can be transferred to the controller as system objects.” — https://instrumentacionycontrol.net/wp-content/uploads/2017/11/IyCnet_BR_AutomationStudio_QuickStart_MASYS2ASQS-E_240.pdf
1.2 .pc Files — Project Configuration
The .pc file is the Automation Studio project container. It is not a compiled binary but rather a project-level configuration and metadata file that holds references to all project components.
Contents:
- Project-level metadata (name, version, Automation Studio version)
- Hardware tree configuration (left panel in AS project view)
- Software tree configuration (right panel in AS project view)
- References to all programs, user files, hardware configuration options
- I/O mapping definitions and hardware module assignments
- Task configuration (cycle times, priorities)
- References to library dependencies
The .pc file acts as the top-level manifest for the entire Automation Studio project. It does not contain compiled code itself but references the .br binary modules that are generated during compilation.
Source: B&R Community forum: “The project itself is a collection of programs, user files, hardware trees, hardware configuration options, configuration files, I/O mappings…” — https://community.br-automation.com/t/referencing-all-resources-from-another-project/2354
1.3 .obj Files — Intermediate Object Files
During the B&R compilation pipeline, intermediate object files may be generated. These are linker-able binary units that contain partially compiled code. In the B&R ecosystem, .obj files typically appear in the build directory of an Automation Studio project and represent pre-linked object code for individual Program Organization Units (POUs) or C source files before final linking into a .br module.
Contents (typical):
- Relocatable machine code sections
- Symbol table (local and external references)
- Relocation entries for linker resolution
- Debug information (if compiled with debug symbols)
These are standard object file formats (likely COFF or ELF derivatives) used by the GNU toolchain that underpins the B&R compiler for C programs, rather than a B&R-proprietary format.
1.4 .l5k Files — Allen-Bradley Export (Not B&R)
The .l5k extension is associated with Rockwell/Allen-Bradley RSLogix/Studio 5000 PLC export files (L5K is an XML-like ASCII export format for ControlLogix/CompactLogix programs). This format is not used by B&R and is included here only for clarity, as it frequently appears in general PLC reverse engineering discussions.
For B&R systems, the relevant export format would be the Automation Studio archive format (.ar) or individual source files (.st, .ld, .c, .h, .var).
1.5 Other Relevant B&R File Formats
| Extension | Purpose |
|---|---|
.st | Structured Text source files |
.ld | Ladder Diagram source files |
.var | Variable declaration files (Global.var, Local.var) |
.c / .h | ANSI C source and header files (B&R supports C programming) |
.ar | Automation Studio project archive (includes all dependencies) |
.exp | Export files (legacy PG2000 format) |
.lh | Library header files |
.vis | Visualization pages |
2. B&R IEC 61131-3 Compiler Architecture
2.1 Compilation Pipeline Overview
B&R Automation Studio compiles IEC 61131-3 programs (Structured Text, Ladder Diagram, Function Block Diagram, Sequential Function Chart) through a multi-stage pipeline:
Source (.st/.ld/.sfc) → Frontend Parser → Intermediate Representation (IR)
↓
C Source (.c/.h) → GCC Cross-Compiler → Object (.obj)
↓
Linker → Binary Module (.br)
Key characteristics:
- The IEC 61131-3 languages are compiled through a proprietary frontend that produces an intermediate representation
- This IR is then translated to C code, which is compiled by an embedded GCC cross-compiler targeting the PLC’s CPU architecture
- Final linking produces the
.brbinary module in native machine code - B&R supports both IEC 61131-3 languages and native ANSI C programming on the same controller
2.2 Target Architectures
B&R controllers span multiple CPU architectures, which determines the instruction set of the compiled binary:
| Controller Series | CPU Architecture | Example CPUs |
|---|---|---|
| X20/X67 | Intel Atom (x86) or ARM | Atom E3940, ARM Cortex |
| Power Panel / Panel PC | Intel Core-i (x86_64) | Celeron to Core i7 |
| CP47x Series | 32-bit (proprietary, ~150 MHz) | CP474-EL |
| APC (Automation PC) | Intel x86_64 | Various Core-i generations |
| ACOPOStrak/motors | ARM or PowerPC | Various embedded cores |
The Claroty Team82 research confirmed: “B&R X20 series offers a modular and compact PLC configuration. It is based on an Intel ATOM CPU (X86) or ARM architecture, and runs VxWorks as its RTOS firmware.”
2.3 Runtime Environment
All modern B&R controllers run Automation Runtime (AR), B&R’s proprietary real-time operating system based on VxWorks (see ar-rtos.md for full OS internals). Older B&R 2005 systems and some legacy controllers used different RTOS solutions. Automation Runtime provides:
- Deterministic cyclic task execution (see execution-model.md for task scheduling details)
- I/O bus management (X2X, POWERLINK, EtherCAT) — see x2x-protocol.md and powerlink-internals.md
- Memory management for program modules — see memory-map.md for the full address layout
- Communication stack (OPC UA, Modbus, proprietary protocols) — see opcua.md and modbus-gateway.md
The compiled .br modules are loaded and executed by Automation Runtime as native code, running directly on the CPU without any bytecode virtual machine layer. The boot sequence that loads these modules is documented in cf-card-boot.md.
3. Bytecode vs. Native Code: B&R’s Approach
3.1 B&R Compiles to Native Code
B&R does not use an intermediate bytecode format like Siemens MC7. This is a critical architectural difference from other major PLC vendors:
| Vendor | Compilation Target | Execution Model |
|---|---|---|
| B&R | Native machine code (x86/ARM) | Direct CPU execution |
| Siemens S7-300/400 | MC7 bytecode | Virtual machine interpreter |
| Siemens S7-1200/1500 | MC7+ bytecode | Virtual machine with JIT |
| CODESYS (generic) | Proprietary bytecode | Virtual machine interpreter |
| Beckhoff TwinCAT | Native machine code | Direct execution |
The B&R compilation pipeline translates IEC 61131-3 source code through C to native machine code using GCC. This means:
- No virtual machine layer — the compiled code runs as direct x86/ARM instructions
- Better performance — no interpretation or JIT overhead
- Harder to reverse engineer — the output is standard machine code, not a structured bytecode with documented opcodes
- Standard tools apply — disassemblers for x86/ARM can analyze the binary directly
3.2 Contrast with Siemens MC7 Bytecode
Siemens S7 PLCs compile all IEC 61131-3 languages into MC7/MC7+ bytecode, a lower-level representation executed by a virtual machine in the PLC. As Claroty’s research describes: “Regardless of input sources, the PLC program will be compiled into MC7 / MC7+ bytecode, which is a lower-level representation of the code. After being compiled by the engineering station, code blocks (in MC7/MC7+ format) are downloaded and installed into a PLC.”
MC7 bytecode has been partially reverse-engineered by the security community:
- The rizin reverse engineering framework includes
rz-libmc7for disassembling MC7 bytecode - PNF Software’s JEB decompiler supports S7 PLC program analysis
Source: https://claroty.com/team82/research/the-race-to-native-code-execution-in-plcs Source: https://github.com/rizinorg/rz-libmc7
B&R’s native code compilation means no equivalent bytecode specification exists to leverage for analysis.
4. Approaches to Decompilation and Disassembly
4.1 Disassembly (Native Code)
Since B&R compiles to native x86/ARM machine code, standard disassembly toolchains apply. The CP1584 uses an Intel Atom E640T (x86, 32-bit). See cp1584-hardware-ref.md for the full CPU specification and ar-rtos.md for the AR runtime environment details.
For x86-based controllers (X20, APC, Power Panel):
- Use disassemblers that support x86 (32-bit or 64-bit depending on CPU)
- Identify code regions by looking for function prologues and epilogues
- The GCC-compiled code will follow standard x86 calling conventions
For ARM-based controllers:
- Use ARM disassemblers (ARMv7, ARMv8 depending on CPU)
- Standard ARM calling conventions (AAPCS) will apply
Practical Disassembly Workflow with Ghidra
Ghidra (NSA’s open-source reverse engineering suite) is the recommended tool for analyzing B&R .br binaries:
# Install Ghidra (requires JDK 17+)
# Download from https://github.com/NationalSecurityAgency/ghidra/releases
# Create a project and import the .br file
# Ghidra will prompt for language/specification:
# - For CP1584 (Intel Atom, 32-bit): x86:LE:32:default
# - For newer X20CP3xxx (x86_64): x86:LE:64:default
# - For ARM-based modules: ARM:LE:32:v8
# After import, run auto-analysis. Key steps:
# 1. Window → Defined Strings — extract all string constants
# 2. Window → Functions — review identified function boundaries
# 3. Window → Data Type Manager — look for known B&R data structures
# 4. Symbol Tree → Exports/Imports — find library function calls
# Search for IO address patterns (memory-mapped IO ranges):
# Search → For Bytes → 0x...
# B&R IO ranges are documented in memory-map.md
Binary Identification Commands
# Step 1: Identify file format
file binary.br
# Expected: may show "data" if proprietary, or "ELF" if B&R wraps standard format
# Step 2: Find embedded format signatures
binwalk binary.br
# Look for: ELF headers, PE headers, LZMA/zlib compressed sections
# Step 3: Extract all strings (minimum 6 characters for useful output)
strings -n 6 -t x binary.br > strings_output.txt
# Step 4: Extract Unicode strings (B&R IEC STRING type may use wide chars)
strings -e l -n 4 binary.br > unicode_strings.txt
# Step 5: Look for B&R-specific identifiers
grep -i "BR_\|Automation\|POWERLINK\|X2X\|mbtcp\|AsMb\|mapp" strings_output.txt
# Step 6: Quick hex analysis of file header
xxd -l 512 binary.br | head -32
Python Script: Automated B&R Binary Analyzer
#!/usr/bin/env python3
"""Analyze B&R .br binary files for recoverable information."""
import struct
import sys
import re
from collections import Counter
def analyze_br_binary(filepath):
with open(filepath, 'rb') as f:
data = f.read()
print(f"=== B&R Binary Analysis: {filepath} ===")
print(f"File size: {len(data):,} bytes ({len(data)/1024:.1f} KB)")
print()
# Check for known file format magic bytes
magic_checks = [
(b'\x7fELF', 'ELF binary'),
(b'MZ', 'PE executable'),
(b'\x1f\x8b', 'gzip compressed'),
(b'BZh', 'bzip2 compressed'),
(b'\x5d\x00\x00', 'LZMA compressed'),
]
for magic, name in magic_checks:
if data[:len(magic)] == magic:
print(f"Format: {name}")
# Check if file starts with a B&R-specific header
if data[:2] == b'BR' or data[:4] == b'BR\x00\x00':
print("Format: B&R proprietary header detected")
print(f"Header bytes: {data[:32].hex()}")
print()
# Extract ASCII strings (min 6 chars)
ascii_pattern = re.compile(rb'[\x20-\x7e]{6,}')
strings_found = ascii_pattern.findall(data)
print(f"ASCII strings found: {len(strings_found)}")
# Categorize strings
categories = Counter()
interesting = []
for s in strings_found:
s_decoded = s.decode('ascii', errors='ignore')
if re.search(r'\.st|\.ld|\.var|\.c|\.h|\.vis', s_decoded):
categories['source_file_refs'] += 1
interesting.append(s_decoded)
elif re.search(r'mapp|AsMb|POWERLINK|X2X|Modbus|OPC|SDM', s_decoded):
categories['library_refs'] += 1
interesting.append(s_decoded)
elif re.search(r'Error|Fault|Alarm|Warning', s_decoded):
categories['diagnostics'] += 1
interesting.append(s_decoded)
elif re.search(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', s_decoded):
categories['ip_addresses'] += 1
interesting.append(s_decoded)
print("String categories:")
for cat, count in categories.most_common():
print(f" {cat}: {count}")
if interesting:
print(f"\nInteresting strings (top 30):")
for s in interesting[:30]:
print(f" {s}")
# Look for x86 function prologue patterns (push ebp; mov ebp, esp)
prologue = b'\x55\x8b\xec'
prologue_count = 0
pos = 0
while True:
pos = data.find(prologue, pos)
if pos == -1:
break
prologue_count += 1
pos += 1
print(f"\nPotential x86 function prologues (55 8B EC): {prologue_count}")
# Look for standard calling convention patterns
ret_count = data.count(b'\xc3') # x86 RET instruction
print(f"RET instructions (C3 hex): {ret_count}")
print(f"\n=== Analysis complete ===")
print(f"For IO address mapping, cross-reference with [memory-map.md](memory-map.md)")
print(f"For runtime environment details, see [ar-rtos.md](ar-rtos.md)")
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <binary.br>")
sys.exit(1)
analyze_br_binary(sys.argv[1])
4.2 Decompilation
Decompilation of native machine code to recover IEC 61131-3 source is effectively impossible. The compilation pipeline goes through C as an intermediate step, and:
- The IEC 61131-3 → C translation is lossy (structured control flow is linearized)
- The C → machine code compilation is lossy (variable names stripped, optimizations applied)
- No decompiler can reconstruct structured text, ladder diagrams, or function block diagrams from x86/ARM machine code
- At best, you can recover C-like pseudocode showing control flow and data operations
4.3 Structured Analysis Methodology
A practical approach to understanding B&R compiled code:
- Binary format identification — Use
file,binwalk, or hex analysis to determine the format - Architecture detection — Identify the target CPU from file headers
- Section mapping — Identify code, data, and symbol sections
- String extraction — Pull all string literals for contextual clues
- Function identification — Locate function boundaries using prologue patterns
- Cross-reference building — Track data references and call relationships
- IO address correlation — Match memory-mapped IO addresses with hardware documentation
4.4 Academic Frameworks
The research community has developed frameworks for PLC binary analysis, though none are B&R-specific:
ICSREF (NDSS 2019): Automated reverse engineering of CODESYS PLC binaries. While focused on CODESYS (not B&R), the methodology of binary format reverse engineering, symbol table recovery, and control flow analysis is applicable.
Source: https://www.ndss-symposium.org/ndss-paper/icsref-a-framework-for-automated-reverse-engineering-of-industrial-control-systems-binaries/ Code: https://github.com/momalab/ICSREF
PLC-BinX (2025): Cross-platform binary code analysis for PLC binaries. Implements CODESYS-specific reverse engineering with three stages: identifying code regions, recovering function boundaries, and semantic analysis.
5. Tools for Analyzing B&R Binary Files
5.1 Standard Reverse Engineering Tools
| Tool | Applicability to B&R | Notes |
|---|---|---|
| IDA Pro | High | Industry-standard disassembler/decompiler. Supports x86, ARM. IDAPython scripting for custom analysis. Commercial license required. |
| Ghidra | High | NSA’s open-source reverse engineering suite. Supports x86, ARM. Built-in decompiler produces C pseudocode. Scriptable via Java/Python. Free. |
| rizin/radare2 | High | Open-source framework. Has rz-libmc7 plugin for Siemens MC7 but also supports standard x86/ARM disassembly. |
| Binary Ninja | Medium-High | Commercial RE platform with good x86/ARM support and API. |
| objdump | Medium | GNU binutils tool. Can disassemble x86/ARM sections if the .br format uses standard ELF/COFF object wrappers. Limited without format documentation. |
| readelf | Medium | Reads ELF headers and sections. Useful if B&R’s internal format wraps standard ELF. |
| file | Low-Medium | Identifies file type from magic bytes. May or may not recognize B&R proprietary formats. |
| binwalk | Medium | Scans for embedded file signatures, compressed sections, and known file headers within the binary. |
| strings | High | Extracts printable ASCII/Unicode strings. Simple but effective for finding variable names, error messages, configuration strings. |
5.2 B&R-Specific Considerations
Standard tools work on B&R binaries only if the underlying format is recognizable (e.g., ELF-wrapped). If B&R uses a fully proprietary container format with custom headers, initial analysis requires:
- Manual hex analysis to identify format structure
- Custom parsing scripts (Python with
structmodule) to extract sections - Pattern-based identification of code vs. data regions
The B&R C compiler is GCC-based, which means compiled C code within B&R modules will exhibit standard GCC characteristics:
- Standard function prologues (
push ebp; mov ebp, espfor x86) - DWARF debug sections (if debug info is present)
- Standard calling conventions
For the complete CP1584 hardware specification (CPU, memory, interfaces) that determines the binary architecture, see cp1584-hardware-ref.md.
5.3 Extracting the Binary from a Running CP1584
When you have physical access to the PLC but no project files, the compiled binaries reside on the CompactFlash card. See cf-card-boot.md for the full CF card file layout and ftp-web-interface.md for remote extraction methods:
# Method 1: FTP access (if FTP server is enabled on the CP1584)
ftp 192.168.10.1
# Navigate to /Card/ or /System/ directories
# Compiled binaries are typically in:
# /Card/System/B&R/ or /System/Objects/
# Files may have .br, .obj, or no extension
# Method 2: Physical CF card extraction (power down first!)
# Remove CF card, image it with dd on a Linux workstation:
dd if=/dev/sdb of=cp1584_cf_card.img bs=4M status=progress
# Mount and explore:
sudo mount -o ro,loop cp1584_cf_card.img /mnt/cf_card/
find /mnt/cf_card/ -name "*.br" -o -name "*.obj"
# Method 3: ARsim (if you have the binary file)
# Load the .br into Automation Studio's ARsim for behavioral analysis
# This runs the binary in a PC-based simulation environment
5.3 Automation Studio’s Own Analysis Tools
While not reverse engineering tools per se, Automation Studio provides capabilities for understanding code structure:
- Cross-Reference Generator: Must be explicitly generated (not built by default). Shows all uses of any variable, function block, or data object across the project.
- List Usage: Tracks variable usage across all code blocks.
- Find in Files: Global text search across project source files.
6. Information Recoverable from Compiled Code
6.1 What CAN Be Recovered
| Information | Recoverability | Method |
|---|---|---|
| String literals | High | strings tool or manual extraction from data sections |
| Error messages / alarm text | High | String extraction from read-only data sections |
| Constant values | High | Found as immediate operands in disassembled code |
| Control flow structure | Medium | Disassembly and control flow graph reconstruction |
| Function boundaries | Medium | Prologue/epilogue pattern matching |
| Library function calls | Medium | External call references and imported function names |
| Symbolic variable names | Medium-Low | Only if symbol table was included in the binary |
| Data structure layout | Low-Medium | Inferred from access patterns in disassembled code |
| IO mapping addresses | Low-Medium | Memory-mapped addresses in data access instructions |
6.2 What CANNOT Be Recovered
| Information | Reason |
|---|---|
| Original IEC 61131-3 language (ST/LD/FBD/SFC) | Language-specific constructs are lost during compilation to C and then to machine code |
| Original variable names | Stripped during compilation unless explicitly retained in symbol table |
| Comments | Never included in compiled output |
| Ladder diagram topology | Rung structure, contacts, and coils cannot be reconstructed from machine code |
| Function block diagram connections | Visual wiring is lost; only the resulting logic remains |
| Visualization pages | Separate from program code; not included in compiled binary |
| Task configuration | Stored in project metadata, not in the compiled binary module |
| Hardware configuration | Separate from program code; defined in the .pc project file |
| Original project organization | POU hierarchy and project tree structure not preserved in binary |
6.3 B&R’s Own Statement
B&R explicitly states that compiled application objects loaded to the controller contain:
- Binary machine code for the CPU
- Compiled library references
- Configuration parameters
- Symbolic variable names (if enabled)
And explicitly do not contain:
- Original POU source files
- Task configuration in XML format
- Visualization pages
7. Configuration Data in Compiled Binaries
7.1 IO Mapping
B&R IO mapping is typically defined in the project hardware configuration and stored in the .pc project file and associated configuration objects. The compiled binary itself contains the machine code that reads from and writes to memory-mapped IO addresses, but the mapping metadata (which physical terminal maps to which software variable) is stored separately in the project configuration.
In the compiled code, IO access appears as memory reads/writes to specific address ranges:
- Digital IO: bit-level access to memory-mapped regions
- Analog IO: word/dword access to specific address offsets
- Communication data: structure-based access to protocol buffer areas
7.2 Task Configuration
Task configuration (cycle times, priorities, task-to-POU assignments) is defined at the project level and is part of the project metadata downloaded to the controller. This configuration tells Automation Runtime when and how to invoke each compiled program module.
The task configuration is likely stored in a separate configuration block within the download package, not within the .br binary module itself. Automation Runtime reads this configuration to set up the cyclic execution schedule.
7.3 Parameter Data
B&R supports “Data Objects” (DatObj) — persistent parameter blocks that can be read/written at runtime. These are managed via the DataObj library and stored in separate memory areas on the PLC, distinct from the compiled program code.
Source: https://community.br-automation.com/t/as4-as6-datobj-data-modules-on-the-plc/7656
8. String Extraction from Compiled Code
8.1 Techniques
String extraction is one of the most productive analysis techniques for B&R binaries:
Basic string extraction:
strings -n 6 -t x binary.br > strings_output.txt
Unicode string extraction:
strings -e l -n 4 binary.br > unicode_strings.txt
Context-aware extraction:
- Look for string references in disassembled code (addresses of
leaormovinstructions pointing to data sections) - Cross-reference string addresses with code that uses them for functional context
- B&R IEC string type uses a structure with length + data; look for these patterns
8.2 What Strings Reveal
In B&R compiled code, strings typically include:
- Variable names: If the symbol table is embedded (controlled by compiler settings)
- Error/alarm messages: Hardcoded message strings from alarm handling
- OPC UA tag names: If OPC UA server configuration includes string identifiers
- File paths: Configuration file paths or log file names
- Network addresses: Hardcoded IP addresses or hostnames
- Protocol identifiers: POWERLINK, EtherCAT, Modbus identifiers
- Function block instance names: If debugging information is included
- User-defined string constants: Any
STRINGtyped constant in the source code
8.3 B&R IEC String Format
B&R’s IEC 61131-3 STRING type uses a specific memory layout: a header byte containing the maximum length followed by the actual string data (not null-terminated in the traditional C sense, though a null terminator may be present for compatibility). When searching for IEC strings in binary data, look for patterns of a length byte followed by ASCII text.
9. Cross-Referencing with Live PLC Behavior
9.1 Online Monitoring with Automation Studio
Automation Studio provides online monitoring capabilities when connected to a running PLC:
Watch/Trace:
- Add variables to the watch window to monitor real-time values
- Force variables to specific values to observe program response
- Set breakpoints in source code (only with source available)
- Single-step through program execution
Online View:
- Connect to a running target via Ethernet
- Monitor variable states in real time
- Examine IO states
- View task cycle information and timing
9.2 Using Online Data to Understand Compiled Code
When source code is unavailable but you can connect to a running PLC:
-
Variable enumeration via PVI: B&R’s PVI (Process Visualization Interface) protocol can enumerate all variables available in the runtime, including their symbolic names and memory addresses. This works without source code. See pvi-api.md for the complete PVI API reference.
-
PVI Monitor tool: Can view all available variables in real-time and export the variable list. The runtime stores variable metadata in its memory structure.
-
OPC UA browsing: If OPC UA is configured on the PLC, any OPC UA client can browse the address space and extract variable names, types, and current values. See opcua.md for OPC-UA configuration details.
-
System variables: AR system variables (CPU temperature, cycle times, task info) are always available and provide runtime context. See system-variables.md for the full list.
-
Behavioral analysis: By manipulating inputs and observing outputs, you can map the functional behavior of the compiled program, even without understanding the internal code. Use io-sniffing.md for intercepting fieldbus traffic and diagnostics-sdm.md for SDM-based error tracking.
9.3 Limitations of Online Analysis
- Cannot see internal logic or program flow
- Cannot modify program code
- Cannot recover original source structure
- Variable names are only available if they were included in the compiled binary
- No access to visualization or task configuration through online monitoring alone
10. Legal Considerations
10.1 Overview of Applicable Law
Reverse engineering of industrial control software is subject to multiple overlapping legal frameworks. This section provides general information, not legal advice. Consult qualified counsel for specific situations.
10.2 U.S. Law — Key Statutes
DMCA Section 1201 (17 U.S.C. § 1201): Prohibits circumventing “technological protection measures” that control access to copyrighted works. Software vendors may argue that authentication, code signing, obfuscation, and protocol encryption are protected technical measures. Section 1201(f) provides a narrow exception for reverse engineering “for the sole purpose of identifying and analyzing elements of the program necessary to achieve interoperability” with an independently created program.
Copyright Law (17 U.S.C. § 107 — Fair Use): Making copies of software for analysis may qualify as fair use, particularly for interoperability research (established in Sega v. Accolade and Sony v. Connectix). However, fair use is a fact-specific defense, not a guarantee.
Trade Secret Law: Reverse engineering through fair and independent means does not generally violate trade secret law. However, if you obtained the software subject to an NDA or contractual obligation prohibiting reverse engineering, analysis may constitute misappropriation.
Contract Law (EULAs/NDAs): Many industrial software licenses include “no reverse engineering” clauses. The Blizzard v. BnetD case established that mass-market EULA provisions prohibiting reverse engineering can be enforceable, potentially overriding fair use rights.
ECPA (18 U.S.C. § 2510): Network packet inspection during analysis may require consent of parties or the network operator.
Source: https://www.eff.org/issues/coders/reverse-engineering-faq
10.3 Industrial Control-Specific Considerations
- Safety implications: Modifying or incorrectly reconstructing PLC logic can cause physical harm, equipment damage, or environmental releases. Any reverse engineering of safety-critical systems carries extraordinary liability risk.
- OEM contractual obligations: Machine builders and system integrators typically own the PLC programs and may have contractual rights protecting their intellectual property.
- Regulatory compliance: Industries such as pharmaceutical, food, nuclear, and chemical have regulatory requirements around validated control systems. Unauthorized modification of validated PLC programs can violate regulations (FDA 21 CFR Part 11, etc.).
- B&R licensing: B&R Automation Studio itself is licensed software. Using it in ways that violate the B&R license agreement creates contractual risk.
10.4 Legitimate Use Cases
Reverse engineering of PLC code may be legally defensible in certain scenarios:
- Security research: Analyzing binaries for vulnerabilities (with responsible disclosure)
- Interoperability: Developing compatible systems when no documentation exists
- Legacy system maintenance: When the original vendor is unavailable and no source exists
- Malware analysis: Investigating known or suspected PLC malware (e.g., Stuxnet-style attacks)
- Forensic investigation: Post-incident analysis after a cybersecurity event
10.5 Risk Mitigation
- Consult legal counsel before beginning any reverse engineering
- Ensure lawful acquisition of the software
- Avoid agreeing to “no reverse engineering” clauses where possible
- Use least-intrusive techniques first (online monitoring before binary disassembly)
- Document the legitimate purpose of the analysis
- Consider engaging the vendor or OEM for authorized access to documentation
11. Using Automation Studio’s Online View
11.1 Connection Setup
- Connect PC to PLC via Ethernet
- In Automation Studio:
Online → Settings → Browse for Targets - Select the target controller from the list
- Establish the online connection
11.2 Available Online Capabilities (Without Source)
Even without the source project, Automation Studio can connect to a running PLC and provide:
| Capability | Without Source | With Source |
|---|---|---|
| Monitor variable values | Yes (if symbols available) | Yes |
| Force variables | Yes (with appropriate permissions) | Yes |
| View task status | Yes | Yes |
| Examine IO states | Yes | Yes |
| Set breakpoints | No | Yes |
| Single-step execution | No | Yes |
| Cross-reference variables | No | Yes |
| Modify program code | No | Yes |
11.3 Extracting Symbol Tables Online
When connected to a running PLC with Automation Studio (even without source code), you may be able to:
- Browse the online variable list
- Export the symbol table if the runtime exposes it
- Monitor and log variable values over time
- Identify the data types and memory addresses of variables
This provides partial documentation of the running program’s data model, which can be combined with binary analysis for a more complete picture.
11.4 ARsim (Simulation)
Automation Studio includes ARsim (Automation Runtime Simulation), which allows running compiled programs on a PC without physical hardware. If you have the compiled binary, you can potentially load it into ARsim and observe its behavior, which provides a controlled environment for behavioral analysis.
12. Recovery of IO Mapping from Compiled Binaries
12.1 Approaches
From the binary itself:
- Disassemble the compiled code and look for memory access patterns to known IO address ranges (see memory-map.md for the full CP1584 address space)
- B&R IO is memory-mapped; IO modules appear at specific addresses in the controller’s address space — see io-card-hardware.md for IO card architecture details
- Identify reads from input addresses and writes to output addresses by analyzing
mov,load, andstoreinstructions - Cross-reference these addresses with B&R hardware documentation to identify physical IO points
From the runtime (online):
- Connect to the running PLC via PVI or OPC UA
- Browse the variable namespace for IO-mapped variables
- Examine the addressing in the variable declarations
- Use Automation Studio’s hardware comparison feature (AS 4.0+): “Automation Studio provides a new access to compare configured hardware and software with online connected hardware.”
- Use the system diagnostic manager (SDM) to identify IO module status — see diagnostics-sdm.md
From project artifacts:
- If any project files survive (even partial), the hardware configuration in the
.pcfile contains the IO mapping — see config-file-formats.md for the file format details - IO configuration is typically stored in XML within the project structure
- Check for backup files, version control archives, or configuration exports
- The CF card contains configuration files that define the IO layout — see cf-card-boot.md
12.2 B&R IO Addressing
B&R uses a hierarchical addressing scheme:
- Hardware modules are addressed by bus and slot position
- Software variables are mapped to these hardware addresses through the IO mapping configuration
- The compiled code accesses IO through these mapped addresses
Without the project configuration, you must reverse-engineer the mapping by:
- Identifying all memory-mapped IO addresses in the disassembled code
- Determining which addresses are reads (inputs) vs. writes (outputs)
- Correlating addresses with known hardware module specifications
- Testing hypotheses by manipulating physical IO and observing program behavior
12.3 Limitations
- Complex IO mapping (aliasing, scaling, offset calculations) embedded in the code may be difficult to identify
- Network-based IO (POWERLINK, EtherCAT, OPC UA) may not follow simple memory-mapped patterns
- IO configuration for Safety systems (Safety PLC) may be additionally protected
13. B&R Symbol Export/Import Mechanisms
13.1 Library-Based Symbol Management
B&R provides a library system that supports partial IP protection through compiled libraries:
Compiled Libraries:
- Functions and function blocks can be compiled into binary libraries and distributed without source code
- The library exports symbolic interface definitions (function names, parameter types) while hiding the implementation
- Consumers can import and use the library in their projects, but cannot view the internal code
- Binary libraries are compiled for specific CPU architectures (ARM, x86)
Library Export:
- Automation Studio supports exporting libraries in compiled (binary) form
- “When exporting binary libraries they are only compiled for the CPU architectures used in the project. So a good way is to have one ARM CPU (Like X20CP0484) and one Intel CPU (Like X20CP1585) to make sure the library can be used on both.”
13.2 Symbol Table Settings
B&R provides compiler settings that control whether symbolic information is included in compiled binaries:
- Symbol export: Can be enabled/disabled at the project or module level
- Debug information: DWARF debug sections can be included (increases binary size but preserves variable names and types)
- Variable address information: Can be exported for online monitoring purposes
13.3 Source Code Protection Features
B&R offers several mechanisms for protecting intellectual property:
- Compiled libraries: Distribute code as pre-compiled binaries with only interface definitions exposed
- Password protection: Tasks and libraries can be password-protected (anyone can use them, but only the password holder can modify them)
- Source file “encryption”: Automation Studio has a source file protection feature, though B&R community discussions reveal it is “more of an access control check/deterrent than true encryption”
Source: https://community.br-automation.com/t/automate-encrypting-source-files/11031 Source: https://community.br-automation.com/t/hiding-parts-of-my-program/3247
13.4 Technology Guarding
B&R’s Technology Guarding system provides additional protection for intellectual property through a server-based licensing system. It uses SSL/TLS encryption for secure communication with Automation Studio. For license recovery procedures when the OEM is unavailable, see license-mgmt.md.
13.5 Extracting Binaries Without Automation Studio Access
When you cannot connect Automation Studio to the PLC (e.g., password-protected — see access-recovery.md for recovery procedures), alternative binary extraction paths exist:
- FTP server: If enabled, the FTP interface exposes the CF card file system remotely (see ftp-web-interface.md)
- Physical CF card removal: Power down, remove the CF card, and image it on a workstation (see cf-card-boot.md)
- Web server / SDM: The System Diagnostics Manager web interface may expose limited file access
- Serial console: The bootloader recovery mode provides limited file system access via serial (see bootloader-recovery.md)
14. Practical Limitations
14.1 Hard Limitations — What Cannot Be Done
-
Source code recovery: B&R compiled binaries cannot be decompiled back to original IEC 61131-3 source code. This is a fundamental limitation, not a tool limitation.
-
Source upload from PLC: “By default, B&R does not save source code on the target. Only the compiled binary is stored, which cannot be decompiled to source code.” Automation Studio cannot upload source code from a connected controller.
-
Language reconstruction: You cannot determine whether the original code was written in Structured Text, Ladder Diagram, or any other IEC 61131-3 language from the compiled binary.
-
Visualization recovery: HMI/visualization pages are never included in compiled program binaries.
-
Project organization: The original project structure, naming conventions, and organization are lost in compilation.
-
Comments and documentation: All developer comments and inline documentation are stripped during compilation.
14.2 Partial Recovery — What Can Sometimes Be Done
-
Variable names: Recoverable if symbol table was included in the binary (controlled by compiler settings) or via online PVI enumeration from a running PLC.
-
Control flow: Recoverable at the machine code level using disassemblers and decompilers, yielding C-like pseudocode. The high-level IEC semantics are lost.
-
String constants: Fully recoverable from the data sections of the binary.
-
IO mapping: Partially recoverable through combination of binary analysis and online monitoring.
-
Library dependencies: Import/export symbols reveal which external libraries the code depends on.
-
Functional behavior: Can be observed and documented through online monitoring and IO manipulation.
14.3 Effort vs. Reward Assessment
| Goal | Feasibility | Effort Required | Practical Approach |
|---|---|---|---|
| Full source recovery | Impossible | N/A | Contact OEM/B&R support |
| Functional understanding | Possible | Very High | Online monitoring + behavioral analysis |
| IO mapping documentation | Possible | High | PVI enumeration + manual tracing |
| Variable list extraction | Possible | Low-Medium | PVI tools or OPC UA browsing |
| Security audit | Possible | Very High | Binary disassembly + fuzzing + protocol analysis |
| Migration to new platform | Possible | Very High | Recreate logic from behavioral analysis + documentation |
14.4 Recommended Practical Workflow
When faced with a B&R PLC running unknown compiled code:
- Connect online and extract the variable list via PVI/OPC UA
- Document all IO behavior by systematically toggling inputs and recording outputs
- Extract all strings from the binary for contextual information
- Identify the CPU architecture to select appropriate disassembly tools
- Disassemble the binary with Ghidra or IDA Pro for structural analysis
- Cross-reference online behavior with disassembled code to build understanding
- Document findings in a format suitable for recreation in a new project
- Recreate the program in a new Automation Studio project based on documented behavior
References
B&R Official Documentation
- B&R Automation Studio Quick Start: https://instrumentacionycontrol.net/wp-content/uploads/2017/11/IyCnet_BR_AutomationStudio_QuickStart_MASYS2ASQS-E_240.pdf
- B&R Automation Runtime product page: https://www.br-automation.com/en-us/products/software/automation-runtime/
- B&R Programming overview: https://www.br-automation.com/en-us/products/software/additional-information/programming/
- Awesome B&R (curated resource list): https://github.com/hilch/awesome-B-R
B&R Community Forum Discussions
- Source code upload from PLC: https://community.br-automation.com/t/upload-program-from-a-plc/1520
- Source file encryption: https://community.br-automation.com/t/automate-encrypting-source-files/11031
- Library export/import: https://community.br-automation.com/t/error-occured-while-build-source-after-export-import-library/6564
- Variable tracking and cross-reference: https://community.br-automation.com/t/new-to-b-r-best-practices-for-tracking-variables-list-usage-cross-ref-and-tracing-physical-i-os/11429
- Cross-reference generation: https://community.br-automation.com/t/cross-reference-doesnt-work/3737
- Data modules on PLC: https://community.br-automation.com/t/as4-as6-datobj-data-modules-on-the-plc/7656
- Technology Guarding: https://community.br-automation.com/t/ssl-tls-encryption-required-for-access-to-technology-guarding-server-and-automation-studio-upgrades/3049
- Password protection: https://community.br-automation.com/t/preventing-unauthorized-writing-to-a-plc-program/3607
- Variable addresses after compilation: https://community.br-automation.com/t/automation-studio-4-7-4-12-variable-addresses-after-compilation/7920
Reverse Engineering Research
- ICSREF Framework (NDSS 2019): https://www.ndss-symposium.org/ndss-paper/icsref-a-framework-for-automated-reverse-engineering-of-industrial-control-systems-binaries/
- ICSREF GitHub: https://github.com/momalab/ICSREF
- PLC-BinX Cross-Platform Analysis: https://arxiv.org/html/2605.17392v2
- Bridging the PLC Binary Analysis Gap: https://arxiv.org/html/2502.19725v1
Siemens MC7 and Comparative Analysis
- Claroty: The Race to Native Code Execution in PLCs: https://claroty.com/team82/research/the-race-to-native-code-execution-in-plcs
- rz-libmc7 (MC7 disassembler): https://github.com/rizinorg/rz-libmc7
- PNF Software: Reversing Simatic S7 PLC Programs: https://www.pnfsoftware.com/blog/reversing-simatic-s7-plc-programs/
- JEB S7 Decompiler: https://www.pnfsoftware.com/decompilation
- PLC Ladder Logic to Machine Code compilation: https://industrialmonitordirect.com/blogs/knowledgebase/how-plcs-compile-ladder-logic-to-machine-code
- PLC Bytecode Decompilation technique: https://www.semanticscholar.org/paper/A-technique-for-bytecode-decompilation-of-PLC-Lv-Xie/af413f314cc5ab57bb94d96ffc110f521a8284b0
Security Research
- Claroty: Evil PLC Attack whitepaper: https://web-assets.claroty.com/resource-downloads/team82-evil-plc-attack-research-paper-1661285586.pdf
Legal References
- EFF Reverse Engineering FAQ: https://www.eff.org/issues/coders/reverse-engineering-faq
- 17 U.S.C. § 1201 (DMCA Anti-Circumvention): https://www.law.cornell.edu/uscode/text/17/1201
- PLC Password Protection and IP: https://industrialmonitordirect.com/blogs/knowledgebase/plc-password-protection-source-code-escrow-and-intellectual-property-management-for-industrial-autom?srsltid=AfmBOopuLnOpof2E3gCKMNhGvoeeNun-gW7fS9KtzlnXhKMcnI9oT661
Practical Guides
- B&R CP474 Source Code Recovery: https://industrialmonitordirect.com/blogs/knowledgebase/br-cp474-source-code-upload-is-recovery-possible
- Extracting Variables Without Source Code: https://industrialmonitordirect.com/blogs/knowledgebase/extracting-variables-from-br-cp476-plc-without-source-code
- Reverse Engineering PLC Programs Without Documentation: https://industrialmonitordirect.com/blogs/knowledgebase/reverse-engineering-plc-programs-without-documentation
- B&R Binary Code Transfer Without Source: https://industrialmonitordirect.com/blogs/knowledgebase/br-3if26060-1-plc-binary-code-transfer-without-source
- B&R Automation Studio Locating Data Files: https://industrialmonitordirect.com/blogs/knowledgebase/br-automation-studio-locating-data-files-and-cross-references
Community Discussions
- Reddit: Reverse engineering a PLC: https://www.reddit.com/r/PLC/comments/tmibn8/my_boss_wants_to_reverse_engineer_a_plc_and_put/
- Reddit: Methods for reverse engineering ladder logic: https://www.reddit.com/r/PLC/comments/1e5kiq6/what_methods_do_you_use_to_reverse_engineer/
- PLCtalk: B&R PLC software formats: https://www.plctalk.net/forums/threads/b-r-plc-software.108978/
- PLCtalk: Uploading from B&R X20CP0292: https://www.plctalk.net/forums/threads/upload-its-program-from-b-r-x20cp0292-by-using-automation-studio-4-3.118261/
- MrPLC: Opening B&R 2005 files: https://mrplc.com/forums/topic/33225-open-br-2005-files/
Key Findings
-
B&R compiles IEC 61131-3 source through a proprietary frontend to C code, then through an embedded GCC cross-compiler to native x86/ARM machine code (
.brfiles). There is no intermediate bytecode layer like Siemens MC7, meaning standard disassemblers (IDA Pro, Ghidra, rizin) can analyze the binaries directly using conventional x86/ARM techniques. -
Source code cannot be recovered from compiled
.brbinaries. The IEC-to-C-to-machine-code pipeline is doubly lossy: language-specific constructs (ladder rungs, FBD wiring, SFC steps) are destroyed in the first translation, and variable names, comments, and project structure are stripped in the second. At best, C-like pseudocode can be recovered via Ghidra’s decompiler. -
Automation Studio cannot upload source code from a running PLC – only compiled binaries are stored on the controller. Without the original
.arproject archive, the only actionable recovery paths are: (a) online monitoring via PVI/AS to extract variable names and values, (b) binary disassembly to recover control flow and constant values, and (c) IO mapping recovery from memory access patterns in the disassembled code. -
Information with the highest recoverability from binaries includes string literals, error messages, constant values (immediate operands), function boundaries (prologue/epilogue patterns), and library call references. Symbolic variable names are only recoverable if the compiler’s symbol export option was enabled at build time.
-
The ICSREF framework (NDSS 2019, github.com/momalab/ICSREF) and PLC-BinX (2025) provide automated PLC binary analysis methodologies, though neither is B&R-specific. ICSREF’s approach – format identification, symbol table recovery, control flow analysis – is directly applicable to B&R’s GCC-compiled output.
-
B&R provides four IP protection mechanisms: compiled libraries (binary distribution with only interface definitions), password protection (per-task/library), source file “encryption” (actually access control, not real encryption), and Technology Guarding (server-based licensing with SSL/TLS). The encryption mechanism is acknowledged by the community as a deterrent, not cryptographic protection.
-
For practical analysis without source code, connect Automation Studio to the running PLC to monitor variable values, force IO states, and browse the online variable list. ARsim can load compiled binaries for behavioral analysis in a sandboxed PC environment without physical hardware.
-
IO mapping recovery requires identifying memory-mapped read/write patterns in disassembled code (mov/load/store instructions targeting known IO address ranges), then cross-referencing those addresses with B&R hardware documentation to map them to physical IO points. Network-based IO (POWERLINK, EtherCAT) does not follow simple memory-mapped patterns.
Cross-References
| Related File | Relevance |
|---|---|
| cp1584-forensics.md | Information extraction methodology from a running CP1584 without project files |
| project-reconstruction.md | Building a new Automation Studio project from an unknown running PLC |
| memory-map.md | CPU memory map and IO address ranges for binary analysis cross-referencing |
| cf-card-boot.md | CF card file structure where compiled binaries are stored |
| config-file-formats.md | Configuration file formats related to compiled project deployment |
| pvi-api.md | PVI API for online variable browsing and runtime analysis |
| execution-model.md | Task structure and IEC 61131-3 execution model relevant to binary analysis |
| firmware.md | AR firmware architecture and how compiled modules are loaded |
| license-mgmt.md | IP protection and Technology Guarding for compiled libraries |
| access-recovery.md | Gaining access to an undocumented PLC for analysis |
| io-card-hardware.md | IO module addressing for mapping binary IO access patterns to physical modules |
| ar-rtos.md | VxWorks-based OS internals that execute the compiled binaries |
| cp1584-hardware-ref.md | CPU architecture (Intel Atom E640T) determining x86/32-bit binary format |
| opcua.md | OPC-UA server for online variable browsing without source code |
| modbus-gateway.md | Modbus TCP as an alternative data extraction protocol |
| system-variables.md | AR system variables available for runtime monitoring during behavioral analysis |
| diagnostics-sdm.md | System Diagnostics Manager for error tracking on running systems |
| io-sniffing.md | Fieldbus traffic interception for IO behavior mapping |
| ftp-web-interface.md | Remote file access methods for binary extraction |
| bootloader-recovery.md | Serial console access in bootloader mode for binary retrieval |
| online-changes.md | Runtime patching techniques for behavioral testing |
| custom-diagnostic-tools.md | Building diagnostic programs that run on the PLC itself |
| python-diagnostics.md | Python + PVI/OPC-UA scripts for automated data extraction |
| documentation-reconstruction.md | Systematic documentation of undocumented B&R machines |
| safe-io-diagnostics.md | Safety system considerations when analyzing safety-related code |
Document compiled from public sources including B&R documentation, academic research, security publications, and community forums. Last updated: July 2026.