NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
51.29k stars 5.84k forks source link

THUMB srsdb not disassembling #216

Closed mumbel closed 5 years ago

mumbel commented 5 years ago

Describe the bug The srsdb instruction is not disassembling on THUMB image (tested with a 4 byte image as well)

objdump -D -Mforce-thumb gives the following e82d c01f srsdb sp!, #31

The SLEIGH looks correct and appears to match the instruction encoding. I have tried v6 and v7 LE and disassemble using F12 key (making sure registers TMode==1).

Environment (please complete the following information):

emteere commented 5 years ago

The current implementation only supports certain values because of the attach:

attach names [ thsrsMode ] [ _ _ _ _ _ _ _ _ usr fiq irq svc _ _ mon abt _ _ _ und _ _ _ sys _ _ _ _ _ _ _ _ ];

The match can be relaxed to accept any value as objdump does. The instruction states it is CONSTRAINED UNPREDICTABLE if the mode is invalid, however it should disassemble.

emteere commented 5 years ago

Patch for the instructions both ARM and Thumb

diff --git a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc
index ea89edd..d335ae0 100644
--- a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc
+++ b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc
@@ -203,8 +203,6 @@
 attach variables [ hrn0002 hrm0305 hrd0002 ]
                  [ r8 r9 r10 r11 r12 sp lr pc ];

-attach names [ thsrsMode ] [ _ _ _ _ _ _ _ _ usr fiq irq svc _ _ mon abt _ _ _ und _ _ _ sys _ _ _ _ _ _ _ _ ];
-
 macro th_addflags(op1,op2) {
   tmpCY = carry(op1,op2);
   tmpOV = scarry(op1,op2);
@@ -924,6 +922,19 @@
 @endif # VERSION_6T2 || VERSION_7

 #
+# Modes for SRS instructions
+#
+thSRSMode: "usr" is thsrsMode=8 & thc0004  { export *[const]:1 thc0004; }
+thSRSMode: "fiq" is thsrsMode=9 & thc0004  { export *[const]:1 thc0004; }
+thSRSMode: "irq" is thsrsMode=10 & thc0004 { export *[const]:1 thc0004; }
+thSRSMode: "svc" is thsrsMode=11 & thc0004 { export *[const]:1 thc0004; }
+thSRSMode: "mon" is thsrsMode=14 & thc0004 { export *[const]:1 thc0004; }
+thSRSMode: "abt" is thsrsMode=15 & thc0004 { export *[const]:1 thc0004; }
+thSRSMode: "und" is thsrsMode=19 & thc0004 { export *[const]:1 thc0004; }
+thSRSMode: "sys" is thsrsMode=23 & thc0004 { export *[const]:1 thc0004; }
+thSRSMode: "#"^thsrsMode is thsrsMode      { export *[const]:1 thsrsMode; }
+
+#
 # Detect if the PC is loaded and do a GOTO
 #
 # TODO: this is how all detections of writes into the PC should be done.
@@ -3962,7 +3973,7 @@
    Rd0811 = tmp:4;
 }

-:srsdb^ItCond sp^"!",thsrsMode         is TMode=1 & ItCond & op6=0x3a0 & sp & thc0505=1 & thc0004=0xd; op8=0xc0 & sop0507=0 & thsrsMode
+:srsdb^ItCond sp^"!",thSRSMode         is TMode=1 & ItCond & op6=0x3a0 & sp & thc0505=1 & thc0004=0xd; op8=0xc0 & sop0507=0 & thSRSMode
 {
   build ItCond;
   # register list is always: r14, spsr
@@ -3973,7 +3984,7 @@
   sp = ptr;
 }

-:srsdb^ItCond sp,thsrsMode         is TMode=1 & ItCond & op6=0x3a0 & sp & thc0505=0 & thc0004=0xd; op8=0xc0 & sop0507=0 & thsrsMode
+:srsdb^ItCond sp,thSRSMode         is TMode=1 & ItCond & op6=0x3a0 & sp & thc0505=0 & thc0004=0xd; op8=0xc0 & sop0507=0 & thSRSMode
 {
   build ItCond;
   # register list is always: r14, spsr
@@ -3983,7 +3994,7 @@
   *ptr = spsr;
 }

-:srsib^ItCond sp^"!",thsrsMode         is TMode=1 & ItCond & op6=0x3a6 & sp & thc0505=1 & thc0004=0xd; op8=0xc0 & sop0507=0 & thsrsMode
+:srsib^ItCond sp^"!",thSRSMode         is TMode=1 & ItCond & op6=0x3a6 & sp & thc0505=1 & thc0004=0xd; op8=0xc0 & sop0507=0 & thSRSMode
 {
   build ItCond;
   # register list is always: r14, spsr
@@ -3994,7 +4005,7 @@
   sp = ptr;
 }

-:srsia^ItCond sp,thsrsMode         is TMode=1 & ItCond & op6=0x3a6 & sp & thc0505=0 & thc0004=0xd; op8=0xc0 & sop0507=0 & thsrsMode
+:srsia^ItCond sp,thSRSMode         is TMode=1 & ItCond & op6=0x3a6 & sp & thc0505=0 & thc0004=0xd; op8=0xc0 & sop0507=0 & thSRSMode
 {
   build ItCond;
   # register list is always: r14, spsr
@@ -4915,7 +4926,7 @@
   tmp1:4 = UnsignedSaturate(diff1, 16:2);
   tmp2:4 = UnsignedSaturate(diff2, 16:2);
   Rd0811[ 0,16] = tmp1[0,16];
-  Rd0811[16,16] = tmp1[0,16];
+  Rd0811[16,16] = tmp2[0,16];
 }

 :uqsub8^ItCond     Rd0811,Rn0003,Rm0003    is TMode=1 & ItCond & op4=0xfac & Rn0003; op12=0xf & Rd0811 & thc0407=0x5 & Rm0003
diff --git a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
index 503a85f..2678813 100644
--- a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
+++ b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
@@ -553,8 +553,7 @@
 attach names [ cpn ] [ p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15  ];
 attach names [ ibOption ] [ opt0 opt1 opt2 opt3 opt4 opt5 opt6 opt7 opt8 opt9 opt10 opt11 opt12 opt13 opt14 SY ];
 attach names [ dbOption ] [ opt0 opt1 OSHST OSH opt4 opt5 NSHST NSH opt8 opt9 ISHST ISH opt12 opt13 ST SY ];
-attach names [ srsMode ] [ _ _ _ _ _ _ _ _ usr fiq irq svc _ _ mon abt _ _ _ und _ _ _ sys _ _ _ _ _ _ _ _ ];
- 
+
 macro addflags(op1,op2) {
  tmpCY = carry(op1,op2);
  tmpOV = scarry(op1,op2);
@@ -1393,6 +1392,21 @@

 @endif # VERSION_6T2 || VERSION_7

+#
+# Modes for SRS instructions
+#
+@if defined(VERSION_6)
+SRSMode: "usr" is srsMode=8 & c0004  { export *[const]:1 c0004; }
+SRSMode: "fiq" is srsMode=9 & c0004  { export *[const]:1 c0004; }
+SRSMode: "irq" is srsMode=10 & c0004 { export *[const]:1 c0004; }
+SRSMode: "svc" is srsMode=11 & c0004 { export *[const]:1 c0004; }
+SRSMode: "mon" is srsMode=14 & c0004 { export *[const]:1 c0004; }
+SRSMode: "abt" is srsMode=15 & c0004 { export *[const]:1 c0004; }
+SRSMode: "und" is srsMode=19 & c0004 { export *[const]:1 c0004; }
+SRSMode: "sys" is srsMode=23 & c0004 { export *[const]:1 c0004; }
+SRSMode: "#"^srsMode is srsMode      { export *[const]:1 srsMode; }
+@endif # VERSION_6
+
 # Add a hat instruction to set the ARMcond context variable which
 # tells whether this is a legal conditional instruction (for v7 and
 # later).
@@ -1662,7 +1676,7 @@
   return [pc];
 }

-:srsia srsMode         is $(AMODE) &  cond=15 & c2527=4 & P24=0 & U23=1 & S22=1 & W21=0 & L20=0 & c1215=0 & c0811=5 & c0507=0 & srsMode
+:srsia SRSMode         is $(AMODE) &  cond=15 & c2527=4 & P24=0 & U23=1 & S22=1 & W21=0 & L20=0 & c1215=0 & c0811=5 & c0507=0 & SRSMode
 {
   # register list is always: r14, spsr
   ptr:4 = sp;
@@ -1672,7 +1686,7 @@
   ptr = ptr + 4;
 }

-:srsib srsMode         is $(AMODE) &  cond=15 & c2527=4 & P24=1 & U23=1 & W21=0 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & srsMode
+:srsib SRSMode         is $(AMODE) &  cond=15 & c2527=4 & P24=1 & U23=1 & W21=0 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & SRSMode
 {
   # register list is always: r14, spsr
   ptr:4 = sp + 4;
@@ -1681,7 +1695,7 @@
   *ptr = spsr;
 }

-:srsda srsMode         is $(AMODE) &  cond=15 & c2527=4 & P24=0 & U23=0 & W21=0 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & srsMode
+:srsda SRSMode         is $(AMODE) &  cond=15 & c2527=4 & P24=0 & U23=0 & W21=0 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & SRSMode
 {
   # register list is always: r14, spsr
   ptr:4 = sp;
@@ -1691,7 +1705,7 @@
   ptr = ptr - 4;
 }

-:srsdb srsMode         is $(AMODE) &  cond=15 & c2527=4 & P24=1 & U23=0 & W21=0 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & srsMode
+:srsdb SRSMode         is $(AMODE) &  cond=15 & c2527=4 & P24=1 & U23=0 & W21=0 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & SRSMode
 {
   # register list is always: r14, spsr
   ptr:4 = sp - 4;
@@ -1700,7 +1714,7 @@
   *ptr = spsr;
 }

-:srsia srsMode!        is $(AMODE) &  cond=15 & c2527=4 & P24=0 & U23=1 & S22=1 & W21=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & srsMode
+:srsia SRSMode!        is $(AMODE) &  cond=15 & c2527=4 & P24=0 & U23=1 & S22=1 & W21=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & SRSMode
 {
   # register list is always: r14, spsr
   ptr:4 = sp;
@@ -1711,7 +1725,7 @@
   sp = ptr;
 }

-:srsib srsMode!        is $(AMODE) &  cond=15 & c2527=4 & P24=1 & U23=1 & W21=1 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & srsMode
+:srsib SRSMode!        is $(AMODE) &  cond=15 & c2527=4 & P24=1 & U23=1 & W21=1 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & SRSMode
 {
   # register list is always: r14, spsr
   ptr:4 = sp + 4;
@@ -1721,7 +1735,7 @@
   sp = ptr;
 }

-:srsda srsMode!        is $(AMODE) &  cond=15 & c2527=4 & P24=0 & U23=0 & W21=1 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & srsMode
+:srsda SRSMode!        is $(AMODE) &  cond=15 & c2527=4 & P24=0 & U23=0 & W21=1 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & SRSMode
 {
   # register list is always: r14, spsr
   ptr:4 = sp;
@@ -1732,7 +1746,7 @@
   sp = ptr;
 }

-:srsdb srsMode!        is $(AMODE) &  cond=15 & c2527=4 & P24=1 & U23=0 & W21=1 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & srsMode
+:srsdb SRSMode!        is $(AMODE) &  cond=15 & c2527=4 & P24=1 & U23=0 & W21=1 & S22=1 & L20=0 & c1215=0 & c0811=5 & c0507=0 & SRSMode
 {
   # register list is always: r14, spsr
   ptr:4 = sp;
mumbel commented 5 years ago

Thanks for taking a look and the patch, will take a look after work.

mumbel commented 5 years ago

Thanks again @emteere , no further problems to report here