-
Notifications
You must be signed in to change notification settings - Fork 173
/
ApiMatchHandler.cpp
124 lines (87 loc) · 4.47 KB
/
ApiMatchHandler.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//
// Created by Vladimir on 20.06.20.
//
#include "ApiMatchHandler.h"
#include <random>
#include <regex>
#include <vector>
#include <string>
#include <sstream>
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/Inclusions/HeaderIncludes.h"
#include "clang/Tooling/Inclusions/IncludeStyle.h"
#include "Globals.h"
#include "Utils.h"
using namespace clang;
std::string ApiMatchHandler::getFunctionIdentifier(const CallExpr *CallExpression) {
const FunctionDecl *FnDeclaration = CallExpression->getDirectCallee();
//abort if invalid call
if (FnDeclaration == nullptr)
return nullptr;
IdentifierInfo *II = FnDeclaration->getIdentifier();
if (II == nullptr) {
return nullptr;
}
return II->getName();
}
bool ApiMatchHandler::replaceIdentifier(const CallExpr *CallExpression, const std::string &ApiName,
const std::string &NewIdentifier) {
return this->ASTRewriter->ReplaceText(CallExpression->getBeginLoc(), ApiName.length(), NewIdentifier);
}
bool ApiMatchHandler::handleCallExpr(const CallExpr *CallExpression, clang::ASTContext *const pContext) {
std::string Identifier = getFunctionIdentifier(CallExpression);
std::string Replacement = Utils::translateStringToIdentifier(Identifier);
if (!addGetProcAddress(CallExpression, pContext, Replacement, Identifier))
return false;
//Globs::PatchedSourceLocation.push_back(LiteralRange);
return replaceIdentifier(CallExpression, Identifier, Replacement);
}
void ApiMatchHandler::run(const MatchResult &Result) {
llvm::outs() << "Found " << _ApiName << "\n";
const auto *CallExpression = Result.Nodes.getNodeAs<clang::CallExpr>("callExpr");
handleCallExpr(CallExpression, Result.Context);
}
bool ApiMatchHandler::addGetProcAddress(const clang::CallExpr *pCallExpression, clang::ASTContext *const pContext,
const std::string &NewIdentifier, std::string &ApiName) {
SourceRange EnclosingFunctionRange = findInjectionSpot(pContext, clang::ast_type_traits::DynTypedNode(),
*pCallExpression, 0);
std::stringstream Result;
// add LoadLibrary with obfuscated strings
std::string LoadLibraryVariable = Utils::translateStringToIdentifier(_Library);
std::string LoadLibraryString = Utils::generateVariableDeclaration(LoadLibraryVariable, _Library);
std::string LoadLibraryHandleIdentifier = Utils::translateStringToIdentifier("hHandle_"+_Library);
Result << LoadLibraryString << std::endl;
Result << "\tHANDLE " << LoadLibraryHandleIdentifier << " = LoadLibrary(" << LoadLibraryVariable << ");\n";
// add GetProcAddress with obfuscated string: TypeDef NewIdentifier = (TypeDef) GetProcAddress(handleIdentifier, ApiName)
std::string ApiNameIdentifier = Utils::translateStringToIdentifier(ApiName);
std::string ApiNameDecl = Utils::generateVariableDeclaration(ApiNameIdentifier, ApiName);
Result << ApiNameDecl << "\n";
Result << "_ "<< ApiName << " " << NewIdentifier << " = (_" << ApiName << ") GetProcAddress("
<< LoadLibraryHandleIdentifier << ", " << ApiNameIdentifier << ");\n";
bool InsertResult = ASTRewriter->InsertText(EnclosingFunctionRange.getBegin(), Result.str());
if (InsertResult) {
llvm::errs() << " Could not finish to patch the function call.\n";
//Globs::PatchedSourceLocation.push_back(range);
}
return !InsertResult;
}
SourceRange
ApiMatchHandler::findInjectionSpot(clang::ASTContext *const Context, clang::ast_type_traits::DynTypedNode Parent,
const clang::CallExpr &Literal, uint64_t Iterations) {
if (Iterations > Globs::CLIMB_PARENTS_MAX_ITER)
throw std::runtime_error("Reached max iterations when trying to find a function declaration");
ASTContext::DynTypedNodeList parents = Context->getParents(Literal);;
if (Iterations > 0) {
parents = Context->getParents(Parent);
}
for (const auto &parent : parents) {
StringRef ParentNodeKind = parent.getNodeKind().asStringRef();
if (ParentNodeKind.find("FunctionDecl") != std::string::npos) {
auto FunDecl = parent.get<clang::FunctionDecl>();
auto *Statement = FunDecl->getBody();
auto *FirstChild = *Statement->child_begin();
return {FirstChild->getBeginLoc(), FunDecl->getEndLoc()};
}
return findInjectionSpot(Context, parent, Literal, ++Iterations);
}
}