Commit 5b9a2a6e authored by Chu's avatar Chu

all ok

parent ebdd7244
......@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(Linux_Library_Inject)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)
add_subdirectory(host)
add_subdirectory(inject)
......
add_library(evil SHARED evil.cpp evil.h)
add_library(evil SHARED evil.c evil.h)
set_target_properties(evil PROPERTIES LINK_FLAGS "-s")
#include "evil.h"
#include <cstdio>
#include <stdio.h>
void __attribute__((constructor)) init()
{
std::puts("hello, world");
puts("hello, world");
}
......@@ -5,7 +5,6 @@
using namespace std::chrono_literals;
void show_message(std::string_view message);
int sum(int a, int b);
int main()
......@@ -14,7 +13,7 @@ int main()
std::uniform_int_distribution distribution(1, 100);
while (true)
{
show_message("working...");
std::cout << "working...\n";
auto a = distribution(engine);
auto b = distribution(engine);
std::cout << a << " + " << b << " = " << sum(a, b) << std::endl;
......@@ -23,11 +22,6 @@ int main()
return 0;
}
void show_message(std::string_view message)
{
std::cout << "message: " << message << std::endl;
}
int sum(int a, int b)
{
return a + b;
......
add_executable(inject main.cpp elf.cpp elf.h process.cpp process.h)
set_target_properties(inject PROPERTIES LINK_FLAGS "-static")
set_target_properties(inject PROPERTIES LINK_FLAGS "-static -s")
......@@ -6,7 +6,6 @@
#include <unistd.h>
#include <cstring>
#include <sstream>
#include <stdexcept>
Elf::~Elf()
......@@ -43,6 +42,17 @@ const void *Elf::find_symbol_address_by_name(std::string_view name)
throw std::runtime_error(std::string(name) + " not found in " + path_);
}
const void *Elf::get_entry()
{
if (!memory_)
load_to_memory();
if (ehdr_->e_type == ET_EXEC)
return reinterpret_cast<const void *>(ehdr_->e_entry);
else
return reinterpret_cast<void *>(reinterpret_cast<std::size_t>(base_) + ehdr_->e_entry);
}
void Elf::load_to_memory()
{
auto fd = open(path_.c_str(), O_RDONLY);
......@@ -68,35 +78,3 @@ void Elf::load_to_memory()
ehdr_ = reinterpret_cast<Elf64_Ehdr *>(memory_);
shdr_ = reinterpret_cast<Elf64_Shdr *>(memory_ + ehdr_->e_shoff);
}
const void *Elf::get_entry()
{
if (!memory_)
load_to_memory();
return reinterpret_cast<void *>(reinterpret_cast<std::size_t>(base_) + ehdr_->e_entry);
}
std::size_t Elf::get_func_size(const void *address)
{
if (!memory_)
load_to_memory();
for (auto i = 0; i != ehdr_->e_shnum; ++i)
{
if (shdr_[i].sh_type == SHT_SYMTAB)
{
auto sym_tab = reinterpret_cast<Elf64_Sym *>(&memory_[shdr_[i].sh_offset]);
for (auto j = 0; j != shdr_[i].sh_size / sizeof(Elf64_Sym); ++j)
{
if (sym_tab->st_value == reinterpret_cast<std::size_t>(address))
return sym_tab->st_size;
++sym_tab;
}
}
}
std::ostringstream stream;
stream << "0x" << std::hex << address << " not found in " << path_;
throw std::runtime_error(stream.str());
}
......@@ -14,7 +14,6 @@ public:
void set_base(const void *base);
const void *find_symbol_address_by_name(std::string_view name);
const void *get_entry();
std::size_t get_func_size(const void *address);
private:
std::string path_;
......
......@@ -15,7 +15,7 @@ int main(int argc, char* argv[])
{
if (argc != 3)
{
std::cerr << "usage: " << argv[0] << " <pid> <evil.so>\n";
std::cerr << "usage: " << argv[0] << " <pid> </path/to/evil.so>\n";
return 1;
}
......
......@@ -2,10 +2,13 @@
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fstream>
#include <regex>
#include "elf.h"
Process::~Process()
{
if (attached_)
......@@ -31,17 +34,9 @@ std::pair<std::string, const void *> Process::find_libc()
const void *Process::find_rx_area()
{
std::string filename("/proc/");
filename += std::to_string(pid_);
filename += "/maps";
std::ifstream file(filename);
std::string line;
while (std::getline(file, line))
{
if (line.find(" r-x") != std::string::npos)
return reinterpret_cast<unsigned char *>(std::stoul(line, nullptr, 16));
}
throw std::runtime_error("rx area not found in " + filename);
Elf elf(get_execute());
elf.set_base(find_r_area());
return elf.get_entry();
}
const void *Process::find_r_area()
......@@ -49,10 +44,15 @@ const void *Process::find_r_area()
std::string filename("/proc/");
filename += std::to_string(pid_);
filename += "/maps";
auto execute = get_execute();
std::ifstream file(filename);
std::string line;
file >> line;
return reinterpret_cast<unsigned char *>(std::stoul(line, nullptr, 16));
while (std::getline(file, line))
{
if (line.find(execute) != std::string::npos)
return reinterpret_cast<unsigned char *>(std::stoul(line, nullptr, 16));
}
return nullptr;
}
void Process::attach()
......@@ -131,11 +131,14 @@ void Process::set_registers(const user_regs_struct &registers)
void Process::call_func(const void *address, std::array<const void *, 6> args)
{
check_for_attached();
// 0: 48 bb ef be ad de ef be ad de movabs $0xdeadbeefdeadbeef, %rbx
// a: ff d3 callq *%rbx
// c: cc int3
std::vector<unsigned char> shellcode = {0x48, 0xbb, 0xef, 0xbe, 0xad, 0xde, 0xef,
0xbe, 0xad, 0xde, 0xff, 0xd3, 0xcc};
// 0: 48 bb ef be ad de ef be ad de movabs $0xdeadbeefdeadbeef, %rbx
// a: 48 83 ec 08 sub $0x8,%rsp
// e: ff d3 callq *%rbx
// 10: 48 83 c4 08 add $0x8,%rsp
// 14: cc int3
// https://stackoverflow.com/questions/44613592/shared-library-injection-dl-relocate-object-segfaults
std::vector<unsigned char> shellcode = {0x48, 0xbb, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0x48,
0x83, 0xec, 0x08, 0xff, 0xd3, 0x48, 0x83, 0xc4, 0x08, 0xcc};
while (shellcode.size() % sizeof(void *) != 0)
shellcode.emplace_back(0x90);
std::memcpy(shellcode.data() + 2, &address, sizeof(address));
......@@ -144,8 +147,7 @@ void Process::call_func(const void *address, std::array<const void *, 6> args)
write(rx_area, shellcode);
auto original_registers = get_registers();
auto registers = original_registers;
// TODO why +0x2
registers.rip = reinterpret_cast<decltype(registers.rip)>(rx_area) + 0x2;
registers.rip = reinterpret_cast<decltype(registers.rip)>(rx_area);
registers.rdi = reinterpret_cast<decltype(registers.rdi)>(args[0]);
registers.rsi = reinterpret_cast<decltype(registers.rsi)>(args[1]);
registers.rdx = reinterpret_cast<decltype(registers.rdx)>(args[2]);
......@@ -158,6 +160,16 @@ void Process::call_func(const void *address, std::array<const void *, 6> args)
set_registers(original_registers);
}
std::string Process::get_execute()
{
std::string filename("/proc/");
filename += std::to_string(pid_);
filename += "/exe";
char buf[1024] = {0};
readlink(filename.c_str(), buf, 1023);
return buf;
}
void Process::check_for_attached()
{
if (!attached_)
......
......@@ -28,6 +28,7 @@ private:
pid_t pid_;
bool attached_;
std::string get_execute();
void check_for_attached();
static void check_for_read_write_size(std::size_t size);
void continue_and_wait_for_trap();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment