Skip to content

Commit

Permalink
manape is now completely decoupled from manacommons and hash-library;…
Browse files Browse the repository at this point in the history
… this means that it's now easy to re-use the PE parser in other projects!

The documentation was updated to indicate how to do this.
  • Loading branch information
JusticeRage committed Mar 27, 2016
1 parent 7fac8c8 commit a3546f6
Show file tree
Hide file tree
Showing 21 changed files with 375 additions and 173 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ external/yara
external/hash-library

# Sphinx build files
docs/_build
docs/_*
docs/.*
docs/html

# Malwares and documentation
Expand Down
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ include_directories(
${Boost_INCLUDE_DIRS}
)

add_definitions(-DWITH_MANACOMMONS) # Use functions from manacommons.
add_library(manape SHARED manape/pe.cpp manape/nt_values.cpp manape/utils.cpp manape/imports.cpp manape/resources.cpp manape/section.cpp)

add_library(manacommons SHARED manacommons/color.cpp manacommons/output_tree_node.cpp manacommons/escape.cpp manacommons/plugin_framework/result.cpp)

add_executable(manalyze src/main.cpp src/config_parser.cpp src/output_formatter.cpp src/dump.cpp
add_executable(manalyze src/main.cpp src/config_parser.cpp src/output_formatter.cpp src/dump.cpp src/import_hash.cpp
src/plugin_framework/dynamic_library.cpp src/plugin_framework/plugin_manager.cpp # Plugin system
plugins/plugins_yara.cpp plugins/plugin_packer_detection.cpp plugins/plugin_imports.cpp plugins/plugin_resources.cpp) # Bundled plugins

Expand Down Expand Up @@ -112,7 +113,7 @@ if (Tests MATCHES [Oo][Nn])
add_subdirectory(test)
endif()

target_link_libraries(manape yara hash-library manacommons ${Boost_LIBRARIES})
target_link_libraries(manape manacommons ${Boost_LIBRARIES})

target_link_libraries(
manalyze
Expand Down
2 changes: 2 additions & 0 deletions docs/before-contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Manalyze is distributed under the terms of the `GPLv3 license <https://www.gnu.o

If the code you are submitting depends on third-party libraries, make sure that their license is compatible - if it's not, we will not be able to accept your contribution. Refer to the `GNU website <https://www.gnu.org/licenses/license-list.en.html>`_ to check whether a particular license can be used alongside the GPLv3.

.. note:: If you would like to use any part of Manalyze in a commercial product but the GPL license isn't compatible with it, get in touch with the maintainer: dual-licensing options are available.

Coding style
============

Expand Down
1 change: 1 addition & 0 deletions docs/developer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ In this chapter, it is assumed that you have obtained a copy of the program's so
before-contributing
code-organization
writing-plugins
reusing-manape
49 changes: 49 additions & 0 deletions docs/reusing-manape.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
*********************
Reusing the PE parser
*********************

This section will explain how you can take the PE parser (ManaPE) out of Manalyze and re-use it in another project. We will focus on Linux environments, but the instructions given here should be easy to apply to other systems.

Let's start by writing some sample code that would read a PE file using Manalyze's parser::

#include <iostream>
#include "manape/pe.h"

int main(int argc, char** argv)
{
mana::PE pe("file.exe");
if (pe.is_valid()) { // Always check this.
std::cout << "File parsed successfully: " << *pe.get_path() << std::endl;
}
else
{
std::cout << "The file is invalid!" << std::endl;
return 1;
}

// Do stuff with the PE
auto sections = pe.get_sections();
for (auto it = sections->begin() ; it != sections->end() ; ++it) {
std::cout << *(*it)->get_name() << std::endl;
}
// ...

return 0;
}

For this to compile, you'll have to grab ManaPE's code and put it inside your project. you need both the ``manape`` and ``include/manape`` folders. ::

~/code/project$ mkdir include
~/code/project$ cp -r [...]/Manalyze/manape/ . && cp -r [...]/Manalyze/include/manape/ include/

You don't have to follow the same folder structure, it's only given as an example. Then, assuming you copied the previous code in ``main.cpp``, the only thing left to do is to compile everything::

~/code/project$ g++ main.cpp manape/*.cpp -lboost_system -lboost_regex -Iinclude -std=c++11
~/code/project$ ./a.out
File parsed successfully: file.exe
.text
.rdata
.data
.rsrc

Obviously, you'll want to write a Makefile or use CMake, but this should be enough to get you started. If you need detailed information on available methods that you can use from here, please see this section on by :ref:`pe_objects`.
2 changes: 2 additions & 0 deletions docs/writing-plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ Internally, all the result data is stored as key-value pairs; if you don't provi
Two
Three

.. _pe_objects:

PE objects
==========

Expand Down
3 changes: 2 additions & 1 deletion include/dump.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ along with Manalyze. If not, see <http://www.gnu.org/licenses/>.

#include "output_formatter.h"
#include "manape/pe.h"
#include "manape/imports.h"
#include "hash-library/hashes.h"
#include "hash-library/ssdeep.h"
#include "yara/yara_wrapper.h"

#include "import_hash.h"

namespace mana
{

Expand Down
10 changes: 2 additions & 8 deletions include/manape/imports.h → include/import_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,10 @@
along with Manalyze. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <string>
#include <algorithm>

#include <boost/filesystem.hpp>
#include <boost/assign.hpp>

#include "hash-library/hashes.h"
#include "pe.h"
#include "manape/pe.h"

namespace bfs = boost::filesystem;

Expand All @@ -38,6 +32,6 @@ namespace hash {
*
* Implementation is located in imports.cpp.
*/
DECLSPEC pString hash_imports(const mana::PE& pe);
std::string hash_imports(const mana::PE& pe);

} //namespace hash
7 changes: 3 additions & 4 deletions include/manacommons/escape.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ along with Manalyze. If not, see <http://www.gnu.org/licenses/>.
#include <string>
#include <boost/static_assert.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
Expand Down Expand Up @@ -91,11 +90,11 @@ struct escaped_string_json
karma::rule<OutputIterator, std::string()> esc_str;
karma::symbols<char, char const*> esc_char;
};

// ----------------------------------------------------------------------------

/*
* Forward-declare the OutputFormatter class, so it can be used in a static
* Forward-declare the OutputFormatter class, so it can be used in a static
* assert in template<typename T> std::string escape(const std::string&).
*/
class OutputFormatter;
Expand Down Expand Up @@ -155,7 +154,7 @@ pString escape(const std::string& s)
/*
* @brief Escapes problematic characters from a string.
*
* Non printable characters found in the input string will be escaped using
* Non printable characters found in the input string will be escaped using
* the C notation (i.e. \x0D).
*
* @param const std::string& s The string to escape.
Expand Down
37 changes: 37 additions & 0 deletions include/manape/color.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
This file is part of Manalyze.
Manalyze is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Manalyze is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Manalyze. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

// Pretty printing functions from manacommons are only imported if available.
// This makes it easier to take the parser out of Manalyze and re-use it for other stuff.
#if defined WITH_MANACOMMONS
# include "manacommons/color.h"
#else
# define PRINT_ERROR std::cerr << "[!] Error: "
# define PRINT_WARNING std::cerr << "[*] Warning: "

# ifdef _DEBUG
# define DEBUG_INFO " (" << __FILE__ << ":" << std::dec << std::dec << __LINE__ << ")"
# define DEBUG_INFO_PE " (" << __FILE__ << ":" << std::dec << __LINE__ << ", " << *pe.get_path() << ")"
# define DEBUG_INFO_INSIDEPE " (" << __FILE__ << ":" << std::dec << __LINE__ << ", " << *get_path() << ")"
# else
# define DEBUG_INFO ""
# define DEBUG_INFO_PE ""
# define DEBUG_INFO_INSIDEPE ""
# endif
#endif
100 changes: 100 additions & 0 deletions include/manape/escape.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
This file is part of Manalyze.
Manalyze is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Manalyze is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Manalyze. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

// Pretty printing functions from manacommons are only imported if available.
// This makes it easier to take the parser out of Manalyze and re-use it for other stuff.
#if defined WITH_MANACOMMONS
# include "manacommons/escape.h"
#else
# include <string>
# include <boost/static_assert.hpp>
# include <boost/spirit/include/karma.hpp>
# include <boost/type_traits/is_base_of.hpp>
# include <boost/shared_ptr.hpp>
# include <boost/make_shared.hpp>


// Escape functions copied from manacommons/escape.h / manacommons/escape.cpp
// I know that's code duplication / generally not great design. The issue is that
// section names need to be escaped, and I have to provide a way to do this when
// manacommons is not provided, for people who just want to reuse the PE parser
// but are not interested in pulling the rest of Manalyze's code.
namespace io {

namespace karma = boost::spirit::karma;
typedef std::back_insert_iterator<std::string> sink_type;
typedef boost::shared_ptr<std::string> pString;

/**
* @brief This grammar is used to escape strings printed to the console.
*
* Printable characters are returned as-is, while the others are displayed using the C
* notation.
*/
template <typename OutputIterator>
struct escaped_string_raw
: karma::grammar<OutputIterator, std::string()>
{
escaped_string_raw()
: escaped_string_raw::base_type(esc_str)
{
esc_str = *(boost::spirit::karma::iso8859_1::print | "\\x" << karma::right_align(2, 0)[karma::hex]);
}

karma::rule<OutputIterator, std::string()> esc_str;
karma::symbols<char, char const*> esc_char;
};

/**
* @brief Performs the actual string escaping based on the grammar given as
* template parameter.
*
* @param const std::string& s The string to escape.
*
* @return A pointer to the escaped string, or a null pointer if an error occurred.
*/
template<typename Grammar>
pString _do_escape(const std::string& s)
{
BOOST_STATIC_ASSERT(boost::is_base_of<karma::grammar<sink_type, std::string()>, Grammar>::value);
typedef std::back_insert_iterator<std::string> sink_type;

std::string generated;
sink_type sink(generated);

Grammar g;
if (!karma::generate(sink, g, s))
{
PRINT_WARNING << "Could not escape \"" << s << "!" << std::endl;
return nullptr;
}
else {
return boost::make_shared<std::string>(generated);
}
}

// ----------------------------------------------------------------------------

inline pString escape(const std::string& s) {
return _do_escape<escaped_string_raw<sink_type> >(s);
}

} // !namespace io

#endif
15 changes: 1 addition & 14 deletions include/manape/pe.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@
#include "manape/utils.h"
#include "manape/resources.h" // Definition of the Resource class
#include "manape/section.h" // Definition of the Section class
#include "manacommons/color.h" // Allows changing the font color in the terminal

// The structure used to communicate with the yara ManaPE module.
#include "yara/modules/manape_data.h"
#include "manape/color.h" // Colored output if available

#if defined BOOST_WINDOWS_API && !defined DECLSPEC
#ifdef MANAPE_EXPORT
Expand Down Expand Up @@ -207,16 +204,6 @@ class PE
*/
void operator delete(void* p);

/**
* @brief Creates the data used by the ManaPE Yara module.
*
* This extracts a few of the PE's parsed elements and stores them inside a structure that the ManaPE Yara module
* can use to do its work.
* The manape_data object contains address information (entry point, sections, ...). Passing them to Yara prevents
* me from using their built in PE parser (since manalyze has already done all the work).
*/
DECLSPEC boost::shared_ptr<manape_data> create_manape_module_data() const;

private:
/**
* @brief The new operator, re-implemented only so it could be made private.
Expand Down
4 changes: 2 additions & 2 deletions include/manape/section.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@

#include "manape/pe_structs.h"
#include "manape/utils.h"
#include "manacommons/color.h"
#include "manacommons/escape.h"
#include "manape/color.h"
#include "manape/escape.h"

#if defined BOOST_WINDOWS_API
#ifdef MANAPE_EXPORT
Expand Down
2 changes: 1 addition & 1 deletion include/manape/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include <boost/make_shared.hpp>
#include <boost/system/api_config.hpp>

#include "manacommons/color.h"
#include "manape/color.h"

// Some miscellaneous functions are exported
#if defined BOOST_WINDOWS_API
Expand Down

0 comments on commit a3546f6

Please sign in to comment.