Merge remote-tracking branch 'origin/Ghidra_12.0'

This commit is contained in:
Ryan Kurtz 2025-09-24 14:33:50 -04:00
commit a51cfb7c09
10 changed files with 150 additions and 13 deletions

View file

@ -566,6 +566,12 @@ public class CreateThunkFunctionCmd extends BackgroundCommand<Program> {
if (instr == null) {
return null;
}
// if there is no pcode, go to the next instruction
// assume fallthrough (ie. x86 instruction ENDBR64)
// TODO: at some point, might need to do a NOP detection
if (instr.getPcode().length == 0) {
instr = listing.getInstructionAfter(entry);
}
FlowType flowType;

View file

@ -17,6 +17,7 @@ package ghidra.app.analyzers;
import java.math.BigInteger;
import java.util.*;
import java.util.regex.Matcher;
import generic.jar.ResourceFile;
import ghidra.app.cmd.function.CreateFunctionCmd;
@ -209,7 +210,7 @@ public class FunctionStartAnalyzer extends AbstractAnalyzer implements PatternFa
private String label = null;
private boolean isThunk = false; // true if this function should be turned into a thunk
private boolean noreturn = false; // true to set function non-returning
private String sectionName = null; // required section name
private java.util.regex.Pattern sectionNamePattern = null; // required section name as a regex pattern
boolean validFunction = false; // must be defined at a function
private boolean contiguous = true; // require validcode instructions be contiguous
@ -227,9 +228,13 @@ public class FunctionStartAnalyzer extends AbstractAnalyzer implements PatternFa
protected boolean checkPreRequisites(Program program, Address addr) {
// check required section name
if (sectionName != null) {
if (sectionNamePattern != null) {
MemoryBlock block = program.getMemory().getBlock(addr);
if (block == null || !block.getName().matches(sectionName)) {
if (block == null) {
return false;
}
Matcher m = sectionNamePattern.matcher(block.getName());
if (!m.matches()) {
return false;
}
}
@ -651,7 +656,7 @@ public class FunctionStartAnalyzer extends AbstractAnalyzer implements PatternFa
break;
case "section":
sectionName = attrValue;
sectionNamePattern = java.util.regex.Pattern.compile(attrValue);
break;
case "noreturn":

View file

@ -240,10 +240,11 @@ public class GhidraApplicationLayout extends ApplicationLayout {
dirs.add(new ResourceFile(new File(userSettingsDir, "Extensions")));
if (SystemUtilities.isInDevelopmentMode()) {
ResourceFile rootDir = getApplicationRootDirs().iterator().next();
File temp = new File(rootDir.getFile(false), "Extensions");
if (temp.exists()) {
dirs.add(new ResourceFile(temp)); // ghidra/Ghidra/Extensions
for (ResourceFile rootDir : getApplicationRootDirs()) {
File temp = new File(rootDir.getFile(false), "Extensions");
if (temp.exists()) {
dirs.add(new ResourceFile(temp)); // i.e., ghidra/Ghidra/Extensions
}
}
}
else {

View file

@ -233,4 +233,13 @@
]]></body>
</pcode>
</callfixup>
<callfixup name="security_check_cookie">
<target name="__security_check_cookie"/>
<pcode>
<body><![CDATA[
tmpzero:4 = 0;
]]></body>
</pcode>
</callfixup>
</compiler_spec>

View file

@ -386,4 +386,13 @@
]]></body>
</pcode>
</callfixup>
<callfixup name="security_check_cookie">
<target name="__security_check_cookie"/>
<pcode>
<body><![CDATA[
tmpzero:4 = 0;
]]></body>
</pcode>
</callfixup>
</compiler_spec>

View file

@ -48,11 +48,70 @@
<data>0x41564155</data> <!-- PUSH R14; PUSH R13-->
<data>0x41554154</data> <!-- PUSH R13; PUSH R12-->
<data>0x41 010101.. 0100100. 0x89 11...... 0x55</data> <!-- PUSH R12/3/4/5; MOV(R12/3/4/5/xX,RxX); PUSH(RBP)-->
<data>0x41 010101.. 0x41 010101.. 0100100. 0x89 11...... </data> <!-- PUSH R12/3/4/5; PUSH R12/3/4/5; MOV(R12/3/4/5/xX,RxX); -->
<!-- These are copies of the patterns above with the ENDBR64 pattern pre-pended. If the above are modified, add here as well -->
<!-- ENDBR followed by two-instruction sequences -->
<data>0xf3 0x0f 0x1e 0xfa 0x48 0x89 0x5c 0x24 11...000 0x48 0x89 0x6c 0x24 11...000</data> <!-- MOV [RSP + C], RBX; MOV [RSP + C], RBP -->
<data>0xf3 0x0f 0x1e 0xfa 0x48 0x89 0x5c 0x24 11...000 0x4c 0x89 0x64 0x24 111..000</data> <!-- MOV [RSP + C], RBX; MOV [RSP + C], R12 -->
<data>0xf3 0x0f 0x1e 0xfa 0x48 0x89 0x6c 0x24 11...000 0x4c 0x89 0x64 0x24 111..000</data> <!-- MOV [RSP + C], RBP; MOV [RSP + C], R12 -->
<data>0xf3 0x0f 0x1e 0xfa 0x5589e5</data> <!-- PUSH RBP; MOV(EBP, ESP) (shared objects) -->
<data>0xf3 0x0f 0x1e 0xfa 0x554889e5</data> <!-- PUSH RBP; MOV(RBP, RSP) (shared objects) -->
<data>0xf3 0x0f 0x1e 0xfa 0x534889fb</data> <!-- PUSH RBX; MOV(RBX,RDI) (shared objects) -->
<data>0xf3 0x0f 0x1e 0xfa 0x554889fd</data> <!-- PUSH (RBP); MOV(RBP, RDI) (kernel objects) -->
<data>0xf3 0x0f 0x1e 0xfa 0x534889fb</data> <!-- PUSH RBX; MOV(RBX,RDI)-->
<data>0xf3 0x0f 0x1e 0xfa 0x53 0x48 0x83 0xec 0....000 </data> <!-- PUSH RBX; SUB RSP, C -->
<data>0xf3 0x0f 0x1e 0xfa 0x53 0x48 0x81 0xec .....000 00...... 0x00 </data> <!-- PUSH RBX; SUB RSP, C -->
<!-- ENDBR followed by three-instruction sequences -->
<data>0xf3 0x0f 0x1e 0xfa 0x55 0x48 0x89 0xe5 0x48 100000.1 0xec .....000</data> <!-- PUSH RBP; MOV RBP, RSP; SUB RSP, C -->
<data>0xf3 0x0f 0x1e 0xfa 0x554889e553</data> <!-- PUSH RBP; MOV RBP, RSP; PUSH RBX -->
<data>0xf3 0x0f 0x1e 0xfa 0x554889fd53</data> <!-- PUSH RBP; MOV RBP, RDI; PUSH RBX -->
<data>0xf3 0x0f 0x1e 0xfa 0x554889e548897df8</data> <!-- PUSH RBP; MOV RBP, RSP; MOV [RBP -0x8], RDI -->
<data>0xf3 0x0f 0x1e 0xfa 0x53 0x48 0x89 0xfb 0xe8 ........ ........ 0xff 0xff</data> <!-- PUSH RBX; MOV RBX,RDI; CALL -->
<data>0xf3 0x0f 0x1e 0xfa 0x4154 0x55 0100100. 0x89 11......</data> <!-- PUSH R12; PUSH RBP; MOV(R12/3/4/5/xX,RxX); -->
<data>0xf3 0x0f 0x1e 0xfa 0x4154 0x55 0x53 0100100. 0x89 11......</data> <!-- PUSH R12; PUSH RBP; PUSH RBX; MOV(R12/3/4/5/xX,RxX); -->
<!-- ENDBR followed by save registers start sequences -->
<data>0xf3 0x0f 0x1e 0xfa 0x415741564155</data> <!-- PUSH R15; PUSH R14; PUSH R13-->
<data>0xf3 0x0f 0x1e 0xfa 0x41564155</data> <!-- PUSH R14; PUSH R13-->
<data>0xf3 0x0f 0x1e 0xfa 0x41554154</data> <!-- PUSH R13; PUSH R12-->
<data>0xf3 0x0f 0x1e 0xfa 0x41 010101.. 0100100. 0x89 11...... 0x55</data> <!-- PUSH R12/3/4/5; MOV(R12/3/4/5/xX,RxX); PUSH(RBP)-->
<data>0xf3 0x0f 0x1e 0xfa 0x41 010101.. 0x41 010101.. 0100100. 0x89 11...... </data> <!-- PUSH R12/3/4/5; PUSH R12/3/4/5; MOV(R12/3/4/5/xX,RxX); -->
<funcstart/>
</postpatterns>
</patternpairs>
<!-- These are copies of the patterns above with the ENDBR64 pattern pre-pended. If the above are modified, add here as well
with the ENDBR64 specifying a code start.-->
<patternpairs totalbits="40" postbits="24">
<prepatterns>
<data>0x90 0x90</data> <!-- NOP NOP -->
<data>0xc3 0x90</data> <!-- RET NOP -->
<data>0x6690</data> <!-- two-byte nop -->
<data>0xc9 0xc3</data> <!-- LEAVE RET -->
<data>0xe9........</data> <!-- JMP xxx - after a shared jump target -->
<data>0xe9........90</data> <!-- JMP xxx, NOP - after a shared jump target -->
<data>0xeb..</data> <!-- JMP small -->
<data>0xeb..90</data> <!-- JMP small , NOP -->
<data>0x5d 0xc3</data> <!-- POP RBP, RET -->
<data>0x5b 0xc3</data> <!-- POP RBX, RET -->
<data>0x41 010111.. 0xc3</data> <!-- POP R12-15, RET -->
<data>0x31c0 0xc3</data> <!-- XOR(EAX,EAX), RET -->
<data>0x4883c4 ....1000 0xc3</data> <!-- ADD RSP, C; RET -->
<data>0x666690</data> <!-- three-byte NOP -->
<data>0x0f1f00</data> <!-- three-byte NOP -->
<data>0x0f1f4000</data> <!-- four-byte NOP -->
<data>0x0f1f440000</data> <!-- five-byte NOP -->
<data>0x660f1f440000</data> <!-- six-byte NOP -->
<data>0x0f1f8000000000</data> <!-- seven-byte NOP -->
<data>0x0f1f840000000000</data> <!-- eight-byte NOP -->
<data>0x660f1f840000000000</data> <!-- nine-byte NOP -->
</prepatterns>
<postpatterns>
<data>0xf3 0x0f 0x1e 0xfa </data> <!-- ENDBR64 -->
<!-- codestart, but could be an exception handler -->
<codeboundary/>
</postpatterns>
</patternpairs>
<pattern>
<data>0x5589e5</data> <!-- PUSH RBP; MOV(EBP, ESP) (shared objects) -->
<funcstart after="defined" /> <!-- must be something defined right before this, or no memory -->

View file

@ -89,4 +89,17 @@
<data>0xcccc * 0x4c8b 11...100 01001.01 0x89</data> <!-- CC filler : MOV -,RSP : MOV [- + #], -->
<funcstart/>
</pattern>
<pattern> <!-- This can most likely be removed when VS2022 FID files are added __security_check_cookie -->
<data> 01001... 0x3b 0x0d ........ ........ ........ ........
0x75 0x10
01001... 0xc1 0xc1 0x10
0x66 0xf7 0xc1 0xff 0xff
0x75 0x01
0xc3
01001... 0xc1 0xc9 0x10
0xe9 </data>
<align mark="0" bits="3"/>
<funcstart label="__security_check_cookie" validcode="function"/>
</pattern>
</patternlist>

View file

@ -108,9 +108,35 @@
<data>0x5589e5</data> <!-- PUSH EBP : MOV EBP,ESP -->
<data>0x8d 0x4c ..100100 0x04 0x83 0xe4 0xf. </data> <!-- LEA ECX [ESP+4] / AND ESP -->
<data>0x57 0x8d 0x7c ..100100 0x08 0x83 0xe4 0xf. </data> <!-- PUSH EDI / LEA EDI [ESP+8] / AND ESP -->
<!-- ENDBR32 followed by above patterns -->
<data>0xf3 0x0f 0x1e 0xfb 0x5589e5</data> <!-- PUSH EBP : MOV EBP,ESP -->
<data>0xf3 0x0f 0x1e 0xfb 0x8d 0x4c ..100100 0x04 0x83 0xe4 0xf. </data> <!-- LEA ECX [ESP+4] / AND ESP -->
<data>0xf3 0x0f 0x1e 0xfb 0x57 0x8d 0x7c ..100100 0x08 0x83 0xe4 0xf. </data> <!-- PUSH EDI / LEA EDI [ESP+8] / AND ESP -->
<codeboundary/>
<possiblefuncstart/>
</postpatterns>
</patternpairs>
<patternpairs totalbits="32" postbits="16">
<prepatterns>
<data>0x90</data> <!-- NOP filler -->
<data>0xc3</data> <!-- RET -->
<data>0xe9........</data> <!-- JMP big -->
<data>0xeb..</data> <!-- JMP small -->
<data>0x89f6</data> <!-- NOP (MOV ESI,ESI) -->
<data>0x8d7600</data> <!-- NOP (LEA ESI,[ESI]) -->
<data>0x8d742600</data> <!-- NOP (LEA ESI,[ESI]) -->
<data>0x8db600000000</data> <!-- NOP (LEA ESI,[ESI]) -->
<data>0x8dbf00000000</data> <!-- NOP (LEA EDI,[EDI]) -->
<data>0x8dbc2700000000</data> <!-- NOP (LEA EDI,[EDI]) -->
<data>0x8db42600000000</data> <!-- NOP (LEA ESI,[ESI]) -->
</prepatterns>
<postpatterns>
<data>0xf3 0x0f 0x1e 0xfb </data> <!-- ENDBR32 -->
<codeboundary/>
</postpatterns>
</patternpairs>
</patternlist>

View file

@ -6,15 +6,15 @@
0x68......00 <!-- push -->
0xe9......ff <!-- jmp -addr -->
</data> <!-- .plt thunk -->
<funcstart thunk="true" section=".plt"/>
<funcstart thunk="true" section="(?i)(\.plt)"/>
</pattern>
<pattern>
<data>
0xf3 0x0f 0x1e 0x1a <!-- ENDBR64 -->
0xf2 0xff 0x25 .. .. .. .. <!-- jmp -->
0xf3 0x0f 0x1e 0xfa <!-- ENDBR64 -->
0xf2 0xff 0x25 <!-- jmp qword ptr [0xxxx] -->
</data> <!-- .plt thunk -->
<funcstart thunk="true" section=".plt"/>
<funcstart thunk="true" section="(?i)(\.plt(\.sec)?)"/>
</pattern>
</patternlist>

View file

@ -144,4 +144,13 @@
<funcstart label="__break" validcode="function" noreturn="true"/> <!-- must be defined at an existing function -->
</pattern>
<pattern> <!-- This can most likely be removed when VS2022 FID files are added __security_check_cookie -->
<data> 0x3b 0x0d 0x.. 0x.. 0x.. 0x..
0x75 0x01
0xc3
0xe9
</data>
<funcstart label="__security_check_cookie" validcode="function"/>
</pattern>
</patternlist>