Open bthiae2934 opened 1 week ago
I'm in agreement that p-code to set FPUInstructionPointer
to 5 is missing. For this particular case, I think the following patch would fix it, but I'm not currently in a great position to test:
diff --git a/Ghidra/Processors/x86/data/languages/ia.sinc b/Ghidra/Processors/x86/data/languages/ia.sinc
index f7a29889a9..fa086de47f 100644
--- a/Ghidra/Processors/x86/data/languages/ia.sinc
+++ b/Ghidra/Processors/x86/data/languages/ia.sinc
@@ -4608,7 +4608,7 @@ define pcodeop to_bcd;
:FNCLEX is vexMode=0 & byte=0xDB; byte=0xE2 { FPUStatusWord[0,8] = 0; FPUStatusWord[15,1] = 0; }
:FCMOVB ST0, freg is vexMode=0 & byte=0xDA; frow=12 & fpage=0 & freg & ST0 { if ( !CF ) goto inst_next; ST0 = freg; }
-:FCMOVE ST0, freg is vexMode=0 & byte=0xDA; frow=12 & fpage=1 & freg & ST0 { if ( !ZF ) goto inst_next; ST0 = freg; }
+:FCMOVE ST0, freg is vexMode=0 & byte=0xDA; frow=12 & fpage=1 & freg & ST0 { FPUInstructionPointer = inst_start; if ( !ZF ) goto inst_next; ST0 = freg; }
:FCMOVBE ST0, freg is vexMode=0 & byte=0xDA; frow=13 & fpage=0 & freg & ST0 { if ( !CF & !ZF ) goto inst_next; ST0 = freg; }
:FCMOVU ST0, freg is vexMode=0 & byte=0xDA; frow=13 & fpage=1 & freg & ST0 { if ( !PF ) goto inst_next; ST0 = freg; }
:FCMOVNB ST0, freg is vexMode=0 & byte=0xDB; frow=12 & fpage=0 & freg & ST0 { if ( CF ) goto inst_next; ST0 = freg; }
This is incomplete, however, as you've pointed out. Many of the FP instructions would need this change. If you can confirm the above change fixes your case, then we'll know how to get started. Thanks!
@nsadeveloper789 I have tried your patch on master branch. Ghidra emulates this shellcode correctly after your patch applied. Thanks! I changed base address and ESP to verify whether it works.
Shellcode after decode:
Describe the bug I tried to use Ghidra to emulate shellcode encoded by shikata_ga_nai. Ghidra can't emulate following instruction sequence correctly:
These three instructions are a clever way to get EIP into EBP. The outcome of the first one is to set FPU instruction pointer to 0x5 and the second one is used to save FPU instruction pointer (and several other registers) on the stack.
Ghidra doesn't change FPU last instruction pointer so this register will remain at 0. Maybe it's necessary to change PCode of many floating-point instructions.
To Reproduce Steps to reproduce the behavior:
bf d3 7a d2 76 da ce d9 74 24 f4 5d 29 c9 b1 06 31 7d 12 83 c5 04 03 ae 74 30 83 61 40 43 8d 31 59 c4 61 42 36 14 16 8b a4 7d 88 5a cb b3 d4
Expected behavior FPUInstructionPointer should change to 0x5.
Screenshots
Attachments Nothing
Environment (please complete the following information):
Additional context From Intel Developer Manual: