# Programmatically NOP the Current Selection in Ghidra **[blag.nullteilerfrei.de/2020/08/23/programmatically-nop-the-current-selection-in-ghidra/](https://blag.nullteilerfrei.de/2020/08/23/programmatically-nop-the-current-selection-in-ghidra/)** born The Zlob malware contains lots of bogus API calls to hinder analysis. This blag post describes how to use a script in Ghidra to automate the process of patching out those calls with `NOP instructions. The malware employs some basic obfuscation techniques, one of` which is performing lots of API calls without side effects. This makes both the disassembly as well as the decompile view hard to read. The following excerpts where take from a random sample belonging to this family (SHA256 hash ``` 0b38ca277bbb042d43bd1f17c4e424e167020883526eb2527ba929b2f0990a8f ): ff d5 | CALL EBP=>KERNEL32.DLL::GetCurrentThreadId ff d5 | CALL EBP=>KERNEL32.DLL::GetCurrentThreadId ff d6 | CALL ESI=>KERNEL32.DLL::GetLastError ff d7 | CALL EDI=>KERNEL32.DLL::GetConsoleCP ff d6 | CALL ESI=>KERNEL32.DLL::GetLastError ff d6 | CALL ESI=>KERNEL32.DLL::GetLastError ff d6 | CALL ESI=>KERNEL32.DLL::GetLastError ff d7 | CALL EDI=>KERNEL32.DLL::GetConsoleCP ff d6 | CALL ESI=>KERNEL32.DLL::GetLastError ff d7 | CALL EDI=>KERNEL32.DLL::GetConsoleCP ff d6 | CALL ESI=>KERNEL32.DLL::GetLastError ``` And the corresponding decompile view: ``` GetCurrentThreadId(); GetCurrentThreadId(); GetLastError(); GetConsoleCP(); GetLastError(); GetLastError(); GetLastError(); GetConsoleCP(); GetLastError(); GetConsoleCP(); GetLastError(); [...] ``` You can "just" hit F2 on every call (and the following byte) to replace it with the `NOP` instruction ( 0x90 ) but this is a more than tedious process. Let's write a handy script to automate this: ----- ``` public void run() throws Exception { if (currentSelection != null) { AddressRangeIterator addressRanges = currentSelection.getAddressRanges(true); for (AddressRange addressRange : addressRanges) { nopOut(addressRange.getMinAddress(), addressRange.getLength()); } } } private void nopOut(Address addressStart, long length) throws CancelledException, MemoryAccessException { clearListing(addressStart, addressStart.add(length)); for (int i = 0; i < length; i++) { Address address = addressStart.add(i); setByte(address, (byte) 0x90); } disassemble(addressStart); } ``` If you assign this script to the keyboard shortcut Ctrl-Alt-Shift-N for example, you can just select regions of disassembly and hit that combination to replace everything with `NOP . ## A` tiny plot-twist Since selecting calls in the decompile view will also highlight disassembly, one might think that you can as easily select region of the decompile view, execute the same script and come to the same result. Sadly this is not the case: If you select a line in the decompile view, the corresponding selection in the disassembly will always only have length 1. While one might think that in the screenshot above, the selection in the disassembly has a lenght of 6 and ranges from 0x10003a34 to 0x10003a3a (exclusively) it is in fact three selections, each of length 1 starting at `0x10003a34,` `0x10003a36 and,` `0x10003a38 .` Executing the above script will hence result in the byte sequence `90 d3 90 d3 90 d3` which cannot even be disassembled. So let's not pass in `addressRange.getLength() into` the `nopOut function but instead extend the length such that the last instruction is always` included completely: ----- ``` / * Searchers backwards for the last assembly instruction and returns the length * of the address range, potentially extended to fully include this last * instruction. */ private long assemblyAlignedLength(AddressRange addressRange) { long length = addressRange.getLength(); for (int i = 1; i <= MAX_ASSEMBLY_INSTRUCTION_LENGTH; i++) { Instruction instruction = getInstructionAt(addressRange.getMinAddress().add(length - i)); if (instruction != null) { return length + (instruction.getLength() - i); } } return length; } ``` [You can find the complete nts.java script on github!](https://github.com/nullteilerfrei/reversing-class/blob/master/scripts/java/NopThisShit.java) -----