Repository: m4b/goblin (language: rust)

Issue:
Support for COFF object files
COFF object files are not supported. The function [goblin::peek()](https://docs.rs/goblin/latest/goblin/fn.peek.html) doesn't seem to support this COFF format.

This lack of support causes the [issue #36 in `bingrep`](https://github.com/m4b/bingrep/issues/36), reproducible as follows:
```bash
$ rustup target add x86_64-pc-windows-gnu
$ echo "" | rustc --target x86_64-pc-windows-gnu --emit obj - --crate-type lib
$ bingrep rust_out.o
Unknown magic: 0x38664
```

Whereas:
```bash
$ file rust_out.o
rust_out.o: Intel amd64 COFF object file, not stripped, 3 sections, symbol offset=0x8c, 10 symbols, 1st section name ".text"
```


Discussion / hints:
i'm hoping a hero comes along and fixes this issue :) @koutheir it sounds like `peek` just needs to be made aware of coff object file magic numbers?
> it sounds like `peek` just needs to be made aware of coff object file magic numbers?

That should help.

Fix patch:
diff --git a/src/lib.rs b/src/lib.rs
index 25ab84132..7d6cd4ab0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -42,6 +42,9 @@
 //!                 Object::PE(pe) => {
 //!                     println!("pe: {:#?}", &pe);
 //!                 },
+//!                 Object::COFF(coff) => {
+//!                     println!("coff: {:#?}", &coff);
+//!                 },
 //!                 Object::Mach(mach) => {
 //!                     println!("mach: {:#?}", &mach);
 //!                 },
@@ -224,6 +227,7 @@ pub enum Hint {
     Mach(HintData),
     MachFat(usize),
     PE,
+    COFF,
     Archive,
     Unknown(u64),
 }
@@ -253,10 +257,14 @@ if_everything! {
             Ok(Hint::Elf(HintData { is_lsb, is_64 }))
         } else if &bytes[0..archive::SIZEOF_MAGIC] == archive::MAGIC {
             Ok(Hint::Archive)
-        } else if (&bytes[0..2]).pread_with::<u16>(0, LE)? == pe::header::DOS_MAGIC {
-            Ok(Hint::PE)
         } else {
-            mach::peek_bytes(bytes)
+            match *&bytes[0..2].pread_with::<u16>(0, LE)? {
+                pe::header::DOS_MAGIC => Ok(Hint::PE),
+                pe::header::COFF_MACHINE_X86 |
+                pe::header::COFF_MACHINE_X86_64 |
+                pe::header::COFF_MACHINE_ARM64 => Ok(Hint::COFF),
+                _ => mach::peek_bytes(bytes)
+            }
         }
     }
 
@@ -279,6 +287,8 @@ if_everything! {
         Elf(elf::Elf<'a>),
         /// A PE32/PE32+!
         PE(pe::PE<'a>),
+        /// A COFF
+        COFF(pe::Coff<'a>),
         /// A 32/64-bit Mach-o binary _OR_ it is a multi-architecture binary container!
         Mach(mach::Mach<'a>),
         /// A Unix archive
@@ -296,7 +306,8 @@ if_everything! {
                     Hint::Mach(_) | Hint::MachFat(_) => Ok(Object::Mach(mach::Mach::parse(bytes)?)),
                     Hint::Archive => Ok(Object::Archive(archive::Archive::parse(bytes)?)),
                     Hint::PE => Ok(Object::PE(pe::PE::parse(bytes)?)),
-                    Hint::Unknown(magic) => Ok(Object::Unknown(magic))
+                    Hint::COFF => Ok(Object::COFF(pe::Coff::parse(bytes)?)),
+                    Hint::Unknown(magic) => Ok(Object::Unknown(magic)),
                 }
             } else {
                 Err(error::Error::Malformed(format!("Object is too small.")))


Test patch: