Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
Linux Library Inject
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chu
Linux Library Inject
Commits
5b9a2a6e
Commit
5b9a2a6e
authored
Dec 26, 2019
by
Chu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
all ok
parent
ebdd7244
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
52 additions
and
66 deletions
+52
-66
CMakeLists.txt
CMakeLists.txt
+1
-0
CMakeLists.txt
evil/CMakeLists.txt
+2
-1
evil.c
evil/evil.c
+2
-2
main.cpp
host/main.cpp
+1
-7
CMakeLists.txt
inject/CMakeLists.txt
+1
-1
elf.cpp
inject/elf.cpp
+11
-33
elf.h
inject/elf.h
+0
-1
main.cpp
inject/main.cpp
+1
-1
process.cpp
inject/process.cpp
+32
-20
process.h
inject/process.h
+1
-0
No files found.
CMakeLists.txt
View file @
5b9a2a6e
...
...
@@ -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
)
...
...
evil/CMakeLists.txt
View file @
5b9a2a6e
add_library
(
evil SHARED evil.cpp evil.h
)
add_library
(
evil SHARED evil.c evil.h
)
set_target_properties
(
evil PROPERTIES LINK_FLAGS
"-s"
)
evil/evil.c
pp
→
evil/evil.c
View file @
5b9a2a6e
#include "evil.h"
#include <
cstdio
>
#include <
stdio.h
>
void
__attribute__
((
constructor
))
init
()
{
std
::
puts
(
"hello, world"
);
puts
(
"hello, world"
);
}
host/main.cpp
View file @
5b9a2a6e
...
...
@@ -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
)
{
s
how_message
(
"working..."
)
;
s
td
::
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
;
...
...
inject/CMakeLists.txt
View file @
5b9a2a6e
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
"
)
inject/elf.cpp
View file @
5b9a2a6e
...
...
@@ -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
());
}
inject/elf.h
View file @
5b9a2a6e
...
...
@@ -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_
;
...
...
inject/main.cpp
View file @
5b9a2a6e
...
...
@@ -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
;
}
...
...
inject/process.cpp
View file @
5b9a2a6e
...
...
@@ -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 ®isters)
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_
)
...
...
inject/process.h
View file @
5b9a2a6e
...
...
@@ -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
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment