163 lines
8.2 KiB
Java
163 lines
8.2 KiB
Java
/* ###
|
|
* 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 applies labels and comments to the WallaceSrc.exe program for use with GhidraClass exercises
|
|
//@category Training.GhidraClass
|
|
|
|
|
|
import ghidra.app.script.GhidraScript;
|
|
import ghidra.program.model.address.Address;
|
|
import ghidra.program.model.data.ArrayDataType;
|
|
import ghidra.program.model.data.BooleanDataType;
|
|
import ghidra.program.model.data.CharDataType;
|
|
import ghidra.program.model.data.IntegerDataType;
|
|
import ghidra.program.model.data.PointerDataType;
|
|
import ghidra.program.model.data.Structure;
|
|
import ghidra.program.model.data.StructureDataType;
|
|
import ghidra.program.model.listing.Function;
|
|
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
|
import ghidra.program.model.listing.Parameter;
|
|
import ghidra.program.model.listing.ParameterImpl;
|
|
import ghidra.program.model.symbol.Namespace;
|
|
import ghidra.program.model.symbol.SourceType;
|
|
import ghidra.program.model.symbol.SymbolTable;
|
|
import ghidra.util.exception.InvalidInputException;
|
|
|
|
public class MarkupWallaceSrcScript extends GhidraScript {
|
|
|
|
|
|
@Override
|
|
public void run() throws Exception {
|
|
|
|
if(!currentProgram.getName().contains("WallaceSrc") || (!currentProgram.getExecutableMD5().equals("2527c463a079c81af7b3bc1d26bd3b5d"))) {
|
|
println("This script is only meant to work on the WallaceSrc executable with md5 hash 2527c463a079c81af7b3bc1d26bd3b5d.");
|
|
return;
|
|
}
|
|
|
|
//Create Person structure
|
|
Structure personStruct = new StructureDataType("Person", 0);
|
|
personStruct.add(new IntegerDataType(), "id", "");
|
|
ArrayDataType adt = new ArrayDataType(new CharDataType(), 32, 1);
|
|
personStruct.add(adt, "name", "");
|
|
personStruct.add(new BooleanDataType(), "likesCheese", "");
|
|
PointerDataType ptrPersonStruct = new PointerDataType(personStruct);
|
|
personStruct.add(ptrPersonStruct, "next", "");
|
|
|
|
//Create Gadget structure
|
|
Structure gadgetStruct = new StructureDataType("Gadget", 0);
|
|
PointerDataType charPtr = new PointerDataType(new CharDataType());
|
|
gadgetStruct.add(charPtr,"name","");
|
|
gadgetStruct.add(new IntegerDataType(),"type", "");
|
|
gadgetStruct.add(new BooleanDataType(), "deployed","");
|
|
gadgetStruct.add(ptrPersonStruct, "workingOn","");
|
|
|
|
//apply data types to function parameters, locals, and returns
|
|
|
|
//Gadget::Gadget(Gadget * this, undefined4 param_1)
|
|
Function gadgetFunction = getFunctionAt(toAddr(0x00411440));
|
|
Parameter[] parameters = gadgetFunction.getParameters();
|
|
parameters[0] = new ParameterImpl("this", new PointerDataType(gadgetStruct), currentProgram);
|
|
gadgetFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
|
|
|
//deployGadget - return type = Gadget *
|
|
Function deployGadgetFunction = getFunctionAt(toAddr(0x004118f0));
|
|
deployGadgetFunction.setReturnType(new PointerDataType(gadgetStruct), SourceType.USER_DEFINED);
|
|
|
|
//initializePeople(Person *)
|
|
Function initPeopleFunction = getFunctionAt(toAddr(0x004117c0));
|
|
parameters = initPeopleFunction.getParameters();
|
|
parameters[0] = new ParameterImpl("people", new PointerDataType(personStruct), currentProgram);
|
|
initPeopleFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
|
|
|
//use(Gadget *this, Person *person)
|
|
Function useFunction = getFunctionAt(toAddr(0x00411570));
|
|
parameters = useFunction.getParameters();
|
|
parameters[0] = new ParameterImpl("this", new PointerDataType(gadgetStruct), currentProgram);
|
|
parameters[1] = new ParameterImpl("person", new PointerDataType(personStruct), currentProgram);
|
|
useFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
|
|
|
//addPerson(Person ** list, char * name)
|
|
Function addPersonFunction = getFunctionAt(toAddr(0x00411860));
|
|
parameters = addPersonFunction.getParameters();
|
|
parameters[0] = new ParameterImpl("list", new PointerDataType(new PointerDataType(personStruct)), currentProgram);
|
|
parameters[1] = new ParameterImpl("name", new PointerDataType(new CharDataType()), currentProgram);
|
|
addPersonFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
|
|
|
//addPeople(Person ** list)
|
|
Function addPeopleFunction = getFunctionAt(toAddr(0x00411700));
|
|
parameters = addPeopleFunction.getParameters();
|
|
parameters[0] = new ParameterImpl("list", new PointerDataType(new PointerDataType(personStruct)), currentProgram);
|
|
addPeopleFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
|
|
|
//print(Gadget * pGadget)
|
|
Function printFunction = getFunctionAt(toAddr(0x004115d0));
|
|
parameters = printFunction.getParameters();
|
|
parameters[0] = new ParameterImpl("this", new PointerDataType(gadgetStruct), currentProgram);
|
|
printFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
|
|
|
// Create labels for some of the functions
|
|
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
|
|
|
|
|
//create the Class "Gadget" to put most function symbols in
|
|
Namespace namespace = null;
|
|
namespace = symbolTable.getNamespace("Gadget", null);
|
|
if(namespace == null) {
|
|
namespace = symbolTable.createClass(null, "Gadget", SourceType.USER_DEFINED);
|
|
}
|
|
|
|
//Functions in Gadget class
|
|
createNewLabel(toAddr(0x00411440), "Gadget", namespace, SourceType.USER_DEFINED);
|
|
createNewLabel(toAddr(0x004115d0), "print", namespace, SourceType.USER_DEFINED);
|
|
createNewLabel(toAddr(0x00411570), "use", namespace, SourceType.USER_DEFINED);
|
|
|
|
//Functions not in class
|
|
createNewLabel(toAddr(0x004117c0), "initializePeople", namespace, SourceType.USER_DEFINED);
|
|
createNewLabel(toAddr(0x004118f0), "deployGadget", namespace, SourceType.USER_DEFINED);
|
|
createNewLabel(toAddr(0x00411700), "addPeople", namespace, SourceType.USER_DEFINED);
|
|
createNewLabel(toAddr(0x00411860), "addPerson", namespace, SourceType.USER_DEFINED);
|
|
createNewLabel(toAddr(0x00418138), "personList", namespace, SourceType.USER_DEFINED);
|
|
createNewLabel(toAddr(0x00411a30), "main", null, SourceType.USER_DEFINED);
|
|
|
|
// Add other labels
|
|
Function function = currentProgram.getFunctionManager().getFunctionAt(toAddr(0x004117c0));
|
|
createNewLabel(toAddr(0x004117e5), "LoopOverPeople", function, SourceType.USER_DEFINED);
|
|
if(getSymbolAt(toAddr(0x00418138)).getSource().equals(SourceType.DEFAULT)){
|
|
createLabel(toAddr(0x00418138),"personList", true);
|
|
}
|
|
|
|
// Add comments
|
|
setPlateComment(toAddr(0x00411440), "This is the init method for the Gadget class");
|
|
setPlateComment(toAddr(0x004115d0), "This method prints the status of a Person -- whether they are deployed or not and who they are deployed on. ");
|
|
setPlateComment(toAddr(0x00411700), "This function adds all the people to the Person list.");
|
|
setPlateComment(toAddr(0x004117c0), "This function initializes each person's record with whether or not they like cheese, their id, and a pointer to the next person.");
|
|
setPlateComment(toAddr(0x00411860), "This function adds a person to the Person list.");
|
|
setPlateComment(toAddr(0x004118f0), "This function checks to see if the person on the list is Wallace and if so, it deploys the Infrared Garden Gnome.");
|
|
setEOLComment(toAddr(0x004117e7), "Randomly assign whether each person likes cheese or not.");
|
|
}
|
|
|
|
void createNewLabel(Address address, String name, Namespace namespace, SourceType sourceType) {
|
|
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
|
if(getSymbolAt(address).getSource().equals(SourceType.DEFAULT)){
|
|
try {
|
|
symbolTable.createLabel(address, name, namespace, sourceType);
|
|
} catch (InvalidInputException e) {
|
|
println("Invalid input to create label.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|