diff --git a/Ghidra/Features/Base/ghidra_scripts/SearchForImageBaseOffsetsScript.java b/Ghidra/Features/Base/ghidra_scripts/SearchForImageBaseOffsetsScript.java new file mode 100644 index 0000000000..df5110d631 --- /dev/null +++ b/Ghidra/Features/Base/ghidra_scripts/SearchForImageBaseOffsetsScript.java @@ -0,0 +1,131 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// This script searches for image base offset references of size 32 and 64 to the current cursor +// location. This script only works on programs of size 32 and 64. +//@category Search + +import ghidra.app.script.GhidraScript; +import ghidra.program.model.address.Address; +import ghidra.util.exception.CancelledException; + +public class SearchForImageBaseOffsetsScript extends GhidraScript { + + @Override + public void run() throws Exception { + + if (currentProgram == null) { + println("No open program"); + return; + } + + long defaultPointerSize = currentProgram.getDefaultPointerSize(); + if (defaultPointerSize != 4 && defaultPointerSize != 8) { + println("This script only works on 32 or 64 bit programs"); + return; + } + + Address imageBase = currentProgram.getImageBase(); + + boolean isBigEndian = currentProgram.getMemory().isBigEndian(); + + long currentAddressOffset = currentAddress.getOffset(); + long imageBaseOffset = imageBase.getOffset(); + + long currentAddressIbo = imageBaseOffset ^ currentAddressOffset; + + byte searchBytes[] = createSearchArray(currentAddressIbo, 8, isBigEndian); + println("searching for possible ibo64 references to " + currentAddress.toString() + " ..."); + searchForByteArray(searchBytes); + + searchBytes = createSearchArray(currentAddressIbo, 4, isBigEndian); + println("searching for possible ibo32 references to " + currentAddress.toString() + " ..."); + searchForByteArray(searchBytes); + + } + + /** + * Method to return an appropriate sized and endian-ordered byte array out of the given long value + * @param value the given value + * @param numBytes the number of bytes to copy into the array + * @return the appropriate sized and endian-ordered byte array for the given value + * @throws CancelledException if cancelled + */ + private byte[] createSearchArray(long value, int numBytes, boolean isBigEndian) + throws CancelledException { + + if (isBigEndian) { + return createBigEndianByteArray(value, numBytes); + } + return createLittleEndianByteArray(value, numBytes); + } + + /** + * Method to create a little endian ordered byte array out of the given long value + * @param value the given value + * @param numBytes the number of bytes to copy into the array + * @return the little endian byte array for the given value + * @throws CancelledException if cancelled + */ + private byte[] createLittleEndianByteArray(long value, int numBytes) + throws CancelledException { + + + byte byteArray[] = new byte[numBytes]; + + for (int i = 0; i < numBytes; i++) { + monitor.checkCanceled(); + byteArray[i] = (byte) (value >> (8 * i) & 0xff); + } + + return byteArray; + } + + /** + * Method to create a big endian byte array out of the given long value + * @param value the given value + * @param numBytes the number of bytes to copy into the array + * @return the big endian byte array for the given value + * @throws CancelledException if cancelled + */ + private byte[] createBigEndianByteArray(long value, int numBytes) throws CancelledException { + + byte byteArray[] = new byte[numBytes]; + + for (int i = 0; i < numBytes; i++) { + monitor.checkCanceled(); + byteArray[i] = (byte) (value >> (8 * (numBytes - (i + 1))) & 0xff); + } + + return byteArray; + } + + /** + * Method to search for the given byte array and print the address(es) where it is found + * @param byteArray the given byte array + * @throws CancelledException if cancelled + */ + private void searchForByteArray(byte[] byteArray) throws CancelledException { + Address start = currentProgram.getMinAddress(); + Address found = find(start, byteArray); + while (found != null) { + monitor.checkCanceled(); + println(found.toString()); + start = found.add(1); + found = find(start, byteArray); + } + } + +}