Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b57d277
Refs #overwrite-fix, Refactor src to common
raffclar Apr 4, 2018
bc0bad4
Refs #overwrite-fix, Add libboost to travis
raffclar May 14, 2018
c17f2f3
Refs #overwrite-fix, Add some ugly code for automating testing on Win…
raffclar May 14, 2018
26973e9
Refs #overwrite-fix, Clean up the CMakeLists.txt file
raffclar May 14, 2018
54115e8
Refs #overwrite-fix, Add exe files to the gitignore
raffclar May 14, 2018
8a728bd
Refs #overwrite-fix, Exit with non-zero when exe edit fails
raffclar May 15, 2018
64f6371
Refs #overwrite-fix, Change initial command message
raffclar May 15, 2018
c19477b
Refs #overwrite-fix, Fix issue where section name was not being passed
raffclar May 23, 2018
a07295a
Refs #overwrite-fix, Clean up PeFile
raffclar May 23, 2018
dabaabe
Refs #overwrite-fix, Improve error handling of the Editor::edit() fun…
raffclar May 23, 2018
af2dc72
Refs #overwrite-fix, Add missing space to command usage output
raffclar Jul 3, 2018
3eefb8d
Refs #overwrite-fix, Move the "Running" output after the argument cou…
raffclar Jul 3, 2018
8899222
Refs #overwrite-fix, Add a TODO to change from mutable lambda to temp…
raffclar Jul 3, 2018
c9c728f
Refs #overwrite-fix, Return the patched file when editing
raffclar Jul 3, 2018
351526e
Refs #overwrite-fix, Remove unused get & set of DOS header
raffclar Jul 4, 2018
7dc4cae
Refs #overwrite-fix, Removed unused header from PePatchX64
raffclar Jul 4, 2018
03dc5e1
Refs #overwrite-fix, Amend comment
raffclar Jul 4, 2018
d1ef729
Refs #overwrite-fix, Close the input file after using it with the editor
raffclar Jul 4, 2018
33eace0
Refs #overwrite-fix, Return if the executable could not be edited
raffclar Jul 4, 2018
df0a776
Refs #overwrite-fix, Clarify image write
raffclar Jul 4, 2018
57d42d0
Refs #overwrite-fix, Fix formatting
raffclar Jul 5, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
cmake-build-debug/
build/
.vs
.idea
.idea
*.exe
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ addons:
packages:
- gcc-6
- g++-6
- libboost-all-dev
notifications:
email:
on_success: never
Expand Down
19 changes: 12 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
cmake_minimum_required(VERSION 3.6)
project(pe_ep_intercept)

set(KEYSTONE_BUILD_STATIC_RUNTIME on)
include_directories(include include/keystone/include)
add_subdirectory(include/keystone)
add_subdirectory(src)
cmake_minimum_required(VERSION 3.6)
project(pe_ep_intercept)

# Keystone
set(KEYSTONE_BUILD_STATIC_RUNTIME on)
include_directories(include include/keystone/include)

file(GLOB COMMON_SOURCE_FILES common/*)

# Sources
add_subdirectory(include/keystone)
add_subdirectory(src)
29 changes: 12 additions & 17 deletions src/PePatch.cpp → common/Assembler.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
#include <keystone/include/keystone/keystone.h>
#include "PePatch.hpp"
#include "Assembler.hpp"

namespace PeEpIntercept {
PePatch::PePatch(std::string &path) : PeFile(path) {

}

std::vector<char> PePatch::Assemble(const std::string &assembly) {
namespace Interceptor {
std::vector<char> Assembler::assemble(Architecture type, const std::string &assembly) {
std::vector<char> instructions;

if (assembly.empty()) {
Expand All @@ -29,35 +25,34 @@ namespace PeEpIntercept {
ks_mode instruct_mode;

switch (type) {
case PeArch::x86:
case Architecture::x86:
instruct_mode = KS_MODE_32;
break;
case PeArch::x64:
case Architecture::x64:
instruct_mode = KS_MODE_64;
break;
default:
throw std::runtime_error("executable type not supported");
throw std::runtime_error("Executable type not supported");
}

if (ks_open(KS_ARCH_X86, instruct_mode, &ks) != KS_ERR_OK) {
throw std::runtime_error("failed to open keystone");
throw std::runtime_error("Failed to open keystone");
}

std::unique_ptr<ks_engine[],
decltype(ks_deleter)> ks_ptr(ks, ks_deleter);
std::unique_ptr<ks_engine[], decltype(ks_deleter)> ks_ptr(ks, ks_deleter);

if (ks_asm(ks, assembly.c_str(), 0, &encode, &size, &count) != KS_ERR_OK) {
throw std::runtime_error("failed to assemble instructions");
throw std::runtime_error("Failed to assemble instructions");
}

std::unique_ptr<unsigned char[],
decltype(code_deleter)> encode_ptr(encode, code_deleter);

if (size > 0xffffffff) {
throw std::runtime_error("exceeded max section size");
if (size > sizeof(uint32_t) * 0xff) {
throw std::runtime_error("Exceeded max section size");
}

for (size_t i = 0; i < size; i++) {
for (auto i = 0; i < size; i++) {
auto encoded = static_cast<char>(encode[i]);
instructions.push_back(encoded);
}
Expand Down
15 changes: 15 additions & 0 deletions common/Assembler.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef PE_EP_INTERCEPT_ASSEMBLER_HPP
#define PE_EP_INTERCEPT_ASSEMBLER_HPP

#include "PeFile.hpp"

namespace Interceptor {
class Assembler {
protected:
public:
std::vector<char> assemble(Architecture type, const std::string &assembly);
};
}


#endif //PE_EP_INTERCEPT_ASSEMBLER_HPP
14 changes: 7 additions & 7 deletions src/PeAssembly.cpp → common/Assembly.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "PeAssembly.hpp"
#include "Assembly.hpp"

namespace PeEpIntercept {
std::string EntryRedirectAssemblyX64(uint32_t oep) {
std::string address = std::to_string(oep);
namespace Interceptor {
std::string entryRedirectAssemblyX64(uint32_t oep) {
auto address = std::to_string(oep);

return "push rbp;"
"mov rbp, rsp;"
Expand Down Expand Up @@ -44,8 +44,8 @@ namespace PeEpIntercept {
"ret;";
}

std::string EntryRedirectAssemblyX86(uint32_t oep) {
std::string address = std::to_string(oep);
std::string entryRedirectAssemblyX86(uint32_t oep) {
auto address = std::to_string(oep);

return "push ebp;"
"mov ebp, esp;"
Expand Down Expand Up @@ -86,4 +86,4 @@ namespace PeEpIntercept {
// patch in ExitProcess
"ret;";
}
} // namespace PeEpIntercept
} // namespace Interceptor
19 changes: 19 additions & 0 deletions common/Assembly.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef PE_EP_INTERCEPT_ASSEMBLY_HPP
#define PE_EP_INTERCEPT_ASSEMBLY_HPP

#include <string>

namespace Interceptor {
enum class Architecture {
x86,
x64,
unknown
};

std::string entryRedirectAssemblyX64(uint32_t oep);

std::string entryRedirectAssemblyX86(uint32_t oep);
}


#endif //PE_EP_INTERCEPT_ASSEMBLY_HPP
43 changes: 43 additions & 0 deletions common/Editor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <iostream>
#include "Editor.hpp"
#include "Assembler.hpp"
#include "PePatchX64.hpp"

namespace Interceptor {
PeFile Editor::original(std::fstream &file) {
try {
return PeFile(file);
} catch (std::runtime_error &ex) {
auto message = std::string("Could not parse the file. Reason: \"") + ex.what() + "\".";
throw std::runtime_error(message);
}
}

std::tuple<PeFile, bool> Editor::edit(
std::fstream &file,
const std::string &section
) {
std::unique_ptr<Interceptor::PePatchX64> patcher;
auto exe_file = original(file);

if (exe_file.hasSection(section)) {
std::cout << "The executable already has the section \"" << section << "\"." << std::endl;
return std::make_tuple(exe_file, false);
}

Assembler assembler;
auto arch = exe_file.getPeArch();

switch (arch) {
case Architecture::x64:
patcher = std::make_unique<Interceptor::PePatchX64>(assembler, exe_file);
break;
default:
std::cout << "The executable has an unsupported architecture." << std::endl;
return std::make_tuple(exe_file, false);
}

auto patched_file = patcher->patch(section);
return std::make_tuple(patched_file, true);
}
}
25 changes: 25 additions & 0 deletions common/Editor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef PE_EP_INTERCEPT_EDITOR_HPP
#define PE_EP_INTERCEPT_EDITOR_HPP

#include "PeFile.hpp"

namespace Interceptor {
class Editor {
private:
static PeFile original(std::fstream &file);
public:
/**
*
* @param file The stream contents will be used to instantiate a PeFile object
* @param section The new section will have this string as its name
* @return Contains a success. Returns original file on failure, patched on success
*/
static std::tuple<PeFile, bool> edit(
std::fstream &file,
const std::string &section
);
};
}


#endif //PE_EP_INTERCEPT_EDITOR_HPP
Loading