-
Notifications
You must be signed in to change notification settings - Fork 47
/
CryptoConstantsSearch.java
142 lines (97 loc) · 4.57 KB
/
CryptoConstantsSearch.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//Fill in the blank demo - search for MD5 crypto constants in code
//@author Alexei Bulazel
//@category INFILTRATE
//@keybinding
//@menupath
//@toolbar
/* Some Ghidra API functions you may find useful...
[Memory method]
Address findBytes(Address startAddr, byte[] bytes, byte[] masks, boolean forward, TaskMonitor monitor)
Finds a sequence of contiguous bytes that match the given byte array at all bit positions where the mask contains an "on" bit. Starts at startAddr and ends at endAddr. If forward is true, search starts at startAddr and will end if startAddr ">" endAddr. If forward is false, search starts at start addr and will end if startAddr "<" endAddr.
Parameters:
startAddr - The beginning address in memory to search.
bytes - the array of bytes to search for.
masks - the array of masks. (One for each byte in the byte array) if all bits of each byte is to be checked (ie: all mask bytes are 0xff), then pass a null for masks.
forward - if true, search in the forward direction.
HINT: for the monitor parameter, you can just use getMonitor()
Returns: The address of where the first match is found. Null is returned if there is no match.
docs/api/ghidra/program/model/mem/Memory.html#findBytes(ghidra.program.model.address.Address,ghidra.program.model.address.Address,byte[],byte[],boolean,ghidra.util.task.TaskMonitor)
***********
[Address method]
Address add(long displacement) throws AddressOutOfBoundsException
Creates a new address (possibly in a new space) by adding the displacement to this address.
Parameters:
displacement - the amount to add to this offset.
Returns: The new address.
Throws: AddressOutOfBoundsException - if wrapping is not supported by the corresponding address space and the addition causes an out-of-bounds error
docs/api/ghidra/program/model/address/Address.html#add(long)
***********
public final Function getFunctionContaining(Address address)
Returns the function containing the specified address.
Parameters:
address - the address
Returns: the function containing the specified address
docs/api/ghidra/program/flatapi/FlatProgramAPI.html#getFunctionContaining(ghidra.program.model.address.Address)
***********
[Function method]
java.lang.String getName()
Get the name of this function.
Specified by:
getName in interface Namespace
Returns: the functions name
docs/api/ghidra/program/model/listing/Function.html#getName()
*/
import ghidra.app.script.GhidraScript;
import ghidra.util.DataConverter;
import ghidra.util.LittleEndianDataConverter;
import ghidra.util.BigEndianDataConverter;
import ghidra.program.model.mem.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.address.*;
import java.util.ArrayList;
public class CryptoConstantsSearch extends GhidraScript {
private ArrayList<Address>getAllOccurrences(int searchPattern) {
DataConverter converter;
Memory memory = currentProgram.getMemory();
Address baseAddr = memory.getMinAddress();
ArrayList<Address> occurrences = new ArrayList<Address>();
//convert byte sequence endianness, per current program endianness
if (currentProgram.getLanguage().isBigEndian()) {
converter = new BigEndianDataConverter();
}
else {
converter = new LittleEndianDataConverter();
}
byte[] asBytes = converter.getBytes(searchPattern);
println("TODO: find the first occurrence of the byte sequence in the program");
Address currentFind = null; //memory.findBytes(...)
//loop saving found addresses of found byte sequence occurences, and finding the next
while(currentFind != null) {
occurrences.add(currentFind);
//find the next occurrence
currentFind = memory.findBytes(currentFind.add(4), asBytes, null, true, getMonitor());
}
return occurrences;
}
public void run() throws Exception {
int[] MD5Constants = new int[] { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};
for (int md5value : MD5Constants) {
if(monitor.isCancelled()) {
break;
}
ArrayList <Address> found = getAllOccurrences(md5value);
for (Address currentFoundAddress : found) {
println("TODO: get the function at currentFoundAddress");
Function currentFunction = null;
String functionName = "n/a";
if(currentFunction != null){
functionName = "TODO: get the function name!";
}
printf("MD5 Constant 0x%x found at 0x%x (%s)\n",
md5value,
currentFoundAddress.getOffset(),
functionName);
}
}
}
}