Skip to content

Commit

Permalink
[plugin_imports] A, W and Ex variants of the same function are no lon…
Browse files Browse the repository at this point in the history
…ger counted multiple times.
  • Loading branch information
JusticeRage committed Aug 19, 2017
2 parents e73a707 + 0385fc8 commit 3dfef3c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 3 deletions.
6 changes: 6 additions & 0 deletions include/manacommons/output_tree_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ class OutputTreeNode

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

DECLSPEC_MANACOMMONS void set_name(const std::string& name) {
_name->assign(name);
}

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

DECLSPEC_MANACOMMONS node_type get_type() const {
return _type;
}
Expand Down
18 changes: 18 additions & 0 deletions manacommons/output_tree_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,24 @@ void OutputTreeNode::append(pNode node)
if (!_list_data || !*_list_data) {
_list_data = boost::make_shared<boost::optional<nodes> >(nodes());
}

// The JSON formatter cannot handle identical names in a list. Rename duplicates if necessary.
int i = 2;
auto initial_name = *node->get_name();
auto current_name = initial_name;
for (auto it = (*_list_data)->begin() ; it != (*_list_data)->end() ; ++it)
{
if (*(*it)->get_name() == current_name)
{
std::stringstream ss;
ss << initial_name << " (#" << i++ << ")";
current_name = ss.str();
}
}
if (current_name != initial_name) {
node->set_name(current_name);
}

(*_list_data)->push_back(node);
}

Expand Down
3 changes: 2 additions & 1 deletion manape/imports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,8 @@ const_shared_strings PE::find_imports(const std::string& function_name_regexp,
else {
name = (*it2)->Name;
}
if (boost::regex_match(name, e)) {
// Functions may be imported multiple times, don't add the same one twice.
if (boost::regex_match(name, e) && std::find(destination->begin(), destination->end(), name) == destination->end()) {
destination->push_back(name);
}
}
Expand Down
41 changes: 39 additions & 2 deletions plugins/plugin_imports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
along with Manalyze. If not, see <http://www.gnu.org/licenses/>.
*/

#include <set>
#include <boost/algorithm/string/predicate.hpp>

#include "plugin_framework/plugin_interface.h"
#include "plugin_framework/auto_register.h"

Expand Down Expand Up @@ -50,7 +53,7 @@ std::string registry_api = "Reg.*(Key|Value).*|SH.*(Reg|Key).*|SHQueryValueEx(A|

std::string process_creation_api = "CreateProcess.*|system|WinExec|ShellExecute(A|W)";

std::string process_manipulation_api = "EnumProcess.*|OpenProcess|(Read|Write)ProcessMemory|Process32(First|Next)(W)?";
std::string process_manipulation_api = "EnumProcess.*|OpenProcess|(Read|Write)ProcessMemory|Process32(First|Next)(A|W)?";

std::string service_manipulation_api = "OpenSCManager(A|W)|(Open|Control|Create|Delete)Service(A|W)?|QueryService.*|"
"ChangeServiceConfig(A|W)|EnumServicesStatus(Ex)?(A|W)";
Expand Down Expand Up @@ -81,6 +84,40 @@ std::string shutdown_functions = "Initiate(System)?Shutdown(Ex)?(A|W)|LockWorkSt

std::string networking_api = "(Un)?EnableRouter|SetAdapterIpAddress|SetIp(Forward|Net|Statistics|TTL).*|SetPerTcp(6)?ConnectionEStats";

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

/**
* @brief Counts the number of different function names in a vector.
*
* A, W and Ex variants of the same function are considered to be the same.
*
* @param v The vector containing the function names.
*
* @return The number of different functions in the vector.
*/
unsigned int count_functions(const std::vector<std::string>& v)
{
unsigned int count = 0;
std::set<std::string> string_set;
for (std::string s : v)
{
if (s.empty()) {
continue;
}
std::string tmp(s);
if (boost::algorithm::ends_with(tmp, "A") || boost::algorithm::ends_with(tmp, "W")) {
tmp.pop_back();
}
if (tmp.size() > 2 && boost::algorithm::ends_with(tmp, "Ex")) {
tmp = tmp.substr(0, tmp.size() - 2);
}
string_set.insert(tmp);
}
return string_set.size();
}

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

/**
* @brief Checks the presence of some functions in the PE and updates the
* result accordingly.
Expand All @@ -105,7 +142,7 @@ bool check_functions(const mana::PE& pe,
pResult res)
{
mana::const_shared_strings found_imports = pe.find_imports(func_regex);
if (found_imports->size() >= static_cast<unsigned int>(req)) // Safe cast: these are positive enum indexes
if (found_imports && count_functions(*found_imports) >= static_cast<unsigned int>(req)) // Safe cast: these are positive enum indexes
{
res->raise_level(level);
io::pNode info = boost::make_shared<io::OutputTreeNode>(description,
Expand Down

0 comments on commit 3dfef3c

Please sign in to comment.