Another PE tool
Analyzing PE files is a basic task in reverse engineering in order to understand their structure, look for anything interesting before going more in depth into the reverse engineering in itself. There are countless tools to do that, on Windows I use PeStudio, PEView and Resource Hacker. But most of the time I want to have a first view of the file before starting my Virtual Machine, so I was looking for a CLI tool on Linux. There is of course PEScanner published by Michael Ligh with the good Malware Analyst’s Cookbook but it is a bit outdated (python2 only) and I like to write my own tools to be sure I understand how they work and what are their limits.
So I wrote a CLI tool plainly called PE, it is written in python 3 and published on github under GPLv3. It is using the good pefile and has a plugin architecture so it is easy to write new commands.
Installation#
The tool is not published under PyPI (yet?), but it is packaged for pip, so pretty easy to install :
git clone git@github.com:Te-k/pe.git
cd pe
pip install .
Plugins#
For now, there are 7 different commands:
- info : Extract info from the PE file
- dump : Dump resource or section of the file
- search : Search a string in a PE file
- checksize : Check size of the PE file
- check : Check for weird stuff in the PE file
- shell : Launch ipython shell to analyze the PE file
Example#
$ pe info playlib.exe
Metadata
================================================================================
MD5: 0963bee29e797ea7481be5f18f354029
SHA1: 2ab43fc90a1928684b8590375643da52285b8625
SHA256: f5967a8f3db4f4f33e89976e39914fceff46401bd2243b29162e1ddeb61f8dd3
Imphash: 25c0914e1e7dc7c3bb957d88e787a155
Size: 6445256 bytes
Type: PE32 executable (GUI) Intel 80386, for MS Windows
Compile Time: 2013-12-23 11:44:26 (UTC - 0x52B8221A)
Entry point: 0x40666e (section .text)
TLS Callback: 0x446bb0 (section .enigma2)
Sections
================================================================================
Name VirtSize VirtAddr RawSize RawAddr Entropy md5
.text 0x6d11 0x1000 0x400 0x6e00 6.0193 5eaee28e37a09d2102eb51e78b45b0c1
.rdata 0x8602 0x8000 0x7200 0x8800 5.5164 21bdbc2bf27fd551101d72b710e7f597
.data 0x8ac 0x11000 0xfa00 0x400 3.7505 9279c174353928a592cd4a7e75ed6b3b
.rsrc 0x1b4 0x12000 0xfe00 0x200 5.0920 81ed975a2d7b4836ff8515ef97ac2232
.reloc 0x1730 0x13000 0x10000 0x1800 6.2184 ce4be3ea2acc52c8fbefcde69e516b47
.enigma1 0x1000 0x15000 0x11800 0x5d4000 7.9314 a7a0284d8da4c85adbc23b8c600fe15f
.enigma2 0x40000 0x16000 0x5e5800 0x40000 6.0038 9314fd6d5c987f829f9f84d4acad0812
Imports
================================================================================
kernel32.dll
0x44b168 DeleteCriticalSection
0x44b16c LeaveCriticalSection
0x44b170 EnterCriticalSection
0x44b174 InitializeCriticalSection
0x44b178 VirtualFree
0x44b17c VirtualAlloc
0x44b180 LocalFree
[SNIP]
Resources:
================================================================================
Id Name Size Lang Sublang Type MD5
24-1-1033 None 346 B LANG_ENGLISH SUBLANG_ENGLISH_US ASCII text, with CRLF line terminators 24d3b502e1846356b0263f945ddd5529
$ pe check playlib.exe
Running checks on playlib.exe:
[+] Abnormal section names: .enigma1 .enigma2
[+] Suspicious section's entropy: .enigma1 - 7.931
[+] Known malicious sections
-.enigma1: Enigma Virtual Box protector
-.enigma2: Enigma Virtual Box protector
[+] 200 extra bytes in the file
[+] TLS Callback: 0x446bb0
[+] PE header in sections .enigma2
[+] Known suspicious import hash: Enigma VirtualBox
$ pe checksize playlib.exe
Name VirtSize VirtAddr RawSize RawAddr Entropy md5
.text 0x6d11 0x1000 0x400 0x6e00 6.0193 5eaee28e37a09d2102eb51e78b45b0c1
.rdata 0x8602 0x8000 0x7200 0x8800 5.5164 21bdbc2bf27fd551101d72b710e7f597
.data 0x8ac 0x11000 0xfa00 0x400 3.7505 9279c174353928a592cd4a7e75ed6b3b
.rsrc 0x1b4 0x12000 0xfe00 0x200 5.0920 81ed975a2d7b4836ff8515ef97ac2232
.reloc 0x1730 0x13000 0x10000 0x1800 6.2184 ce4be3ea2acc52c8fbefcde69e516b47
.enigma1 0x1000 0x15000 0x11800 0x5d4000 7.9314 a7a0284d8da4c85adbc23b8c600fe15f
.enigma2 0x40000 0x16000 0x5e5800 0x40000 6.0038 9314fd6d5c987f829f9f84d4acad0812
200 bytes of extra data (6445256 while it should be 6445056)
Creating a new command#
As it is based on a plugin model, it is pretty easy to extend with new commands. You need to create a new file in pe/plugin having the following model :
#! /usr/bin/env python
from pe.plugins.base import Plugin
class PluginLambda(Plugin):
name = "lambda"
description = "Description of the plugin here"
def add_arguments(self, parser):
# Add argparse arguments
parser.add_argument('INFORMATION')
def run(self, args, pe, data):
# Code here
Feel free to open issues and propose Pull Requests.