2

In the analysis of an ARM binary, when would one normally encounter transfer operations between memory and a coprocessor? These are encoded as the LDC and STC operators.

Would it be common for programs to have this functionality or is it more specific for system-related operations? Any insight would be helpful, thanks in advance.

analysis with STC operator

3
  • 1
    Can you post some snippets?
    – Igor Skochinsky
    Sep 25 at 0:28
  • yes, added to question ^^
    – aug2uag
    Sep 25 at 2:46
  • 1
    where did you get the binary from? two ed five bytes apart look strange...
    – Igor Skochinsky
    Sep 25 at 16:34
4

Standalone LDC and STC instructions are almost never used in ARM binaries. They were used for a short time in early ARM ISA extensions:

  1. FPA (Floating-point accelerator) used some variants of LDC/STC etc. to load and store data. IIRC they used coprocessor numbers 0/1/2. It used custom 48-bit floating point format and just a few processors were released that supported it in hardware (but it lived for a few more years thanks to software emulation).
  2. wMMX and wMMX2 extension was implemented in some Intel XScale(PXA) chip series for DSP acceleration. IIRC it used mostly coprocessor 1 opcodes.

In both cases, the extensions introduce custom instruction mnemonics rather than use raw coprocessor instructions (but I don't know of Ghidra supports any besides VFP).

VFP (Vector Floating Point) instructions replaced the short-lived FPA with full IEEE-754 support. Coprocessor numbers 10 and 11 were used. It is still present in ARMv7 (and in some form in ARMv8-M/R). It also uses dedicated mnemonics instead of raw coprocessor instructions.

Your snippet uses coprocessor 0 so in theory it could be FPA (or possibly wMMX) but the other instructions do not make much sense, especially the two following ones which both overwrite r5. So I think it's just being disassembled in wrong mode. Going by the disassembly, you seem to have set up it in big endian mode, but it seems to make more sense in little endian:

CODE:0002E910 0B 06                       LSLS            R3, R1, #0x18
CODE:0002E912 ED 00                       LSLS            R5, R5, #3
CODE:0002E914 90 2B                       CMP             R3, #0x90
CODE:0002E916 00 ED 9D 1B                 VSTR            D1, [R0,#-0x274]

It makes somewhat more sense because R3 is being checked after being written to, but the R5 change still looks out of place, and the VSTR too. Are you sure the code is actually for ARM? In any case, check your settings, especially big/little endian and maybe also Thumb/ARM mode.

P.S. What you can sometimes actually encounter in real code are MRC and MCR instructions for controlling the system coprocessor (p15) and sometimes debug hardware (p14). Anything else is highly likely to be bogus.

1
  • binwalk identified the architecture as 16 bit little endian but the disassembly above was 32 bit big endian-- it's from an older PLC
    – aug2uag
    Sep 25 at 19:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.