Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/GP-1461_GhidraKnight_Android12--…
Browse files Browse the repository at this point in the history
…SQUASHED'
  • Loading branch information
ryanmkurtz committed Jun 6, 2022
2 parents 4104dc3 + a200850 commit d575bdb
Show file tree
Hide file tree
Showing 38 changed files with 1,735 additions and 635 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@
import ghidra.program.model.data.StringDataType;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.NotEmptyException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;

public abstract class FileFormatAnalyzer implements Analyzer {
Expand Down Expand Up @@ -151,7 +154,7 @@ protected void changeFormatToString(Data data) {
}

protected ProgramFragment createFragment(Program program, String fragmentName, Address start,
Address end) throws Exception {
Address end) throws DuplicateNameException, NotFoundException {
ProgramModule module = program.getListing().getDefaultRootModule();
ProgramFragment fragment = getFragment(module, fragmentName);
if (fragment == null) {
Expand Down Expand Up @@ -187,18 +190,17 @@ protected Address toAddr(Program program, long offset) {
return program.getAddressFactory().getDefaultAddressSpace().getAddress(offset);
}

protected Data createData(Program program, Address address, DataType datatype)
throws Exception {
protected Data createData(Program program, Address address, DataType datatype) throws CodeUnitInsertionException {
if (datatype instanceof StringDataType) {
CreateStringCmd cmd = new CreateStringCmd(address);
if (!cmd.applyTo(program)) {
throw new RuntimeException(cmd.getStatusMsg());
throw new CodeUnitInsertionException(cmd.getStatusMsg());
}
}
else {
CreateDataCmd cmd = new CreateDataCmd(address, datatype);
if (!cmd.applyTo(program)) {
throw new RuntimeException(cmd.getStatusMsg());
throw new CodeUnitInsertionException(cmd.getStatusMsg());
}
}
return program.getListing().getDefinedDataAt(address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
*/
package ghidra.file.formats.android.art;

import ghidra.app.util.bin.*;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.MemoryByteProvider;
import ghidra.app.util.importer.MessageLog;
import ghidra.app.util.opinion.BinaryLoader;
import ghidra.file.analyzers.FileFormatAnalyzer;
import ghidra.file.formats.android.oat.OatConstants;
import ghidra.file.formats.android.oat.OatUtilities;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.data.DataType;
Expand Down Expand Up @@ -49,7 +51,7 @@ public boolean canAnalyze(Program program) {
//HACK:
//Make analyzer appear after ART is merged with OAT program
//Currently, analyzers will not recognize the new ART block being added
|| OatConstants.isOAT(program);
|| OatUtilities.isOAT(program);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package ghidra.file.formats.android.bootimg;

import java.io.IOException;

import ghidra.app.plugin.core.analysis.AnalysisWorker;
import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
import ghidra.app.util.bin.BinaryReader;
Expand All @@ -27,7 +29,10 @@
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Program;
import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;

public class BootImageAnalyzer extends FileFormatAnalyzer implements AnalysisWorker {
Expand All @@ -47,6 +52,11 @@ public String getDescription() {
return "Annotates Android Boot, Recovery, or Vendor Image files.";
}

@Override
public String getWorkerName() {
return "BootImageAnalyzer";
}

@Override
public boolean canAnalyze(Program program) {
try {
Expand All @@ -68,100 +78,148 @@ public boolean isPrototype() {
@Override
public boolean analyze(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws Exception {

this.messageLog = log;
AutoAnalysisManager manager = AutoAnalysisManager.getAnalysisManager(program);
return manager.scheduleWorker(this, null, false, monitor);
}

@Override
public boolean analysisWorkerCallback(Program program, Object workerContext,
TaskMonitor monitor) throws Exception, CancelledException {
TaskMonitor monitor)
throws Exception, CancelledException {

Address address = program.getMinAddress();

ByteProvider provider = new MemoryByteProvider(program.getMemory(), address);
BinaryReader reader = new BinaryReader(provider, true);

if (BootImageUtil.isBootImage(program)) {
markupBootImage(program, reader, monitor);
}
else if (BootImageUtil.isVendorBootImage(program)) {
markupVendorBootImage(program, reader, monitor);
}

BootImageHeader header = BootImageHeaderFactory.getBootImageHeader(reader);

if (!BootImageConstants.BOOT_MAGIC.equals(header.getMagic())) {
return false;
}
removeEmptyFragments(program);

DataType headerDataType = header.toDataType();
return true;
}

Data headerData = createData(program, address, headerDataType);
private void markupBootImage(Program program, BinaryReader reader, TaskMonitor monitor)
throws IOException, DuplicateNameException, NotFoundException,
CodeUnitInsertionException {

if (headerData == null) {
messageLog.appendMsg("Unable to create header data.");
return false;
}
Address address = program.getMinAddress();

createFragment(program, headerDataType.getName(), toAddr(program, 0),
toAddr(program, header.getPageSize()));
BootImageHeader header = BootImageHeaderFactory.getBootImageHeader(reader);

if (header.getKernelSize() > 0) {
Address start = toAddr(program, header.getKernelOffset());
Address end = toAddr(program, header.getKernelOffset() + header.getKernelSize());
createFragment(program, BootImageConstants.KERNEL, start, end);
}
DataType headerDataType = header.toDataType();
Data headerData = createData(program, address, headerDataType);
if (headerData == null) {
messageLog.appendMsg("Unable to create header data.");
return;
}
createFragment(program, headerDataType.getName(), toAddr(program, 0),
toAddr(program, header.getPageSize()));

if (header.getRamdiskSize() > 0) {
Address start = toAddr(program, header.getRamdiskOffset());
Address end = toAddr(program, header.getRamdiskOffset() + header.getRamdiskSize());
createFragment(program, BootImageConstants.RAMDISK, start, end);
}
if (header.getKernelSize() > 0) {
Address start = toAddr(program, header.getKernelOffset());
Address end = toAddr(program, header.getKernelOffset() + header.getKernelSize());
createFragment(program, BootImageConstants.KERNEL, start, end);
}

if (header.getSecondSize() > 0) {
Address start = toAddr(program, header.getSecondOffset());
Address end = toAddr(program, header.getSecondOffset() + header.getSecondSize());
createFragment(program, BootImageConstants.SECOND_STAGE, start, end);
}
if (header.getRamdiskSize() > 0) {
Address start = toAddr(program, header.getRamdiskOffset());
Address end = toAddr(program, header.getRamdiskOffset() + header.getRamdiskSize());
createFragment(program, BootImageConstants.RAMDISK, start, end);
}

changeDataSettings(program, monitor);
if (header.getSecondSize() > 0) {
Address start = toAddr(program, header.getSecondOffset());
Address end = toAddr(program, header.getSecondOffset() + header.getSecondSize());
createFragment(program, BootImageConstants.SECOND_STAGE, start, end);
}
else if (BootImageUtil.isVendorBootImage(program)) {
VendorBootImageHeader header =
VendorBootImageHeaderFactory.getVendorBootImageHeader(reader);

if (!header.getMagic().equals(BootImageConstants.VENDOR_BOOT_MAGIC)) {
return false;
}
changeDataSettings(program, monitor);
}

DataType headerDataType = header.toDataType();
private void markupVendorBootImage(Program program, BinaryReader reader, TaskMonitor monitor)
throws IOException, DuplicateNameException, CodeUnitInsertionException,
NotFoundException, CancelledException {

Data headerData = createData(program, address, headerDataType);
Address address = program.getMinAddress();

if (headerData == null) {
messageLog.appendMsg("Unable to create header data.");
}
VendorBootImageHeader header =
VendorBootImageHeaderFactory.getVendorBootImageHeader(reader);

DataType headerDataType = header.toDataType();
Data headerData = createData(program, address, headerDataType);
if (headerData == null) {
messageLog.appendMsg("Unable to create header data.");
}
createFragment(program, headerDataType.getName(), toAddr(program, 0),
toAddr(program, headerData.getLength()));

createFragment(program, headerDataType.getName(), toAddr(program, 0),
toAddr(program, headerData.getLength()));
markupVendorRamdisk(program, header);

if (header.getDtbSize() > 0) {
Address start = toAddr(program, header.getDtbOffset());
Address end = toAddr(program, header.getDtbOffset() + header.getDtbSize());
createFragment(program, BootImageConstants.DTB, start, end);
}

markupVendorBootImageV4(header, program, monitor);
}

private void markupVendorRamdisk(Program program, VendorBootImageHeader header)
throws IOException, DuplicateNameException, NotFoundException {

if (header.getNestedVendorRamdiskCount() > 1) {
for (int i = 0; i < header.getNestedVendorRamdiskCount(); ++i) {
Address start = toAddr(program, header.getNestedVendorRamdiskOffset(i));
Address end = toAddr(program,
header.getNestedVendorRamdiskOffset(i) +
header.getNestedVendorRamdiskSize(i));
createFragment(program, BootImageConstants.RAMDISK + "_" + i, start, end);
}
}
else {
if (header.getVendorRamdiskSize() > 0) {
Address start = toAddr(program, header.getVendorRamdiskOffset());
Address end = toAddr(program,
header.getVendorRamdiskOffset() + header.getVendorRamdiskSize());
createFragment(program, BootImageConstants.RAMDISK, start, end);
}

if (header.getDtbSize() > 0) {
Address start = toAddr(program, header.getDtbOffset());
Address end = toAddr(program, header.getDtbOffset() + header.getDtbSize());
createFragment(program, BootImageConstants.DTB, start, end);
}
}
}

removeEmptyFragments(program);
private void markupVendorBootImageV4(VendorBootImageHeader header, Program program,
TaskMonitor monitor) throws DuplicateNameException, NotFoundException,
CancelledException, IOException, CodeUnitInsertionException {

return true;
}
if (header instanceof VendorBootImageHeaderV4) {
VendorBootImageHeaderV4 v4 = (VendorBootImageHeaderV4) header;

@Override
public String getWorkerName() {
return "BootImageAnalyzer";
if (v4.getVendorRamdiskTableEntrySize() > 0) {
Address start = toAddr(program, v4.getVendorRamdiskTableOffset());
Address end = toAddr(program,
v4.getVendorRamdiskTableOffset() + v4.getVendorRamdiskTableSize());
createFragment(program, "Ramdisk Table", start, end);

for (VendorRamdiskTableEntryV4 entry : v4.getVendorRamdiskTableEntryList()) {
monitor.checkCanceled();
DataType entryDataType = entry.toDataType();
createData(program, start, entryDataType);
start = start.add(entryDataType.getLength());
}
}

if (v4.getBootConfigSize() > 0) {
Address start = toAddr(program, v4.getBootConfigOffset());
Address end = toAddr(program, v4.getBootConfigOffset() + v4.getBootConfigSize());
createFragment(program, "Boot Config", start, end);
}
}
}
}
Loading

0 comments on commit d575bdb

Please sign in to comment.