diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2013, Eyal Lotem
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Eyal Lotem nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/extractelf.cabal b/extractelf.cabal
new file mode 100644
--- /dev/null
+++ b/extractelf.cabal
@@ -0,0 +1,22 @@
+name:                extractelf
+version:             0.1.0.0
+synopsis:            Extract an ELF's metadata and sections into files
+homepage:            https://github.com/Peaker/extractelf
+license:             BSD3
+license-file:        LICENSE
+author:              Eyal Lotem
+maintainer:          eyal.lotem@gmail.com
+category:            Development
+build-type:          Simple
+cabal-version:       >=1.10
+
+executable extractelf
+  main-is:             extractelf.hs
+  build-depends:       base >=4.6 && <4.7
+                     , directory < 1.3
+                     , optparse-applicative >= 0.5.2 && < 0.5.3
+                     , elf >= 0.27 && < 0.28
+                     , bytestring >= 0.9 && < 0.11
+                     , bytestring-mmap >= 0.2 && < 0.3
+                     , filepath >= 1.3 && < 1.4
+  default-language:    Haskell2010
diff --git a/extractelf.hs b/extractelf.hs
new file mode 100644
--- /dev/null
+++ b/extractelf.hs
@@ -0,0 +1,94 @@
+{-# OPTIONS -Wall #-}
+{-# LANGUAGE RecordWildCards #-}
+import Control.Applicative (Applicative(..), (<$>))
+import Control.Monad (forM_)
+import Data.Elf (Elf(..), ElfSegment(..), ElfSection(..))
+import Data.Maybe (fromMaybe)
+import Data.Monoid (Monoid(..), (<>))
+import Numeric (showHex)
+import System.FilePath ((</>), (<.>))
+import System.IO.Posix.MMap (unsafeMMapFile)
+import qualified Data.ByteString as BS
+import qualified Data.Elf as Elf
+import qualified Options.Applicative as Opts
+import qualified System.Directory as Dir
+
+data Options = Options
+  { _optFilenames :: FilePath
+  , _outputDirName :: Maybe FilePath
+  }
+
+optsParser :: Opts.Parser Options
+optsParser =
+  Options
+  <$> Opts.argument Opts.str (Opts.metavar "filename")
+  <*> Opts.optional outputDirNameParser
+
+outputDirNameParser :: Opts.Parser FilePath
+outputDirNameParser =
+  Opts.strOption $
+     Opts.short 'o'
+  <> Opts.long "output-prefix"
+  <> Opts.metavar "output-directory"
+  <> Opts.help "Output the ELF information files into this directory (defaults to <filename>.extracted)"
+
+main :: IO ()
+main = Opts.execParser opts >>= run
+  where
+    opts = Opts.info (Opts.helper <*> optsParser) mempty
+
+-----------------
+
+hex :: (Show a, Integral a) => a -> String
+hex = (`showHex` "")
+
+showSegment :: ElfSegment -> String
+showSegment ElfSegment{..} = concat
+  [ "VA: 0x", hex elfSegmentVirtAddr
+  , ", PA: 0x", hex elfSegmentPhysAddr
+  , ", Align: 0x", hex elfSegmentAlign
+  , ", MemSize: 0x", hex elfSegmentMemSize
+  , ", type:", show elfSegmentType
+  , ", flags:", show elfSegmentFlags
+  ]
+
+sectionsDirName :: FilePath
+sectionsDirName = "sections"
+
+run :: Options -> IO ()
+run (Options fileName mOutputDir) = do
+  bs <- unsafeMMapFile fileName
+  let outputDir = fromMaybe (fileName <.> "extracted") mOutputDir
+  Dir.createDirectory outputDir
+  Dir.createDirectory (outputDir </> sectionsDirName)
+  let Elf{..} = Elf.parseElf bs
+  writeFile (outputDir </> "hdr") . unlines . map unwords $
+    [ [ "Class", show elfClass ]
+    , [ "Data", show elfData ]
+    , [ "Version", show elfVersion ]
+    , [ "OSABI", show elfOSABI ]
+    , [ "ABIVersion", show elfABIVersion ]
+    , [ "Type", show elfType ]
+    , [ "Machine", show elfMachine ]
+    , [ "Entry", show elfEntry ]
+    , [ "Segments:" ]
+    ] ++
+    map ((:[]) . ("  "++) . showSegment) elfSegments
+  forM_ elfSections $ \ElfSection{..} -> do
+    let
+      sectionPrefix =
+        outputDir </> sectionsDirName </>
+        ("section" <.> elfSectionName)
+    writeFile (sectionPrefix <.> "hdr") $
+      unlines . map unwords $
+      [ [ "Name", show elfSectionName ]
+      , [ "  Type", show elfSectionType ]
+      , [ "  Flgs", show elfSectionFlags ]
+      , [ "  Addr", show elfSectionAddr ]
+      , [ "  Size", show elfSectionSize ]
+      , [ "  Link", show elfSectionLink ]
+      , [ "  Info", show elfSectionInfo ]
+      , [ "  Algn", show elfSectionAddrAlign ]
+      , [ "  EnSz", show elfSectionEntSize ]
+      ]
+    BS.writeFile (sectionPrefix <.> "data") elfSectionData
