public byte[] askBytes(String title, String message) throws CancelledException {

		String key = join(title, message);
		byte[] existingValue = loadAskValue(this::parseBytes, key);
		if (isRunningHeadless()) {
			return existingValue;
		}

		byte[] choice = doAsk(byte[].class, title, message, existingValue, lastValue -> {

			String lastByteString = NumericUtilities.convertBytesToString(lastValue, " ");
			AskDialog<Byte> dialog =
				new AskDialog<>(title, message, AskDialog.BYTES, lastByteString);
			if (dialog.isCanceled()) {
				throw new CancelledException();
			}

			String bytesString = dialog.getValueAsString();
			byte[] bytes = NumericUtilities.convertStringToBytes(bytesString);
			return bytes;
		});

		return choice;
	}
Returns a byte array, using the String parameters for guidance. The actual behavior of the
method depends on your environment, which can be GUI or headless.
<p>
Regardless of environment -- if script arguments have been set, this method will use the
next argument in the array and advance the array index so the next call to an ask method
will get the next argument.  If there are no script arguments and a .properties file
sharing the same base name as the Ghidra Script exists (i.e., Script1.properties for
Script1.java), then this method will then look there for the String value to return.
The method will look in the .properties file by searching for a property name that is a
space-separated concatenation of the input String parameters (title + " " + message).
If that property name exists and its value represents valid bytes, then the
.properties value will be used in the following way:
<ol>
		<li>In the GUI environment, this method displays a popup dialog that prompts the
			user for a byte pattern. If the same popup has been run before in the same session,
			the byte pattern input field will be pre-populated with	the last-used bytes string.
			If not, the byte pattern input field will be pre-populated with the .properties
			value (if it exists).</li>
		<li>In the headless environment, this method returns a byte array representing the
			.properties byte pattern value (if it exists), or throws an Exception if there is
			an invalid or missing .properties value.</li>
</ol>


@param title the title of the dialog (in GUI mode) or the first part of the variable
			name (in headless mode or when using .properties file)
@param message the message to display next to the input field (in GUI mode) or the
			second part of the variable name (in headless mode or when using .properties file)
@return the user-specified byte array
@throws CancelledException if the user hit the 'cancel' button in GUI mode
@throws IllegalArgumentException if in headless mode, there was a missing or invalid bytes
			string specified in the .properties file
Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java