Skip to content

Commit

Permalink
Implement symbol detection using the ".XTLID" section
Browse files Browse the repository at this point in the history
  • Loading branch information
thrimbor authored and mborgerson committed Mar 20, 2024
1 parent 741fc5a commit 49e2071
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ jobs:
steps:
- name: Clone Tree
uses: actions/checkout@v2
- name: Install xsltproc
run: |
sudo apt-get -y update
sudo apt-get -y install xsltproc
- name: Build
id: build
run: ./build.sh
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ dist/
.classpath
.project
XbSymbolDatabaseTool*
src/main/java/XbeLoader/XbeXtlidDb.java
4 changes: 4 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ export GRADLE_URL=https://services.gradle.org/distributions/${GRADLE_ARCHIVE}
export XBSYMBOLDATABASE_VER=v3.1.156
export XBSYMBOLDATABASE_ARCHIVE=XbSymbolDatabase.zip
export XBSYMBOLDATABASE_URL=https://github.com/Cxbx-Reloaded/XbSymbolDatabase/releases/download/${XBSYMBOLDATABASE_VER}/${XBSYMBOLDATABASE_ARCHIVE}
export XTLID_VER=v0.1.2
export XTLID_URL=https://github.com/XboxDev/xtlid/releases/download/${XTLID_VER}/xtlid.xml
declare -a URLS=(
$CORRETTO_URL
$GHIDRA_URL
$GRADLE_URL
$XBSYMBOLDATABASE_URL
$XTLID_URL
)

pushd /tmp
Expand Down Expand Up @@ -57,6 +60,7 @@ chmod +x os/linux_x86_64/XbSymbolDatabaseTool
chmod +x os/mac_x86_64/XbSymbolDatabaseTool

echo "[*] Building..."
xsltproc -o src/main/java/XbeLoader/XbeXtlidDb.java xtlid2java.xslt /tmp/xtlid.xml
gradle -b build.gradle

if [[ "$RUNTESTS" == "1" || "$CI" == "true" ]]; then
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/XbeLoader/XbeLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,20 @@ protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> optio
createStruct(api, log, libDT, header.libFeaturesAddr + i * libDT.getLength());
}
}

// Set .XTLID data types
MemoryBlock xtlidSection = program.getMemory().getBlock(".XTLID");
if (xtlidSection != null) {
Listing listing = program.getListing();
for (Address addr = xtlidSection.getStart(); addr.compareTo(xtlidSection.getEnd()) <= 0; addr = addr.add(8)) {
try {
listing.createData(addr, new DWordDataType(), 4);
listing.createData(addr.add(4), new PointerDataType(), 4);
} catch (CodeUnitInsertionException e) {
log.appendMsg("Could not set data type in .XTLID section: " + e.getMessage());
}
}
}
}

void createStruct(FlatProgramAPI api, MessageLog log, DataType dataType, long address) {
Expand Down
90 changes: 90 additions & 0 deletions src/main/java/XbeLoader/XbeXtlidAnalyzer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package xbeloader;

import ghidra.app.util.importer.MessageLog;
import ghidra.app.services.AbstractAnalyzer;
import ghidra.app.services.AnalyzerType;
import ghidra.framework.options.Options;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Listing;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.SourceType;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.task.TaskMonitor;

public class XbeXtlidAnalyzer extends AbstractAnalyzer {
public XbeXtlidAnalyzer() {
super("Xbox XTLID Symbol ID Analyzer", "Scan XBE for known library functions", AnalyzerType.BYTE_ANALYZER);
}

@Override
public boolean getDefaultEnablement(Program program) {
return program.getExecutableFormat().equals(XbeLoader.XBE_NAME);
}

@Override
public boolean canAnalyze(Program program) {
return program.getExecutableFormat().equals(XbeLoader.XBE_NAME);
}

@Override
public void registerOptions(Options options, Program program) {
// options.registerOption("Option name goes here", false, null,
// "Option description goes here");
}

@Override
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws CancelledException {
AddressFactory af = program.getAddressFactory();
AddressSpace space = af.getDefaultAddressSpace();
Listing listing = program.getListing();
MemoryBlock section = program.getMemory().getBlock(".XTLID");

if (section != null) {
for (Address cur_addr = section.getStart(); cur_addr.compareTo(section.getEnd()) <= 0; cur_addr = cur_addr.add(8)) {
try {
Data data = listing.getDataAt(cur_addr);
long id = data.getUnsignedInt(0);
if (id == 0) {
continue;
}

data = listing.getDataAt(cur_addr.add(4));
Address address = space.getAddress(data.getUnsignedInt(0));

String[] name_namespace = XbeXtlidDb.xtlids.get(id);
if (name_namespace == null) {
log.appendMsg("Unknown XTLID id 0x" + Long.toHexString(id) + " @ 0x" + address.toString());
continue;
}
program.getSymbolTable().createLabel(address, name_namespace[1], getNamespace(program, name_namespace[0]), SourceType.ANALYSIS);
} catch (MemoryAccessException e) {
log.appendMsg("Failed to read memory: " + e.getMessage());
break;
} catch (InvalidInputException e) {
log.appendMsg("Failed to set label: " + e.getMessage());
}
}
}

return true;
}

private Namespace getNamespace(Program program, String namespace) {
Namespace space = program.getSymbolTable().getNamespace(namespace, null);
if (space != null) {
return space;
}
try {
return program.getSymbolTable().createNameSpace(null, namespace, SourceType.IMPORTED);
}
catch (Exception e) {
return null;
}
}
}
35 changes: 35 additions & 0 deletions xtlid2java.xslt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />

<xsl:template match="/">
<xsl:text>package xbeloader;&#xa;</xsl:text>
<xsl:text>&#xa;</xsl:text>
<xsl:text>import java.util.HashMap;&#xa;</xsl:text>
<xsl:text>import java.util.Map;&#xa;</xsl:text>
<xsl:text>&#xa;</xsl:text>
<xsl:text>public class XbeXtlidDb {&#xa;</xsl:text>
<xsl:text> public static final Map&lt;Long, String[]&gt; xtlids;&#xa;</xsl:text>
<xsl:text>&#xa;</xsl:text>
<xsl:text> static {&#xa;</xsl:text>
<xsl:text> xtlids = new HashMap&lt;&gt;();&#xa;</xsl:text>

<xsl:apply-templates select="//lib"/>

<xsl:text> }&#xa;</xsl:text>
<xsl:text>}&#xa;</xsl:text>
</xsl:template>

<xsl:template match="lib">
<xsl:apply-templates select="func"/>
</xsl:template>

<xsl:template match="func">
<xsl:text> xtlids.put(</xsl:text>
<xsl:value-of select="@id"/>
<xsl:text>L, new String[]{"</xsl:text>
<xsl:value-of select="../@name"/>
<xsl:text>", "</xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>"});&#xa;</xsl:text>
</xsl:template>
</xsl:stylesheet>

0 comments on commit 49e2071

Please sign in to comment.