From 133c1cf513a3c94207a4b4721bb414c0c672033e Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sat, 27 Jul 2019 18:03:21 +0200 Subject: [PATCH 01/29] Reduce far pointers to near in segmented code Proposal to convert far pointers to near pointers which are bound as far pointers in type parameters to functions for example which is otherwise not detected or properly translated. The casting time is a too late and not ideal time for this code. Possibly at function binding time would be better to detect it. However it is tested and working and reasonably generic using the default segment e.g. global RAM for its basis, checking the segment op, checking matching sizes, and finally that a near pointer already is present which can cause discarding of the segment and this awkward CONCAT structure that gets emitted in code. CALLOTHER or even SEGMENTOP is better but needs to be processed earlier or CONCAT just becomes SEGMENT in the code. Otherwise this direct simplification (which ruleaction segment reducer should deal with) also works. First proposal only. Sequences like this are now fixed: PUSH SS PUSH AX Fixes other half of #817 --- .../src/decompile/cpp/coreaction.cc | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index b2ac97b7c29..cc6fca35103 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1966,8 +1966,30 @@ int4 ActionSetCasts::castOutput(PcodeOp *op,Funcdata &data,CastStrategy *castStr // Preserve implied pointer if it points to a composite if ((meta!=TYPE_ARRAY)&&(meta!=TYPE_STRUCT)) outvn->updateType(tokenct,false,false); // Otherwise ignore it in favor of the token type - } - if (outvn->getType() != tokenct) + } else { + if (op->code() == CPUI_PIECE) { + Architecture* glb = data.getArch(); + AddrSpace* rspc = glb->getDefaultSpace(); + bool arenearpointers = glb->hasNearPointers(rspc); + if (arenearpointers && rspc->getAddrSize() == op->getOut()->getSize()) { + SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); + if (segdef->getBaseSize() == op->getIn(0)->getSize() && + segdef->getInnerSize() == op->getIn(1)->getSize() && + op->getIn(1)->getType()->getMetatype() == TYPE_PTR) { //far pointer found + //data.opSetOpcode(op, CPUI_CALLOTHER); //this is ideal but its way too late + //data.opInsertInput(op, op->getIn(1), 2); //need to check size of offset + //data.opSetInput(op, op->getIn(0), 1); //need to check size of segment + //data.opSetInput(op, data.newConstant(4, glb->userops.getSegmentOp(rspc->getIndex())->getIndex()), 0); + //data.opSetOpcode(op, CPUI_SEGMENTOP); //possible but again segmentizing occurs much earlier + //data.opSetInput(op, data.newVarnodeSpace(containerid), 0); //spacebase + data.opSetOpcode(op, CPUI_COPY); + data.opSwapInput(op, 0, 1); + data.opRemoveInput(op, 1); + } + } + } + } + if (outvn->getType() != tokenct) force=true; // Make sure not to drop pointer type } if (!force) { From 019daaa5c308735de916738e92bb7d63880fb448 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sat, 27 Jul 2019 18:17:58 +0200 Subject: [PATCH 02/29] Update coreaction.cc --- .../src/decompile/cpp/coreaction.cc | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index cc6fca35103..d17538535fe 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1966,29 +1966,29 @@ int4 ActionSetCasts::castOutput(PcodeOp *op,Funcdata &data,CastStrategy *castStr // Preserve implied pointer if it points to a composite if ((meta!=TYPE_ARRAY)&&(meta!=TYPE_STRUCT)) outvn->updateType(tokenct,false,false); // Otherwise ignore it in favor of the token type - } else { - if (op->code() == CPUI_PIECE) { - Architecture* glb = data.getArch(); - AddrSpace* rspc = glb->getDefaultSpace(); - bool arenearpointers = glb->hasNearPointers(rspc); - if (arenearpointers && rspc->getAddrSize() == op->getOut()->getSize()) { - SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); - if (segdef->getBaseSize() == op->getIn(0)->getSize() && - segdef->getInnerSize() == op->getIn(1)->getSize() && - op->getIn(1)->getType()->getMetatype() == TYPE_PTR) { //far pointer found - //data.opSetOpcode(op, CPUI_CALLOTHER); //this is ideal but its way too late - //data.opInsertInput(op, op->getIn(1), 2); //need to check size of offset - //data.opSetInput(op, op->getIn(0), 1); //need to check size of segment - //data.opSetInput(op, data.newConstant(4, glb->userops.getSegmentOp(rspc->getIndex())->getIndex()), 0); - //data.opSetOpcode(op, CPUI_SEGMENTOP); //possible but again segmentizing occurs much earlier - //data.opSetInput(op, data.newVarnodeSpace(containerid), 0); //spacebase - data.opSetOpcode(op, CPUI_COPY); - data.opSwapInput(op, 0, 1); - data.opRemoveInput(op, 1); - } - } - } - } + } else { + if (op->code() == CPUI_PIECE) { + Architecture* glb = data.getArch(); + AddrSpace* rspc = glb->getDefaultSpace(); + bool arenearpointers = glb->hasNearPointers(rspc); + if (arenearpointers && rspc->getAddrSize() == op->getOut()->getSize()) { + SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); + if (segdef->getBaseSize() == op->getIn(0)->getSize() && + segdef->getInnerSize() == op->getIn(1)->getSize() && + op->getIn(1)->getType()->getMetatype() == TYPE_PTR) { //far pointer found + //data.opSetOpcode(op, CPUI_CALLOTHER); //this is ideal but its way too late + //data.opInsertInput(op, op->getIn(1), 2); //need to check size of offset + //data.opSetInput(op, op->getIn(0), 1); //need to check size of segment + //data.opSetInput(op, data.newConstant(4, glb->userops.getSegmentOp(rspc->getIndex())->getIndex()), 0); + //data.opSetOpcode(op, CPUI_SEGMENTOP); //possible but again segmentizing occurs much earlier + //data.opSetInput(op, data.newVarnodeSpace(containerid), 0); //spacebase + data.opSetOpcode(op, CPUI_COPY); + data.opSwapInput(op, 0, 1); + data.opRemoveInput(op, 1); + } + } + } + } if (outvn->getType() != tokenct) force=true; // Make sure not to drop pointer type } From 1d975bb8505d05123d3803d16336f00c1bf0130c Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sat, 27 Jul 2019 18:18:38 +0200 Subject: [PATCH 03/29] Update coreaction.cc --- Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index d17538535fe..e5ef7ed1fe0 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1989,7 +1989,7 @@ int4 ActionSetCasts::castOutput(PcodeOp *op,Funcdata &data,CastStrategy *castStr } } } - if (outvn->getType() != tokenct) + if (outvn->getType() != tokenct) force=true; // Make sure not to drop pointer type } if (!force) { From 40ae483be18a729d380bbc65392eea45479a4cd0 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sat, 3 Aug 2019 06:21:44 +0200 Subject: [PATCH 04/29] Update coreaction.cc --- .../src/decompile/cpp/coreaction.cc | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index e5ef7ed1fe0..9c79604ab71 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1213,7 +1213,24 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) uintb off = param->getAddress().getOffset(); int4 sz = param->getSize(); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative - Varnode *loadval = data.opStackLoad(spc,off,sz,op,(Varnode *)0,false); + Varnode* loadval; + if ((param->getType()->getMetatype() == TYPE_PTR || + param->getType()->getMetatype() == TYPE_CODE) && param->isTypeLocked()) { + Architecture* glb = data.getArch(); + AddrSpace* rspc = glb->getDefaultSpace(); + bool arenearpointers = glb->hasNearPointers(rspc); + if (arenearpointers && rspc->getAddrSize() == param->getSize()) { + SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); + PcodeOp* newop = data.newOp(3, op->getAddr()); + data.newUniqueOut(param->getSize(), newop); + data.opSetOpcode(newop, CPUI_CALLOTHER); + data.opSetInput(newop, data.newConstant(4, segdef->getIndex()), 0); + data.opSetInput(newop, data.opStackLoad(spc, off + segdef->getBaseSize(), segdef->getInnerSize(), op, (Varnode*)0, false), 1); //need to check size of segment + data.opSetInput(newop, data.opStackLoad(spc, off, segdef->getBaseSize(), op, (Varnode*)0, false), 2); //need to check size of offset + data.opInsertBefore(newop, op); + loadval = newop->getOut(); + } else loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); + } else loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { setplaceholder = true; @@ -1966,28 +1983,6 @@ int4 ActionSetCasts::castOutput(PcodeOp *op,Funcdata &data,CastStrategy *castStr // Preserve implied pointer if it points to a composite if ((meta!=TYPE_ARRAY)&&(meta!=TYPE_STRUCT)) outvn->updateType(tokenct,false,false); // Otherwise ignore it in favor of the token type - } else { - if (op->code() == CPUI_PIECE) { - Architecture* glb = data.getArch(); - AddrSpace* rspc = glb->getDefaultSpace(); - bool arenearpointers = glb->hasNearPointers(rspc); - if (arenearpointers && rspc->getAddrSize() == op->getOut()->getSize()) { - SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); - if (segdef->getBaseSize() == op->getIn(0)->getSize() && - segdef->getInnerSize() == op->getIn(1)->getSize() && - op->getIn(1)->getType()->getMetatype() == TYPE_PTR) { //far pointer found - //data.opSetOpcode(op, CPUI_CALLOTHER); //this is ideal but its way too late - //data.opInsertInput(op, op->getIn(1), 2); //need to check size of offset - //data.opSetInput(op, op->getIn(0), 1); //need to check size of segment - //data.opSetInput(op, data.newConstant(4, glb->userops.getSegmentOp(rspc->getIndex())->getIndex()), 0); - //data.opSetOpcode(op, CPUI_SEGMENTOP); //possible but again segmentizing occurs much earlier - //data.opSetInput(op, data.newVarnodeSpace(containerid), 0); //spacebase - data.opSetOpcode(op, CPUI_COPY); - data.opSwapInput(op, 0, 1); - data.opRemoveInput(op, 1); - } - } - } } if (outvn->getType() != tokenct) force=true; // Make sure not to drop pointer type From b56d0bbb9db8b72e3833d5be25ec17669692bd55 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sun, 4 Aug 2019 05:43:20 +0200 Subject: [PATCH 05/29] Update coreaction.cc --- .../src/decompile/cpp/coreaction.cc | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 9c79604ab71..6d74f2b2ee7 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1214,23 +1214,13 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) int4 sz = param->getSize(); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative Varnode* loadval; - if ((param->getType()->getMetatype() == TYPE_PTR || - param->getType()->getMetatype() == TYPE_CODE) && param->isTypeLocked()) { - Architecture* glb = data.getArch(); - AddrSpace* rspc = glb->getDefaultSpace(); - bool arenearpointers = glb->hasNearPointers(rspc); - if (arenearpointers && rspc->getAddrSize() == param->getSize()) { - SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); - PcodeOp* newop = data.newOp(3, op->getAddr()); - data.newUniqueOut(param->getSize(), newop); - data.opSetOpcode(newop, CPUI_CALLOTHER); - data.opSetInput(newop, data.newConstant(4, segdef->getIndex()), 0); - data.opSetInput(newop, data.opStackLoad(spc, off + segdef->getBaseSize(), segdef->getInnerSize(), op, (Varnode*)0, false), 1); //need to check size of segment - data.opSetInput(newop, data.opStackLoad(spc, off, segdef->getBaseSize(), op, (Varnode*)0, false), 2); //need to check size of offset - data.opInsertBefore(newop, op); - loadval = newop->getOut(); - } else loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); - } else loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); + SegmentOp* segdef = data.canSegmentizeFarPtr(param->getType(), param->isTypeLocked(), sz); + if (segdef != (SegmentOp*)0) + loadval = data.segmentizeFarPtr(sz, op, + data.opStackLoad(spc, off + segdef->getInnerSize(), + segdef->getBaseSize(), op, (Varnode*)0, false), + data.opStackLoad(spc, off, segdef->getInnerSize(), op, (Varnode*)0, false)); + else loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { setplaceholder = true; From 4aea5d68aa87b3482e22a1d708dfc0cb17a4bc3b Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sun, 4 Aug 2019 05:44:17 +0200 Subject: [PATCH 06/29] Update funcdata.hh --- Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh index 9ced5d3f611..5b196c12f16 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh @@ -370,6 +370,8 @@ public: } ParamActive *getActiveOutput(void) const { return activeoutput; } ///< Get the \e return prototype recovery object void setHighLevel(void); ///< Turn on HighVariable objects for all Varnodes + SegmentOp* canSegmentizeFarPtr(Datatype* typ, bool locked, int4 sz); + Varnode* segmentizeFarPtr(int4 sz, PcodeOp* op, Varnode* segvn, Varnode* offvn); void clearDeadVarnodes(void); ///< Delete any dead Varnodes void calcNZMask(void); ///< Calculate \e non-zero masks for all Varnodes void clearDeadOps(void) { obank.destroyDead(); } ///< Delete any dead PcodeOps From ed765ca9d1a7074fbe9e047c3a42511ccba6e83f Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sun, 4 Aug 2019 05:45:45 +0200 Subject: [PATCH 07/29] Update funcdata_varnode.cc --- .../src/decompile/cpp/funcdata_varnode.cc | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc index bce59397aba..7a340ca9ba2 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc @@ -479,6 +479,36 @@ void Funcdata::setHighLevel(void) assignHigh(*iter); } + +SegmentOp* Funcdata::canSegmentizeFarPtr(Datatype* typ, bool locked, int4 sz) +{ + if ((typ->getMetatype() == TYPE_PTR || + typ->getMetatype() == TYPE_CODE) && locked) { + Architecture* glb = getArch(); + AddrSpace* rspc = glb->getDefaultSpace(); + bool arenearpointers = glb->hasNearPointers(rspc); + if (arenearpointers && rspc->getAddrSize() == sz) + return glb->userops.getSegmentOp(rspc->getIndex()); + } + return (SegmentOp*)0; +} + +Varnode* Funcdata::segmentizeFarPtr(int4 sz, PcodeOp* op, Varnode* segvn, Varnode* offvn) +{ + Architecture* glb = getArch(); + AddrSpace* rspc = glb->getDefaultSpace(); + SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); + PcodeOp* newop = newOp(3, op->getAddr()); + newUniqueOut(sz, newop); + opSetOpcode(newop, CPUI_CALLOTHER); + //endianness could matter here - e.g. CALLF addr16 on x86 uses segment(*:2 (ptr+2),*:2 ptr) + opSetInput(newop, newConstant(4, segdef->getIndex()), 0); + opSetInput(newop, segvn, 1); //need to check size of segment + opSetInput(newop, offvn, 2); //need to check size of offset + opInsertBefore(newop, op); + return newop->getOut(); +} + /// \brief Create two new Varnodes which split the given Varnode /// /// Attributes are copied from the original into the split pieces if appropriate From 3298e4b8b1f50ccda8b2c143844171d391c7342a Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sun, 4 Aug 2019 06:12:17 +0200 Subject: [PATCH 08/29] Update funcdata_varnode.cc --- .../Decompiler/src/decompile/cpp/funcdata_varnode.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc index 7a340ca9ba2..3dd15f78376 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc @@ -493,19 +493,20 @@ SegmentOp* Funcdata::canSegmentizeFarPtr(Datatype* typ, bool locked, int4 sz) return (SegmentOp*)0; } -Varnode* Funcdata::segmentizeFarPtr(int4 sz, PcodeOp* op, Varnode* segvn, Varnode* offvn) +Varnode* Funcdata::segmentizeFarPtr(int4 sz, PcodeOp* op, + Varnode* segvn, Varnode* offvn, Varnode* outvn) { Architecture* glb = getArch(); AddrSpace* rspc = glb->getDefaultSpace(); SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); PcodeOp* newop = newOp(3, op->getAddr()); - newUniqueOut(sz, newop); + outvn == (Varnode*)0 ? newUniqueOut(sz, newop) : opSetOutput(op, outvn); opSetOpcode(newop, CPUI_CALLOTHER); //endianness could matter here - e.g. CALLF addr16 on x86 uses segment(*:2 (ptr+2),*:2 ptr) opSetInput(newop, newConstant(4, segdef->getIndex()), 0); opSetInput(newop, segvn, 1); //need to check size of segment opSetInput(newop, offvn, 2); //need to check size of offset - opInsertBefore(newop, op); + outvn == (Varnode*)0 ? opInsertBefore(newop, op) : opInsertAfter(newop, op); return newop->getOut(); } From c92b7ad4a9211a6d4c0a0bad3e10de17565f5485 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sun, 4 Aug 2019 06:12:49 +0200 Subject: [PATCH 09/29] Update funcdata.hh --- Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh index 5b196c12f16..d4881a49b8b 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh @@ -371,7 +371,7 @@ public: ParamActive *getActiveOutput(void) const { return activeoutput; } ///< Get the \e return prototype recovery object void setHighLevel(void); ///< Turn on HighVariable objects for all Varnodes SegmentOp* canSegmentizeFarPtr(Datatype* typ, bool locked, int4 sz); - Varnode* segmentizeFarPtr(int4 sz, PcodeOp* op, Varnode* segvn, Varnode* offvn); + Varnode* segmentizeFarPtr(int4 sz, PcodeOp* op, Varnode* segvn, Varnode* offvn, Varnode* outvn); void clearDeadVarnodes(void); ///< Delete any dead Varnodes void calcNZMask(void); ///< Calculate \e non-zero masks for all Varnodes void clearDeadOps(void) { obank.destroyDead(); } ///< Delete any dead PcodeOps From df639b5fdb7cc3dfe4d029145b9376d2ff8c6ed6 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sun, 4 Aug 2019 06:16:44 +0200 Subject: [PATCH 10/29] Update coreaction.cc --- .../src/decompile/cpp/coreaction.cc | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 6d74f2b2ee7..2898ddfd480 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1212,14 +1212,13 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) AddrSpace *spc = param->getAddress().getSpace(); uintb off = param->getAddress().getOffset(); int4 sz = param->getSize(); + SegmentOp* segdef = data.canSegmentizeFarPtr(param->getType(), param->isTypeLocked(), sz); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative Varnode* loadval; - SegmentOp* segdef = data.canSegmentizeFarPtr(param->getType(), param->isTypeLocked(), sz); - if (segdef != (SegmentOp*)0) - loadval = data.segmentizeFarPtr(sz, op, - data.opStackLoad(spc, off + segdef->getInnerSize(), - segdef->getBaseSize(), op, (Varnode*)0, false), - data.opStackLoad(spc, off, segdef->getInnerSize(), op, (Varnode*)0, false)); + if (segdef != (SegmentOp*)0) loadval = data.segmentizeFarPtr(sz, op, + data.opStackLoad(spc, off + segdef->getInnerSize(), + segdef->getBaseSize(), op, (Varnode*)0, false), + data.opStackLoad(spc, off, segdef->getInnerSize(), op, (Varnode*)0, false), (Varnode*)0); else loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { @@ -1227,9 +1226,12 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) loadval->setSpacebasePlaceholder(); spacebase = (AddrSpace *)0; // With a locked stack parameter, we don't need a stackplaceholder } - } - else - data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); + } else if (segdef != (SegmentOp*)0) { + data.opInsertInput(op, data.segmentizeFarPtr(sz, op, + data.newVarnode(segdef->getBaseSize(), Address(spc, off + segdef->getInnerSize())), + data.newVarnode(segdef->getInnerSize(), param->getAddress()), (Varnode*)0), op->numInput()); + } else + data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); } } if (spacebase != (AddrSpace *)0) { // If we need it, create the stackplaceholder @@ -1258,6 +1260,13 @@ void ActionFuncLink::funcLinkOutput(FuncCallSpecs *fc,Funcdata &data) int4 sz = outparam->getSize(); Address addr = outparam->getAddress(); data.newVarnodeOut(sz,addr,fc->getOp()); + SegmentOp* segdef = data.canSegmentizeFarPtr(outparam->getType(), + outparam->isTypeLocked(), sz); + if (segdef != (SegmentOp*)0) { + data.segmentizeFarPtr(sz, fc->getOp(), + data.newVarnode(segdef->getBaseSize(), addr + segdef->getInnerSize()), + data.newVarnode(segdef->getInnerSize(), addr), fc->getOp()->getOut()); + } VarnodeData vdata; OpCode res = fc->assumedOutputExtension(addr,sz,vdata); if (res == CPUI_PIECE) { // Pick an extension based on type From a018e1991cb4bbd24c57828a50b3b9055e226d7b Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sun, 4 Aug 2019 07:06:24 +0200 Subject: [PATCH 11/29] Update funcdata_varnode.cc --- .../Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc index 3dd15f78376..a95b1d8923f 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc @@ -500,13 +500,13 @@ Varnode* Funcdata::segmentizeFarPtr(int4 sz, PcodeOp* op, AddrSpace* rspc = glb->getDefaultSpace(); SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); PcodeOp* newop = newOp(3, op->getAddr()); - outvn == (Varnode*)0 ? newUniqueOut(sz, newop) : opSetOutput(op, outvn); + if (outvn == (Varnode*)0) newUniqueOut(sz, newop); else opSetOutput(op, outvn); opSetOpcode(newop, CPUI_CALLOTHER); //endianness could matter here - e.g. CALLF addr16 on x86 uses segment(*:2 (ptr+2),*:2 ptr) opSetInput(newop, newConstant(4, segdef->getIndex()), 0); opSetInput(newop, segvn, 1); //need to check size of segment opSetInput(newop, offvn, 2); //need to check size of offset - outvn == (Varnode*)0 ? opInsertBefore(newop, op) : opInsertAfter(newop, op); + if (outvn == (Varnode*)0) opInsertBefore(newop, op); else opInsertAfter(newop, op); return newop->getOut(); } From 7318b17481d7e8307f78c30b2599ea28aca02a5c Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Sun, 4 Aug 2019 08:03:35 +0200 Subject: [PATCH 12/29] Update coreaction.cc --- .../Decompiler/src/decompile/cpp/coreaction.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 2898ddfd480..13ebe0e8e36 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1262,10 +1262,15 @@ void ActionFuncLink::funcLinkOutput(FuncCallSpecs *fc,Funcdata &data) data.newVarnodeOut(sz,addr,fc->getOp()); SegmentOp* segdef = data.canSegmentizeFarPtr(outparam->getType(), outparam->isTypeLocked(), sz); - if (segdef != (SegmentOp*)0) { - data.segmentizeFarPtr(sz, fc->getOp(), - data.newVarnode(segdef->getBaseSize(), addr + segdef->getInnerSize()), - data.newVarnode(segdef->getInnerSize(), addr), fc->getOp()->getOut()); + if (segdef != (SegmentOp*)0) { + PcodeOp* op = data.newOp(1, fc->getOp()->getAddr()); + data.opSetOpcode(op, CPUI_COPY); //must because of join spaces + data.newUniqueOut(sz, op); + data.opSetInput(op, fc->getOp()->getOut(), 0); + data.opInsertAfter(op, fc->getOp()); + data.segmentizeFarPtr(sz, op, + data.newVarnode(segdef->getBaseSize(), op->getOut()->getAddr() + segdef->getInnerSize()), + data.newVarnode(segdef->getInnerSize(), op->getOut()->getAddr()), data.newVarnode(sz, addr)); } VarnodeData vdata; OpCode res = fc->assumedOutputExtension(addr,sz,vdata); From 97a372da9a7d77e05590de0111a368c0bd54bf83 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Mon, 5 Aug 2019 09:58:51 +0200 Subject: [PATCH 13/29] Update funcdata.hh --- Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh index d4881a49b8b..9ced5d3f611 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh @@ -370,8 +370,6 @@ public: } ParamActive *getActiveOutput(void) const { return activeoutput; } ///< Get the \e return prototype recovery object void setHighLevel(void); ///< Turn on HighVariable objects for all Varnodes - SegmentOp* canSegmentizeFarPtr(Datatype* typ, bool locked, int4 sz); - Varnode* segmentizeFarPtr(int4 sz, PcodeOp* op, Varnode* segvn, Varnode* offvn, Varnode* outvn); void clearDeadVarnodes(void); ///< Delete any dead Varnodes void calcNZMask(void); ///< Calculate \e non-zero masks for all Varnodes void clearDeadOps(void) { obank.destroyDead(); } ///< Delete any dead PcodeOps From d72a2ee41043e45b41f4e25a71a1ea06fd6a32af Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Mon, 5 Aug 2019 09:59:19 +0200 Subject: [PATCH 14/29] Update funcdata_varnode.cc --- .../src/decompile/cpp/funcdata_varnode.cc | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc index a95b1d8923f..bce59397aba 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_varnode.cc @@ -479,37 +479,6 @@ void Funcdata::setHighLevel(void) assignHigh(*iter); } - -SegmentOp* Funcdata::canSegmentizeFarPtr(Datatype* typ, bool locked, int4 sz) -{ - if ((typ->getMetatype() == TYPE_PTR || - typ->getMetatype() == TYPE_CODE) && locked) { - Architecture* glb = getArch(); - AddrSpace* rspc = glb->getDefaultSpace(); - bool arenearpointers = glb->hasNearPointers(rspc); - if (arenearpointers && rspc->getAddrSize() == sz) - return glb->userops.getSegmentOp(rspc->getIndex()); - } - return (SegmentOp*)0; -} - -Varnode* Funcdata::segmentizeFarPtr(int4 sz, PcodeOp* op, - Varnode* segvn, Varnode* offvn, Varnode* outvn) -{ - Architecture* glb = getArch(); - AddrSpace* rspc = glb->getDefaultSpace(); - SegmentOp* segdef = glb->userops.getSegmentOp(rspc->getIndex()); - PcodeOp* newop = newOp(3, op->getAddr()); - if (outvn == (Varnode*)0) newUniqueOut(sz, newop); else opSetOutput(op, outvn); - opSetOpcode(newop, CPUI_CALLOTHER); - //endianness could matter here - e.g. CALLF addr16 on x86 uses segment(*:2 (ptr+2),*:2 ptr) - opSetInput(newop, newConstant(4, segdef->getIndex()), 0); - opSetInput(newop, segvn, 1); //need to check size of segment - opSetInput(newop, offvn, 2); //need to check size of offset - if (outvn == (Varnode*)0) opInsertBefore(newop, op); else opInsertAfter(newop, op); - return newop->getOut(); -} - /// \brief Create two new Varnodes which split the given Varnode /// /// Attributes are copied from the original into the split pieces if appropriate From 0288c7bfe468d79fbe50ba0f7a40a334dfa70990 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Mon, 5 Aug 2019 10:08:12 +0200 Subject: [PATCH 15/29] Update coreaction.cc --- .../src/decompile/cpp/coreaction.cc | 98 ++++++++++++++----- 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 13ebe0e8e36..13c4e220cd3 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1212,24 +1212,14 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) AddrSpace *spc = param->getAddress().getSpace(); uintb off = param->getAddress().getOffset(); int4 sz = param->getSize(); - SegmentOp* segdef = data.canSegmentizeFarPtr(param->getType(), param->isTypeLocked(), sz); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative - Varnode* loadval; - if (segdef != (SegmentOp*)0) loadval = data.segmentizeFarPtr(sz, op, - data.opStackLoad(spc, off + segdef->getInnerSize(), - segdef->getBaseSize(), op, (Varnode*)0, false), - data.opStackLoad(spc, off, segdef->getInnerSize(), op, (Varnode*)0, false), (Varnode*)0); - else loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); + Varnode* loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { setplaceholder = true; loadval->setSpacebasePlaceholder(); spacebase = (AddrSpace *)0; // With a locked stack parameter, we don't need a stackplaceholder } - } else if (segdef != (SegmentOp*)0) { - data.opInsertInput(op, data.segmentizeFarPtr(sz, op, - data.newVarnode(segdef->getBaseSize(), Address(spc, off + segdef->getInnerSize())), - data.newVarnode(segdef->getInnerSize(), param->getAddress()), (Varnode*)0), op->numInput()); } else data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); } @@ -1260,18 +1250,6 @@ void ActionFuncLink::funcLinkOutput(FuncCallSpecs *fc,Funcdata &data) int4 sz = outparam->getSize(); Address addr = outparam->getAddress(); data.newVarnodeOut(sz,addr,fc->getOp()); - SegmentOp* segdef = data.canSegmentizeFarPtr(outparam->getType(), - outparam->isTypeLocked(), sz); - if (segdef != (SegmentOp*)0) { - PcodeOp* op = data.newOp(1, fc->getOp()->getAddr()); - data.opSetOpcode(op, CPUI_COPY); //must because of join spaces - data.newUniqueOut(sz, op); - data.opSetInput(op, fc->getOp()->getOut(), 0); - data.opInsertAfter(op, fc->getOp()); - data.segmentizeFarPtr(sz, op, - data.newVarnode(segdef->getBaseSize(), op->getOut()->getAddr() + segdef->getInnerSize()), - data.newVarnode(segdef->getInnerSize(), op->getOut()->getAddr()), data.newVarnode(sz, addr)); - } VarnodeData vdata; OpCode res = fc->assumedOutputExtension(addr,sz,vdata); if (res == CPUI_PIECE) { // Pick an extension based on type @@ -4303,6 +4281,80 @@ int4 ActionInferTypes::apply(Funcdata &data) } return 0; } + + if (localcount == 0) { + Datatype* ct; + Varnode* vn; + VarnodeLocSet::const_iterator iter; + + for (iter = data.beginLoc(); iter != data.endLoc(); ++iter) { + vn = *iter; + if (vn->isAnnotation()) continue; + if ((!vn->isWritten()) && (vn->hasNoDescend())) continue; + ct = vn->getLocalType(); + SegmentOp* segdef = (SegmentOp*)0; + if ((ct->getMetatype() == TYPE_PTR || + ct->getMetatype() == TYPE_CODE) && vn->isTypeLock()) { + Architecture* glb = data.getArch(); + AddrSpace* rspc = glb->getDefaultSpace(); + bool arenearpointers = glb->hasNearPointers(rspc); + if (arenearpointers && rspc->getAddrSize() == vn->getSize()) + segdef = glb->userops.getSegmentOp(rspc->getIndex()); + } + //need to go through every single time this varnode is written to + if (segdef != (SegmentOp*)0 && vn->getDef() != (PcodeOp*)0 && + vn->getDef()->code() != CPUI_SEGMENTOP && vn->getDef()->code() != CPUI_CALLOTHER) { + iter--; + PcodeOp* segroot = vn->getDef(); + Varnode* outvn = data.newUnique(vn->getSize()); + data.opSetOutput(segroot, outvn); + PcodeOp* piece1 = data.newOp(2, segroot->getAddr()); + data.opSetOpcode(piece1, CPUI_SUBPIECE); + Varnode* vn1 = data.newUniqueOut(segdef->getBaseSize(), piece1); + data.opSetInput(piece1, outvn, 0); + data.opSetInput(piece1, data.newConstant(outvn->getSize(), segdef->getInnerSize()), 1); + data.opInsertAfter(piece1, segroot); + PcodeOp* piece2 = data.newOp(2, segroot->getAddr()); + data.opSetOpcode(piece2, CPUI_SUBPIECE); + Varnode* vn2 = data.newUniqueOut(segdef->getInnerSize(), piece2); + data.opSetInput(piece2, outvn, 0); + data.opSetInput(piece2, data.newConstant(outvn->getSize(), 0), 1); + data.opInsertAfter(piece2, piece1); + PcodeOp* newop = data.newOp(3, segroot->getAddr()); + data.opSetOutput(newop, vn); + data.opSetOpcode(newop, CPUI_CALLOTHER); + //endianness could matter here - e.g. CALLF addr16 on x86 uses segment(*:2 (ptr+2),*:2 ptr) + data.opSetInput(newop, data.newConstant(4, segdef->getIndex()), 0); + data.opSetInput(newop, vn1, 1); //need to check size of segment + data.opSetInput(newop, vn2, 2); //need to check size of offset + data.opInsertAfter(newop, piece2); + + segroot = vn->getDef(); + vector bindlist; + bindlist.push_back((Varnode*)0); + bindlist.push_back((Varnode*)0); + if (!segdef->unify(data, segroot, bindlist)) { + ostringstream err; + err << "Segment op in wrong form at "; + segroot->getAddr().printRaw(err); + throw LowlevelError(err.str()); + } + + if (segdef->getNumVariableTerms() == 1) + bindlist[1] = data.newConstant(4, 0); + // Redefine the op as a segmentop + data.opSetOpcode(segroot, CPUI_SEGMENTOP); + data.opSetInput(segroot, data.newVarnodeSpace(segdef->getSpace()), 0); + data.opSetInput(segroot, bindlist[1], 1); + data.opSetInput(segroot, bindlist[0], 2); + for (int4 j = segroot->numInput() - 1; j > 2; --j) // Remove anything else + data.opRemoveInput(segroot, j); + + iter++; + } + } + } + buildLocaltypes(data); // Set up initial types (based on local info) for(iter=data.beginLoc();iter!=data.endLoc();++iter) { vn = *iter; From e1245cb2c492fa3c47c1c2cdb6430dbd7f8e1495 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Mon, 5 Aug 2019 10:09:56 +0200 Subject: [PATCH 16/29] Update coreaction.cc --- Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 13c4e220cd3..9f21a808836 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1220,7 +1220,8 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) loadval->setSpacebasePlaceholder(); spacebase = (AddrSpace *)0; // With a locked stack parameter, we don't need a stackplaceholder } - } else + } + else data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); } } @@ -4281,7 +4282,7 @@ int4 ActionInferTypes::apply(Funcdata &data) } return 0; } - + if (localcount == 0) { Datatype* ct; Varnode* vn; From deb526148b810f86a37677dc74ab819bb020c216 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Mon, 5 Aug 2019 10:11:52 +0200 Subject: [PATCH 17/29] Update coreaction.cc --- Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 9f21a808836..977d4bf360e 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1213,7 +1213,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) uintb off = param->getAddress().getOffset(); int4 sz = param->getSize(); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative - Varnode* loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); + Varnode *loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { setplaceholder = true; @@ -1222,7 +1222,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) } } else - data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); + data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); } } if (spacebase != (AddrSpace *)0) { // If we need it, create the stackplaceholder @@ -4282,7 +4282,6 @@ int4 ActionInferTypes::apply(Funcdata &data) } return 0; } - if (localcount == 0) { Datatype* ct; Varnode* vn; From 3f039d9ffec23d66a17fff0dfe7f6e544a247903 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Mon, 5 Aug 2019 10:13:42 +0200 Subject: [PATCH 18/29] Update coreaction.cc --- Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 977d4bf360e..aafe57b289b 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1213,7 +1213,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) uintb off = param->getAddress().getOffset(); int4 sz = param->getSize(); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative - Varnode *loadval = data.opStackLoad(spc, off, sz, op, (Varnode*)0, false); + Varnode *loadval = data.opStackLoad(spc,off,sz,op,(Varnode *)0,false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { setplaceholder = true; @@ -1222,7 +1222,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) } } else - data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); + data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); } } if (spacebase != (AddrSpace *)0) { // If we need it, create the stackplaceholder From 2775aa11a7379ea5d8a6f746edb17090f0b4a569 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 03:20:35 +0200 Subject: [PATCH 19/29] Update funcdata.hh --- Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh index 9ced5d3f611..374690b76db 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh @@ -196,6 +196,7 @@ public: Varnode *newSpacebasePtr(AddrSpace *id); ///< Construct a new \e spacebase register for a given address space Varnode *findSpacebaseInput(AddrSpace *id) const; void spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const Address &rampoint,uintb origval,int4 origsize); + void segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize); /// \brief Get the number of heritage passes performed for the given address space /// From 2e4cc70b831a0b4e744107509c53fd2fef40cf8c Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 03:22:22 +0200 Subject: [PATCH 20/29] Update funcdata.cc --- .../Decompiler/src/decompile/cpp/funcdata.cc | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc index 13308f7604b..1bac2ec7caa 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc @@ -343,6 +343,71 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const opSetInput(op,outvn,slot); } +void Funcdata::segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize) +{ + SegmentOp* segdef = (SegmentOp*)0; + if ((ct->getMetatype() == TYPE_PTR || + ct->getMetatype() == TYPE_CODE) && locked) { + Architecture* glb = getArch(); + AddrSpace* rspc = glb->getDefaultSpace(); + bool arenearpointers = glb->hasNearPointers(rspc); + if (arenearpointers && rspc->getAddrSize() == vn->getSize()) + segdef = glb->userops.getSegmentOp(rspc->getIndex()); + } + //need to go through every single time this varnode is written to + if (segdef != (SegmentOp*)0 && vn->getDef() != (PcodeOp*)0 && !vn->isPtrCheck() && + vn->getDef()->code() != CPUI_SEGMENTOP && vn->getDef()->code() != CPUI_CALLOTHER) { + PcodeOp* segroot = vn->getDef(); + Varnode* outvn = newUnique(vn->getSize()); + opSetOutput(segroot, outvn); + PcodeOp* piece1 = newOp(2, segroot->getAddr()); + opSetOpcode(piece1, CPUI_SUBPIECE); + Varnode* vn1 = newUniqueOut(segdef->getBaseSize(), piece1); + opSetInput(piece1, outvn, 0); + opSetInput(piece1, newConstant(outvn->getSize(), segdef->getInnerSize()), 1); + opInsertAfter(piece1, segroot); + PcodeOp* piece2 = newOp(2, segroot->getAddr()); + opSetOpcode(piece2, CPUI_SUBPIECE); + Varnode* vn2 = newUniqueOut(segdef->getInnerSize(), piece2); + opSetInput(piece2, outvn, 0); + opSetInput(piece2, newConstant(outvn->getSize(), 0), 1); + opInsertAfter(piece2, piece1); + PcodeOp* newop = newOp(3, segroot->getAddr()); + opSetOutput(newop, vn); + opSetOpcode(newop, CPUI_CALLOTHER); + //endianness could matter here - e.g. CALLF addr16 on x86 uses segment(*:2 (ptr+2),*:2 ptr) + opSetInput(newop, newConstant(4, segdef->getIndex()), 0); + opSetInput(newop, vn1, 1); //need to check size of segment + opSetInput(newop, vn2, 2); //need to check size of offset + opInsertAfter(newop, piece2); + vn->setPtrCheck(); + outvn->setPtrCheck(); + + if (segmentize) {//FuncLinkInput/FuncLinkOutput come before segmentize, the rest require at least Spacebase for type locks + segroot = vn->getDef(); + vector bindlist; + bindlist.push_back((Varnode*)0); + bindlist.push_back((Varnode*)0); + if (!segdef->unify(*this, segroot, bindlist)) { + ostringstream err; + err << "Segment op in wrong form at "; + segroot->getAddr().printRaw(err); + throw LowlevelError(err.str()); + } + + if (segdef->getNumVariableTerms() == 1) + bindlist[1] = newConstant(4, 0); + // Redefine the op as a segmentop + opSetOpcode(segroot, CPUI_SEGMENTOP); + opSetInput(segroot, newVarnodeSpace(segdef->getSpace()), 0); + opSetInput(segroot, bindlist[1], 1); + opSetInput(segroot, bindlist[0], 2); + for (int4 j = segroot->numInput() - 1; j > 2; --j) // Remove anything else + opRemoveInput(segroot, j); + } + } +} + void Funcdata::clearCallSpecs(void) { From cc7e98b2a87de49e62c5c04b6f7e099e486cbf12 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 03:25:34 +0200 Subject: [PATCH 21/29] Update coreaction.cc --- .../src/decompile/cpp/coreaction.cc | 73 +++---------------- 1 file changed, 11 insertions(+), 62 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index aafe57b289b..dd88357d61f 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1214,6 +1214,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) int4 sz = param->getSize(); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative Varnode *loadval = data.opStackLoad(spc,off,sz,op,(Varnode *)0,false); + data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { setplaceholder = true; @@ -1221,8 +1222,11 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) spacebase = (AddrSpace *)0; // With a locked stack parameter, we don't need a stackplaceholder } } - else - data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); + else { + Varnode* loadval = data.newVarnode(param->getSize(), param->getAddress()); + data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false); + data.opInsertInput(op, loadval, op->numInput()); + } } } if (spacebase != (AddrSpace *)0) { // If we need it, create the stackplaceholder @@ -1251,6 +1255,7 @@ void ActionFuncLink::funcLinkOutput(FuncCallSpecs *fc,Funcdata &data) int4 sz = outparam->getSize(); Address addr = outparam->getAddress(); data.newVarnodeOut(sz,addr,fc->getOp()); + data.segmentizeFarPtr(outparam->getType(), outparam->isTypeLocked(), fc->getOp()->getOut(), false); VarnodeData vdata; OpCode res = fc->assumedOutputExtension(addr,sz,vdata); if (res == CPUI_PIECE) { // Pick an extension based on type @@ -4292,66 +4297,10 @@ int4 ActionInferTypes::apply(Funcdata &data) if (vn->isAnnotation()) continue; if ((!vn->isWritten()) && (vn->hasNoDescend())) continue; ct = vn->getLocalType(); - SegmentOp* segdef = (SegmentOp*)0; - if ((ct->getMetatype() == TYPE_PTR || - ct->getMetatype() == TYPE_CODE) && vn->isTypeLock()) { - Architecture* glb = data.getArch(); - AddrSpace* rspc = glb->getDefaultSpace(); - bool arenearpointers = glb->hasNearPointers(rspc); - if (arenearpointers && rspc->getAddrSize() == vn->getSize()) - segdef = glb->userops.getSegmentOp(rspc->getIndex()); - } - //need to go through every single time this varnode is written to - if (segdef != (SegmentOp*)0 && vn->getDef() != (PcodeOp*)0 && - vn->getDef()->code() != CPUI_SEGMENTOP && vn->getDef()->code() != CPUI_CALLOTHER) { - iter--; - PcodeOp* segroot = vn->getDef(); - Varnode* outvn = data.newUnique(vn->getSize()); - data.opSetOutput(segroot, outvn); - PcodeOp* piece1 = data.newOp(2, segroot->getAddr()); - data.opSetOpcode(piece1, CPUI_SUBPIECE); - Varnode* vn1 = data.newUniqueOut(segdef->getBaseSize(), piece1); - data.opSetInput(piece1, outvn, 0); - data.opSetInput(piece1, data.newConstant(outvn->getSize(), segdef->getInnerSize()), 1); - data.opInsertAfter(piece1, segroot); - PcodeOp* piece2 = data.newOp(2, segroot->getAddr()); - data.opSetOpcode(piece2, CPUI_SUBPIECE); - Varnode* vn2 = data.newUniqueOut(segdef->getInnerSize(), piece2); - data.opSetInput(piece2, outvn, 0); - data.opSetInput(piece2, data.newConstant(outvn->getSize(), 0), 1); - data.opInsertAfter(piece2, piece1); - PcodeOp* newop = data.newOp(3, segroot->getAddr()); - data.opSetOutput(newop, vn); - data.opSetOpcode(newop, CPUI_CALLOTHER); - //endianness could matter here - e.g. CALLF addr16 on x86 uses segment(*:2 (ptr+2),*:2 ptr) - data.opSetInput(newop, data.newConstant(4, segdef->getIndex()), 0); - data.opSetInput(newop, vn1, 1); //need to check size of segment - data.opSetInput(newop, vn2, 2); //need to check size of offset - data.opInsertAfter(newop, piece2); - - segroot = vn->getDef(); - vector bindlist; - bindlist.push_back((Varnode*)0); - bindlist.push_back((Varnode*)0); - if (!segdef->unify(data, segroot, bindlist)) { - ostringstream err; - err << "Segment op in wrong form at "; - segroot->getAddr().printRaw(err); - throw LowlevelError(err.str()); - } - - if (segdef->getNumVariableTerms() == 1) - bindlist[1] = data.newConstant(4, 0); - // Redefine the op as a segmentop - data.opSetOpcode(segroot, CPUI_SEGMENTOP); - data.opSetInput(segroot, data.newVarnodeSpace(segdef->getSpace()), 0); - data.opSetInput(segroot, bindlist[1], 1); - data.opSetInput(segroot, bindlist[0], 2); - for (int4 j = segroot->numInput() - 1; j > 2; --j) // Remove anything else - data.opRemoveInput(segroot, j); - - iter++; - } + bool bBegin = false; + if (iter == data.beginLoc()) bBegin = true; else iter--; + data.segmentizeFarPtr(ct, vn->isTypeLock(), vn, true); + if (bBegin) iter = data.beginLoc(); else iter++; } } From 6a1b8cef0ac13978c90c67d2c777e57ca9731e54 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 03:53:48 +0200 Subject: [PATCH 22/29] Update funcdata.hh --- Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh index 374690b76db..172a861d261 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh @@ -196,7 +196,7 @@ public: Varnode *newSpacebasePtr(AddrSpace *id); ///< Construct a new \e spacebase register for a given address space Varnode *findSpacebaseInput(AddrSpace *id) const; void spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const Address &rampoint,uintb origval,int4 origsize); - void segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize); + void segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize, bool bAfter); /// \brief Get the number of heritage passes performed for the given address space /// From d7ab5f62338ef5872058649fb47fedbd86b59234 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 03:54:28 +0200 Subject: [PATCH 23/29] Update funcdata.cc --- Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc index 1bac2ec7caa..9aea0838c6f 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc @@ -343,7 +343,7 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const opSetInput(op,outvn,slot); } -void Funcdata::segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize) +void Funcdata::segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize, bool bAfter) { SegmentOp* segdef = (SegmentOp*)0; if ((ct->getMetatype() == TYPE_PTR || @@ -365,7 +365,7 @@ void Funcdata::segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool seg Varnode* vn1 = newUniqueOut(segdef->getBaseSize(), piece1); opSetInput(piece1, outvn, 0); opSetInput(piece1, newConstant(outvn->getSize(), segdef->getInnerSize()), 1); - opInsertAfter(piece1, segroot); + if (bAfter) opInsertAfter(piece1, segroot); else opInsertBefore(piece1, segroot); PcodeOp* piece2 = newOp(2, segroot->getAddr()); opSetOpcode(piece2, CPUI_SUBPIECE); Varnode* vn2 = newUniqueOut(segdef->getInnerSize(), piece2); From 72923b9b2082114b439eeaa9c07de7e2cb619c81 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 03:56:07 +0200 Subject: [PATCH 24/29] Update coreaction.cc --- .../Features/Decompiler/src/decompile/cpp/coreaction.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index dd88357d61f..4397e0efeb6 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1214,7 +1214,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) int4 sz = param->getSize(); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative Varnode *loadval = data.opStackLoad(spc,off,sz,op,(Varnode *)0,false); - data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false); + data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false, false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { setplaceholder = true; @@ -1224,7 +1224,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) } else { Varnode* loadval = data.newVarnode(param->getSize(), param->getAddress()); - data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false); + data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false, false); data.opInsertInput(op, loadval, op->numInput()); } } @@ -1255,7 +1255,7 @@ void ActionFuncLink::funcLinkOutput(FuncCallSpecs *fc,Funcdata &data) int4 sz = outparam->getSize(); Address addr = outparam->getAddress(); data.newVarnodeOut(sz,addr,fc->getOp()); - data.segmentizeFarPtr(outparam->getType(), outparam->isTypeLocked(), fc->getOp()->getOut(), false); + data.segmentizeFarPtr(outparam->getType(), outparam->isTypeLocked(), fc->getOp()->getOut(), false, true); VarnodeData vdata; OpCode res = fc->assumedOutputExtension(addr,sz,vdata); if (res == CPUI_PIECE) { // Pick an extension based on type @@ -4299,7 +4299,7 @@ int4 ActionInferTypes::apply(Funcdata &data) ct = vn->getLocalType(); bool bBegin = false; if (iter == data.beginLoc()) bBegin = true; else iter--; - data.segmentizeFarPtr(ct, vn->isTypeLock(), vn, true); + data.segmentizeFarPtr(ct, vn->isTypeLock(), vn, true, true); if (bBegin) iter = data.beginLoc(); else iter++; } } From 1dde9ec3a158283104d7717995ce8f581bf81731 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 03:58:51 +0200 Subject: [PATCH 25/29] Update funcdata.hh --- Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh index 172a861d261..374690b76db 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.hh @@ -196,7 +196,7 @@ public: Varnode *newSpacebasePtr(AddrSpace *id); ///< Construct a new \e spacebase register for a given address space Varnode *findSpacebaseInput(AddrSpace *id) const; void spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const Address &rampoint,uintb origval,int4 origsize); - void segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize, bool bAfter); + void segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize); /// \brief Get the number of heritage passes performed for the given address space /// From f0eb3427256b388c29703b1152ccb4ab380630ca Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 03:59:35 +0200 Subject: [PATCH 26/29] Update funcdata.cc --- Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc index 9aea0838c6f..1bac2ec7caa 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc @@ -343,7 +343,7 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const opSetInput(op,outvn,slot); } -void Funcdata::segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize, bool bAfter) +void Funcdata::segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool segmentize) { SegmentOp* segdef = (SegmentOp*)0; if ((ct->getMetatype() == TYPE_PTR || @@ -365,7 +365,7 @@ void Funcdata::segmentizeFarPtr(Datatype* ct, bool locked, Varnode* vn, bool seg Varnode* vn1 = newUniqueOut(segdef->getBaseSize(), piece1); opSetInput(piece1, outvn, 0); opSetInput(piece1, newConstant(outvn->getSize(), segdef->getInnerSize()), 1); - if (bAfter) opInsertAfter(piece1, segroot); else opInsertBefore(piece1, segroot); + opInsertAfter(piece1, segroot); PcodeOp* piece2 = newOp(2, segroot->getAddr()); opSetOpcode(piece2, CPUI_SUBPIECE); Varnode* vn2 = newUniqueOut(segdef->getInnerSize(), piece2); From fb2c20f524764679958a8928e37877572fa860e3 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 04:00:20 +0200 Subject: [PATCH 27/29] Update coreaction.cc --- .../Features/Decompiler/src/decompile/cpp/coreaction.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 4397e0efeb6..dd88357d61f 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1214,7 +1214,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) int4 sz = param->getSize(); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative Varnode *loadval = data.opStackLoad(spc,off,sz,op,(Varnode *)0,false); - data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false, false); + data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { setplaceholder = true; @@ -1224,7 +1224,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) } else { Varnode* loadval = data.newVarnode(param->getSize(), param->getAddress()); - data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false, false); + data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false); data.opInsertInput(op, loadval, op->numInput()); } } @@ -1255,7 +1255,7 @@ void ActionFuncLink::funcLinkOutput(FuncCallSpecs *fc,Funcdata &data) int4 sz = outparam->getSize(); Address addr = outparam->getAddress(); data.newVarnodeOut(sz,addr,fc->getOp()); - data.segmentizeFarPtr(outparam->getType(), outparam->isTypeLocked(), fc->getOp()->getOut(), false, true); + data.segmentizeFarPtr(outparam->getType(), outparam->isTypeLocked(), fc->getOp()->getOut(), false); VarnodeData vdata; OpCode res = fc->assumedOutputExtension(addr,sz,vdata); if (res == CPUI_PIECE) { // Pick an extension based on type @@ -4299,7 +4299,7 @@ int4 ActionInferTypes::apply(Funcdata &data) ct = vn->getLocalType(); bool bBegin = false; if (iter == data.beginLoc()) bBegin = true; else iter--; - data.segmentizeFarPtr(ct, vn->isTypeLock(), vn, true, true); + data.segmentizeFarPtr(ct, vn->isTypeLock(), vn, true); if (bBegin) iter = data.beginLoc(); else iter++; } } From 3934d7100713b14c1c607cac57f6eb6d2792718e Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 04:10:07 +0200 Subject: [PATCH 28/29] Update coreaction.cc --- .../Features/Decompiler/src/decompile/cpp/coreaction.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index dd88357d61f..59219cd46bf 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1214,7 +1214,6 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) int4 sz = param->getSize(); if (spc->getType() == IPTR_SPACEBASE) { // Param is stack relative Varnode *loadval = data.opStackLoad(spc,off,sz,op,(Varnode *)0,false); - data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false); data.opInsertInput(op,loadval,op->numInput()); if (!setplaceholder) { setplaceholder = true; @@ -1222,11 +1221,9 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) spacebase = (AddrSpace *)0; // With a locked stack parameter, we don't need a stackplaceholder } } - else { - Varnode* loadval = data.newVarnode(param->getSize(), param->getAddress()); - data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), loadval, false); - data.opInsertInput(op, loadval, op->numInput()); - } + else + data.opInsertInput(op, data.newVarnode(param->getSize(), param->getAddress()), op->numInput()); + data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), op->getIn(op->numInput() - 1), false); } } if (spacebase != (AddrSpace *)0) { // If we need it, create the stackplaceholder From 26d65c86b4a1f38a7470d0753a020b79b86f53d8 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Tue, 6 Aug 2019 04:11:13 +0200 Subject: [PATCH 29/29] Update coreaction.cc --- Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 59219cd46bf..26e73972156 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1222,7 +1222,7 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) } } else - data.opInsertInput(op, data.newVarnode(param->getSize(), param->getAddress()), op->numInput()); + data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput()); data.segmentizeFarPtr(param->getType(), param->isTypeLocked(), op->getIn(op->numInput() - 1), false); } }