Skip to content

Commit

Permalink
Merge branch 'master' into ruff_unsafe
Browse files Browse the repository at this point in the history
  • Loading branch information
cooljeanius authored Sep 20, 2024
2 parents a05b9d9 + eeada6f commit d335027
Show file tree
Hide file tree
Showing 32 changed files with 1,396 additions and 569 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
uses: actions/checkout@v4

- name: Setup Java JDK
uses: actions/setup-java@v4.2.2
uses: actions/setup-java@v4.3.0
if: matrix.language == 'c-cpp' || matrix.language == 'java-kotlin'
with:
distribution: 'temurin'
Expand Down
2 changes: 1 addition & 1 deletion Ghidra/Debug/Debugger-agent-dbgeng/Module.manifest
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
MODULE FILE LICENSE: pypkg/dist/capstone-5.0.1-py3-none-win_amd64.whl BSD-3-CAPSTONE
MODULE FILE LICENSE: pypkg/dist/comtypes-1.4.1-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/Pybag-2.2.10-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/Pybag-2.2.12-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/pywin32-306-cp312-cp312-win_amd64.whl Python Software Foundation License

6 changes: 3 additions & 3 deletions Ghidra/Debug/Debugger-agent-dbgeng/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* 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.
Expand Down Expand Up @@ -93,7 +93,7 @@ else {
}
}

distributePyDep("Pybag-2.2.10-py3-none-any.whl")
distributePyDep("Pybag-2.2.12-py3-none-any.whl")
distributePyDep("capstone-5.0.1-py3-none-win_amd64.whl")
distributePyDep("comtypes-1.4.1-py3-none-any.whl")
distributePyDep("pywin32-306-cp312-cp312-win_amd64.whl")
Expand Down
142 changes: 116 additions & 26 deletions Ghidra/Features/Base/ghidra_scripts/PasteCopiedListingBytesScript.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,26 @@
* 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.
*/
//Useful for getting bytes into a program that have been copied and pasted
//as text onto a website or other text documents. If there is no program open
//when the script is run, you will be prompted to select a processor and a
//new empty program will be created. Text in the copy buffer will be parsed
//to extract address and bytes, and everything else will be ignored.
//Example listing text:
// Useful for getting bytes into a program that have been copied and pasted
// as text onto a website or other text documents. The bytes can be from a listing
// or from a hexdump.
//
// If there is no program open when the script is run, you will be prompted
// to select a processor and a new empty program will be created.
//
// Text in the clipboard will be parsed
// to extract address and bytes, and everything else will be ignored.
//
// Example listing text:
// LAB_0007aaca XREF[1]:
// 0007aac0(j)
// 0007aaca 01 24
Expand All @@ -30,20 +35,33 @@
//
// 0007aad6 1f d0
// beq LAB_0007ab18
//
// Example hexdump text:
// Hex dump of section '.text':
// NOTE: This section has relocations against it, but these have NOT been applied to this dump.
// 0x00000000 80b487b0 00aff860 c7e90023 3b683b61 .......`...#;h;a
// 0x00000010 b7f92030 7b61fb68 1a4607f1 100393e8 .. 0{a.h.F......
// ...
// 0x00000210 1a443b6a 13441846 1437bd46 5df8047b .D;j.D.F.7.F]..{
//
//@category Program
//@menupath Edit.Paste Listing Text
import java.awt.datatransfer.*;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;

import docking.dnd.GClipboard;
import ghidra.app.script.GhidraScript;
import ghidra.app.services.ProgramManager;
import ghidra.program.model.address.*;
import ghidra.program.model.mem.*;
import ghidra.util.NumericUtilities;
import ghidra.util.exception.CancelledException;

public class PasteCopiedListingBytesScript extends GhidraScript {

@Override
public void run() throws Exception {
int id = 0;
if (currentProgram == null) {
Expand All @@ -57,18 +75,20 @@ public void run() throws Exception {
Memory memory = currentProgram.getMemory();

// get data from the clip board and turn it into a string
String ClipboardText = retrieveClipBoardText();
if (ClipboardText == null) {
String clipBoardText = retrieveClipBoardText();
if (clipBoardText == null) {
println("Nothing is copied to your clip board");
return;
}

// evaluate the copy buffer and get the byte array
Map<Address, byte[]> bytesToAdd = parseListingStringToByte(ClipboardText);
Map<Address, byte[]> bytesToAdd = parseListingStringToByte(clipBoardText);
if (bytesToAdd.isEmpty()) {
println("There are no bytes copied to your clip board");
return;
}

coalesceBytes(bytesToAdd);

// Check if memory block with the byte+address exists
boolean exists = checkForExistingMemory(memory, bytesToAdd);
Expand Down Expand Up @@ -97,6 +117,35 @@ public void run() throws Exception {
println("Created " + getNeededAddressSet(bytesToAdd));
}

private void coalesceBytes(Map<Address, byte[]> bytesToAdd) {
// Map is assumed to be a sorted Map
Set<Entry<Address, byte[]>> entrySet = bytesToAdd.entrySet();
Iterator<Entry<Address, byte[]>> iterator = entrySet.iterator();
Map.Entry<Address, byte[]> entryA = iterator.next();
while (entryA != null && iterator.hasNext()) {
Map.Entry<Address, byte[]> entryB = iterator.next();
Address addrA = entryA.getKey();
Address addrB = entryB.getKey();
byte bytesA[] = entryA.getValue();
if (addrA.add(bytesA.length).equals(addrB)) {
byte bytesB[] = entryB.getValue();
// coalesce, and res-start iterator
byte concatBytes[] = Arrays.copyOf(bytesA,bytesA.length+bytesB.length);
System.arraycopy(bytesB, 0, concatBytes, bytesA.length, bytesB.length);

bytesToAdd.replace(addrA, concatBytes);
bytesToAdd.remove(addrB);
iterator = entrySet.iterator();
entryA = null;
if (iterator.hasNext()) {
entryA = iterator.next();
}
continue;
}
entryA = entryB;
}
}

private void createMissingMemory(Map<Address, byte[]> bytesToAdd, Memory memory)
throws CancelledException, Exception {
AddressSet neededMem = getNeededAddressSet(bytesToAdd);
Expand Down Expand Up @@ -151,44 +200,85 @@ private AddressSet getNeededAddressSet(Map<Address, byte[]> Addresses)

private Map<Address, byte[]> parseListingStringToByte(String ClipboardText)
throws CancelledException {
// TreeMap so the entries will be sorted by Address
Map<Address, byte[]> newMap = new TreeMap<Address, byte[]>();
String[] bufferLines = ClipboardText.split("\n");
Map<Address, byte[]> newMap = new HashMap<Address, byte[]>();

Address firstAddress = null;

// For each line, look for address and bytes, accumlate address/byteStrings
// in a list, throwing out any text that can't be parsed
for (String line : bufferLines) {
monitor.checkCancelled();
line = line.trim();
if (line.isEmpty()) {
continue;
}
String[] words = line.split(" ");
if (words.length == 0) {
continue;
}
String startOfLine = words[0];
Address firstAddress = toAddr(startOfLine);
// if start of line word is > 2 assume address
// other wise, consider it a continuation of the
// previous address
// 001325a4 03 00 0b0 sethi %hi(0x1000),g1
// 00 04

boolean skipFirstWord = false;
if (startOfLine.length() > 2) {
firstAddress = toAddr(startOfLine);
skipFirstWord = true;
}
if (firstAddress == null) {
continue;
}
List<String> bytesFound = new ArrayList<String>();
List<String> bytesStringsList = new ArrayList<String>();
int numBytesFound = 0;
for (String word : words) {
monitor.checkCancelled();
if (word == words[0]) {
if (skipFirstWord) {
skipFirstWord = false;
continue;
}
if (word.isBlank() || word.length() > 2) {
// break if bytes already found and separator more than one " "
// 001325a4 03 00 0b0 sethi %hi(0x1000),g1
if (numBytesFound > 0 && word.isBlank()) {
break;
}
int len = word.length();
if (word.isBlank() || len > 8 || (len % 2) != 0) {
break;
}
try {
Integer.parseInt(word, 16);
Long.parseLong(word, 16);
}
catch (Exception e) {
break;
}
bytesFound.add(word);

}
byte[] newBytes = new byte[bytesFound.size()];
int i = 0;
for (String byteString : bytesFound) {
monitor.checkCancelled();
byte bVal = (byte) Integer.parseInt(byteString, 16);
newBytes[i++] = bVal;
bytesStringsList.add(word);
numBytesFound += len / 2;
}

// parse found address/byteStrings into byte array
byte newBytes[] = parseHexStrings(bytesStringsList,numBytesFound);
newMap.put(firstAddress, newBytes);
firstAddress = firstAddress.add(newBytes.length);
}
return newMap;
}

private byte[] parseHexStrings(List<String> byteStringsList, int numBytesFound)
throws CancelledException {
byte[] newBytes = new byte[numBytesFound];
int byteArrayIndex = 0;
for (String byteString : byteStringsList) {
monitor.checkCancelled();
int numBytes = byteString.length() / 2;
byte[] bytes = NumericUtilities.convertStringToBytes(byteString);
System.arraycopy(bytes, 0, newBytes, byteArrayIndex, bytes.length);
byteArrayIndex += bytes.length;
}
return newBytes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* 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.
Expand Down Expand Up @@ -45,8 +45,8 @@ public CallNode(CallTreeOptions callTreeOptions) {
}

/**
* Returns this node's remote function, where remote is the source function for
* an incoming call or a destination function for an outgoing call. May return
* Returns this node's remote function, where remote is the source function for
* an incoming call or a destination function for an outgoing call. May return
* null for nodes that do not have functions.
* @return the function or null
*/
Expand All @@ -65,8 +65,8 @@ public CallNode(CallTreeOptions callTreeOptions) {
public abstract Address getSourceAddress();

/**
* Called when this node needs to be reconstructed due to external changes, such as when
* functions are renamed.
* Called when this node needs to be reconstructed due to external changes, such as when
* functions are renamed.
*
* @return a new node that is the same type as 'this' node.
*/
Expand All @@ -93,12 +93,6 @@ protected Set<Reference> getReferencesFrom(Program program, AddressSetView addre
protected void addNode(LazyMap<Function, List<GTreeNode>> nodesByFunction, CallNode node) {

Function function = node.getRemoteFunction();
if (function != null && function.isThunk()) {
if (!callTreeOptions.allowsThunks()) {
return;
}
}

List<GTreeNode> nodes = nodesByFunction.get(function);
if (nodes.contains(node)) {
return; // never add equal() nodes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* 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.
Expand Down Expand Up @@ -681,18 +681,18 @@ public boolean isAddToPopup(ActionContext context) {
"Show the Function Call Tree window for the function " + "selected in the call tree");
tool.addLocalAction(this, newCallTree);

//
//
// Provider menu actions
//
//@formatter:off
filterThunksAction = new ToggleActionBuilder("Filter Thunks", plugin.getName())
.selected(false)
.selected(false)
.description("Thunk functions will not be shown in the tree when selected")
.helpLocation(new HelpLocation(plugin.getName(), "Call_Tree_Action_Filter_Thunks"))
.menuPath("Filter Thunks")
.onAction(c -> {
callTreeOptions = callTreeOptions.withFilterThunks(filterThunksAction.isSelected());
doUpdate();
doUpdate();
})
.buildAndInstallLocal(this);
//@formatter:on
Expand All @@ -705,7 +705,7 @@ public boolean isAddToPopup(ActionContext context) {
.menuPath("Show Namespace")
.onAction(c -> {
callTreeOptions = callTreeOptions.withShowNamespace(showNamespaceAction.isSelected());
doUpdate();
doUpdate();
})
.buildAndInstallLocal(this);
//@formatter:on
Expand Down Expand Up @@ -860,6 +860,7 @@ protected boolean supportsPopupActions() {
}
};
tree.setPaintHandlesForLeafNodes(false);
tree.setDoubleClickExpansionEnabled(false); // reserve double-click for navigation
// tree.setFilterVisible(false);
return tree;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* 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.
Expand Down Expand Up @@ -65,6 +65,10 @@ public Address getSourceAddress() {
return reference.getFromAddress();
}

public Address getRemoteAddress() {
return reference.getToAddress();
}

@Override
public Icon getIcon(boolean expanded) {
return ICON;
Expand Down
Loading

0 comments on commit d335027

Please sign in to comment.