ConceptioArchivearXiv CS
arXiv CSopen access

One Step Further: Understanding PLC Binaries Through Cross-Platform Reverse Engineering and Function-Level Semantic Analysis

2026 · arxiv_cs
arXiv CS · Papers · License: Open Access · 2026
Open Source ↗Direct PDF ↓
software-architecturesoftware-engineeringtesting
software engineering, software architecture, testing

1

One Step Further: Understanding PLC Binaries Through Cross-Platform Reverse Engineering and Function-Level Semantic Analysis

arXiv:2605.17392v1 [cs.SE] 17 May 2026

Ang Jia, Yaxin Duan, He Jiang, Zhenzhou Tian, Zhilei Ren, and Xiaochen Li

Abstract—As emerging attacks increasingly target Industrial Control Systems (ICS), the security of Programmable Logic Controllers (PLCs) has become a critical concern. Binary Code Analysis (BCA), which enables analysts to understand compiled programs without source code, is essential for ICS security tasks such as post-attack digital forensics and incident response. However, automated BCA for PLC binaries remains challenging due to three key issues: heterogeneous binary formats across PLC platforms, entangled program semantics caused by the mixture of control logic with runtime code, and limited semantic representations for interpretable and learning-based downstream analysis. In this paper, we present PLC-BinX, a BCA workflow for cross-platform PLC binary understanding. PLC-BinX analyzes PLC binaries from four platforms: CODESYS v3, GEB, OpenPLC v2, and OpenPLC v3, and recovers function-level information through cross-platform reverse engineering, corefunction extraction, and function-level semantic representation construction. Based on the recovered semantic representations, we further study two downstream tasks: toolchain prediction and functionality prediction. Under ten-fold program-level evaluation, PLC-BinX achieves 100.00% precision, recall, and F1 in toolchain prediction, and 51.43% precision, 49.38% recall, and 49.18% F1 in functionality prediction over 22 labels. The results demonstrate that PLC-BinX provides an effective and interpretable approach to cross-platform PLC binary understanding by exposing taskrelevant function-level semantics from heterogeneous PLC binaries. Index Terms—PLC binary analysis, cross-platform reverse engineering, function-level semantic representation

I. I NTRODUCTION

I

NDUSTRIAL Control Systems (ICS) are increasingly exposed to cyber threats that can affect not only digital assets but also physical processes. At the center of many ICS environments are Programmable Logic Controllers (PLCs), which are attractive targets. For example, Stuxnet targeted Siemens industrial control systems and modified PLC logic to manipulate the operation of centrifuges while hiding abnormal behavior from operators [1]. Other studies have shown that vulnerabilities in widely deployed PLC runtime components can be abused to implant backdoors or gain control of industrial applications [2]. Since PLCs are the core components that bridge software decisions and physical process execution, their This work has been submitted to the IEEE for possible publication. Copyright may be transferred without notice, after which this version may no longer be accessible. Corresponding author: He Jiang. E-mail: [email protected]. Ang Jia, Yaxin Duan, He Jiang, Zhilei Ren, and Xiaochen Li are with the School of Software, Dalian University of Technology, Dalian, China. Zhenzhou Tian is with the School of Computer Science and Technology, Xi’an University of Posts and Telecommunications, Xi’an, China.

binary-level security directly affects the safety and reliability of industrial operations. Understanding PLC binaries is therefore important for ICS security. After an attack, digital-forensics and incidentresponse (DFIR) analysts may need to inspect a deployed PLC binary to determine what logic was executed and which control routine was modified. However, attackers rarely leave behind the source code, engineering project, or build configuration of their malicious logic. In many cases, the deployed binary is the only available program representation. Binary Code Analysis (BCA), which enables analysts to understand compiled programs without source code, is therefore a fundamental capability for post-attack forensics, incident response, and deployed-binary auditing. Existing studies have advanced PLC binary analysis and ICS binary reverse engineering. For example, PLC-BEAD [3] provides a benchmark of PLC binaries compiled from multiple platforms and programming languages, enabling systematic evaluation of learning techniques for PLC binaries. It further proposes PLCEmbed for functionality prediction and toolchain prediction from raw binary bytes. ICSREF [4] automates the reverse engineering of CODESYS v2-compiled PLC binaries and demonstrates how such capability can support both defensive analysis and process-aware attack generation. These efforts have improved PLC binary understanding for security analysis. However, existing methods still face three challenges, especially when moving to cross-platform PLC binary understanding. C1: Heterogeneous Binary Formats. PLC binaries are highly heterogeneous across platforms. Existing reverseengineering frameworks such as ICSREF show that automated analysis is feasible for CODESYS v2 binaries, but PLC binaries produced by different platforms expose substantially different binary structures. For example, CODESYS v3 applications are packaged as .app containers rather than standard ELF or PE executables, GEB binaries appear as ARM ELF executables with generated POU-style symbols, and OpenPLC v2 and OpenPLC v3 binaries appear as PE executables. These binaries differ in binary format, architecture, and runtime organization. Therefore, a method designed for one PLC platform cannot be directly applied to others. C2: Entangled Program Semantics. A PLC binary contains application logic, compiler-generated support code, runtime and library functions, and platform-support code. Only the application logic directly reflects user-defined PLC control semantics, while the other parts may dominate binary rep-

2

resentations and obscure application semantics. For example, PLCEmbed uses the entire binary for functionality prediction, where irrelevant semantics may dominate the learned representation and obscure the actual control logic. C3: Limited Semantic Representation. Existing PLC binary code analysis methods either rely on low-level inputs or stop at assembly-level reverse-engineering outputs. For example, PLCEmbed predicts functionality from raw bytes, which do not explicitly encode functions, basic blocks, or calls. ICSREF raises the abstraction level by recovering function boundaries and function call relationships, but its representation still largely remains at the assembly level. Therefore, existing representations remain insufficient for interpretable and learning-based PLC binary understanding. This paper presents PLC-BinX, a BCA workflow for crossplatform PLC binary understanding across CODESYS v3, GEB, OpenPLC v2, and OpenPLC v3. To address C1: Heterogeneous Binary Formats, PLC-BinX performs cross-platform reverse engineering and normalizes different PLC binaries into comparable function-level information, including instructions, function identities, function boundaries, and function calls. To address C2: Entangled Program Semantics, PLC-BinX extracts core control functions using platform-specific functionidentification rules, while preserving runtime functions separately for provenance analysis. To address C3: Limited Semantic Representation, PLC-BinX constructs functionlevel semantic representations, including normalized instruction sequences and ACFGs, to capture instruction semantics and intra-function control-flow structure. We evaluate PLC-BinX on PLC-BEAD, which contains 2,431 PLC binaries across four platforms, through two downstream tasks: toolchain prediction and functionality prediction. Experimental results show that PLC-BinX achieves 100.00% precision, recall, and F1 in toolchain prediction, and 51.43% precision, 49.38% recall, and 49.18% F1 in functionality prediction over 22 labels. These results demonstrate that reverse engineering can transform raw PLC binaries into inspectable function-level semantic representations for ICS security analysis. This paper makes the following contributions: To the best of our knowledge, we present the first BCA workflow, PLC-BinX, for cross-platform PLC binary understanding across four platforms: CODESYS v3, GEB, OpenPLC v2, and OpenPLC v3. • We design a three-stage analysis workflow in PLCBinX, including cross-platform reverse engineering, corefunction extraction, and function-level semantic representation construction. • Based on the recovered semantic representations, we propose two representation-based learning frameworks for toolchain prediction and functionality prediction. • We evaluate PLC-BinX on PLC-BEAD, which contains 2,431 PLC binaries across four platforms, through toolchain prediction and functionality prediction. Experimental results show that PLC-BinX achieves 100.00% precision, recall, and F1 in toolchain prediction, and 51.43% precision, 49.38% recall, and 49.18% F1 in func-

Fig. 1. The role of PLCs in a typical ICS.

tionality prediction under ten-fold program-level evaluation. II. BACKGROUND A. PLCs in Industrial Control Systems Industrial Control Systems (ICS) are used to monitor and control physical processes in domains such as manufacturing, energy, transportation, and water treatment. A typical ICS contains multiple layers, including supervisory software, communication networks, industrial controllers, and field devices. Among these components, PLCs play a central role because they directly bridge cyber decisions and physical process execution. Figure 1 shows how PLCs connect supervisory components, field devices, and physical processes in a typical ICS. PLCs receive sensor inputs from the field, execute control logic, and output commands to actuators such as motors, valves, pumps, and relays. In a typical deployment, supervisory components such as engineering workstations, Human–Machine Interfaces (HMIs), or SCADA servers configure and monitor the control system, while PLCs execute time-critical control tasks close to the physical process. Because PLC behavior directly affects plant operation, the correctness and security of PLC software are critical to industrial safety and reliability. Most PLCs operate in a cyclic scan model. In each scan cycle, the controller first reads process inputs, then executes the user-defined control program, and finally writes outputs to the field devices. As a result, even small changes in PLC logic may directly alter the behavior of physical processes. This tight coupling between software and process control is what makes PLC software security particularly important in ICS. B. PLC Source Code and Compilation Process PLC applications are commonly developed in IEC 611313 languages, including Structured Text (ST), Ladder Diagram (LD), Function Block Diagram (FBD), Instruction List (IL),

3

TYPE oscat_PT_ARRAY: ARRAY [1..100] OF REAL; END_TYPE FUNCTION _ARRAY_ABS : BOOL VAR_IN_OUT PT : oscat_PT_ARRAY; END_VAR VAR_INPUT SIZE : UINT; END_VAR VAR i : INT; STOP : INT; END_VAR STOP := SHR(SIZE, 2) - 1; FOR i := 1 TO STOP DO PT[i] := ABS(PT[i]); END_FOR; _ARRAY_ABS := TRUE; END_FUNCTION PROGRAM program0 VAR LocalVar0 : oscat_PT_ARRAY; LocalVar1 : UINT; LocalOUT : BOOL; END_VAR LocalOUT := _ARRAY_ABS(LocalVar0, LocalVar1); END_PROGRAM

Fig. 2. Example of PLC source organization using POUs.

and Sequential Function Chart (SFC) [5]. These languages provide different programming abstractions for industrial control tasks. For example, ST is a textual language similar to Pascal, LD is a graphical language derived from relay logic, and FBD expresses programs through interconnected function blocks. A PLC project is usually organized into Program Organization Units (POUs), such as programs, functions, and function blocks. Programs typically define the main control logic, functions encapsulate reusable computations, and function blocks combine logic with internal state. As shown in Figure 2, the program program0 invokes the user-defined function _ARRAY_ABS, which iterates over an array and replaces each element with its absolute value. The example also shows typical PLC project elements, including data declarations and function interfaces. Compared with ordinary desktop software, PLC source projects contain not only algorithmic logic but also engineering context that binds the software to the physical process. After development, the source project is compiled by a platform-specific engineering environment or compiler toolchain into a deployable binary for the target PLC runtime. For example, in CODESYS, the development system generates PLC-executable application code from the source project before downloading the application to the controller; this process checks allocations, data types, and library availability, and allocates memory addresses during code generation [6]. A boot application can then be created as an .app file for execution on the PLC [7]. In OpenPLC toolchains, IEC 61131-3 programs can be translated into lower-level C code by compilers such as matiec before the generated code is compiled into a binary [8]. Consequently, the final deployed binary contains both user-defined control logic and systemgenerated code introduced by the compiler, libraries, and

runtime environment.

C. PLC Binary Formats This paper analyzes the compiled PLC binary rather than the source project. Compared with the source-level view, the binary-level view is much less transparent: source-level names, POU boundaries, variable declarations, and engineering context may be transformed, partly or completely hidden depending on the target platform and compilation process. As a result, analysts cannot assume that the structure visible in the source project can be directly observed from the deployed binary. PLC binaries also vary substantially across platforms. Some platforms generate conventional executable files, while others package code and metadata into vendor-specific containers. Moreover, the deployed binary usually contains not only application-level control logic, but also compiler-generated support code, runtime and library functions, and platformsupport code. Therefore, a PLC binary is a composite compiled output shaped by the source project, the compiler toolchain, and the runtime environment, rather than a simple translation of the user program. From a security perspective, these binary forms are important because the deployed binary is often the only available form of the program for incident response, malware analysis, and supply-chain auditing. Even when analysts cannot access the original project files, source code, or engineering environment, they may still inspect the binary deployed on the controller. This makes PLC binary understanding a necessary step toward analyzing real-world industrial software.

III. A PPROACH The goal of PLC-BinX is to transform a deployed PLC binary into structured and inspectable function-level semantic representations for downstream security analysis. As shown in Figure 3, PLC-BinX takes PLC binaries from four platform settings, including CODESYS v3 .app containers, GEB ARM ELF executables, and OpenPLC v2 and OpenPLC v3 PE executables, as input. The workflow consists of three stages. First, PLC-BinX performs platform-aware reverse engineering to recover comparable function-level information from heterogeneous binary formats. Second, PLC-BinX identifies core control functions that are more likely to represent userdefined PLC logic, while preserving runtime functions separately. Third, PLC-BinX constructs function-level semantic representations, including normalized instruction sequences and ACFGs, for recovered functions. These representations are then used in two downstream tasks: toolchain prediction and functionality prediction. Toolchain prediction uses normalized instruction sequences of runtime functions to capture compiler and runtime provenance, while functionality prediction uses ACFGs of core functions to model application-level PLC behavior. The following subsections describe these stages in detail.

4

Input PLC Binaries

.app

CODESYS v3 (.app)

ELF

GEB (ARM ELF)

PE

OpenPLC v2 (PE)

PE

Cross-Platform Reverse Engineering

Core Function Identification

Function-Level Semantic Representation

Downstream Tasks

Runtime Functions CODESYS-specific Reverse Engineering Tool

Runtime Environment

Normalized instructions

Toolchain Prediction

ACFG structures

Functionality Prediction

Core Functions Control Logic

IDA-based Analysis for GEB and OpenPLC

OpenPLC v3 (PE)

Fig. 3. Overview of the PLC-BinX workflow.

TABLE I PLC PLATFORMS AND BINARY FORMS IN THE DATASET. Platform

Binary form

CODESYS v3 [7] GEB [3] OpenPLC v2 [9] OpenPLC v3 [9]

.app container ARM ELF executable PE executable PE executable

Total

# Binaries 555 617 619 640 2,431

A. Input PLC Binaries We use PLC-BEAD [3] as the dataset for our study. To the best of our knowledge, PLC-BEAD is the only publicly available and well-documented PLC binary dataset for systematic PLC binary analysis. Table I summarizes the PLC platforms, binary forms, and dataset scale of this dataset. The dataset contains 729 PLC programs and 2,431 compiled binaries across four platform settings. Not every source program has a corresponding binary on every platform, because some programs cannot be compiled under specific toolchains. The four platform settings cover three representative PLC binary forms: vendor-specific application containers, ELF executables, and PE executables. CODESYS v3 applications are distributed as vendor-specific .app containers. GEB binaries are ARM ELF executables, while OpenPLC v2 and OpenPLC v3 binaries are PE executables. These differences show why PLC binary understanding requires platform-aware analysis instead of a single uniform parsing strategy. B. Cross-Platform Reverse Engineering Because PLC platforms use different binary formats, PLCBinX applies platform-specific reverse-engineering procedures. For standard executable formats, including GEB ARM ELF binaries and OpenPLC v2 and OpenPLC v3 PE binaries, PLC-BinX uses IDA-based disassembly and controlflow recovery. For CODESYS v3, whose .app files are vendor-specific application containers rather than standard executables, PLC-BinX proposes a CODESYS-specific reverse-

engineering method. Although these procedures differ internally, their outputs are normalized into the same functionlevel information, including instructions, function identities, function boundaries, and function calls. 1) IDA-based Reverse Engineering: For GEB and OpenPLC binaries, PLC-BinX first loads the executable into IDA and performs batch disassembly. IDA recovers function names, function boundaries, assembly instructions, basic blocks, control-flow edges, and direct call relationships. These outputs provide both identity-level and semantic-level information for later analysis. Function boundaries and assembly instructions define the instruction sequence of each recovered function, basic blocks and control-flow edges support CFG and ACFG construction, and direct call relationships are used to build callrelated representations such as FCGs. The recovered names also support later core-function identification. For example, the control logic functions in GEB binaries expose generated POU-style names such as dt_PR_* and dt_FN_*, while the control logic functions in OpenPLC binaries expose C++style generated names such as PROGRAM0_body__ and __PROGRAM0__*. 2) CODESYS v3 Reverse Engineering: CODESYS v3 requires a separate reverse-engineering method because its .app files are vendor-specific application containers rather than standard ELF or PE executables. As a result, they cannot be directly analyzed by the ordinary IDA-based batch disassembly process, which assumes a conventional executable loader, section layout, entry information, and symbol information. PLC-BinX therefore implements CODESYS-specific reverse engineering with three main steps: identifying code regions, recovering function boundaries and control flow, and recovering function names from metadata records. The recovered outputs are then converted into the same unified schema used by the IDA-based platforms. Code region identification. Since a CODESYS v3 .app file does not provide a standard executable header or section table, PLC-BinX first probes the container layout to locate candidate code regions. To separate executable code from container-level data, PLC-BinX compares the byte layouts

5

of multiple .app files. Regions that remain highly similar across different applications are more likely to correspond to fixed container structures, metadata records, headers, or tables, whereas regions that vary substantially across applications are more likely to contain application-specific compiled code. PLC-BinX then scans aligned byte sequences in these variable regions as ARM32 little-endian instructions. Regions that can be consistently decoded into valid instruction sequences with plausible control-transfer patterns are treated as executable code regions. This step recovers code regions directly from the .app binary without relying on source code or vendor tooling. Function Boundary and Control Flow Recovery. After locating candidate code regions, PLC-BinX uses Capstone [10] to disassemble the recovered ARM32 instruction streams. Since CODESYS v3 .app files do not expose standard function tables or symbol-based entry lists, PLC-BinX recovers function boundaries from several binary-level indicators. First, it identifies potential function entries from common ARM prologue patterns and branch or call targets that point into executable regions. Second, starting from each candidate entry, it expands the function body by following the sequential instruction stream, conditional branches, and intra-function jump targets. Direct call targets are recorded as call relations, while the fall-through path after the call is kept in the current function. Third, PLC-BinX determines function exits using return-like transfers, tail branches, jumps to known function entries, and the boundary imposed by the next candidate function entry. When all reachable paths from an entry reach such stopping points, the covered address range is treated as a recovered function. Each recovered function is exported with an address-based identity, such as sub_000145E0, together with its assembly instructions, basic blocks, controlflow edges, and call-related transfer information. Function name recovery. Finally, PLC-BinX parses metadata records embedded in the .app file to recover binaryvisible symbol names. These records may contain symbol names and associated code or data pointers. PLC-BinX uses these code pointers to associate metadata-visible symbols with recovered functions. In this way, metadata-visible units such as PLC_PRG and user-defined POU functions receive recovered names, while runtime helpers and support functions without metadata-visible names remain represented by addressbased identities. For example, in _ARRAY_ABS.app, PLCBinX associates metadata symbols such as PLC_PRG and _ARRAY_ABS with recovered functions, producing named recovered functions for later core-function identification and semantic modeling. C. Core Function Identification Function recovery is a necessary intermediate step, but it does not by itself distinguish application-level semantics from platform and runtime behavior. PLC binaries contain not only application logic functions, but also compiler-generated support code, runtime and library functions, and platformsupport functions. These non-application functions provide toolchain-provenance information, but they can obscure the

TABLE II C ORE - FUNCTION NAMING PATTERNS ACROSS PLC PLATFORMS . Platform

Core-function naming patterns

CODESYS v3 GEB OpenPLC v2 and v3

PLC_PRG, recovered function names dt_PR_*, dt_FN_*, dt_FB_* PROGRAM0_body__, __PROGRAM0__*

application-specific control logic needed for functionality prediction. PLC-BinX therefore separates recovered functions into two categories: Core functions: functions most likely to implement application-level PLC semantics. These functions describe what the PLC program does and are therefore used as the primary input for functionality prediction. • Runtime functions: non-core functions outside the application control logic, including compiler-generated support code, runtime and library functions, and platformsupport functions. Their instruction sequences, function hashes, and call patterns provide toolchain-related features. •

Core functions are used to represent application semantics for functionality prediction, whereas runtime functions are retained for toolchain prediction. This separation is necessary because functions that are less relevant to application understanding can still be informative for identifying the compilation toolchain or runtime version. Table II shows the core-function naming patterns across PLC platforms. For CODESYS v3, PLC-BinX uses symbols recovered from .app records as the main criterion for core-function identification. The PLC_PRG symbol is treated as the primary seed because it represents the main PLC program organization unit. Other recovered POU, function, or method symbols are also included as application-level semantic units. PLC-BinX associates these metadata-visible symbols with recovered CODESYS functions and excludes unmatched runtime, wrapper, and container-level code from the core functions. For GEB, program logic is usually rooted at dt_PR_program0_exec. PLC-BinX therefore chooses the program execution function as the seed and follows function calls to collect the user-level callable region. When this traversal reaches GEB runtime hooks, PLC-BinX records the outgoing calls but does not expand the hook implementations into the core-function set. For OpenPLC v2 and OpenPLC v3, PLC-BinX uses functions containing PROGRAM0_body__ as the core seeds because they implement the main ST program body. Starting from these seeds, PLC-BinX follows function calls to collect candidate functions. It then filters functions that match standard C and C++ library patterns, OpenPLC runtime patterns, or platform-support patterns. This keeps the core functions focused on application logic rather than runtime or library functions. The same extraction rule is used for OpenPLC v2 and v3 because their application-level program bodies follow the same generated-code structure. After core-function identification, PLC-BinX treats the re-

6

TABLE III E XAMPLES OF INSTRUCTION NORMALIZATION .

TABLE IV E XAMPLES OF ACFG NODE INFORMATION .

Raw instruction

Normalized tokens

Node information

Example values

MOV R3, R0 CMP R3, #2 LDR R0, [SP,#8] BL _ARRAY_ABS BL 0x4012A0 MOV PC, R6

mov reg reg cmp reg imm ldr reg mem bl call_name:_ARRAY_ABS bl call_addr mov call_indirect

Instruction tokens Instruction count Control-flow degree Function category

mov reg reg; cmp reg imm bb_len:9-16 bb_in:1; bb_out:2 core_function

CODESYS

maining recovered non-core functions as runtime functions. In this work, the term “runtime functions” is used broadly to include runtime functions, library functions, compiler-generated support code, and platform-support functions. These functions are not used as the primary input for functionality prediction, but they are preserved because they contain distinctive toolchain and runtime-version fingerprints.

Runtime functions

Normalized instruction sequences

Stage 1 Transformer

GEB

OpenPLC

OpenPLC runtime hashes + layout + names

Stage 2 lightweight classifier

OpenPLC v2

OpenPLC v3

Fig. 4. Workflow of PLC-BinX for toolchain prediction.

D. Function-Level Semantic Representation After identifying core functions and runtime functions, PLC-BinX constructs semantic representations for the functions selected by each task. Both core functions and runtime functions can be represented as normalized instruction sequences or ACFGs. The runtime-function fingerprints used later for OpenPLC version prediction are derived task features, not a separate function-level representation. Normalized instruction sequences. For each selected function, PLC-BinX normalizes assembly instructions before constructing model inputs. As shown in Table III, the normalization keeps the opcode semantics while abstracting unstable operands. Mnemonics are lowercased, registers are replaced with reg, memory operands are represented by abstract memory tokens, and numeric immediates are replaced with imm. For example, MOV R3, R0 becomes mov reg reg, while CMP R3, #2 becomes cmp reg imm. Direct calls are handled specially because they carry semantic information about inter-function dependencies. If the call target can be resolved to a binary-recovered function name, PLC-BinX keeps a name-aware call token such as call_name:_ARRAY_ABS; otherwise, unresolved direct calls and indirect transfers are represented using generic tokens such as call_addr and call_indirect. This representation preserves semantic information available in the recovered binary while reducing sensitivity to unstable low-level operands. ACFGs. Recovered functions can also be represented as an ACFG. Each node corresponds to a basic block, and its primary feature is the normalized instruction sequence inside that basic block. The normalization follows Table III. As shown in Table IV, PLC-BinX also adds lightweight blocklevel context and function-category information when such information can be recovered. Edges are derived from decoded control-transfer instructions. A conditional branch such as BNE loc_1 adds both a target edge and a fall-through edge, while an unconditional branch such as B loc_2 or JMP loc_2 adds only a target edge. Return-like instructions such as BX LR, RET, or MOV PC, LR mark function exits.

E. Downstream Tasks Based on the recovered function-level representations of core and runtime functions, PLC-BinX supports two downstream PLC binary understanding tasks: toolchain prediction and functionality prediction. These two tasks require different function categories and representations. Toolchain prediction asks which compiler and runtime produced the binary, so it mainly relies on normalized instruction sequences of runtime functions and derived runtime-function fingerprints. Functionality prediction asks what application behavior the PLC program implements, so it focuses on ACFGs of core functions that carry application-level control logic. Toolchain prediction. As shown in Figure 4, we design a two-stage toolchain prediction model. The first stage performs coarse-grained platform-family prediction, distinguishing CODESYS, GEB, and OpenPLC. The second stage is applied only to binaries predicted as OpenPLC and further distinguishes OpenPLC v2 from OpenPLC v3. This design is motivated by our reverse-engineering observations. Across CODESYS, GEB, and OpenPLC, binaries differ substantially in file format, instruction architecture, symbol style, function organization, and runtime structure. Therefore, the coarse platform family can be reliably identified from broad binarylevel and function-level features. In contrast, OpenPLC v2 and OpenPLC v3 are much closer: they compile the same ST programs into highly similar application-level functions, but slightly differ in the surrounding runtime functions and platform-support code. A flat classifier tends to learn the large gap among platform families while missing the subtle versionlevel distinction inside OpenPLC. The hierarchical design therefore separates these two levels of variation. In the first stage, PLC-BinX uses runtime functions as input. For each binary, runtime functions are represented as normalized instruction sequences. These sequences are then concatenated into a binary-level token sequence and fed into a Transformer classifier to predict one of three platform

7

Core functions

ACFGs

Function embeddings

GNN encoder

encode the application-level PLC behavior. IV. E XPERIMENTS

Binary-level aggregation

Binary embeddings

Classifier

Functionality label

Fig. 5. Workflow of PLC-BinX for functionality prediction.

families: CODESYS, GEB, or OpenPLC. Runtime functions are used because they are introduced by the compiler, runtime, and platform environment, whereas core functions are mainly derived from user-written PLC logic. Therefore, normalized instruction sequences of runtime functions provide more stable and platform-specific features for toolchain prediction, while representations derived from core functions may vary with the application semantics. In the second stage, PLC-BinX focuses on OpenPLC samples and derives runtime-function fingerprints to distinguish OpenPLC v2 from OpenPLC v3. These fingerprints are taskspecific binary-level features derived from normalized instruction sequences of runtime functions and metadata, rather than function-level semantic representations. They include hashes of normalized instruction sequences of runtime functions, layout features such as the number and size distribution of runtime functions, and recovered runtime function names. A lightweight classifier based on runtime-function fingerprints then predicts the final OpenPLC version label, either OpenPLC v2 or OpenPLC v3. Functionality prediction. For functionality prediction, PLC-BinX adopts a hierarchical ACFG-GNN architecture over recovered core functions, as shown in Figure 5. The input to the model is a set of core-function ACFGs extracted from one PLC binary. Each ACFG represents one core function: basic blocks are modeled as graph nodes, node features are constructed from normalized instruction tokens and recovered function categories, and edges encode intra-function control flow. The model contains two levels of representation learning. At the function level, a GNN encoder propagates information along the ACFG edges and computes a graph-level embedding for each core function. This embedding summarizes the instruction semantics and control-flow structure inside the function. At the binary level, an aggregation layer combines the embeddings of all selected core functions into a single binary representation. The final classifier predicts the functionality label from this binary-level representation. This hierarchical design allows PLC-BinX to preserve intra-function controlflow semantics while still modeling the fact that a PLC binary may contain multiple application-level functions. In summary, the two downstream tasks are derived from the unified recovered function-level schema, but they instantiate different task inputs. Toolchain prediction relies on normalized instruction sequences of runtime functions and runtimefunction fingerprints because runtime functions preserve compiler and runtime information, while functionality prediction relies on ACFGs of core functions because core functions

In this section, we first examine how recovered PLC binary functions are distributed across core functions and runtime functions, and then evaluate whether these functionlevel representations improve PLC binary understanding over PLCEmbed-style baselines based on raw bytes. We further analyze the importance of task-specific function-type selection through an ablation study. We answer the following research questions. RQ 1: How are core functions and runtime functions distributed across PLC platforms? RQ 2: How effective is PLC-BinX for PLC binary toolchain prediction compared with PLCEmbed? RQ 3: How effective is PLC-BinX for PLC binary functionality prediction compared with PLCEmbed? RQ 4: How important is the task-specific separation between core functions and runtime functions? A. Study Setup 1) Evaluation Dataset.: We use PLC-BEAD [3] as the evaluation dataset. The dataset contains 729 PLC programs and 2,431 compiled binaries across four platform settings: CODESYS v3, GEB, OpenPLC v2, and OpenPLC v3. The stage-1 toolchain family prediction task uses all 2,431 binaries, including 555 CODESYS samples, 617 GEB samples, and 1,259 OpenPLC samples. The OpenPLC version stage uses 619 OpenPLC v2 samples and 640 OpenPLC v3 samples. The functionality prediction experiments use 2,430 labeled binaries across 22 functionality labels, because one CODESYS v3 binary in PLC-BEAD does not have a functionality label and is excluded only from functionality-related experiments. 2) Experimental Setting.: All inputs to PLC-BinX are constructed from compiled binaries. Source code is not used for reverse engineering, core-function selection, semantic representation construction, or model training. For the learning tasks, we use validation performance for model selection and test-fold performance for reporting. All reported learning experiments use ten-fold program-level cross-validation. In each fold, the programs assigned to the test fold are held out, and the ten test folds together cover the valid binaries once; binaries compiled from the same PLC program are not simultaneously used for training and testing. This stricter program-level setting is different from the evaluation setting used for the PLCEmbed numbers reported in the original paper; therefore, the PLCEmbed baseline in our tables is evaluated under the same program-level split. 3) Evaluation Metrics.: For learning tasks, we report precision, recall, and F1. Unless otherwise specified, aggregate rows, platform-wise results, and ablation results are weighted by the number of samples in each label. We also report perlabel precision, recall, and F1 so that the comparison between PLCEmbed and PLC-BinX can be inspected at each toolchain or functionality label. For the ablation study, we use the same ten-fold program-level protocol and the same metrics as the corresponding downstream task.

8

4) Implementation.: In the reverse-engineering stage, PLCBinX uses platform-specific procedures for different PLC binary formats. For GEB and OpenPLC binaries, PLC-BinX uses the IDA-based extractor [11] to recover assembly and construct ACFGs. For CODESYS v3 .app files, PLC-BinX uses the proposed container-aware reverse-engineering method and Capstone [10] to recover ARM32 instruction streams, function boundaries, and metadata-visible symbols. The toolchain family classifier uses a Transformer encoder [12] over normalized instruction sequences of runtime functions. The OpenPLC version classifier uses a lightweight linear classifier over sparse runtime-function fingerprints. For functionality prediction, PLC-BinX implements a hierarchical ACFG-GNN. At the function level, each corefunction ACFG is encoded by a GraphSAGE-style messagepassing network [13], where basic blocks are nodes and intrafunction control-flow edges define message propagation. The graph-level function embedding is obtained by pooling node embeddings within each function graph. At the binary level, function embeddings from the same binary are aggregated with an attention-based pooling layer and max pooling, and the resulting binary embedding is fed into a two-layer feedforward classifier for functionality prediction. B. RQ 1: Core and Runtime Function Distribution We first characterize how recovered functions are distributed after platform-aware core-function identification. The distinction is necessary because the two downstream tasks rely on different function categories: core functions capture application-level PLC logic, whereas runtime functions capture compiler, runtime, and platform-specific code. Table V reports two aspects of the recovered distribution for each platform: the quantity of recovered functions and the address-range size of these functions. The quantity distribution shows that PLC binaries contain a small number of application-level core functions. Across the four platforms, each binary contains 2.13–3.31 core functions on average. This matches the structure of PLC programs, where the main program body and user-defined routines carry most application semantics. In contrast, runtime functions are much more numerous. GEB contains 754,223 runtime functions in total, corresponding to 1,222.40 per binary on average. OpenPLC v2 and OpenPLC v3 contain 960.99 and 1,079.44 runtime functions per binary, respectively. CODESYS v3 also contains a large surrounding runtime context, with 219,901 runtime functions and 396.22 runtime functions per binary on average. The size distribution further shows that the recovered function categories have different structural characteristics. CODESYS v3 core functions are much larger on average than those of the other platforms, and their mean size is also much larger than their median size. This indicates that a small number of large program-level or POU-level recovered functions dominate the average. Runtime functions are typically smaller than core functions: GEB runtime functions have an average size of 86.6 bytes, and OpenPLC runtime functions have median sizes of 48.0 bytes. OpenPLC v2 and

v3 have similar core-function sizes, but OpenPLC v3 contains more runtime functions, consistent with the additional runtime and communication-support code recovered from OpenPLC v3 binaries. These results support the need for two separated function categories. Runtime functions dominate the set of recovered functions, so a frequency-based or top-k function selection rule can easily select toolchain-related code rather than user PLC logic. PLC-BinX therefore uses platform-specific rules to identify core functions for application-semantics modeling, and preserves the remaining functions as runtime-function features for toolchain analysis. In particular, the similarity between OpenPLC v2 and v3 in core-function statistics motivates the use of runtime-function identities and communicationrelated runtime function names in the second stage of toolchain prediction. Answering RQ 1: Core functions are sparse across PLC binaries, with only 2.13–3.31 core functions per binary on average, while runtime functions are substantially more numerous and platform-dependent, ranging from 396.22 to 1,222.40 functions per binary. This distribution supports our task-specific design: core functions are used for functionality prediction because they encode application logic, whereas runtime functions are used for toolchain prediction because they provide platform- and runtime-specific features. C. RQ 2: Toolchain Prediction We then evaluate whether recovered runtime-function features improve toolchain prediction compared with the PLCEmbed byte-embedding baseline. All results in this RQ use the ten-fold program-level evaluation described in the study setup. Table VI reports per-label precision, recall, and F1. The PLCEmbed byte-embedding baseline reaches 89.49% precision, 89.47% recall, and 89.48% F1, while PLC-BinX reaches 100.00% precision, recall, and F1. Because PLC-BinX performs toolchain prediction hierarchically, Table VI reports the final four toolchain labels: CODESYS v3, GEB, OpenPLC v2, and OpenPLC v3. The results show that PLCEmbed performs well on CODESYS v3 and GEB, but it is less stable on OpenPLC v2 and OpenPLC v3. In contrast, the stage-1 runtime Transformer correctly classifies all CODESYS v3, GEB, and OpenPLC test samples across the ten folds, and the stage-2 runtime-fingerprint classifier correctly separates all OpenPLC v2 and v3 test samples. The most discriminative signals for separating OpenPLC v2 from OpenPLC v3 come from the recovered runtime functions: OpenPLC v3 exposes communication-related runtime functions and names associated with ENIP, PCCC, and Modbus, whereas OpenPLC v2 exposes WiringPi and hardware input and output function names such as wiringPiSetup, digitalRead, digitalWrite, and pwmWrite. Answering RQ 2: PLC-BinX reaches 100.00% precision, recall, and F1 in toolchain prediction under ten-fold programlevel evaluation, while the PLCEmbed byte-embedding baseline reaches 89.49% precision, 89.47% recall, and 89.48% F1. Runtime functions provide stable toolchain-specific features because they are introduced by the compiler, runtime, and platform environment rather than by user-written PLC logic.

9

TABLE V D ISTRIBUTION OF CORE AND RUNTIME FUNCTIONS ACROSS PLC PLATFORMS . Core functions Platform

Binaries

CODESYS v3 GEB OpenPLC v2 OpenPLC v3

555 617 619 640

Quantity

Runtime functions Size

Quantity

Size

Total

Per binary

Mean

Median

Total

Per binary

Mean

Median

1,184 2,042 1,816 1,947

2.13 3.31 2.93 3.04

2,930.6 339.7 517.8 537.4

604.0 142.0 260.0 264.0

219,901 754,223 594,850 690,844

396.22 1,222.40 960.99 1,079.44

359.2 86.6 165.4 174.2

116.0 68.0 48.0 48.0

TABLE VI T OOLCHAIN PREDICTION RESULTS UNDER TEN - FOLD PROGRAM - LEVEL EVALUATION . Platform CODESYS GEB OpenPLC Avg.

PLCEmbed

Version

PLC-BinX

Precision

Recall

F1

Precision

Recall

F1

v3 – v2 v3

99.96% 98.92% 82.77% 85.94%

99.90% 98.81% 83.55% 85.33%

99.93% 98.86% 83.16% 85.63%

100.00% 100.00% 100.00% 100.00%

100.00% 100.00% 100.00% 100.00%

100.00% 100.00% 100.00% 100.00%

89.49%

89.47%

89.48%

100.00%

100.00%

100.00%

D. RQ 3: Functionality Prediction This RQ evaluates whether recovered core-function semantics support functionality prediction. Table VII reports perlabel precision, recall, and F1, together with the number of test binaries for each label after combining the test-fold predictions. After all fold predictions are combined, the hierarchical ACFG-GNN reaches 51.43% precision, 49.38% recall, and 49.18% F1. In comparison, the PLCEmbed baseline based on binary bytes reaches 5.11% precision, 11.85% recall, and 4.90% F1 under the same program-level split. Note that the PLCEmbed results reported here may differ from those in the original PLC-BEAD paper because the training and test partitions are different. We re-evaluate PLCEmbed under the same ten-fold program-level protocol used for PLC-BinX, where binaries compiled from the same PLC program are assigned to the same fold. This prevents binaries derived from the same source program from appearing in both training and test sets. The same protocol is also used for the PLCEmbed baseline in RQ 2. PLC-BinX obtains higher F1 results on labels such as Network_1 (71.93%), Vector_Math (67.53%), Time_and_Date (63.55%), Complex_Math (60.39%), and Ctrl_Mods (59.12%), showing that recovered core functions and their ACFG-level semantics provide taskrelevant signals for PLC functionality prediction. The remaining difficult labels include Arithmetic_Func (17.28%), Basic_Other_Func (25.67%), Signal_Proc (32.35%), and Measure_Mods (33.33%). These results suggest that some minority, scan-cycle-sensitive, or stateful behaviors are still not fully captured by the current functionlevel representation. The small support of several labels, such as Arithmetic_Func with 44 samples and Sensors with 40 samples, can also make functionality prediction less stable across folds. To further inspect platform-level variation, we aggregate the ten-fold predictions of the hierarchical ACFG-GNN by

platform. Table VIII reports the number of valid test binaries, precision, recall, and F1 for each platform. These ten-fold results indicate that core-function recovery and ACFG-based semantic modeling provide a meaningful signal for PLC functionality prediction. However, the task remains difficult. The platform-wise results show that CODESYS v3 has the lowest F1 (34.43%), while GEB reaches 52.46% F1 and OpenPLC v2 and v3 reach 46.67% and 47.49% F1, respectively. This gap suggests that reverse-engineering quality and representation density still affect functionality prediction. Answering RQ 3: PLC-BinX reaches 51.43% precision, 49.38% recall, and 49.18% F1 for functionality prediction over 22 labels under ten-fold program-level evaluation. The result shows the benefit of recovering core functions and modeling their ACFG-level semantics, although functionality prediction remains substantially harder than toolchain prediction. E. RQ 4: Ablation Study on Function-Type Selection RQ 2 and RQ 3 use different categories of recovered functions. Toolchain prediction uses runtime functions because they are introduced by the compiler, runtime, and platform environment, whereas functionality prediction uses core functions because they encode application-level PLC control logic. To test whether this separation is necessary, we design an ablation study that changes the function category used by each downstream task while keeping the corresponding model architecture and ten-fold program-level protocol unchanged. We use a complementary ablation design for the two downstream tasks. For toolchain prediction, the main runtimefunction input is replaced with core functions only and with core plus runtime functions. This tests whether applicationlevel PLC logic can substitute for runtime provenance signals, and whether adding core functions improves platform identification, especially for OpenPLC v2 and OpenPLC v3 binaries that often share similar core logic but differ in runtime and

10

TABLE VII F UNCTIONALITY PREDICTION RESULTS UNDER TEN - FOLD PROGRAM - LEVEL EVALUATION . Functionality label

PLCEmbed

Number

Actuators HVAC Arithmetic Func Array Buffer Mem List Basic Dev Drivers Basic Other Func Building Other Func Calculations Complex Math Ctrl Mods Latches FlipFlop ShiftReg Logic Mods Mathematics Measure Mods Network 1 Network 2 Pulse Gen Sensors Signal Gen Signal Proc Str Func Time and Date Vector Math Avg.

Recall

F1

Precision

Recall

F1

80 44 115 78 75 69 80 104 127 64 216 274 72 56 70 95 40 56 167 177 314 57

0.00% 0.00% 0.00% 0.00% 0.00% 0.07% 0.00% 0.00% 0.00% 0.00% 13.81% 4.34% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 26.24% 0.00%

0.00% 0.00% 0.00% 0.00% 0.00% 4.35% 0.00% 0.00% 0.00% 0.00% 28.70% 1.82% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 69.43% 0.00%

0.00% 0.00% 0.00% 0.00% 0.00% 0.13% 0.00% 0.00% 0.00% 0.00% 18.41% 2.39% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 23.14% 0.00%

54.17% 18.92% 52.68% 37.97% 21.43% 59.65% 38.76% 50.99% 55.10% 56.76% 53.39% 63.89% 33.33% 70.69% 53.85% 38.10% 27.55% 29.07% 41.90% 53.42% 66.90% 53.61%

32.50% 15.91% 51.30% 38.46% 32.00% 49.28% 62.50% 74.04% 63.78% 32.81% 58.33% 41.97% 33.33% 73.21% 30.00% 42.11% 67.50% 44.64% 26.35% 48.59% 60.51% 91.23%

40.62% 17.28% 51.98% 38.22% 25.67% 53.97% 47.85% 60.39% 59.12% 41.58% 55.75% 50.66% 33.33% 71.93% 38.53% 40.00% 39.13% 35.21% 32.35% 50.89% 63.55% 67.53%

2,430

5.11%

11.85%

4.90%

51.43%

49.38%

49.18%

TABLE VIII P LATFORM - WISE FUNCTIONALITY PREDICTION RESULTS OF PLC-B IN X UNDER THE TEN - FOLD PROGRAM - LEVEL EVALUATION . Platform CODESYS v3 GEB OpenPLC v2 OpenPLC v3

PLC-BinX

Precision

Number

Precision

Recall

F1

554 617 619 640

33.62% 52.52% 50.80% 51.43%

37.91% 55.21% 49.79% 50.61%

34.43% 52.46% 46.67% 47.49%

platform-support code. For functionality prediction, the main core-function ACFG input is replaced with runtime functions only and with core plus runtime functions. This complementary setting tests whether non-core functions add useful behavioral information or mainly introduce toolchain-specific signals that are weakly related to application functionality. Table IX reports the main results and the corresponding function-type ablation settings. For toolchain prediction, the main runtime-function setting reaches 100.00% precision, recall, and F1. Replacing runtime functions with core functions reduces the result to 74.19% precision, 74.13% recall, and 74.16% F1, while using core plus runtime functions reaches 74.14% precision, 74.25% recall, and 74.19% F1. This result indicates that directly concatenating application logic with runtime code does not improve over the task-specific runtimefunction representation. For functionality prediction, the main core-function setting reaches 51.43% precision, 49.38% recall, and 49.18% F1. Runtime-only ACFGs reach 16.13% precision, 7.78% recall, and 7.40% F1, indicating that non-core functions mainly encode toolchain and runtime environment information rather than application behavior. Core plus runtime functions reach 48.50% precision, 47.53% recall, and 47.38% F1, which is lower than the core-only setting. This suggests that adding broad runtime-function inputs can weaken the application-

TABLE IX F UNCTION - TYPE ABLATION RESULTS . Task

Function set

Supp.

Prec.

Rec.

F1

Toolchain

Runtime (main) Core (abl.) Core+runtime (abl.)

2,431 2,431 2,431

100.00% 74.19% 74.14%

100.00% 74.13% 74.25%

100.00% 74.16% 74.19%

Functionality

Core (main) Runtime (abl.) Core+runtime (abl.)

2,430 2,430 2,430

51.43% 16.13% 48.50%

49.38% 7.78% 47.53%

49.18% 7.40% 47.38%

level semantic signal needed for functionality prediction. Answering RQ 4: The ablation results support task-specific function selection. Runtime functions provide more stable features for toolchain prediction, while core functions provide the primary semantic representation for functionality prediction. Using core functions for toolchain prediction reduces F1 from 100.00% to 74.16%, and using core plus runtime functions reaches an F1 of 74.19%. For functionality prediction, replacing core functions with runtime functions reduces F1 by 41.78 percentage points, and replacing core functions with core plus runtime functions reduces F1 by 1.80 percentage points. V. D ISCUSSION A. Correctness of CODESYS v3 Reverse Engineering Validating CODESYS v3 reverse engineering is difficult because CODESYS is a closed-source platform. Unlike an open compiler toolchain, it does not allow us to instrument the compiler during code generation, emit complete metadata about function boundaries, or generate a source-to-binary mapping that can serve as an oracle for the PLC-BEAD binaries. Therefore, we do not claim complete ground-truth reconstruction of all CODESYS functions. Instead, we validate the CODESYS reverse-engineering method through two complementary validation sources.

11

First, we audit a stratified sample of 100 CODESYS .app files. For each audited sample, after recovering CODESYS functions, we compare the source-level core POUs and functions with the recovered CODESYS functions. The audit checks whether recovered symbols such as PLC_PRG, userdefined POU names, and function names are mapped to non-empty recovered functions that correspond to the same source-level control logic. Among the 100 audited samples, 71 achieve full core-function coverage, meaning that all sourcelevel core functions are recovered as independent functions. The remaining 29 samples have partial core-function coverage. Across these samples, 272 of 317 source-level core-function mappings are recovered, giving an audited mapping coverage of 85.80%. The partial-coverage cases still recover the main application-level logic, but may miss small helper routines such as bit-extraction helpers, numeric-conversion helpers, date-conversion helpers, or setup functions. Some missing helpers may be inlined, merged into caller functions, or transformed by the CODESYS compilation process. However, the closed-source toolchain prevents us from confirming this for every case. Representative cases illustrate the correspondence. In CMP.app, the recovered functions PLC_PRG, CMP, EXP10, and FLOOR match the source program entry and its floatingpoint comparison helper chain. In DT2_TO_SDT.app, the recovered functions include PLC_PRG, DT2_TO_SDT, DAY_OF_MONTH, DAY_OF_WEEK, DAY_OF_YEAR, LEAP_OF_DATE, MONTH_OF_DATE, and YEAR_OF_DATE, matching the source-level date and time decomposition logic. A partial-coverage example is STAIR.app: the recovered functions PLC_PRG and STAIR match the source program entry and stair-step calculation logic, while the sourcelevel numeric-conversion helper _REAL_TO_DINT does not appear as an independent recovered function. These observations show that the recovered CODESYS functions preserve meaningful source-level function structure in the inspected cases, while also exposing the limitations and granularity differences of helper-level recovery. Second, we use downstream-task performance as an indirect validation signal for CODESYS reverse-engineering quality. The recovered CODESYS functions and representations produced by PLC-BinX are converted into the same function-level schema as GEB and OpenPLC, and are then used in both toolchain prediction and functionality prediction. The results reported in RQ 2 and RQ 3 show that the recovered representations support cross-platform prediction, indicating that the CODESYS reverse-engineering process preserves task-relevant function structure and semantic signals for downstream learning. This result complements the manual inspection by showing that the recovered function-level representations remain effective in complete prediction workflows. Nevertheless, the functionality-prediction result on CODESYS is lower than those on GEB and OpenPLC. This gap indicates that our CODESYS-specific reverse-engineering method provides meaningful recovery but still does not yet match the robustness of IDA-based disassembly for standard ELF and PE binaries, especially in recovering precise function boundaries, resolving call targets, and recovering semantics

inside closed .app containers. B. Failure Modes of PLC-BinX on Functionality Prediction Functionality prediction remains substantially harder than toolchain prediction because functionality labels depend on application semantics rather than stable runtime-function fingerprints. The hardest labels in our results include stateful and scan-cycle-sensitive categories such as Pulse_Gen and Latches_FlipFlop_ShiftReg. These behaviors often depend on persistent memory roles, timer state, rising-edge or falling-edge conditions, and repeated execution across PLC scan cycles. The current ACFG-based representation captures instruction tokens, local control flow, recovered call targets, and coarse function categories, but it does not explicitly model variable roles, data-flow dependencies across scans, or the semantics of IEC 61131-3 runtime state. The label distribution is another factor that affects functionality prediction. As shown in Table VII, several functionality categories contain relatively few binaries even after aggregating the ten folds, such as Sensors with 40 samples, Arithmetic_Func with 44 samples, Network_1 and Signal_Gen with 56 samples, and Vector_Math with 57 samples. With limited examples, the model observes fewer variants of PLC behavior patterns and recovered binary representations for these categories, making the learned decision boundaries less stable. This sample-size limitation partly explains why these labels remain difficult, especially when it is combined with stateful or scan-cycle-sensitive semantics. The performance differences across platforms also suggest that reverse-engineering quality and representation density affect downstream learning. CODESYS v3 has fewer named symbols and larger recovered functions, which can make fine-grained semantic localization harder. GEB and OpenPLC expose more conventional executable structures and generated names, which provide more explicit information for function selection and call-target normalization. These observations motivate two directions for future work. First, richer state-aware representations could explicitly model variable roles, timer and counter states, inter-function data dependencies, and value flows across PLC scan cycles. Such features would help distinguish functionality labels whose semantics depend on persistent memory and repeated execution rather than only local instruction patterns. Second, the CODESYS reverse-engineering method can be further improved by refining function boundary recovery, call target resolution, symbol propagation, and the separation between application logic and runtime code inside .app containers. These improvements would support finer-grained functionality prediction and provide more reliable foundations for broader PLC binary-analysis tasks. C. Scope of Downstream Tasks in PLC Binary Analysis The goal of this paper is to enhance PLC binary understanding by transforming heterogeneous compiled PLC binaries into inspectable function-level semantic representations. In this broader goal, toolchain prediction and functionality prediction serve as two representative and measurable downstream tasks.

12

They capture complementary aspects of PLC binary analysis: toolchain prediction evaluates whether runtime-derived features can reveal the platform or toolchain family, while functionality prediction evaluates whether recovered corefunction semantics can support coarse-grained applicationbehavior recognition. The results on these two tasks suggest that reverseengineered PLC representations can provide task-relevant semantic information beyond syntactic disassembly and can support cross-platform learning under a shared function-level representation. Nevertheless, the scope of this evaluation remains limited. PLC binary analysis can also include vulnerability discovery, forensic auditing, control-flow and dataflow inspection, and safety-property verification. Therefore, our results should be viewed as a concrete step toward PLC binary understanding rather than complete coverage of all PLC binary-analysis goals. VI. T HREATS TO VALIDITY Internal validity. Reverse-engineering tools may introduce errors in function boundary recovery, call-edge recovery, or core-function identification, and such errors can affect both the semantic representations and the downstream prediction results. To reduce this risk, we use IDA Pro, one of the most mature and widely adopted disassembly tools, for reverse engineering on GEB and OpenPLC binaries. For CODESYS, where IDA-based recovery is not directly applicable to closed .app containers, we build a CODESYSspecific reverse-engineering method and validate its recovered functions and representations through the manual inspection and downstream-task validation discussed above. Nevertheless, some errors in recovered boundaries, call targets, or the separation between application logic and runtime code may remain. External validity. Our evaluation uses PLC-BEAD binaries from CODESYS v3, GEB, OpenPLC v2, and OpenPLC v3. These platforms cover multiple binary forms, including .app containers, ELF executables, and PE executables, but they do not cover all commercial PLC vendors, processor architectures, compiler toolchains, or deployment configurations. Results may differ for platforms or compiler toolchains not represented in the dataset. Construct validity. The main construct threat comes from how the evaluation dataset and labels operationalize PLC binary-understanding tasks. Toolchain labels are derived from the platform and compiler toolchain used to build each binary, while functionality labels are inherited from the PLC-BEAD source-program categories. Because our evaluation reuses PLC-BEAD, any errors in its dataset construction, compilation records, or label assignment would be inherited by this study and could affect the measured performance. In addition, the functionality labels are coarse-grained and may not capture all fine-grained PLC control semantics. VII. R ELATED W ORK A. PLC Binary Reverse Engineering General-purpose binary reverse engineering. Generalpurpose reverse-engineering tools provide the foundation for

analyzing conventional executable formats. IDA Pro [11], Ghidra [14], and Capstone [10] support disassembly and control-flow recovery across mainstream architectures, while angr provides a program-analysis platform for binary-level reasoning [15]. Prior studies also show that accurate disassembly remains difficult even for standard binaries because code discovery, function boundary recovery, and indirect control flow recovery are error-prone [16]. Recent learningbased work such as XDA further improves robust disassembly through transfer learning [17]. These tools are suitable for PLC binaries that use standard executable formats, so PLCBinX uses IDA-based disassembly and control-flow recovery for GEB and OpenPLC binaries. However, cross-platform PLC binary understanding also requires additional PLC-specific processing. In particular, PLC-BinX must recover executable code from CODESYS .app containers and separate recovered functions into runtime functions for toolchain prediction and core functions for functionality prediction. PLC binary reverse engineering. PLC binaries have recently attracted increasing attention as reverse-engineering and forensic targets because they contain compiled logic that directly controls physical processes. Denial-of-engineeringoperations attacks introduced Laddis to recover Allen-Bradley ladder logic from binaries [18], while SIMILO reconstructs PLC control logic for forensics by combining dataflow, control-flow, and syntax-flow information [19]. ICSREF provides an automated framework for reverse engineering CODESYS v2-compiled industrial control binaries [4]. CLEVER decompiles PLC applications into control logic [20], and CLADF combines reverse engineering and verification to detect and investigate control-logic attacks [21]. Benkraouda et al. further investigate PLC applications compiled by CODESYS 2.x and 3.x and highlight the need for PLC-specific binary-analysis tools [22]. These studies demonstrate the feasibility and value of recovering PLC semantics from binaries, and prior work has already examined important properties of CODESYS 3.x-compiled PLC binaries. However, existing PLC reverse-engineering studies mainly focus on a specific PLC platform, vendor format, compiler behavior, or forensic target. Moreover, their outputs are often assembly code, decompiled logic, binary characteristics, or task-specific reconstruction results, rather than a unified high-level semantic representation that can support cross-platform downstream analysis. In contrast, PLC-BinX targets a cross-platform PLCbinary setting and normalizes CODESYS v3 .app containers, GEB binaries, OpenPLC v2 binaries, and OpenPLC v3 binaries into a shared function-level semantic representation for toolchain and functionality prediction. B. PLC Binary Datasets and Representation Learning PLC binary datasets. PLC-BEAD bridges the PLC binary analysis gap by providing a cross-compiler dataset of PLC binaries across multiple platforms and compiler settings [3]. This dataset enables systematic evaluation beyond a single vendor, architecture, or binary format, and it is the basis of our study. PLC-BinX reuses PLC-BEAD, but focuses on whether reverse engineering can expose inspectable function-level information

13

from the compiled binaries rather than treating each binary only as a byte sequence. PLC binary representation learning. PLCEmbed introduces a neural framework for PLC binaries based on representations over raw bytes [3]. This design is valuable because it avoids directly handling heterogeneous binary formats. However, raw bytes provide limited access to higher-level semantic information such as functions, calls, control-flow structure, and recovered symbols. In contrast, PLC-BinX studies a representation based on reverse engineering: it separates runtime and core functions, builds function-level semantic representations, and evaluates whether these representations improve interpretability and downstream prediction. Traditional binary representation learning. Binary-code similarity and representation learning have been extensively studied for general-purpose binaries [23], [24]. Early crossarchitecture bug-search systems such as discovRE and Genius rely on numeric features, CFG structure, and graphbased indexing to compare binary functions at scale [25], [26]. Later learning-based methods move from handcrafted features to learned representations: Gemini learns graph embeddings from attributed CFGs [27]; VulSeeker and Order Matters enrich graph representations with semantic block features and order-aware neural modeling [28], [29]; and DeepBinDiff learns program-wide representations for binary diffing [30]. Sequence- and language-model-based approaches further model instruction streams or execution semantics, including SAFE’s self-attentive function embeddings [31], Asm2Vec’s instruction-level representation for clone search [32], PalmTree’s assembly-language pretraining [33], jTrans’s jump-aware Transformer [34], and Trex’s micro-trace-based execution semantics [35]. Recent studies also show that compiler transformations such as function inlining complicate the assumed one-to-one function-matching granularity [36], [37]. These works motivate our use of instruction tokens, ACFGs, and hierarchical aggregation, while PLC-BinX adapts these ideas to heterogeneous PLC binaries. C. Related Research on PLC Security PLC testing. Testing and fuzzing are another important line of PLC security research. ICSFuzz manipulates input and output values and repurposes binary code to enable instrumented fuzzing of ICS control applications [38]. FieldFuzz performs in-situ black-box fuzzing of proprietary industrial automation runtimes through network interfaces [39]. ICSQuartz further introduces scan-cycle-aware fuzzing to align test injection with PLC execution semantics [40]. These approaches are effective for exposing runtime failures or vulnerable behaviors through execution. PLC formal verification. Formal methods provide rigorous reasoning about PLC control logic and safety properties. PLCverif supports formal verification of programmable-logiccontroller programs [41], and VoICS extends this direction to binary-level formal verification for PLC control logic in industrial IoT systems [42]. Such techniques motivate the need to reason about deployed PLC binaries rather than relying only on source-level checks. PLC-BinX shares this binary-level

motivation, but focuses on reverse engineering and semantic representation as a front end for learning-based PLC binary understanding rather than on proving a manually specified safety property. VIII. C ONCLUSION This paper presents PLC-BinX, a cross-platform PLC binary understanding workflow built on reverse engineering and function-level semantic analysis. PLC-BinX recovers functionlevel information from CODESYS v3, GEB, OpenPLC v2, and OpenPLC v3 binaries, normalizes the recovered outputs into a shared semantic schema, and separates runtime functions from application-level core functions for toolchain prediction and functionality prediction. On PLC-BEAD, PLC-BinX achieves 100.00% precision, recall, and F1 for toolchain prediction, and 51.43% precision, 49.38% recall, and 49.18% F1 for functionality prediction under ten-fold program-level evaluation. These results demonstrate that reverse engineering can expose task-relevant semantic information from heterogeneous PLC binaries and support more interpretable PLC binary analysis. These results also suggest two opportunities to further extend PLC binary understanding. First, CODESYS reverse engineering can be improved by refining function-boundary recovery, call-target resolution, symbol propagation, and the separation between application logic and runtime code inside .app containers. Second, state-aware representations could be developed to model persistent memory, timers, counters, interfunction data dependencies, and repeated execution across PLC scan cycles, thereby strengthening functionality prediction for stateful PLC behavior. R EFERENCES [1] D. E. Denning, “Stuxnet: What has changed?” Future Internet, vol. 4, no. 3, pp. 672–687, 2012. [Online]. Available: https: //www.mdpi.com/1999-5903/4/3/672 [2] Nozomi Networks Labs, “Backdooring CODESYS applications via vulnerability chaining,” Nozomi Networks Blog, Apr. 2026, accessed: 2026-05-08. [Online]. Available: https://www.nozominetworks.com/ blog/backdooring-codesys-applications-via-vulnerability-chaining [3] Y. G. Achamyeleh, S.-Y. Yu, G. Q. Araya, and M. A. A. Faruque, “Bridging the binary analysis gap: A cross-compiler dataset and neural framework for industrial control systems,” in Proceedings of the 31st ACM SIGKDD Conference on Knowledge Discovery and Data Mining (KDD). ACM, 2025, pp. 5260–5269. [4] A. Keliris and M. Maniatakos, “ICSREF: A framework for automated reverse engineering of industrial control systems binaries,” in Proceedings of the Network and Distributed System Security Symposium (NDSS). Internet Society, 2019. [5] PLCopen, “IEC 61131-3 programming languages,” Technical documentation, 2013. [Online]. Available: https://plcopen.org/iec-61131-3 [6] CODESYS GmbH, “Generating application code,” https: //content.helpme-codesys.com/en/CODESYS%20Development% accessed: 20System/ cds creating application code for plc.html, 2026-05-08. [7] ——, “Creating a boot application,” https://content.helpme-codesys. com/en/CODESYS%20Development%20System/ cds creating a boot application.html, accessed: 2026-05-08. [8] OpenPLC Project, “MATIEC: IEC 61131-3 compiler,” https:// openplcproject.gitlab.io/matiec/, accessed: 2026-05-08. [9] ——, “OpenPLC Project,” https://openplcproject.github.io/, accessed: 2026-05-11. [10] N. A. Quynh and D. H. Vu, “Capstone: Next-gen disassembly framework,” in Black Hat USA, 2014. [Online]. Available: https: //www.capstone-engine.org/ [11] Hex-Rays, “IDA Pro disassembler and debugger,” Software, 2024. [Online]. Available: https://hex-rays.com/ida-pro/

14

[12] A. Vaswani, N. Shazeer, N. Parmar, J. Uszkoreit, L. Jones, A. N. Gomez, Ł. Kaiser, and I. Polosukhin, “Attention is all you need,” in Advances in Neural Information Processing Systems (NeurIPS), vol. 30, 2017. [Online]. Available: https://papers.nips.cc/ paper/7181-attention-is-all-you-need [13] W. L. Hamilton, R. Ying, and J. Leskovec, “Inductive representation learning on large graphs,” in Advances in Neural Information Processing Systems (NeurIPS), vol. 30, 2017. [Online]. Available: https://papers. nips.cc/paper/6703-inductive-representation-learning-on-large-graphs [14] National Security Agency, “Ghidra software reverse engineering framework,” Software, 2019. [Online]. Available: https://ghidra-sre.org/ [15] Y. Shoshitaishvili, R. Wang, C. Salls, N. Stephens, M. Polino, A. Dutcher, J. Grosen, S. Feng, C. Hauser, C. Kruegel, and G. Vigna, “SoK: (state of) the art of war: Offensive techniques in binary analysis,” in Proceedings of the IEEE Symposium on Security and Privacy. IEEE, 2016, pp. 138–157. [16] D. Andriesse, X. Chen, V. van der Veen, A. Slowinska, and H. Bos, “An in-depth analysis of disassembly on full-scale x86/x64 binaries,” in Proceedings of the USENIX Security Symposium. USENIX Association, 2016, pp. 583–600. [Online]. Available: https://www.usenix.org/ conference/usenixsecurity16/technical-sessions/presentation/andriesse [17] K. Pei, J. Guan, D. Williams-King, J. Yang, and S. Jana, “XDA: Accurate, robust disassembly with transfer learning,” in Proceedings of the Network and Distributed System Security Symposium (NDSS). Internet Society, 2021. [18] S. Senthivel, S. Dhungana, H. Yoo, I. Ahmed, and V. Roussev, “Denial of engineering operations attacks in industrial control systems,” in Proceedings of the Eighth ACM Conference on Data and Application Security and Privacy (CODASPY). ACM, 2018, pp. 319–329. [19] S. A. Qasim, J. L. Jr., and I. Ahmed, “Automated reconstruction of control logic for programmable logic controller forensics,” in Proceedings of the 22nd International Conference on Information Security (ISC). Springer, 2019, pp. 402–422. [20] C. Sang, J. Wu, J. Li, and M. Guizani, “From control application to control logic: PLC decompile framework for industrial control system,” IEEE Transactions on Information Forensics and Security, vol. 19, pp. 8685–8700, 2024. [21] Y. Geng, X. Che, R. Ma, Q. Wei, M. Wang, and Y. Chen, “Control logic attack detection and forensics through reverse-engineering and verifying PLC control applications,” IEEE Internet of Things Journal, vol. 11, no. 5, pp. 8386–8400, 2024. [22] H. Benkraouda, A. Agrawal, D. Tychalas, M. Sazos, and M. Maniatakos, “Towards PLC-specific binary analysis tools: An investigation of CODESYS-compiled PLC software applications,” in Proceedings of the 5th Workshop on CPS and IoT Security and Privacy (CPSIoTSec). ACM, 2023, pp. 83–89. [23] I. U. Haq and J. Caballero, “A survey of binary code similarity,” ACM Computing Surveys, vol. 54, no. 3, pp. 51:1–51:38, 2021. [24] A. Marcelli, M. Graziano, X. Ugarte-Pedrero, Y. Fratantonio, M. Mansouri, and D. Balzarotti, “How machine learning is solving the binary function similarity problem,” in Proceedings of the USENIX Security Symposium. USENIX Association, 2022, pp. 2099–2116. [Online]. Available: https://www.usenix.org/conference/ usenixsecurity22/presentation/marcelli [25] S. Eschweiler, K. Yakdan, and E. Gerhards-Padilla, “discovre: Efficient cross-architecture identification of bugs in binary code,” in Proceedings of the Network and Distributed System Security Symposium (NDSS). Internet Society, 2016. [26] Q. Feng, R. Zhou, C. Xu, Y. Cheng, B. Testa, and H. Yin, “Scalable graph-based bug search for firmware images,” in Proceedings of the ACM SIGSAC Conference on Computer and Communications Security (CCS). ACM, 2016, pp. 480–491. [27] X. Xu, C. Liu, Q. Feng, H. Yin, L. Song, and D. Song, “Neural networkbased graph embedding for cross-platform binary code similarity detection,” in Proceedings of the 2017 ACM SIGSAC Conference on Computer and Communications Security (CCS). ACM, 2017, pp. 363–376. [28] J. Gao, X. Yang, Y. Fu, Y. Jiang, and J. Sun, “VulSeeker: A semantic learning based vulnerability seeker for cross-platform binary,” in Proceedings of the IEEE/ACM International Conference on Automated Software Engineering (ASE). ACM, 2018, pp. 896–899. [29] Z. Yu, R. Cao, Q. Tang, S. Nie, J. Huang, and S. Wu, “Order matters: Semantic-aware neural networks for binary code similarity detection,” in Proceedings of the AAAI Conference on Artificial Intelligence, vol. 34, no. 1, 2020, pp. 1145–1152. [30] Y. Duan, X. Li, J. Wang, and H. Yin, “DeepBinDiff: Learning programwide code representations for binary diffing,” in Proceedings of the

Network and Distributed System Security Symposium (NDSS). Internet Society, 2020. [31] L. Massarelli, G. A. D. Luna, F. Petroni, R. Baldoni, and L. Querzoni, “SAFE: Self-attentive function embeddings for binary similarity,” in Detection of Intrusions and Malware, and Vulnerability Assessment (DIMVA). Springer, 2019, pp. 309–329. [32] S. H. H. Ding, B. C. M. Fung, and P. Charland, “Asm2Vec: Boosting static representation robustness for binary clone search against code obfuscation and compiler optimization,” in Proceedings of the IEEE Symposium on Security and Privacy. IEEE, 2019, pp. 472–489. [33] X. Li, Y. Qu, and H. Yin, “PalmTree: Learning an assembly language model for instruction embedding,” in Proceedings of the ACM SIGSAC Conference on Computer and Communications Security (CCS). ACM, 2021, pp. 3236–3251. [34] H. Wang, W. Qu, G. Katz, W. Zhu, Z. Gao, H. Qiu, J. Zhuge, and C. Zhang, “jTrans: Jump-aware transformer for binary code similarity detection,” in Proceedings of the 31st ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA). ACM, 2022, pp. 1–13. [35] K. Pei, Z. Xuan, J. Yang, S. Jana, and B. Ray, “Trex: Learning execution semantics from micro-traces for binary similarity,” arXiv:2012.08680, 2020. [Online]. Available: https://arxiv.org/abs/2012.08680 [36] A. Jia, M. Fan, W. Jin, X. Xu, Z. Zhou, Q. Tang, S. Nie, S. Wu, and T. Liu, “1-to-1 or 1-to-n? investigating the effect of function inlining on binary similarity analysis,” ACM Transactions on Software Engineering and Methodology, vol. 32, no. 4, pp. 87:1–87:26, 2023. [37] A. Jia, M. Fan, X. Xu, W. Jin, H. Wang, and T. Liu, “Cross-inlining binary function similarity detection,” in Proceedings of the IEEE/ACM International Conference on Software Engineering (ICSE). ACM, 2024, pp. 1–13. [38] D. Tychalas, H. Benkraouda, and M. Maniatakos, “ICSFuzz: Manipulating I/Os and repurposing binary code to enable instrumented fuzzing in ICS control applications,” in Proceedings of the 30th USENIX Security Symposium (USENIX Security). USENIX Association, 2021, pp. 2847–2862. [Online]. Available: https: //www.usenix.org/conference/usenixsecurity21/presentation/tychalas [39] A. Bytes, P. H. N. Rajput, C. Doumanidis, M. Maniatakos, J. Zhou, and N. O. Tippenhauer, “FieldFuzz: In situ blackbox fuzzing of proprietary industrial automation runtimes via the network,” in Proceedings of the 26th International Symposium on Research in Attacks, Intrusions and Defenses (RAID). ACM, 2023, pp. 499–512. [40] C. Villa, C. Doumanidis, H. Lamri, P. H. N. Rajput, and M. Maniatakos, “ICSQuartz: Scan cycle-aware and vendor-agnostic fuzzing for industrial control systems,” in Proceedings of the Network and Distributed System Security Symposium (NDSS). Internet Society, 2025. [41] I. D. Lopez-Miguel, J.-C. Tournier, and B. F. Adiego, “PLCverif: Status of a formal verification tool for programmable logic controller,” arXiv:2203.17253, 2022. [Online]. Available: https://arxiv.org/abs/2203. 17253 [42] X. Zhang, J. Li, J. Wu, G. Chen, Y. Meng, H. Zhu, and X. Zhang, “Binary-level formal verification based automatic security ensurement for PLC in industrial IoT,” IEEE Transactions on Dependable and Secure Computing, vol. 22, no. 3, pp. 2211–2226, 2025.

Record · ID 200567 · SHA-256 3498963548bac92f
Retrieved via Conceptio — every document is proof-bundled with source, license, and retrieval metadata.