wargio / r2dec-js

radare2 plugin - converts asm to pseudo-C code.
514 stars 50 forks source link

Add support for SuperH #178

Closed brainstorm closed 5 years ago

brainstorm commented 5 years ago

Thanks for this decompiler @wargio!!

It would be awesome to have SuperH(4) support for my ongoing work with an Anritsu MS2721B. I can provide example bins if you need.

:> pdd
sh is not currently supported.
Please open an enhancement issue at https://github.com/wargio/r2dec-js/issues
Supported architectures:
    arm, avr, dalvik, m68k, mips, ppc, sparc, v850, wasm, x86
brainstorm commented 5 years ago

... like this SuperH good stuff :)

wargio commented 5 years ago

Yes, definetly i can add this arch. I'll try to implement it asap

wargio commented 5 years ago

https://github.com/wargio/r2dec-js/pull/181

wargio commented 5 years ago

support added.

brainstorm commented 5 years ago

Unbelievable, that was fast O_o''' Thanks so much, I'll give it a go right now! :D

wargio commented 5 years ago

if you find any bug, please report them :)

brainstorm commented 5 years ago
[0x08000460]> pddc
r2dec has crashed (info: cst_base.out @ 0x8000460).
Please report the bug at https://github.com/wargio/r2dec-js/issues
Use the option '--issue' or the command 'pddi' to generate
the needed data for the issue.
[0x08000460]> pddi
{"addr":134788896,"type":"CALL","at":134788036},{"addr":134788888,"type":"CALL","at":134788044},{"addr":134788880,"type":"CALL","at":134788052},{"addr":134792146,"type":"CODE","at":134788054},{"addr":134788872,"type":"CALL","at":134788060},{"addr":134788060,"type":"CALL","at":134788062},{"addr":134789594,"type":"CODE","at":134788062},{"addr":134788864,"type":"CALL","at":134788068},{"addr":134788856,"type":"CALL","at":134788076},{"addr":134788076,"type":"CALL","at":134788078},{"addr":134788848,"type":"CALL","at":134788084},{"addr":134788084,"type":"CALL","at":134788086},{"addr":134788840,"type":"CALL","at":134788092},{"addr":134788092,"type":"CALL","at":134788094},{"addr":134788808,"type":"CALL","at":134788100},{"addr":134788816,"type":"CALL","at":134788100},{"addr":134788832,"type":"CALL","at":134788100},{"addr":134788800,"type":"CALL","at":134788108},{"addr":134788108,"type":"CALL","at":134788110},{"addr":134788792,"type":"CALL","at":134788116},{"addr":134788784,"type":"CALL","at":134788124},{"addr":134788776,"type":"CALL","at":134788132},{"addr":134788768,"type":"CALL","at":134788140},{"addr":134788760,"type":"CALL","at":134788148},{"addr":134788148,"type":"CALL","at":134788150},{"addr":134788752,"type":"CALL","at":134788156},{"addr":134788156,"type":"CALL","at":134788158},{"addr":134788744,"type":"CALL","at":134788164},{"addr":134788736,"type":"CALL","at":134788172},{"addr":134788712,"type":"CALL","at":134788180},{"addr":134788720,"type":"CALL","at":134788180},{"addr":134788728,"type":"CALL","at":134788180},{"addr":134788704,"type":"CALL","at":134788188},{"addr":134788696,"type":"CALL","at":134788196},{"addr":134788194,"type":"CODE","at":134788198},{"addr":134788688,"type":"CALL","at":134788204},{"addr":134788680,"type":"CALL","at":134788212},{"addr":134788672,"type":"CALL","at":134788220},{"addr":134788222,"type":"CALL","at":134788226},{"addr":134788664,"type":"CALL","at":134788228},{"addr":134788656,"type":"CALL","at":134788236},{"addr":134788238,"type":"CODE","at":134788242},{"addr":134788648,"type":"CALL","at":134788244},{"addr":134788632,"type":"CALL","at":134788252},{"addr":134788640,"type":"CALL","at":134788252},{"addr":134788624,"type":"CALL","at":134788260},{"addr":134788608,"type":"CALL","at":134788268},{"addr":134788616,"type":"CALL","at":134788268},{"addr":134788600,"type":"CALL","at":134788276},{"addr":134788592,"type":"CALL","at":134788284},{"addr":134788584,"type":"CALL","at":134788292},{"addr":134788568,"type":"CALL","at":134788300},{"addr":134788576,"type":"CALL","at":134788300},{"addr":134788560,"type":"CALL","at":134788308},{"addr":134788552,"type":"CALL","at":134788316},{"addr":134788544,"type":"CALL","at":134788324},{"addr":134788536,"type":"CALL","at":134788332},{"addr":134788520,"type":"CALL","at":134788340},{"addr":134788528,"type":"CALL","at":134788340},{"addr":134788512,"type":"CALL","at":134788348},{"addr":134788504,"type":"CALL","at":134788356},{"addr":134788866,"type":"CODE","at":134788358},{"addr":134788488,"type":"CALL","at":134788364},{"addr":134788496,"type":"CALL","at":134788364},{"addr":134788480,"type":"CALL","at":134788372},{"addr":134788472,"type":"CALL","at":134788380},{"addr":134788464,"type":"CALL","at":134788388},{"addr":134788388,"type":"CALL","at":134788392},{"addr":134788388,"type":"CALL","at":134788392},{"addr":134788456,"type":"CALL","at":134788396},{"addr":134788448,"type":"CALL","at":134788404},{"addr":134788440,"type":"CALL","at":134788412},{"addr":134788432,"type":"CALL","at":134788420},{"addr":134788938,"type":"CALL","at":134788430},{"addr":134788236,"type":"CALL","at":134788448},{"addr":134788236,"type":"CALL","at":134788448},{"addr":134788252,"type":"CALL","at":134788464},{"addr":134788252,"type":"CALL","at":134788464},{"addr":134788260,"type":"CALL","at":134788472},{"addr":134788260,"type":"CALL","at":134788472},{"addr":134788468,"type":"CALL","at":134788472},{"addr":134788468,"type":"CALL","at":134788472},{"addr":134789514,"type":"CODE","at":134788494},{"addr":134788526,"type":"CODE","at":134788530},{"addr":134789090,"type":"CODE","at":134788582},{"addr":134788618,"type":"CALL","at":134788622},{"addr":134788708,"type":"CALL","at":134788710},{"addr":134788218,"type":"CODE","at":134788734},{"addr":134789266,"type":"CALL","at":134788758},{"addr":134789858,"type":"CALL","at":134788838},{"addr":134788386,"type":"CALL","at":134788902},{"addr":134789070,"type":"CALL","at":134789074},{"addr":134789094,"type":"CODE","at":134789098},{"addr":134789146,"type":"CODE","at":134789150},{"addr":134789260,"type":"CALL","at":134789264},{"addr":134789260,"type":"CALL","at":134789264},{"addr":134789268,"type":"CALL","at":134789272},{"addr":134789268,"type":"CALL","at":134789272},{"addr":134789358,"type":"CALL","at":134789362},{"addr":134788890,"type":"CODE","at":134789406},{"addr":134788466,"type":"CALL","at":134789494},{"addr":134789532,"type":"CALL","at":134789534},{"addr":134788522,"type":"CODE","at":134789550},{"addr":134789612,"type":"CALL","at":134789616},{"addr":134789612,"type":"CALL","at":134789616},{"addr":134789670,"type":"CALL","at":134789674},{"addr":134789686,"type":"CODE","at":134789690},{"addr":134788234,"type":"CODE","at":134789774},{"addr":134788392,"type":"CALL","at":134789796},{"addr":134789828,"type":"CALL","at":134789830},{"addr":134789394,"type":"CALL","at":134789910},{"addr":134787926,"type":"CALL","at":134789978},{"addr":134788824,"type":"CALL","at":134790244},{"addr":134788250,"type":"CODE","at":134790302},{"addr":134788810,"type":"CALL","at":134790350},{"addr":134788354,"type":"CALL","at":134790406},{"addr":134789080,"type":"CALL","at":134790492},{"addr":134788502,"type":"CALL","at":134790554},{"addr":134788518,"type":"CODE","at":134790570},{"addr":134788586,"type":"CODE","at":134790638},{"addr":134788626,"type":"CALL","at":134790678},{"addr":134789674,"type":"CALL","at":134790702},{"addr":134788782,"type":"CALL","at":134790834},{"addr":134788798,"type":"CODE","at":134790850},{"addr":134788290,"type":"CODE","at":134790854},{"addr":134789440,"type":"CALL","at":134790868},{"addr":134789402,"type":"CODE","at":134790942},{"addr":134788570,"type":"CALL","at":134791134},{"addr":134789682,"type":"CALL","at":134791222},{"addr":134788186,"type":"CODE","at":134791262},{"addr":134788706,"type":"CALL","at":134791270},{"addr":134789382,"type":"CODE","at":134791434},{"addr":134787938,"type":"CODE","at":134791526},{"addr":134788474,"type":"CODE","at":134791550},{"addr":134788482,"type":"CODE","at":134791558},{"addr":134789106,"type":"CALL","at":134791670},{"addr":134789362,"type":"CODE","at":134791926},{"addr":134788722,"type":"CALL","at":134792310},{"addr":134789338,"type":"CALL","at":134792414},{"addr":134789874,"type":"CODE","at":134792438},{"addr":134789114,"type":"CALL","at":134792702},{"addr":134789890,"type":"CALL","at":134792966},{"addr":134789586,"type":"CODE","at":134793174},{"addr":134792142,"type":"CALL","at":134794194}],"dataxrefs":[134787886,134787890,134787894,134787922,134787954,134787958,134787962,134787966,134787970,134788002,134788010,134788026,134788058,134788074,134788082,134788090,134788098,134788106,134788122,134788130,134788138,134788154,134788162,134788166,134788170,134788174,134788178,134788242,134788246,134788254,134788258,134788266,134788274,134788282,134788298,134788306,134788314,134788330,134788462,134788462,134788470,134788470,134788534,134788542,134788594,134788610,134788742,134788742,134788750,134788750,134788762,134788806,134788814,134788830,134788834,134788842,134788970,134789002,134789014,134789014,134789022,134789022,134789030,134789030,134789102,134789110,134789274,134789318,134789318,134789322,134789326,134789326,134789386,134789390,134789398,134789450,134789482,134789614,134789614,134789622,134789622,134789630,134789630,134789694,134789698,134789702,134789730,134789754,134789762,134789778,134789794,134789826,134789902,134789902,134792130,134792150],"indegree":264,"outdegree":471,"nlocals":0,"nargs":0,"bpvars":[],"spvars":[],"regvars":[],"difftype":"new"},{"offset":134787308,"name":"fcn.0808b0ec","size":8788,"is-pure":"false","realsz":8788,"stackframe":0,"cost":0,"cc":3,"bits":32,"type":"fcn","nbbs":3,"edges":0,"ebbs":3,"signature":"fcn.0808b0c4 ();","minbound":134787308,"maxbound":134796096,"callrefs":[{"addr":134787895,"type":"CALL"
brainstorm commented 5 years ago
$ r2 -e io.cache=true cst_base.out
 -- Switch between print modes using the 'p' and 'P' keys in visual mode
[0x08000040]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Check for vtables
[x] Finding xrefs in noncode section with anal.in=io.maps
[x] Analyze value pointers (aav)
[x] Value from 0x080a3504 to 0x080c5824 (aav)
[x] 0x080a3504-0x080c5824 in 0x80a3504-0x80c5824 (aav)
[x] 0x080a3504-0x080c5824 in 0x8000040-0x80921f4 (aav)
[x] Value from 0x08000040 to 0x080921f4 (aav)
[x] 0x08000040-0x080921f4 in 0x80a3504-0x80c5824 (aav)
[x] 0x08000040-0x080921f4 in 0x8000040-0x80921f4 (aav)
[Warning: No SN reg alias for current architecture.
Warning: No SN reg alias for current architecture.
[x] Emulate code to find computed references (aae)
[x] Type matching analysis for all functions (aaft)
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x08000040]> s 0x08000260
[0x08000260]> pddc
Missing " in (CL 0x8000260 r2dec.c:0 r15 -= 4).Usage: / ABCD @..0x1000 0x3000
|ERROR| Invalid command 'wx  (int32_t) r14@(r15) ' (0x77)
Missing " in ().|ERROR| Invalid command '*(r15) = (int32_t) r14;"' (0x2a)
Missing " in (CL 0x8000264 r2dec.c:2 r15 -= 4).Usage: / ABCD @..0x1000 0x3000
|ERROR| Invalid command 'wx  (int32_t) pr@(r15) ' (0x77)
Missing " in ().|ERROR| Invalid command '*(r15) = (int32_t) pr;"' (0x2a)
Missing " in (CL 0x800027e r2dec.c:15 pr = (int32_t) *(r15)).Missing " in ().Missing " in (CL 0x8000280 r2dec.c:16 r14 = (int32_t) *(r15)).Missing " in ().[r2dec] new code lines applied for "sym._lociGetModelNumber".
[0x08000260]>
wargio commented 5 years ago

ok, i patched the crash, sorry for that. i forgot to test it with aaa i'll check this one

wargio commented 5 years ago

ok, fixed that one too. sorry for that, but i forgot this use-case when i added pddc XD

brainstorm commented 5 years ago

Following up on a current r2dec SH4 usecase... here you have a pdda:

    ; assembly                                       | /* r2dec pseudo code output */
                                                     | /* sh4.out @ 0x8009c20 */
                                                     | #include <stdint.h>
                                                     |
    ; (fcn) sym.afunc ()           | void afunc () {
    0x08009c20 mov.l r8, @-r15                       |     r15 -= 4;
                                                     |     *(r15) = (int32_t) r8;
    0x08009c22 mov.w @(0x186,PC), r3                 |     r3 = (int16_t) *(0x8009da8);
    0x08009c24 mov.l r9, @-r15                       |     r15 -= 4;
                                                     |     *(r15) = (int32_t) r9;
    0x08009c26 mov.l r10, @-r15                      |     r15 -= 4;
                                                     |     *(r15) = (int32_t) r10;
    0x08009c28 mov.l r11, @-r15                      |     r15 -= 4;
                                                     |     *(r15) = (int32_t) r11;
    0x08009c2a mov.l r12, @-r15                      |     r15 -= 4;
                                                     |     *(r15) = (int32_t) r12;
    0x08009c2c mov.l r13, @-r15                      |     r15 -= 4;
                                                     |     *(r15) = (int32_t) r13;
    0x08009c2e mov.l r14, @-r15                      |     r15 -= 4;
                                                     |     *(r15) = (int32_t) r14;
    0x08009c30 sts.l pr, @-r15                       |     r15 -= 4;
                                                     |     *(r15) = (int32_t) pr;
    0x08009c32 mov.w @(0x178,PC), r0                 |     r0 = (int16_t) *(0x8009daa);
    0x08009c34 sub r3, r15                           |     r15 -= r3;
    0x08009c36 mov r15, r14                          |     r14 = r15;
    0x08009c38 mov r14, r1                           |     r1 = r14;
    0x08009c3a add r14, r0                           |     r0 += r14;
    0x08009c3c mov r14, r2                           |     r2 = r14;
    0x08009c3e add 0x30, r1                          |     r1 += 0x30;
    0x08009c40 mov.l @(0x178,PC), r10                |     r10 = (int32_t) *(0x8009db8);
    0x08009c42 add 0x10, r2                          |     r2 += 0x10;
    0x08009c44 mov.l r1, @(0x10,r0)                  |     *((r0 + 0x10)) = (int32_t) r1;
    0x08009c46 mov.l r2, @(0x8,r0)                   |     *((r0 + 0x8)) = (int32_t) r2;
    0x08009c48 add 0xF0, r1                          |     r1 += 0xf0;
    0x08009c4a mov.l @(0x10,r0), r8                  |     r8 = (int32_t) *((r0 + 0x10));
    0x08009c4c mov 0x2C, r9                          |     r9 = 0x2c;
    0x08009c4e mov.l r1, @(0xC,r0)                   |     *((r0 + 0xc)) = (int32_t) r1;
                                                     |     do {
    0x08009c50 mov.l @(0x16C,PC), r2                 |         r2 = (int32_t) *(0x8009dbc);
    0x08009c52 mov.l @(0x170,PC), r5                 |         r5 = (int32_t) *(0x8009dc2);
    0x08009c54 mov r8, r4                            |         r4 = r8;
    0x08009c56 jsr @r2                               |         void (*r2)() ();
    0x08009c58 dt r9                                 |         r9 -= r9;
    0x08009c5a add 0x10, r8                          |         r8 += 0x10;
    0x08009c5c bf.s 0x08009c50                       |
                                                     |     } while (? != ?);
                                                     | }

And then a GHidra decompile of the same func over here:

undefined4 afunc(void)

{
  char cVar1;
  undefined4 uVar2;
  undefined4 uVar3;
  uint uVar4;
  undefined4 uVar5;
  int iVar6;
  undefined *puVar7;
  int iVar8;
  uint uVar9;
  undefined *puVar10;
  undefined auStack1648 [16];
  undefined auStack1632 [16];
  undefined auStack1616 [16];
  undefined auStack1600 [704];
  undefined auStack896 [16];
  undefined auStack880 [704];
  char local_b0 [64];
  undefined auStack112 [64];
  int local_30;
  undefined *local_2c;
  undefined *local_28;
  undefined *local_24;

  puVar7 = auStack1600;
  local_2c = auStack1632;
  local_28 = auStack1616;
  iVar8 = 0x2c;
  local_24 = puVar7;
  do {
    (*(code *)0x0)(puVar7,0x701b8);
    iVar8 = iVar8 + -1;
    puVar7 = puVar7 + 0x10;
  } while (iVar8 != 0);
  uVar2 = (*(code *)0x0)();
  (*(code *)0x0)(auStack1648,uVar2);
  iVar6 = 0;
  (*(code *)0x0)(local_2c,0x701b8);
  iVar8 = (*(code *)0x0)(0x701bc,local_28);
  if ((iVar6 == -1) && (iVar8 == -1)) {
    iVar8 = 0x701d0;
  }
  else {
    local_30 = (*(code *)0x0)(&DAT_000701f8,0x70214);
    if (local_30 == 0) {
      iVar8 = 0x70218;
    }
    else {
      iVar8 = 0x2c;
      puVar7 = auStack880;
      do {
        (*(code *)0x0)(puVar7,0x701b8);
        iVar8 = iVar8 + -1;
        puVar7 = puVar7 + 0x10;
      } while (iVar8 != 0);
      (*(code *)0x0)(local_b0,0x40,local_30);
      (*(code *)0x0)(local_b0,0x7023c);
      iVar8 = (*(code *)0x0)(local_b0);
      iVar6 = (*(code *)0x0)();
      if (iVar8 == iVar6) {
        (*(code *)0x0)(0x200,0x40,local_30);
        do {
          while( true ) {
            while( true ) {
              iVar8 = (*(code *)0x0)(local_b0,0x40,local_30);
              if (iVar8 == 0) {
                (*(code *)0x0)(local_30);
                iVar8 = (*(code *)0x0)(local_28,auStack896);
                if ((iVar8 != 0) ||
                   (((iVar8 = (*(code *)0x0)(local_2c,0x701b8), iVar8 == 0 ||
                     (iVar8 = (*(code *)0x0)(auStack1648,local_2c), iVar8 != 0)) &&
                    (iVar8 = (*(code *)0x0)(local_2c,0x701b8), iVar8 != 0)))) {
                  (*(code *)0x0)(0x702cc,auStack1648,local_2c);
                  return 0;
                }
                uVar9 = 0;
                puVar10 = auStack880;
                puVar7 = local_24;
                do {
                  iVar8 = (*(code *)0x0)(puVar10,0x701b8);
                  if (iVar8 != 0) {
                    uVar2 = (*(code *)0x0)(uVar9 & 0xffff);
                    (*(code *)0x0)(auStack112,0x70284,uVar2);
                    iVar6 = 0;
                    iVar8 = (*(code *)0x0)(auStack112,0x2f);
                    if (iVar8 != 0) {
                      iVar6 = 0;
                      *(undefined *)(iVar8 + 1) = 0;
                    }
                    iVar8 = (*(code *)0x0)(auStack112,puVar7);
                    if ((iVar6 == -1 && iVar8 == -1) ||
                       (iVar8 = (*(code *)0x0)(puVar10,puVar7), iVar8 != 0)) {
                      (*(code *)0x0)(0x70288);
                      (*(code *)0x0)(&LAB_000702a8,uVar9,puVar10,puVar7);
                      return 0;
                    }
                  }
                  puVar7 = puVar7 + 0x10;
                  uVar9 = uVar9 + 1;
                  puVar10 = puVar10 + 0x10;
                  if (0x2b < (int)uVar9) {
                    return 0x200;
                  }
                } while( true );
              }
              uVar9 = 0;
              while( true ) {
                uVar4 = (*(code *)0x0)(local_b0);
                if (uVar4 <= uVar9) break;
                cVar1 = (*(code *)0x0)((int)local_b0[uVar9]);
                local_b0[uVar9] = cVar1;
                uVar9 = uVar9 + 1;
              }
              uVar2 = (*(code *)0x0)(local_b0,0x7023c);
              uVar3 = (*(code *)0x0)(0,0x7023c);
              iVar8 = (*(code *)0x0)(uVar2,0x70264);
              if (iVar8 != 0) break;
              (*(code *)0x0)(auStack896,uVar3);
            }
            iVar8 = (*(code *)0x0)(uVar2,0x7026c);
            if (iVar8 != 0) break;
            (*(code *)0x0)(local_2c,uVar3);
            (*(code *)0x0)(0x70270,local_2c);
          }
          uVar9 = 0;
          puVar7 = auStack880;
          while ((int)uVar9 < 0x2c) {
            uVar5 = (*(code *)0x0)(uVar9 & 0xffff);
            iVar8 = (*(code *)0x0)(uVar5,uVar2);
            if (iVar8 == 0) {
              (*(code *)0x0)(puVar7,uVar3);
              break;
            }
            puVar7 = puVar7 + 0x10;
            uVar9 = uVar9 + 1;
          }
        } while( true );
      }
      uVar2 = (*(code *)0x0)(local_b0);
      uVar3 = (*(code *)0x0)();
      (*(code *)0x0)(0x70240,uVar2,uVar3);
      iVar8 = local_30;
    }
  }
  (*(code *)0x0)(iVar8);
  return 0;
}

I'm a bit concerned about:

1) } while (? != ?) on r2dec 2) The relative length and complexity of both dissassemblies... to put it simply: which one should I trust more? :-S

Happy to share the bin privately if that helps, unless you are already around r2-bins?

/cc @radare

radare commented 5 years ago

Is this using af or a2f? Ive seen some issues in af lately..

On 20 Sep 2019, at 00:48, Roman Valls Guimera notifications@github.com wrote:

 Following up on a current r2dec SH4 usecase... here you have a pdda:

; assembly                                       | /* r2dec pseudo code output */
                                                 | /* sh4.out @ 0x8009c20 */
                                                 | #include <stdint.h>
                                                 |
; (fcn) sym.afunc ()           | void afunc () {
0x08009c20 mov.l r8, @-r15                       |     r15 -= 4;
                                                 |     *(r15) = (int32_t) r8;
0x08009c22 mov.w @(0x186,PC), r3                 |     r3 = (int16_t) *(0x8009da8);
0x08009c24 mov.l r9, @-r15                       |     r15 -= 4;
                                                 |     *(r15) = (int32_t) r9;
0x08009c26 mov.l r10, @-r15                      |     r15 -= 4;
                                                 |     *(r15) = (int32_t) r10;
0x08009c28 mov.l r11, @-r15                      |     r15 -= 4;
                                                 |     *(r15) = (int32_t) r11;
0x08009c2a mov.l r12, @-r15                      |     r15 -= 4;
                                                 |     *(r15) = (int32_t) r12;
0x08009c2c mov.l r13, @-r15                      |     r15 -= 4;
                                                 |     *(r15) = (int32_t) r13;
0x08009c2e mov.l r14, @-r15                      |     r15 -= 4;
                                                 |     *(r15) = (int32_t) r14;
0x08009c30 sts.l pr, @-r15                       |     r15 -= 4;
                                                 |     *(r15) = (int32_t) pr;
0x08009c32 mov.w @(0x178,PC), r0                 |     r0 = (int16_t) *(0x8009daa);
0x08009c34 sub r3, r15                           |     r15 -= r3;
0x08009c36 mov r15, r14                          |     r14 = r15;
0x08009c38 mov r14, r1                           |     r1 = r14;
0x08009c3a add r14, r0                           |     r0 += r14;
0x08009c3c mov r14, r2                           |     r2 = r14;
0x08009c3e add 0x30, r1                          |     r1 += 0x30;
0x08009c40 mov.l @(0x178,PC), r10                |     r10 = (int32_t) *(0x8009db8);
0x08009c42 add 0x10, r2                          |     r2 += 0x10;
0x08009c44 mov.l r1, @(0x10,r0)                  |     *((r0 + 0x10)) = (int32_t) r1;
0x08009c46 mov.l r2, @(0x8,r0)                   |     *((r0 + 0x8)) = (int32_t) r2;
0x08009c48 add 0xF0, r1                          |     r1 += 0xf0;
0x08009c4a mov.l @(0x10,r0), r8                  |     r8 = (int32_t) *((r0 + 0x10));
0x08009c4c mov 0x2C, r9                          |     r9 = 0x2c;
0x08009c4e mov.l r1, @(0xC,r0)                   |     *((r0 + 0xc)) = (int32_t) r1;
                                                 |     do {
0x08009c50 mov.l @(0x16C,PC), r2                 |         r2 = (int32_t) *(0x8009dbc);
0x08009c52 mov.l @(0x170,PC), r5                 |         r5 = (int32_t) *(0x8009dc2);
0x08009c54 mov r8, r4                            |         r4 = r8;
0x08009c56 jsr @r2                               |         void (*r2)() ();
0x08009c58 dt r9                                 |         r9 -= r9;
0x08009c5a add 0x10, r8                          |         r8 += 0x10;
0x08009c5c bf.s 0x08009c50                       |
                                                 |     } while (? != ?);
                                                 | }

And then a GHidra decompile of the same func over here:

undefined4 afunc(void)

{ char cVar1; undefined4 uVar2; undefined4 uVar3; uint uVar4; undefined4 uVar5; int iVar6; undefined puVar7; int iVar8; uint uVar9; undefined puVar10; undefined auStack1648 [16]; undefined auStack1632 [16]; undefined auStack1616 [16]; undefined auStack1600 [704]; undefined auStack896 [16]; undefined auStack880 [704]; char local_b0 [64]; undefined auStack112 [64]; int local_30; undefined local_2c; undefined local_28; undefined *local_24;

puVar7 = auStack1600; local_2c = auStack1632; local_28 = auStack1616; iVar8 = 0x2c; local_24 = puVar7; do { ((code )0x0)(puVar7,0x701b8); iVar8 = iVar8 + -1; puVar7 = puVar7 + 0x10; } while (iVar8 != 0); uVar2 = ((code )0x0)(); ((code )0x0)(auStack1648,uVar2); iVar6 = 0; ((code )0x0)(local_2c,0x701b8); iVar8 = ((code )0x0)(0x701bc,local_28); if ((iVar6 == -1) && (iVar8 == -1)) { iVar8 = 0x701d0; } else { local_30 = ((code )0x0)(&DAT_000701f8,0x70214); if (local_30 == 0) { iVar8 = 0x70218; } else { iVar8 = 0x2c; puVar7 = auStack880; do { ((code )0x0)(puVar7,0x701b8); iVar8 = iVar8 + -1; puVar7 = puVar7 + 0x10; } while (iVar8 != 0); ((code )0x0)(local_b0,0x40,local_30); ((code )0x0)(local_b0,0x7023c); iVar8 = ((code )0x0)(local_b0); iVar6 = ((code )0x0)(); if (iVar8 == iVar6) { ((code )0x0)(0x200,0x40,local_30); do { while( true ) { while( true ) { iVar8 = ((code )0x0)(local_b0,0x40,local_30); if (iVar8 == 0) { ((code )0x0)(local_30); iVar8 = ((code )0x0)(local_28,auStack896); if ((iVar8 != 0) || (((iVar8 = ((code )0x0)(local_2c,0x701b8), iVar8 == 0 || (iVar8 = ((code )0x0)(auStack1648,local_2c), iVar8 != 0)) && (iVar8 = ((code )0x0)(local_2c,0x701b8), iVar8 != 0)))) { ((code )0x0)(0x702cc,auStack1648,local_2c); return 0; } uVar9 = 0; puVar10 = auStack880; puVar7 = local_24; do { iVar8 = ((code )0x0)(puVar10,0x701b8); if (iVar8 != 0) { uVar2 = ((code )0x0)(uVar9 & 0xffff); ((code )0x0)(auStack112,0x70284,uVar2); iVar6 = 0; iVar8 = ((code )0x0)(auStack112,0x2f); if (iVar8 != 0) { iVar6 = 0; (undefined )(iVar8 + 1) = 0; } iVar8 = ((code )0x0)(auStack112,puVar7); if ((iVar6 == -1 && iVar8 == -1) || (iVar8 = ((code )0x0)(puVar10,puVar7), iVar8 != 0)) { ((code )0x0)(0x70288); ((code )0x0)(&LAB_000702a8,uVar9,puVar10,puVar7); return 0; } } puVar7 = puVar7 + 0x10; uVar9 = uVar9 + 1; puVar10 = puVar10 + 0x10; if (0x2b < (int)uVar9) { return 0x200; } } while( true ); } uVar9 = 0; while( true ) { uVar4 = ((code )0x0)(local_b0); if (uVar4 <= uVar9) break; cVar1 = ((code )0x0)((int)local_b0[uVar9]); local_b0[uVar9] = cVar1; uVar9 = uVar9 + 1; } uVar2 = ((code )0x0)(local_b0,0x7023c); uVar3 = ((code )0x0)(0,0x7023c); iVar8 = ((code )0x0)(uVar2,0x70264); if (iVar8 != 0) break; ((code )0x0)(auStack896,uVar3); } iVar8 = ((code )0x0)(uVar2,0x7026c); if (iVar8 != 0) break; ((code )0x0)(local_2c,uVar3); ((code )0x0)(0x70270,local_2c); } uVar9 = 0; puVar7 = auStack880; while ((int)uVar9 < 0x2c) { uVar5 = ((code )0x0)(uVar9 & 0xffff); iVar8 = ((code )0x0)(uVar5,uVar2); if (iVar8 == 0) { ((code )0x0)(puVar7,uVar3); break; } puVar7 = puVar7 + 0x10; uVar9 = uVar9 + 1; } } while( true ); } uVar2 = ((code )0x0)(local_b0); uVar3 = ((code )0x0)(); ((code )0x0)(0x70240,uVar2,uVar3); iVar8 = local_30; } } ((code )0x0)(iVar8); return 0; } I'm a bit concerned about:

} while (? != ?) on r2dec The relative length and complexity of both dissassemblies... which on to trust more? :-S Happy to share the bin privately if that helps, unless you are already around r2-bins?

/cc @radare

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

brainstorm commented 5 years ago

Tried with both (via e anal.a2f=true as you suggested). Same effect/output from what I can see.

wargio commented 5 years ago

R2dec relies on agf flow graph, so i think there is an issue on the anal plugin for the SuperH.

Regarding } while (? != ?);, well, i didn't implement the flags update on superh. you can guess easily that the add operation updates the flag internally in the SuperH CPU and they are used to branch after.