Skip to content
Permalink
Browse files

option_rom: Add support for compressed EFI images

This commit also adds basic support for loading JNI libraries from the
os/platform directory.
  • Loading branch information...
al3xtjames committed Jun 4, 2019
1 parent add750a commit c853f0d45a548414d5fab72746e913c1c0f88bbc
@@ -9,4 +9,6 @@ gradle/
.project
.pydevproject
.classpath

*.dll
*.dylib
*.so
@@ -0,0 +1,13 @@
Copyright 2019 Alex James <theracermaster@gmail.com>.

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.
@@ -8,12 +8,11 @@ This was accepted as a [coreboot project][2] for GSoC 2019.
### PCI option ROM loader
- Implements a FS loader for PCI option ROMs (handles hybrid ROMs,
e.g. legacy x86 + UEFI)
- Loads uncompressed UEFI executables from PCI option ROMs
- Loads UEFI executables from PCI option ROMs (including compressed images)
- Calculates entry point address for legacy x86 option ROMs (still needs to be
manually loaded as a raw real-mode binary)
- TODO: Write loader for legacy x86 option ROMs (automatically select
real-mode x86)
- TODO: Implement support for compressed UEFI executables

## Planned functionality / TODO
### Firmware image loader
@@ -30,21 +29,32 @@ Ghidra's standard Gradle build system is used. Set the `GHIDRA_INSTALL_DIR`
environment variable before building:

```bash
export GHIDRA_INSTALL_DIR="/path/to/ghidra"
gradle
$ export GHIDRA_INSTALL_DIR="/path/to/ghidra"
$ gradle
```

The module ZIP will be output to `dist/`. Use **File > Install Extensions** and
select the green plus to browse to the extension. Restart Ghidra when prompted.

## Usage

### PCI option ROM loader
Add a PCI option ROM to a Ghidra project. When prompted to select an import
mode, select **File system**. The images contained within the option ROM will
be displayed, and can be imported for analysis. Information for each image can
be displayed by selecting **Get Info** in the right-click menu for an image.

## License
Apache 2.0, with some exceptions:

- `src/efidecompress/c/efidecompress.c`: BSD

## Credits
`src/efidecompress/c/efidecompress.c` is a lightly modified version of
[Decompress.c][4] from uefi-firmware-parser (which itself is derived from
[the original in EDK2 BaseTools][5]).

[1]: https://ghidra-sre.org/
[2]: https://summerofcode.withgoogle.com/projects/#6413737605464064
[3]: https://github.com/danse-macabre/ida-efitools
[4]: https://github.com/theopolis/uefi-firmware-parser/blob/21106baf019db9dcd046a3c01ee7b32212de45a5/uefi_firmware/compression/Tiano/Decompress.c
[5]: https://github.com/tianocore/edk2/blob/2e351cbe8e190271b3716284fc1076551d005472/BaseTools/Source/C/Common/Decompress.c
@@ -1,9 +1,9 @@
// Builds a Ghidra Extension for a given Ghidra installation.
//
// An absolute path to the Ghidra installation directory must be supplied either by setting the
// An absolute path to the Ghidra installation directory must be supplied either by setting the
// GHIDRA_INSTALL_DIR environment variable or Gradle project property:
//
// > export GHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
// > export GHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
// > gradle
//
// or
@@ -14,6 +14,54 @@
// application.gradle.version property in <GHIDRA_INSTALL_DIR>/Ghidra/application.properties
// for the correction version of Gradle to use for the Ghidra installation you specify.

apply plugin: 'c'
model {
components {
efidecompress(NativeLibrarySpec) {
sources {
c {
source {
srcDir 'src/efidecompress/c'
include 'efidecompress.c'
}
}
}

binaries.all {
if (targetPlatform.operatingSystem.macOsX) {
cCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include"
cCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include/darwin"
cCompiler.args '-mmacosx-version-min=10.4'
linker.args '-mmacosx-version-min=10.4'
} else if (targetPlatform.operatingSystem.linux) {
cCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include"
cCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include/linux"
cCompiler.args '-D_FILE_OFFSET_BITS=64'
} else if (targetPlatform.operatingSystem.windows) {
// TODO: test Windows JNI library support
cCompiler.args "-I${org.gradle.internal.jvm.Jvm.current().javaHome}/include"
cCompiler.args "-I${org.gradle.internal.jvm.Jvm.current().javaHome}/include/win32"
linker.args "Shlwapi.lib", "Advapi32.lib"
}
}
}
}
}

import org.apache.tools.ant.taskdefs.condition.Os;

task copyLibrary(type: Copy) {
if (Os.isFamily(Os.FAMILY_MAC)) {
from file("$buildDir/libs/efidecompress/shared/libefidecompress.dylib") into "$projectDir/os/osx64"
} else if (Os.isFamily(Os.FAMILY_UNIX)) {
from file("$buildDir/libs/efidecompress/shared/libefidecompress.so") into "$projectDir/os/linux64"
} else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
from file("$buildDir/libs/efidecompress/shared/libefidecompress/win32.dll") into file("$projectDir/os/win64/efidecompress.dll")
}
}

copyLibrary.dependsOn 'efidecompressSharedLibrary'

//----------------------START "DO NOT MODIFY" SECTION------------------------------
def ghidraInstallDir

@@ -31,3 +79,11 @@ else {
throw new GradleException("GHIDRA_INSTALL_DIR is not defined!")
}
//----------------------END "DO NOT MODIFY" SECTION-------------------------------

buildExtension.dependsOn 'copyLibrary'

clean {
delete "$projectDir/os/linux64/libefidecompress.libefidecompress.so"
delete "$projectDir/os/osx64/libefidecompress.dylib"
delete "$projectDir/os/win64/libefidecompress.dll"
}
@@ -0,0 +1,3 @@
The "os/linux64" directory is intended to hold Linux native binaries
which this module is dependent upon. This directory may be eliminated for a specific
module if native binaries are not provided for the corresponding platform.
@@ -0,0 +1,3 @@
The "os/osx64" directory is intended to hold macOS (OS X) native binaries
which this module is dependent upon. This directory may be eliminated for a specific
module if native binaries are not provided for the corresponding platform.
@@ -0,0 +1,3 @@
The "os/win64" directory is intended to hold MS Windows native binaries (.exe)
which this module is dependent upon. This directory may be eliminated for a specific
module if native binaries are not provided for the corresponding platform.

0 comments on commit c853f0d

Please sign in to comment.
You can’t perform that action at this time.