Skip to content

Commit 5b005bb

Browse files
committed
added noreturn to runtimepanic, improved return types and fixed the slice type
1 parent d9a2d4a commit 5b005bb

9 files changed

+94
-10
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.DS_Store
12
.antProperties.xml
23
.classpath
34
.gradle/

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ Plugin to assist reversing Golang binaries with Ghidra.
55

66
This is in a VERY early stage and for now only handles linux/x86_64 binaries.
77

8+
# Usage
9+
10+
When importing, select the Language **x86:LE:64:golang:default**
811

912
# Features
1013

data/languages/golang1.12.cspec

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ felber: copied from Ghidra/Processors/x86/data/languages/x86-64-gcc.cspec
6969
</input>
7070
<output killedbycall="true">
7171
<pentry minsize="1" maxsize="64" align="8">
72-
<addr offset="-24" space="stack"/>
72+
<!-- TODO(felber) offset=0 is wrong, but I cannot seem to fix this -->
73+
<addr offset="8" space="stack"/>
7374
</pentry>
7475
</output>
7576
<!-- <killedbycall>

src/main/java/gotools/GoReturntypeAnalyzer.java

+12-6
Original file line numberDiff line numberDiff line change
@@ -106,32 +106,38 @@ private void detectReturnTypes(Program p, TaskMonitor m, MessageLog log, Functio
106106
return;
107107
}
108108
long numberOfArgs = totalArgReturnVals - numberOfRet;
109-
if (f.getReturnType().getLength() != numberOfRet * pointerSize) {
109+
if (f.getReturnType().getLength() != numberOfRet * pointerSize
110+
|| (numberOfRet != 0 && f.getReturn().getStackOffset() != minWrite)) {
111+
f.setCustomVariableStorage(true);
110112
try {
111113
switch (numberOfRet) {
112114
case 0:
113115
f.setReturnType(DataType.VOID, SourceType.ANALYSIS);
114116
break;
115117
case 1:
116-
f.setCustomVariableStorage(true);
117118
Undefined8DataType t = new Undefined8DataType();
118-
f.setReturn(t, new VariableStorage(p, minWrite, t.getLength()), SourceType.ANALYSIS);
119+
// The type is set to imported because otherwise we cannot overwrite it
120+
f.setReturn(t, new VariableStorage(p, minWrite, t.getLength()), SourceType.IMPORTED);
119121
break;
120122
default:
121-
f.setCustomVariableStorage(true);
122123
StructureDataType s =
123124
new StructureDataType(String.format("ret_%d", f.getSymbol().getID()), 0);
124125
for (int i = 0; i < numberOfRet; i++) {
125126
s.add(new Undefined8DataType());
126127
}
127-
f.setReturn(s, new VariableStorage(p, minWrite, s.getLength()), SourceType.ANALYSIS);
128+
// The type is set to imported because otherwise we cannot overwrite it
129+
f.setReturn(s, new VariableStorage(p, minWrite, s.getLength()), SourceType.IMPORTED);
128130
break;
129131
}
130132
} catch (InvalidInputException e) {
131133
log.appendException(e);
132134
}
133135
}
134-
if (f.getParameterCount() != numberOfArgs) {
136+
int paramenterLen = 0;
137+
for (Parameter param : f.getParameters()) {
138+
paramenterLen += param.getLength();
139+
}
140+
if (paramenterLen != numberOfArgs) {
135141
// Set the parameters
136142
Parameter[] params = f.getParameters();
137143
List<Variable> newParams = new Vector<>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package gotools;
2+
3+
import ghidra.app.services.AnalyzerType;
4+
import ghidra.app.util.importer.MessageLog;
5+
import ghidra.program.model.address.AddressSetView;
6+
import ghidra.program.model.listing.Function;
7+
import ghidra.program.model.listing.Program;
8+
import ghidra.program.model.symbol.Symbol;
9+
import ghidra.util.exception.CancelledException;
10+
import ghidra.util.task.TaskMonitor;
11+
12+
public class GoSpecialFunctionAnalyzer extends AnalyzerBase {
13+
public GoSpecialFunctionAnalyzer() {
14+
super("Golang Special functions analyzer", "analyzes special functiosn in go",
15+
AnalyzerType.FUNCTION_ANALYZER);
16+
}
17+
18+
@Override
19+
public boolean added(Program program, AddressSetView addressSetView, TaskMonitor taskMonitor,
20+
MessageLog messageLog) throws CancelledException {
21+
for (Symbol s : program.getSymbolTable().getSymbols("runtime.panicindex")) {
22+
Function f = program.getFunctionManager().getFunctionAt(s.getAddress());
23+
if (f == null) {
24+
continue;
25+
}
26+
f.setNoReturn(true);
27+
}
28+
return false;
29+
}
30+
}

src/main/java/gotools/GoTypesAnalyzer.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import ghidra.util.task.TaskMonitor;
1010

1111
public class GoTypesAnalyzer extends AnalyzerBase {
12-
GoTypesAnalyzer() {
12+
public GoTypesAnalyzer() {
1313
super("Go Types Analyzer", "Analyzes Types like string and slices",
1414
AnalyzerType.FUNCTION_ANALYZER);
1515
}
@@ -19,13 +19,14 @@ public boolean added(Program program, AddressSetView addressSetView, TaskMonitor
1919
MessageLog messageLog) throws CancelledException {
2020
StructureDataType s = new StructureDataType("GoString", 0);
2121
s.add(new QWordDataType(), "len", null);
22-
s.add(new PointerDataType(new CharDataType()), "str", null);
22+
s.add(new Pointer64DataType(new CharDataType()), "str", null);
2323
program.getDataTypeManager().addDataType(s, DataTypeConflictHandler.KEEP_HANDLER);
2424

2525
StructureDataType sl = new StructureDataType("GoSlice", 0);
26+
sl.add(new PointerDataType(), 8, "data", null);
2627
sl.add(new QWordDataType(), "len", null);
2728
sl.add(new QWordDataType(), "cap", null);
28-
sl.add(new PointerDataType());
29+
2930
program.getDataTypeManager().addDataType(sl, DataTypeConflictHandler.KEEP_HANDLER);
3031
return false;
3132
}

testdata/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
slices

testdata/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
slices:
2+
GOOS=linux go build -gcflags '-N -l' slices.go

testdata/slices.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package main
2+
3+
/*
4+
undefined8 <RETURN> Stack[0x20]:8
5+
1 /GoSlice Unaligned
6+
Structure GoSlice {
7+
}
8+
Size = 24 Actual Alignment = 1
9+
slice Stack[0x8]:24
10+
*/
11+
func getLen(a []int) int {
12+
return len(a)
13+
}
14+
15+
func getFirst(a []int) int {
16+
return a[0]
17+
}
18+
19+
func get(a []int, x int) int {
20+
return a[x]
21+
}
22+
23+
func getCap(a []int) int {
24+
return cap(a)
25+
}
26+
27+
func createSlice() []int {
28+
return []int{1, 2, 3, 4, 5, 6, 7}
29+
}
30+
31+
func main() {
32+
a := createSlice()
33+
l := getLen(a)
34+
f := getFirst(a)
35+
e := get(a, 3)
36+
c := getCap(a)
37+
38+
_ = l + f + e + c
39+
}

0 commit comments

Comments
 (0)