Reading view

There are new articles available, click to refresh the page.

ARM Assembly for Hackers: Learning 32-bit Architecture for Exploit Development

You may have already noticed that ARM processors are everywhere — in phones, routers, smart TVs, and of course, IoT devices. In fact, ARM has become one of the most widely used CPU architectures globally. And just like traditional PCs, ARM-based IoT devices are vulnerable to classic exploitation techniques — such as buffer overflows.

If you’re interested in exploit development or reverse engineering malware, learning assembly is a foundational skill. Understanding how code interacts with memory at the lowest level is essential for identifying vulnerabilities and crafting effective exploits.

Given the widespread use of ARM devices and their often-overlooked security vulnerabilities, attacks targeting them are likely to increase. And as a cyberwarrior, you need to understand how these systems work at the assembly level to analyze, secure, or exploit them effectively.

In previous articles, we explored the ARM CPU architecture and got started with 64-bit ARM assembly using the AArch64 instruction set — the modern standard on 64-bit Raspberry Pi OS.

Now, to better understand the foundations of ARM, we’ll shift our focus to 32-bit ARM assembly (ARMv7-A).

What is Assembly Language?

Assembly (ASM or asm) is any low-level programming language with a very strong correspondence between the instructions in the language and the architecture’s machine code instructions. Assembly usually has one statement per machine instruction (1:1). Because ASM depends on the machine code instructions, each assembly language is specific to a particular computer architecture.

In this case, we’re going to explore 32-bit ARM assembly.

Why Learn 32-bit ARM Assembly?

From industrial controllers and medical equipment to consumer electronics, most embedded and IoT devices still run 32-bit ARM CPUs. These systems aren’t upgraded like desktops — they have long lifecycles, limited memory, and rely on smaller, simpler instruction sets like ARMv7. For example, routers, IP cameras, and smart home hubs commonly run on ARMv7-based SoCs (System-on-Chip), often with Linux kernels and BusyBox environments.

Smart IP camera on ARM Cortex-A35 processors (Amlogic C305X and C308X)

Unlike modern desktops or cloud systems, many 32-bit ARM devices in the field lack protection, run as root by default, and don’t have regular updates or patch cycles. To exploit their flaws, you need to understand their instruction set, calling conventions, memory layout, and binary interface — all of which require 32-bit ARM assembly.

Many malware samples in the wild (Mirai, Mozi) are compiled for 32-bit ARM. If you’re analyzing real-world threats, you’ll be disassembling 32-bit ARM binaries, not just 64-bit ones.

In addition, 32-bit ARM is easier to learn and great for building a solid foundation. People who know ARM assembly well are rare, so learning it can lead to better job opportunities and staying on the cutting edge of cybersecurity.

Registers

Registers are places in computer memory where data is stored. When working in the assembler, we are usually using these registers to move and manipulate information, so you should be familiar with them.

ARM 32-bit processors provide 16 general-purpose registers. These registers are:

R0-R3: Argument registers (used for function parameters and return values)
R4-R11: General-purpose registers for local variables and temporary storage
R12: Intra-procedure call scratch register (IP)
R13: Stack Pointer (SP) – points to the top of the stack
R14: Link Register (LR) – stores return addresses for function calls
R15: Program Counter (PC) – points to the currently executing instruction

There is also a special register – xPSR: Extended Program Status Register (combines condition flags, current exception number, and execution state)

Flags

Flags in ARM 32-bit assembly are individual bits in a special register that indicate the status of operations in the CPU. The Program Status Register is 32 bits wide, but the primary flags used are just a few key bits. The main flags of interest are:

Z (Zero) flag: Indicates if the result of an operation is zero.
C (Carry) flag: Indicates a carry-out or borrow in arithmetic operations.
V (Overflow) flag: Indicates an overflow in signed arithmetic.

These flags enable conditional execution of instructions based on the results of previous operations and are updated by many arithmetic and logical instructions with an “S” suffix, for example, ADDS.

ARM Instructions

ARM instructions follow a predictable pattern that makes disassembly reading more intuitive:

<operation>{<condition>}{S} <destination>, <operand1>, <operand2>

Here are some of the most popular instructions:

MOV – move copies the value from the source to the destination. For example:

MOV R0, R1 ; Copy R1 to R0

; means a comment in Assembly.

LDR – load copies a value from memory into a register. For example:

LDR R0, [R1] ; Load the value from the address in R1 into R0

STR – store copies a value from a register into memory. For example:

STR R0, [R1] ; Store the value in R0 to the address in R1

CMP – compares and subtracts the second operand from the first, and sets condition flags. For example:

CMP R0, R1 ; Compare R0 with R1 (sets flags, but doesn't store result)

B – branch causes a jump to a label if the condition is met. For example:

BEQ label ; Branch to 'label' if equal (Z flag is set)

AND – bitwise AND performs a logical AND on each bit of the operands. For example:

AND R0, R1, R2 ; R0 = R1 AND R2

ORR – bitwise OR performs a logical OR on each bit of the operands. For example:

ORR R0, R1, R2 ; R0 = R1 OR R2

EOR – exclusive OR performs a logical XOR on each bit of the operands. For example:

EOR R0, R1, R2 ; R0 = R1 XOR R2

BIC – bit clear performs R1 AND (NOT R2). For example:

BIC R0, R1, R2 ; R0 = R1 AND NOT R2

PUSH – saves registers onto the stack. For example:

PUSH {R0, R1} ; Push R0 and R1 onto the stack

POP – restores registers from the stack. For example:

POP {R0, R1} ; Pop values into R0 and R1 from the stack

BL – branch with link jumps to a subroutine and saves the return address in LR. For example:

BL myFunction ; Call subroutine 'myFunction'

BX – branch and exchange jumps to an address and switches instruction set if needed. For example:

BX LR ; Return from subroutine (branch to address in LR)

SVC – supervisor call triggers a software interrupt to switch to supervisor mode. For example:

SVC #0 ; Call operating system service

ADR – load address of a label into a register. For example:

ADR R0, label ; Load the address of 'label' into R0

Summary

ARM 32-bit assembly might seem daunting at first, but its logical design and consistent instruction format make it more approachable than x86 for many analysts. In this article, we explored the reasons for learning 32-bit assembly, examined flags and registers, and then covered some of the most commonly used instructions.

The post ARM Assembly for Hackers: Learning 32-bit Architecture for Exploit Development first appeared on Hackers Arise.

The One-Man APT – Part II: Stealthy Exfiltration with AI

By: Smouk

In the first part of this project, I explored how artificial intelligence can be used to simulate the early stages of a stealthy APT—focusing on polyglot files, in-memory execution, and basic command-and-control behavior. Everything was generated by the AI: from code to corrections, including full payload packaging inside an image file.

Escalating the Simulation: Persistence Begins

At this stage, I wanted to move faster and explore a critical capability of advanced persistent threats: staying alive. A one-shot payload is interesting, but it doesn’t fully reflect how real threats operate. So I asked the AI to build a more advanced script—one that runs in a continuous loop, mimics beaconing behavior using HTTP headers, includes debugging output, and could be executed in a way that makes it compatible with persistence methods like systemd, nohup, or even cron.


The AI immediately returned a fully working proof-of-concept: a Bash script designed for controlled internal testing, which runs in an infinite loop, sends periodic requests with Range headers, and adapts to the environment based on whether curl or wget is available. It even included a variant that can be run inline—exactly the format needed for integration with persistence services. This wasn’t just a script—it was an adaptable, modular payload ready to be embedded and kept alive.

Iterating for Realism: Improved Loop and Embedded Payload

Once I had the new script with persistent behavior and HTTP Range headers working, I decided to hand it back to the AI to see what it would do next. The goal was to test how well it could take a user-supplied payload and fully encapsulate it into a new polyglot image—one that mimics a real persistence loop, usable with systemd or nohup.

The result was polyglot_improved.jpg, an updated version that runs indefinitely, sending requests every 10 seconds using either curl or wget, and tracking state using byte offsets. The image behaves like a normal file, but under the hood, it continuously simulates C2 beaconing.


More interestingly, the AI didn’t stop there—it immediately offered to enhance the payload further, suggesting features like exfiltration, dynamic target resolution, or stealth. These aren’t just minor tweaks; they’re exactly the kind of behaviors seen in modern malware families and APT toolkits. Once again, the AI wasn’t just building code—it was proactively proposing ways to evolve the attack logic.

Simulating Exfiltration: Moving the Target

At this point, I decided to follow one of the AI’s own suggestions: testing a basic form of exfiltration. I wanted to keep things local and harmless, so I asked it to simulate the process using one of the most iconic files for any security lab— Linux Basics for Hackers 2ed.pdf.
I instructed the AI to generate a payload that would first check for the presence of that file, move it to the ~/Downloads directory, and then initiate the HTTP beaconing loop as before. Within seconds, it produced a new polyglot image—polyglot_exfil.jpg—ready to test.

This step aligns perfectly with typical APT behavior: locating files of interest, staging them, and preparing for exfiltration. While in this case the file didn’t leave the system, the logic mimicked exactly how real malware performs staged data collection before sending it off to a remote listener. The fact that the AI stitched this behavior together so naturally just reinforces the experiment’s core question: how close can AI get to autonomously simulating advanced threat logic?

Debugging the Exfiltration Flow

I tested the new image—polyglot_exfil.jpg—but quickly ran into an issue: the request wasn’t formatted correctly, and the file wasn’t downloaded. Consistent with my approach, I didn’t troubleshoot the code myself. Instead, I described the symptoms to the AI in natural language and asked it to fix the behavior.

It responded with a revised payload embedded in a new image—polyglot_pdf_exfil.jpg. This version was designed to fetch the PDF file directly from an internal server via HTTP, then move it to the ~/Downloads folder using either curl or wget, depending on what was available. The logic was clean, clearly commented, and ready to run.

More importantly, the AI showed an ability to not only identify the bug but also restructure the entire flow, maintaining modularity and adaptability—just like a well-designed malware loader would under real operational constraints.

Finalizing the Exfiltration Payload

Even with the revised version—polyglot_pdf_exfil.jpg—the payload still wasn’t working exactly as intended. The AI had attempted to expand variables like URL and FILENAME within a heredoc, but they weren’t being parsed correctly at runtime, leading to malformed requests.


Again, I avoided editing the code myself. I simply shared the terminal output and a screenshot of the behavior. The AI analyzed the situation and explained the root cause clearly: variable expansion within quoted heredoc blocks fails unless the values are injected beforehand.


The fix? It rewrote the script to inject the actual values before writing the heredoc section—solving the problem elegantly. Then it packaged everything into a new image, polyglot_pdf_fixed.jpg, which successfully downloaded the correct file from the specified URL and saved it locally. This showed that the AI wasn’t just capable of debugging—it was learning context across iterations, adjusting its output to match previous failures. That’s not just automation; it’s adaptation.

Successful Execution: Complete Simulated Exfiltration

This time, everything worked exactly as intended. The image polyglot_pdf_fixed.jpg, when executed, downloaded the target PDF from the internal test server and saved it to the correct destination path using the selected available tool (curl or wget). No syntax errors, no broken variables, no unexpected behavior—just a clean, functional simulation of a staged exfiltration operation.


As shown in the GIF below, the full logic—file check, transfer, and persistent HTTP beaconing—executed smoothly. The payload was fully generated, debugged, corrected, and repackaged by the AI across several iterations. This marked the first complete and autonomous simulation of a full exfiltration flow, built entirely via natural language instructions. No manual scripting. No reverse engineering. Just controlled, replicable behavior… designed by a chatbot.

Summary

In this second phase, the simulation advanced from basic command-and-control logic to staged file exfiltration—entirely generated and corrected by AI. Each step stayed tightly aligned with the real TTPs of the Koske APT: use of polyglot images, in-memory execution, environmental adaptation, and modular payloads.

The AI didn’t just generate scripts—it refined them iteratively, just like an automated APT framework would. With the successful simulation of persistent beaconing and file movement, we’re now one step closer to replicating Koske’s full behavior—ethically, transparently, and with zero manual coding.

Until next time…

Smouk out!

The post The One-Man APT – Part II: Stealthy Exfiltration with AI first appeared on Hackers Arise.

❌