From 168b8d682dc1b8015d0dc332ccf4ae55f8c4f939 Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Sun, 9 Jun 2024 22:50:38 +0100 Subject: [PATCH] Add Relocation Types --- Cargo.lock | 189 +++++++++---------- Cargo.toml | 4 +- fuzz/Cargo.lock | 26 +-- src/coff.rs | 8 +- src/lib.rs | 2 + src/relocation.rs | 454 +++++++++++++++++++++++++++++++++++++++++++++ tests/pe-parser.rs | 6 +- 7 files changed, 564 insertions(+), 125 deletions(-) create mode 100644 src/relocation.rs diff --git a/Cargo.lock b/Cargo.lock index cdf1aec..6a36d6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,56 +4,57 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys", @@ -61,9 +62,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bit-set" @@ -97,9 +98,9 @@ dependencies = [ [[package]] name = "bytemuck_derive" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" dependencies = [ "proc-macro2", "quote", @@ -108,9 +109,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" [[package]] name = "chrono" @@ -123,9 +124,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "a9689a29b593160de5bc4aacab7b5d54fb52231de70122626c178e6a368994c7" dependencies = [ "clap_builder", "clap_derive", @@ -133,9 +134,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "2e5387378c84f6faa26890ebf9f0a92989f8873d4d380467bcd0d8d8620424df" dependencies = [ "anstream", "anstyle", @@ -145,9 +146,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck", "proc-macro2", @@ -157,15 +158,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "datatest-stable" @@ -181,12 +182,9 @@ dependencies = [ [[package]] name = "escape8259" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4911e3666fcd7826997b4745c8224295a6f3072f1418c3067b97a67557ee" -dependencies = [ - "rustversion", -] +checksum = "5692dd7b5a1978a5aeb0ce83b7655c58ca8efdcb79d21036ea249da95afec2c6" [[package]] name = "fancy-regex" @@ -207,21 +205,27 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.5" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libtest-mimic" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fefdf21230d6143476a28adbee3d930e2b68a3d56443c777cae3fe9340eebff9" +checksum = "cc0bda45ed5b3a2904262c1bb91e526127aa70e7ef3758aba2ef93cf896b9b58" dependencies = [ "clap", "escape8259", @@ -231,9 +235,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "num-derive" @@ -267,7 +271,7 @@ dependencies = [ [[package]] name = "pe-parser" -version = "0.5.1" +version = "0.6.0" dependencies = [ "bitflags", "bytemuck", @@ -280,27 +284,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -309,15 +313,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "rustversion" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "same-file" @@ -330,15 +328,15 @@ dependencies = [ [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -371,9 +369,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "walkdir" @@ -385,37 +383,15 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-sys" version = "0.52.0" @@ -427,13 +403,14 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -442,42 +419,48 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/Cargo.toml b/Cargo.toml index f9d8cdc..1200d60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pe-parser" -version = "0.5.1" +version = "0.6.0" edition = "2021" license = "MIT" authors = ["Isaac Marovitz "] @@ -22,7 +22,7 @@ num-traits = { version = "0.2.19", default-features = false } num-derive = "0.4.2" bitflags = { version = "2.5.0", default-features = false } chrono = { version = "0.4.38", default-features = false } -clap = { version = "4.5.4", features = ["cargo"], optional = true } +clap = { version = "4.5.6", features = ["cargo"], optional = true } [dev-dependencies] datatest-stable = "0.2.9" diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 374d2e6..9a6e749 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -64,15 +64,15 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bytemuck" -version = "1.14.3" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" dependencies = [ "bytemuck_derive", ] @@ -100,27 +100,27 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "num-traits", ] [[package]] name = "clap" -version = "4.5.0" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +checksum = "a9689a29b593160de5bc4aacab7b5d54fb52231de70122626c178e6a368994c7" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.0" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +checksum = "2e5387378c84f6faa26890ebf9f0a92989f8873d4d380467bcd0d8d8620424df" dependencies = [ "anstream", "anstyle", @@ -179,9 +179,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -194,7 +194,7 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "pe-parser" -version = "0.5.1" +version = "0.6.0" dependencies = [ "bitflags", "bytemuck", diff --git a/src/coff.rs b/src/coff.rs index ca970e2..e1fbb3f 100644 --- a/src/coff.rs +++ b/src/coff.rs @@ -3,7 +3,7 @@ use num_derive::FromPrimitive; use num_traits::FromPrimitive; use bitflags::bitflags; use core::{fmt, str}; -use chrono::NaiveDateTime; +use chrono::{DateTime, Utc}; use crate::prelude::*; /// COFF File Header (Object and Image) @@ -193,8 +193,8 @@ impl CoffFileHeader { Characteristics::from_bits(self.characteristics) } - /// Returns the Unix epoch timestamp as a `NaiveDateTime` - pub fn get_time_date_stamp(&self) -> Option { - NaiveDateTime::from_timestamp_opt(self.time_date_stamp.into(), 0) + /// Returns the Unix epoch timestamp as a `DateTime` + pub fn get_time_date_stamp(&self) -> Option> { + DateTime::from_timestamp(self.time_date_stamp.into(), 0) } } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index b1cd203..936bb48 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,8 @@ use core::fmt; /// COFF file header definitions and helper functions pub mod coff; +/// COFF relocation definitions and helper functions +pub mod relocation; /// Optional header definitions and helper functions pub mod optional; /// Section header definitions and helper functions diff --git a/src/relocation.rs b/src/relocation.rs new file mode 100644 index 0000000..3052a42 --- /dev/null +++ b/src/relocation.rs @@ -0,0 +1,454 @@ +use num_derive::FromPrimitive; + +/// Relocation type indicators for x64 and compatible processors. +#[derive(FromPrimitive, Debug, PartialEq)] +#[repr(u16)] +pub enum X86RelocationType { + /// The relocation is ignored. + Absolute = 0x0000, + /// The 64-bit VA of the relocation target. + Addr64 = 0x0001, + /// The 32-bit VA of the relocation target. + Addr32 = 0x0002, + /// The 32-bit address without an image base (RVA). + Addr32Nb = 0x0003, + /// The 32-bit relative address from the byte following the relocation. + Rel32 = 0x0004, + /// The 32-bit address relative to byte distance 1 from the relocation. + Rel321 = 0x0005, + /// The 32-bit address relative to byte distance 2 from the relocation. + Rel322 = 0x0006, + /// The 32-bit address relative to byte distance 3 from the relocation. + Rel323 = 0x0007, + /// The 32-bit address relative to byte distance 4 from the relocation. + Rel324 = 0x0008, + /// The 32-bit address relative to byte distance 5 from the relocation. + Rel325 = 0x0009, + /// The 16-bit section index of the section that contains the target. + /// This is used to support debugging information. + Section = 0x000A, + /// The 32-bit offset of the target from the beginning of its section. + /// This is used to support debugging information and static thread local storage. + SecRel = 0x000B, + /// A 7-bit unsigned offset from the base of the section that contains the target. + SecRel7 = 0x000C, + /// CLR tokens. + Token = 0x000D, + /// A 32-bit signed span-dependent value emitted into the object. + SRel32 = 0x000E, + /// A pair that must immediately follow every span-dependent value. + Pair = 0x000F, + /// A 32-bit signed span-dependent value that is applied at link time. + SSpan32 = 0x0010, +} + +/// Relocation type indicators for ARM processors. +#[derive(FromPrimitive, Debug, PartialEq)] +#[repr(u16)] +pub enum ARMRelocationType { + /// The relocation is ignored. + Absolute = 0x0000, + /// The 32-bit VA of the target. + Addr32 = 0x0001, + /// The 32-bit RVA of the target. + Addr32Nb = 0x0002, + /// The 24-bit relative displacement to the target. + Branch24 = 0x0003, + /// The reference to a subroutine call. + /// The reference consists of two 16-bit instructions with 11-bit offsets. + Branch11 = 0x0004, + /// The 32-bit relative address from the byte following the relocation. + Rel32 = 0x000A, + /// The 16-bit section index of the section that contains the target. + /// This is used to support debugging information. + Section = 0x000E, + /// The 32-bit offset of the target from the beginning of its section. + /// This is used to support debugging information and static thread local storage. + SecRel = 0x000F, + /// The 32-bit VA of the target. + /// This relocation is applied using a MOVW instruction for the low 16 bits followed by a MOVT for the high 16 bits. + Mov32 = 0x0010, + /// The 32-bit VA of the target. + /// This relocation is applied using a MOVW instruction for the low 16 bits followed by a MOVT for the high 16 bits. + ImageRelThumbMOV32 = 0x0011, + /// The instruction is fixed up with the 21-bit relative displacement to the 2-byte aligned target. + /// The least significant bit of the displacement is always zero and is not stored. + /// This relocation corresponds to a Thumb-2 32-bit conditional B instruction. + ImageRelThumbBranch20 = 0x0012, + /// Unused relocation type. + Unused = 0x0013, + /// The instruction is fixed up with the 25-bit relative displacement to the 2-byte aligned target. + /// The least significant bit of the displacement is zero and is not stored. + /// This relocation corresponds to a Thumb-2 B instruction. + ImageRelThumbBranch24 = 0x0014, + /// The instruction is fixed up with the 25-bit relative displacement to the 4-byte aligned target. + /// The low 2 bits of the displacement are zero and are not stored. + /// This relocation corresponds to a Thumb-2 BLX instruction. + ImageRelThumbBLX23 = 0x0015, + /// The relocation is valid only when it immediately follows a ARM_REFHI or THUMB_REFHI. + /// Its SymbolTableIndex contains a displacement and not an index into the symbol table. + Pair = 0x0016, +} + +/// Relocation type indicators for ARM64 processors. +#[derive(FromPrimitive, Debug, PartialEq)] +#[repr(u16)] +pub enum ARM64RelocationType { + /// The relocation is ignored. + Absolute = 0x0000, + /// The 32-bit VA of the target. + Addr32 = 0x0001, + /// The 32-bit RVA of the target. + Addr32Nb = 0x0002, + /// The 26-bit relative displacement to the target, for B and BL instructions. + Branch26 = 0x0003, + /// The page base of the target, for ADRP instruction. + PageBaseRel21 = 0x0004, + /// The 12-bit relative displacement to the target, for instruction ADR. + Rel21 = 0x0005, + /// The 12-bit page offset of the target, for instructions ADD/ADDS (immediate) with zero shift. + PageOffset12A = 0x0006, + /// The 12-bit page offset of the target, for instruction LDR (indexed, unsigned immediate). + PageOffset12L = 0x0007, + /// The 32-bit offset of the target from the beginning of its section. + /// This is used to support debugging information and static thread local storage. + SecRel = 0x0008, + /// Bit 0:11 of section offset of the target, for instructions ADD/ADDS (immediate) with zero shift. + SecRelLow12A = 0x0009, + /// Bit 12:23 of section offset of the target, for instructions ADD/ADDS (immediate) with zero shift. + SecRelHigh12A = 0x000A, + /// Bit 0:11 of section offset of the target, for instruction LDR (indexed, unsigned immediate). + SecRelLow12L = 0x000B, + /// CLR token. + Token = 0x000C, + /// The 16-bit section index of the section that contains the target. + /// This is used to support debugging information. + Section = 0x000D, + /// The 64-bit VA of the relocation target. + Addr64 = 0x000E, + /// The 19-bit offset to the relocation target, for conditional B instruction. + Branch19 = 0x000F, + /// The 14-bit offset to the relocation target, for instructions TBZ and TBNZ. + Branch14 = 0x0010, + /// The 32-bit relative address from the byte following the relocation. + Rel32 = 0x0011, +} + +/// Relocation type indicators for SH3 and SH4 processors. +/// SH5-specific relocations are noted as SHM (SH Media). +#[derive(FromPrimitive, Debug, PartialEq)] +#[repr(u16)] +pub enum SuperHRelocationType { + /// The relocation is ignored. + Absolute = 0x0000, + /// A reference to the 16-bit location that contains the VA of the target symbol. + Direct16 = 0x0001, + /// The 32-bit VA of the target symbol. + Direct32 = 0x0002, + /// A reference to the 8-bit location that contains the VA of the target symbol. + Direct8 = 0x0003, + /// A reference to the 8-bit instruction that contains the effective 16-bit VA of the target symbol. + Direct8Word = 0x0004, + /// A reference to the 8-bit instruction that contains the effective 32-bit VA of the target symbol. + Direct8Long = 0x0005, + /// A reference to the 8-bit location whose low 4 bits contain the VA of the target symbol. + Direct4 = 0x0006, + /// A reference to the 8-bit instruction whose low 4 bits contain the effective 16-bit VA of the target symbol. + Direct4Word = 0x0007, + /// A reference to the 8-bit instruction whose low 4 bits contain the effective 32-bit VA of the target symbol. + Direct4Long = 0x0008, + /// A reference to the 8-bit instruction that contains the effective 16-bit relative offset of the target symbol. + PCRel8Word = 0x0009, + /// A reference to the 8-bit instruction that contains the effective 32-bit relative offset of the target symbol. + PCRel8Long = 0x000A, + /// A reference to the 16-bit instruction whose low 12 bits contain the effective 16-bit relative offset of the target symbol. + PCRel12Word = 0x000B, + /// A reference to a 32-bit location that is the VA of the section that contains the target symbol. + StartOfSection = 0x000C, + /// A reference to the 32-bit location that is the size of the section that contains the target symbol. + SizeOfSection = 0x000D, + /// The 16-bit section index of the section that contains the target. This is used to support debugging information. + Section = 0x000E, + /// The 32-bit offset of the target from the beginning of its section. + /// This is used to support debugging information and static thread local storage. + SecRel = 0x000F, + /// The 32-bit RVA of the target symbol. + Direct32Nb = 0x0010, + /// GP relative. + GPRel4Long = 0x0011, + /// CLR token. + Token = 0x0012, + /// The offset from the current instruction in longwords. + /// If the NOMODE bit is not set, insert the inverse of the low bit at bit 32 to select PTA or PTB. + SHMPCRelPT = 0x0013, + /// The low 16 bits of the 32-bit address. + SHMRefLo = 0x0014, + /// The high 16 bits of the 32-bit address. + SHMRefHalf = 0x0015, + /// The low 16 bits of the relative address. + SHMRelLo = 0x0016, + /// The high 16 bits of the relative address. + SHMRelHalf = 0x0017, + /// The relocation is valid only when it immediately follows a REFHALF, RELHALF, or RELLO relocation. + /// The SymbolTableIndex field of the relocation contains a displacement and not an index into the symbol table. + SHMPair = 0x0018, + /// The relocation ignores section mode. + SHMNoMode = 0x8000, +} + +/// Relocation type indicators for PowerPC processors. +#[derive(FromPrimitive, Debug, PartialEq)] +#[repr(u16)] +pub enum PowerPCRelocationType { + /// The relocation is ignored. + Absolute = 0x0000, + /// The 64-bit VA of the target. + Addr64 = 0x0001, + /// The 32-bit VA of the target. + Addr32 = 0x0002, + /// The low 24 bits of the VA of the target. + /// This is valid only when the target symbol is absolute and can be sign-extended to its original value. + Addr24 = 0x0003, + /// The low 16 bits of the target's VA. + Addr16 = 0x0004, + /// The low 14 bits of the target's VA. + /// This is valid only when the target symbol is absolute and can be sign-extended to its original value. + Addr14 = 0x0005, + /// A 24-bit PC-relative offset to the symbol's location. + Rel24 = 0x0006, + /// A 14-bit PC-relative offset to the symbol's location. + Rel14 = 0x0007, + /// The 32-bit RVA of the target. + Addr32Nb = 0x000A, + /// The 32-bit offset of the target from the beginning of its section. + /// This is used to support debugging information and static thread local storage. + SecRel = 0x000B, + /// The 16-bit section index of the section that contains the target. + /// This is used to support debugging information. + Section = 0x000C, + /// The 16-bit offset of the target from the beginning of its section. + /// This is used to support debugging information and static thread local storage. + SecRel16 = 0x000F, + /// The high 16 bits of the target's 32-bit VA. + /// This is used for the first instruction in a two-instruction sequence that loads a full address. + /// This relocation must be immediately followed by a PAIR relocation whose SymbolTableIndex contains a signed + /// 16-bit displacement that is added to the upper 16 bits that was taken from the location that is being relocated. + RefHi = 0x0010, + /// The low 16 bits of the target's VA. + RefLo = 0x0011, + /// A relocation that is valid only when it immediately follows a REFHI or SECRELHI relocation. + /// Its SymbolTableIndex contains a displacement and not an index into the symbol table. + Pair = 0x0012, + /// The low 16 bits of the 32-bit offset of the target from the beginning of its section. + SecRelLo = 0x0013, + /// The 16-bit signed displacement of the target relative to the GP register. + GPRel = 0x0015, + /// The CLR token. + Token = 0x0016, +} + +/// Relocation type indicators for Intel 386 processors. +#[derive(FromPrimitive, Debug, PartialEq)] +#[repr(u16)] +pub enum I386RelocationType { + /// The relocation is ignored. + Absolute = 0x0000, + /// Not supported. + Dir16 = 0x0001, + /// Not supported. + Rel16 = 0x0002, + /// The target's 32-bit VA. + Dir32 = 0x0006, + /// The target's 32-bit RVA. + Dir32Nb = 0x0007, + /// Not supported. + Seg12 = 0x0009, + /// The 16-bit section index of the section that contains the target. + /// This is used to support debugging information. + Section = 0x000A, + /// The 32-bit offset of the target from the beginning of its section. + /// This is used to support debugging information and static thread local storage. + SecRel = 0x000B, + /// The CLR token. + Token = 0x000C, + /// A 7-bit offset from the base of the section that contains the target. + SecRel7 = 0x000D, + /// The 32-bit relative displacement to the target. + /// This supports the x86 relative branch and call instructions. + Rel32 = 0x0014, +} + +/// Relocation type indicators for the Intel Itanium processor family and compatible processors. +/// Note that relocations on instructions use the bundle's offset and slot number for the relocation offset. +#[derive(FromPrimitive, Debug, PartialEq)] +#[repr(u16)] +pub enum IA64RelocationType { + /// The relocation is ignored. + Absolute = 0x0000, + /// The instruction relocation can be followed by an ADDEND relocation whose value is added + /// to the target address before it is inserted into the specified slot in the IMM14 bundle. + /// The relocation target must be absolute or the image must be fixed. + IMM14 = 0x0001, + /// The instruction relocation can be followed by an ADDEND relocation whose value is added + /// to the target address before it is inserted into the specified slot in the IMM22 bundle. + /// The relocation target must be absolute or the image must be fixed. + IMM32 = 0x0002, + /// The slot number of this relocation must be one (1). + /// The relocation can be followed by an ADDEND relocation whose value is added + /// to the target address before it is stored in all three slots of the IMM64 bundle. + IMM64 = 0x0003, + /// The target's 32-bit VA. + /// This is supported only for /LARGEADDRESSAWARE:NO images. + Dir32 = 0x0004, + /// The target's 64-bit VA. + Dir64 = 0x0005, + /// The instruction is fixed up with the 25-bit relative displacement to the 16-bit aligned target. + /// The low 4 bits of the displacement are zero and are not stored. + PCRel21B = 0x0006, + /// The instruction is fixed up with the 25-bit relative displacement to the 16-bit aligned target. + /// The low 4 bits of the displacement, which are zero, are not stored. + PCRel21M = 0x0007, + /// The LSBs of this relocation's offset must contain the slot number whereas the rest is the bundle address. The bundle is fixed up with the 25-bit relative displacement to the 16-bit aligned target. + /// The low 4 bits of the displacement are zero and are not stored. + PCRel21F = 0x0008, + /// The instruction relocation can be followed by an ADDEND relocation whose value is added + /// to the target address and then a 22-bit GP-relative offset that is calculated and applied to the GPREL22 bundle. + GPRel22 = 0x0009, + /// The instruction is fixed up with the 22-bit GP-relative offset to the target symbol's literal table entry. + /// The linker creates this literal table entry based on this relocation and the ADDEND relocation that might follow. + LTOff22 = 0x000A, + /// The 16-bit section index of the section contains the target. + /// This is used to support debugging information. + Section = 0x000B, + /// The instruction is fixed up with the 22-bit offset of the target from the beginning of its section. + /// This relocation can be followed immediately by an ADDEND relocation, whose Value field contains the 32-bit unsigned offset of the target from the beginning of the section. + SecRel22 = 0x000C, + /// The slot number for this relocation must be one (1). The instruction is fixed up with the 64-bit offset of the target from the beginning of its section. + /// This relocation can be followed immediately by an ADDEND relocation whose Value field contains the 32-bit unsigned offset of the target from the beginning of the section. + SecRel64I = 0x000D, + /// The address of data to be fixed up with the 32-bit offset of the target from the beginning of its section. + SecRel32 = 0x000E, + /// The target's 32-bit RVA. + Dir32Nb = 0x0010, + /// This is applied to a signed 14-bit immediate that contains the difference between two relocatable targets. + /// This is a declarative field for the linker that indicates that the compiler has already emitted this value. + SRel14 = 0x0011, + /// This is applied to a signed 22-bit immediate that contains the difference between two relocatable targets. + /// This is a declarative field for the linker that indicates that the compiler has already emitted this value. + SRel22 = 0x0012, + /// This is applied to a signed 32-bit immediate that contains the difference between two relocatable values. + /// This is a declarative field for the linker that indicates that the compiler has already emitted this value. + SRel32 = 0x0013, + /// This is applied to an unsigned 32-bit immediate that contains the difference between two relocatable values. + /// This is a declarative field for the linker that indicates that the compiler has already emitted this value. + URel32 = 0x0014, + /// A 60-bit PC-relative fixup that always stays as a BRL instruction of an MLX bundle. + PCRel60X = 0x0015, + /// A 60-bit PC-relative fixup. + /// If the target displacement fits in a signed 25-bit field, convert the entire bundle to an MBB bundle with NOP.B in slot 1 and a 25-bit BR instruction (with the 4 lowest bits all zero and dropped) in slot 2. + PCRel60B = 0x0016, + /// A 60-bit PC-relative fixup. + /// If the target displacement fits in a signed 25-bit field, convert the entire bundle to an MFB bundle with NOP.F in slot 1 and a 25-bit (4 lowest bits all zero and dropped) BR instruction in slot 2. + PCRel60F = 0x0017, + /// A 60-bit PC-relative fixup. + /// If the target displacement fits in a signed 25-bit field, convert the entire bundle to an MIB bundle with NOP.I in slot 1 and a 25-bit (4 lowest bits all zero and dropped) BR instruction in slot 2. + PCRel60I = 0x0018, + /// A 60-bit PC-relative fixup. + /// If the target displacement fits in a signed 25-bit field, convert the entire bundle to an MMB bundle with NOP.M in slot 1 and a 25-bit (4 lowest bits all zero and dropped) BR instruction in slot 2. + PCRel60M = 0x0019, + /// A 64-bit GP-relative fixup. + IMMGPRel64 = 0x001A, + /// A CLR token. + Token = 0x001B, + /// A 32-bit GP-relative fixup. + GPRel32 = 0x001C, + /// The relocation is valid only when it immediately follows one of the following relocations: IMM14, IMM22, IMM64, GPREL22, LTOFF22, LTOFF64, SECREL22, SECREL64I, or SECREL32. + /// Its value contains the addend to apply to instructions within a bundle, not for data. + AddEnd = 0x001F, +} + +/// Relocation type indicators for MIPS processors. +#[derive(FromPrimitive, Debug, PartialEq)] +#[repr(u16)] +pub enum MIPSRelocationType { + /// The relocation is ignored. + Absolute = 0x0000, + /// The high 16 bits of the target's 32-bit VA. + RefHalf = 0x0001, + /// The target's 32-bit VA. + RefWord = 0x0002, + /// The low 26 bits of the target's VA. + /// This supports the MIPS J and JAL instructions. + JMPAddr = 0x0003, + /// The high 16 bits of the target's 32-bit VA. + /// This is used for the first instruction in a two-instruction sequence that loads a full address. + /// This relocation must be immediately followed by a PAIR relocation whose SymbolTableIndex contains a signed 16-bit displacement that is added to the upper 16 bits that are taken from the location that is being relocated. + RefHi = 0x0004, + /// The low 16 bits of the target's VA. + RefLo = 0x0005, + /// A 16-bit signed displacement of the target relative to the GP register. + GPRel = 0x0006, + /// The same as `MIPSRelocationType::GPRel`. + Literal = 0x0007, + /// The 16-bit section index of the section contains the target. + /// This is used to support debugging information. + Section = 0x000A, + /// The 32-bit offset of the target from the beginning of its section. + /// This is used to support debugging information and static thread local storage. + SecRel = 0x000B, + /// The low 16 bits of the 32-bit offset of the target from the beginning of its section. + SecRelLo = 0x000C, + /// The high 16 bits of the 32-bit offset of the target from the beginning of its section. + /// A PAIR relocation must immediately follow this one. + /// The SymbolTableIndex of the PAIR relocation contains a signed 16-bit displacement that is added to the upper 16 bits that are taken from the location that is being relocated. + SecRelHi = 0x000D, + /// The low 26 bits of the target's VA. + /// This supports the MIPS16 JAL instruction. + JMPAddr16 = 0x0010, + /// The target's 32-bit RVA. + RefWordNb = 0x0022, + /// The relocation is valid only when it immediately follows a REFHI or SECRELHI relocation. + /// Its SymbolTableIndex contains a displacement and not an index into the symbol table. + Pair = 0x0025, +} + +/// Relocation type indicators for Mitsubishi M32R processors. +#[derive(FromPrimitive, Debug, PartialEq)] +#[repr(u16)] +pub enum M32RRelocationType { + /// The relocation is ignored. + Absolute = 0x0000, + /// The target's 32-bit VA. + Addr32 = 0x0001, + /// The target's 32-bit RVA. + Addr32Nb = 0x0002, + /// The target's 24-bit VA. + Addr24 = 0x0003, + /// The target's 16-bit offset from the GP register. + GPRel16 = 0x0004, + /// The target's 24-bit offset from the program counter (PC), shifted left by 2 bits and sign-extended. + PCRel24 = 0x0005, + /// The target's 16-bit offset from the PC, shifted left by 2 bits and sign-extended. + PCRel16 = 0x0006, + /// The target's 8-bit offset from the PC, shifted left by 2 bits and sign-extended. + PCRel8 = 0x0007, + /// The 16 MSBs of the target VA. + RefHalf = 0x0008, + /// The 16 MSBs of the target VA, adjusted for LSB sign extension. + /// This is used for the first instruction in a two-instruction sequence that loads a full 32-bit address. + /// This relocation must be immediately followed by a PAIR relocation whose SymbolTableIndex contains a signed 16-bit displacement that is added to the upper 16 bits that are taken from the location that is being relocated. + RefHi = 0x0009, + /// The 16 LSBs of the target VA. + RefLo = 0x000A, + /// The relocation must follow the REFHI relocation. + /// Its SymbolTableIndex contains a displacement and not an index into the symbol table. + Pair = 0x000B, + /// The 16-bit section index of the section that contains the target. + /// This is used to support debugging information. + Section = 0x000C, + /// The 32-bit offset of the target from the beginning of its section. + /// This is used to support debugging information and static thread local storage. + SecRel = 0x000D, + /// The CLR token. + Token = 0x000E, +} \ No newline at end of file diff --git a/tests/pe-parser.rs b/tests/pe-parser.rs index 91be320..f6c9674 100644 --- a/tests/pe-parser.rs +++ b/tests/pe-parser.rs @@ -3,11 +3,11 @@ use datatest_stable::Result; use pe_parser::pe::parse_portable_executable; use std::fs; -fn gaunlet(path: &Path) -> Result<()> { +fn gauntlet(path: &Path) -> Result<()> { let binary = fs::read(path)?; let pe = parse_portable_executable(binary.as_slice())?; - // Binary passed inital parsing, now check if reserved fields are 0 + // Binary passed initial parsing, now check if reserved fields are 0 if let Some(optional) = pe.optional_header_32 { assert_eq!(optional.data_directories.architecture.size, 0); @@ -32,4 +32,4 @@ fn gaunlet(path: &Path) -> Result<()> { Ok(()) } -datatest_stable::harness!(gaunlet, "tests/pe", r"\.((dat)|(exe)|(dll))$"); \ No newline at end of file +datatest_stable::harness!(gauntlet, "tests/pe", r"\.((dat)|(exe)|(dll))$"); \ No newline at end of file