NationalSecurityAgency / ghidra

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

Undocumented Z80 machine code instructions are not decompiled #1335

Open jirkadanek opened 4 years ago

jirkadanek commented 4 years ago

When disassembling code that contains undocumented Z80 machine instructions, they are skipped by the disassembler. For example

They are documented in http://www.z80.info/z80undoc.htm or http://www.myquest.nl/z80undocumented/z80-documented-v0.91.pdf.

The FUSE ZX Spectrum emulator http://fuse-emulator.sourceforge.net/ recognizes them just fine.

Environment:

jirkadanek commented 4 years ago

Just out of curiosity, I've been adding to z80.slaspec, to see if I can add them. I'd have to check the emulator to be certain of the semantics, and I'd have to learn more of Sleigh, so I probably won't pursue this, at least not right now.

:LD A,"IYh"         is op0_8=0xfd & A; op0_8=0x7c {
    A = IY(1);
}

:INC "IXh"         is op0_8=0xdd; op0_8=0x24 {
    local ixh_temp:1 = IX(1);

    IX = ((IX >> 8) + 1) << 8 + IX & 0xff;
    setResultFlags(IX:1);
    additionFlags(ixh_temp, 1);
}

#TODO #DD #BC      CP   IXH

:INC "IYh"         is op0_8=0xfd; op0_8=0x24 {
    local iyh_temp:1 = IY(1);

    IY = ((IY >> 8) + 1) << 8 + IY & 0xff;
    setResultFlags(IY:1);
    additionFlags(iyh_temp, 1);
}

:DEC "IYh"         is op0_8=0xfd; op0_8=0x25 {
    local iyh_temp:1 = IY(1);

    IY = ((IY >> 8) - 1) << 8 + IY & 0xff;
    subtractionFlagsNoC(iyh_temp, 1);
    setResultFlags(IY:1);
}

There has to be some way to declare overlapping registers (IY and IYh), me thinks.

esaulenka commented 4 years ago

@jdanekrh, you can simply dublicate register definitions: extend define register offset=0x40 size=2 [ _ PC SP IX IY ]; with define register offset=0x46 size=1 [ IXL IXH IYL IYH ];

also, you can combine two instructions in one table:

ixh_iyh: IXH is op0_8=0xdd & IXH { export IXH; }
ixh_iyh: IYH is op0_8=0xfd & IYH { export IYH; }

:INC ixh_iyh is ixh_iyh; op0_8=0x24 {
   ixh_iyh = ixh_iyh + 1;
  # modify flags
}
:DEC ixh_iyh is ixh_iyh; op0_8=0x25 {
   ixh_iyh = ixh_iyh - 1;
  # modify flags
}

PS code above is not tested, sorry

jirkadanek commented 4 years ago

Thanks, I might try to fix it myself, after all.

@ryanmkurtz @esaulenka Is there existing test infrastructure in the project sources for disassemble/decompile functionality?

Currently, I have to 1) edit z80.slaspec, 2) recompile z80.slaspec, 3) restart ghidra 4) press d on a line I need to disassemble and see what happens.

I'd like to be able to instead write few JUnit tests and assert that a given machine code produces certain disassembly. Then I'd avoid restarting the full ghidra all the time.

Found https://github.com/NationalSecurityAgency/ghidra/tree/master/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/program, is that it?

esaulenka commented 4 years ago

I dont know, sorry. I wrote whole processor sleigh (and one half for another processor) without any tests. Of course, this way is full of pain..

ryanmkurtz commented 4 years ago

We recently released a processor test framework in 9.1. From the change history:

Sleigh. Added two new extension modules (SleighDevTools and GnuDisassembler) in support of processor module development. Added support for pcode junit tests which utilize emulation of cross-compiled C test code to verify sleigh pcode (i.e., instruction semantics). The SleighDevTools extension provides the pcode test C source and associated build scripts, as well as external disassembler support for aiding in the validation of disassembled instruction syntax. (GT-3067)

Any of the test.processors sub-directories in our source code should provide good examples.

esaulenka commented 4 years ago

Ryan, unfortunately I couldnt build DevTools on Windows. The problem also that I am not familiar enough with too complex Java projects... However, I never tried prebuild Ghidra 9.1.

You are right, it looks as a good tool and I should try to use it.

GhidorahRex commented 4 years ago

@esaulenka the pcodetest scripts in SleighDevTools are written in python and don't need to be built, but they do assume that you're working on linux.