Skip to content

Rprop/JRelocator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

ARM64 ELF Relocator (Pure Java)

ARM64 Linker relocation implemented in pure Java! This is a fully functional ARM64 ELF relocator that requires no native code.

Core Features

  • 42+ ARM64 relocation types
  • Complete instruction-level relocation (ADR/ADD/LDR/MOVW)
  • GOT/PLT relocation support
  • TLS relocation support
  • PC-relative branch relocation
  • Pure Java implementation, no JNI required

Project Structure

java_relocator/
├── src/main/java/rprop/java/relocator/
│   ├── ElfParser.java        # ELF file parser
│   ├── Arm64Relocator.java   # ARM64 relocation engine
│   └── Main.java             # Demo program
└── README.md

Supported Relocation Types

Basic Absolute Address

Type Description
R_AARCH64_ABS64 64-bit absolute address
R_AARCH64_ABS32 32-bit absolute address
R_AARCH64_ABS16 16-bit absolute address

PC-Relative

Type Description
R_AARCH64_PREL64 64-bit PC-relative
R_AARCH64_PREL32 32-bit PC-relative
R_AARCH64_PREL16 16-bit PC-relative

GOT/PLT

Type Description
R_AARCH64_GLOB_DAT Global data pointer
R_AARCH64_JUMP_SLOT PLT jump slot
R_AARCH64_GOT_LD_PREL19 GOT load PC-relative
R_AARCH64_GOT_GOTPAGE_LO15 GOT page low bits
R_AARCH64_GOT_GOTREL_PAGE GOT page-relative

ADR Instructions

Type Description
R_AARCH64_ADR_PREL_LO21 ADR low 21-bit
R_AARCH64_ADR_PREL_PG_HI21 ADR page high bits
R_AARCH64_ADR_PREL_PG_HI21_NC ADR page high bits (no check)

ADD/LDR Instructions

Type Description
R_AARCH64_ADD_ABS_LO12_NC ADD low 12-bit
R_AARCH64_LDST8_ABS_LO12_NC 8-bit load/store
R_AARCH64_LDST16_ABS_LO12_NC 16-bit load/store
R_AARCH64_LDST32_ABS_LO12_NC 32-bit load/store
R_AARCH64_LDST64_ABS_LO12_NC 64-bit load/store
R_AARCH64_LDST128_ABS_LO12_NC 128-bit load/store

Branch Instructions

Type Description
R_AARCH64_JUMP26 Unconditional jump (26-bit)
R_AARCH64_CALL26 Function call (26-bit)
R_AARCH64_CONDBR19 Conditional branch (19-bit)
R_AARCH64_LD_PREL_LO19 LDR PC-relative (19-bit)

MOVW Instructions

Type Description
R_AARCH64_MOVW_ABS_G0 MOVW absolute G0 group
R_AARCH64_MOVW_ABS_G1 MOVW absolute G1 group
R_AARCH64_MOVW_ABS_G2 MOVW absolute G2 group
R_AARCH64_MOVW_ABS_G3 MOVW absolute G3 group
R_AARCH64_MOVW_PREL_G0~G3 MOVW PC-relative G0~G3 groups

TLS

Type Description
R_AARCH64_TLS_DTPMOD64 TLS module ID
R_AARCH64_TLS_DTPREL64 TLS dynamic offset
R_AARCH64_TLS_TPREL64 TLS thread-local offset

Usage

Build and Run

cd java_relocator
javac -d . src/main/java/rprop/java/relocator/*.java
java rprop.java.relocator.Main

Basic Usage

// 1. Parse ELF file
byte[] elfData = readFile("libnative.so");
Arm64Relocator relocator = new Arm64Relocator(elfData);

// 2. Load into memory
long loadBase = 0x7fff00000000L;
relocator.load(loadBase);

// 3. Add external symbols
relocator.addSymbol("printf", 0x7fff00001234L);
relocator.addSymbol("malloc", 0x7fff00005678L);
relocator.addSymbol("strlen", 0x7fff00009abcL);

// 4. Apply relocations
relocator.applyRelocations();

// 5. Get result
byte[] relocatedImage = relocator.getLoadedImage();

Handling TLS

relocator.addTlsSymbol("thread_local_var", 0x100L);
relocator.applyRelocations();

Core Implementation Principles

Instruction Relocation

ARM64 uses specific instruction formats; relocation requires modifying instruction fields:

// ADR_PREL_PG_HI21 relocation
case R_AARCH64_ADR_PREL_PG_HI21:
    // Target page address
    long targetPage = (symbolValue + addend) & ~0xFFF;
    // Current page address
    long currentPage = (baseAddress + relAddr) & ~0xFFF;
    // Calculate page offset
    long pageOffset = targetPage - currentPage;
    
    // Read instruction
    int instr = readInstruction32(relAddr);
    // Clear original field and set new value
    instr = (instr & ~0x3FFFE0) | ((pageOffset & 0x1FFFFC) >> 2);
    // Write back
    writeInstruction32(relAddr, instr);

GOT Entry Filling

case R_AARCH64_JUMP_SLOT:
    // GOT entry = symbol address
    write64(relAddr, symbolValue);

Relative Relocation

case R_AARCH64_RELATIVE:
    // *offset = base + addend
    write64(relAddr, baseAddress + addend);

Example Output

=== ARM64 ELF Relocator Demo (Pure Java) ===

Created mini ARM64 ELF (4096 bytes)

=== ARM64 Relocator Summary ===
ELF Type: 64-bit ARM64 (AArch64)
Machine: AArch64
Symbols: 7
Relocations: 6
Load Base: 0x400000
Page Size: 4096

Added external symbols:
  printf  = 0x7fff00001234
  malloc  = 0x7fff00005678
  free    = 0x7fff00005688
  memcpy  = 0x7fff00005698
  GOT     = 0x7fff00010000

Applying relocations...
Applied: 6, Skipped: 0

=== Demo Complete ===
This ARM64 relocator supports:
- 42+ relocation types
- ADR/ADD/LDR/MOVW instructions
- GOT/PLT relocations
- TLS relocations
- PC-relative branches

All implemented in pure Java!

Comparison with Real Linker

Feature Java Implementation bionic/linker
Architecture Simulated memory Real memory
Performance Slightly lower High
Memory Protection No Yes (mprotect)
Completeness 42+ types Complete
Security Educational use Production grade

Extension Directions

  1. Support more types: TLSDESC, other special relocations
  2. Optimize performance: Use ByteBuffer batch operations
  3. Android integration: Combine with NativeMemoryUtils to write to real memory
  4. Symbol resolution: Resolve DSO dependency chains

Learning Resources

License

For educational and research purposes only.

About

ARM64 Linker relocation implemented in pure Java

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages