Skip to content

Commit f1fcd42

Browse files
committed
Merge remote-tracking branch 'origin/GT-3320_ghidra1_PR-1192_brggs_ElfAndroidRelocs'
2 parents c15b263 + d68f369 commit f1fcd42

File tree

14 files changed

+1014
-49
lines changed

14 files changed

+1014
-49
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/* ###
2+
* IP: GHIDRA
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package ghidra.app.util.bin;
17+
18+
import java.io.*;
19+
20+
import ghidra.program.model.mem.MemBuffer;
21+
import ghidra.program.model.mem.MemoryAccessException;
22+
23+
/**
24+
* <code>MemBufferByteProvider</code> provide a {@link ByteProvider} backed by
25+
* a {@link MemBuffer}.
26+
*/
27+
public class MemBufferByteProvider implements ByteProvider {
28+
29+
private MemBuffer buffer;
30+
31+
/**
32+
* Constructor
33+
* @param buffer memory buffer
34+
*/
35+
public MemBufferByteProvider(MemBuffer buffer) {
36+
this.buffer = buffer;
37+
}
38+
39+
@Override
40+
public File getFile() {
41+
return null;
42+
}
43+
44+
@Override
45+
public String getName() {
46+
return null;
47+
}
48+
49+
@Override
50+
public String getAbsolutePath() {
51+
return null;
52+
}
53+
54+
/**
55+
* Return maximum length since actual length is unknown
56+
* @return maximum possible length
57+
*/
58+
@Override
59+
public long length() {
60+
return Integer.MAX_VALUE;
61+
}
62+
63+
@Override
64+
public boolean isValidIndex(long index) {
65+
if (index < 0 || index > Integer.MAX_VALUE) {
66+
return false;
67+
}
68+
try {
69+
buffer.getByte((int) index);
70+
return true;
71+
}
72+
catch (MemoryAccessException e) {
73+
return false;
74+
}
75+
}
76+
77+
@Override
78+
public void close() throws IOException {
79+
// not applicable
80+
}
81+
82+
@Override
83+
public byte readByte(long index) throws IOException {
84+
if (index < 0 || index > Integer.MAX_VALUE) {
85+
throw new IOException("index out of range");
86+
}
87+
try {
88+
return buffer.getByte((int) index);
89+
}
90+
catch (MemoryAccessException e) {
91+
throw new IOException("index out of range");
92+
}
93+
}
94+
95+
@Override
96+
public byte[] readBytes(long index, long length) throws IOException {
97+
if (index < 0 || (index + length - 1) > Integer.MAX_VALUE) {
98+
throw new IOException("index/length of range");
99+
}
100+
int len = (int) length;
101+
byte[] bytes = new byte[len];
102+
if (buffer.getBytes(bytes, (int) index) != len) {
103+
throw new IOException("index/length of range");
104+
}
105+
return bytes;
106+
}
107+
108+
@Override
109+
public InputStream getInputStream(long index) throws IOException {
110+
if (index < 0 || index > Integer.MAX_VALUE) {
111+
throw new IOException("index out of range");
112+
}
113+
return new MemBufferProviderInputStream((int) index);
114+
}
115+
116+
private class MemBufferProviderInputStream extends InputStream {
117+
118+
private int initialOffset;
119+
private int offset;
120+
121+
MemBufferProviderInputStream(int offset) {
122+
this.offset = offset;
123+
this.initialOffset = offset;
124+
}
125+
126+
@Override
127+
public int read() throws IOException {
128+
byte b = readByte(offset++);
129+
return b & 0xff;
130+
}
131+
132+
@Override
133+
public int read(byte[] b, int off, int len) {
134+
byte[] bytes = new byte[len];
135+
int count = buffer.getBytes(bytes, offset);
136+
System.arraycopy(bytes, 0, b, off, count);
137+
offset += count;
138+
return count;
139+
}
140+
141+
@Override
142+
public int available() {
143+
return (int) length() - offset;
144+
}
145+
146+
@Override
147+
public synchronized void reset() throws IOException {
148+
offset = initialOffset;
149+
}
150+
151+
@Override
152+
public void close() throws IOException {
153+
// not applicable
154+
}
155+
}
156+
157+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/* ###
2+
* IP: GHIDRA
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package ghidra.app.util.bin.format.elf;
17+
18+
import ghidra.app.plugin.exceptionhandlers.gcc.datatype.AbstractLeb128DataType;
19+
import ghidra.docking.settings.Settings;
20+
import ghidra.docking.settings.SettingsDefinition;
21+
import ghidra.program.model.address.Address;
22+
import ghidra.program.model.data.DataType;
23+
import ghidra.program.model.data.DataTypeManager;
24+
25+
/**
26+
* <code>AndroidElfRelocationData</code> provides a dynamic LEB128 data
27+
* component for packed Android ELF Relocation Table.
28+
* See {@link AndroidElfRelocationTableDataType}.
29+
* <br>
30+
* Secondary purpose is to retain the relocation offset associated with a
31+
* component instance. This functionality relies on the 1:1 relationship
32+
* between this dynamic datatype and the single component which references it.
33+
*/
34+
class AndroidElfRelocationData extends AbstractLeb128DataType {
35+
36+
private final long relocationOffset;
37+
38+
/**
39+
* Creates a packed relocation offset data type based upon a signed LEB128
40+
* value.
41+
* @param dtm the data type manager to associate with this data type.
42+
* @param relocationOffset relocation offset associated with component.
43+
*/
44+
AndroidElfRelocationData(DataTypeManager dtm, long relocationOffset) {
45+
super("sleb128", true, dtm);
46+
this.relocationOffset = relocationOffset;
47+
}
48+
49+
@Override
50+
public DataType clone(DataTypeManager dtm) {
51+
if (dtm == getDataTypeManager()) {
52+
return this;
53+
}
54+
return new AndroidElfRelocationData(dtm, relocationOffset);
55+
}
56+
57+
@Override
58+
public String getMnemonic(Settings settings) {
59+
return name;
60+
}
61+
62+
@Override
63+
public String getDescription() {
64+
return "Android Packed Relocation Data for ELF";
65+
}
66+
67+
@Override
68+
public String getDefaultLabelPrefix() {
69+
return "sleb128";
70+
}
71+
72+
@Override
73+
protected SettingsDefinition[] getBuiltInSettingsDefinitions() {
74+
return null;
75+
}
76+
77+
@Override
78+
public Class<?> getValueClass(Settings settings) {
79+
return Address.class;
80+
}
81+
82+
/**
83+
* Get the relocation offset associated with this data item
84+
* @return the relocation offset associated with this data item
85+
*/
86+
long getRelocationOffset() {
87+
return relocationOffset;
88+
}
89+
}

0 commit comments

Comments
 (0)