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
ebdd7244
Commit
ebdd7244
authored
Dec 26, 2019
by
Chu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new method
parent
c630fe56
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
83 additions
and
261 deletions
+83
-261
elf.cpp
inject/elf.cpp
+7
-7
elf.h
inject/elf.h
+5
-5
main.cpp
inject/main.cpp
+27
-13
process.cpp
inject/process.cpp
+37
-30
process.h
inject/process.h
+7
-6
process_old.cpp
inject/process_old.cpp
+0
-166
process_old.h
inject/process_old.h
+0
-34
No files found.
inject/elf.cpp
View file @
ebdd7244
...
...
@@ -15,12 +15,12 @@ Elf::~Elf()
munmap
(
memory_
,
memory_length_
);
}
void
Elf
::
set_base
(
std
::
size_t
base
)
void
Elf
::
set_base
(
const
void
*
base
)
{
base_
=
base
;
}
std
::
size_t
Elf
::
find_symbol_address_by_name
(
std
::
string_view
name
)
const
void
*
Elf
::
find_symbol_address_by_name
(
std
::
string_view
name
)
{
if
(
!
memory_
)
load_to_memory
();
...
...
@@ -34,7 +34,7 @@ std::size_t Elf::find_symbol_address_by_name(std::string_view name)
for
(
auto
j
=
0
;
j
!=
shdr_
[
i
].
sh_size
/
sizeof
(
Elf64_Sym
);
++
j
)
{
if
(
&
str_tab
[
sym_tab
->
st_name
]
==
name
)
return
base_
+
sym_tab
->
st_value
;
return
reinterpret_cast
<
void
*>
(
reinterpret_cast
<
std
::
size_t
>
(
base_
)
+
sym_tab
->
st_value
)
;
++
sym_tab
;
}
}
...
...
@@ -69,15 +69,15 @@ void Elf::load_to_memory()
shdr_
=
reinterpret_cast
<
Elf64_Shdr
*>
(
memory_
+
ehdr_
->
e_shoff
);
}
std
::
size_t
Elf
::
get_entry
()
const
void
*
Elf
::
get_entry
()
{
if
(
!
memory_
)
load_to_memory
();
return
base_
+
ehdr_
->
e_entry
;
return
reinterpret_cast
<
void
*>
(
reinterpret_cast
<
std
::
size_t
>
(
base_
)
+
ehdr_
->
e_entry
)
;
}
std
::
size_t
Elf
::
get_func_size
(
std
::
size_t
address
)
std
::
size_t
Elf
::
get_func_size
(
const
void
*
address
)
{
if
(
!
memory_
)
load_to_memory
();
...
...
@@ -89,7 +89,7 @@ std::size_t Elf::get_func_size(std::size_t address)
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
==
address
)
if
(
sym_tab
->
st_value
==
reinterpret_cast
<
std
::
size_t
>
(
address
)
)
return
sym_tab
->
st_size
;
++
sym_tab
;
}
...
...
inject/elf.h
View file @
ebdd7244
...
...
@@ -11,14 +11,14 @@ class Elf final
public
:
explicit
Elf
(
std
::
string
path
)
:
path_
(
std
::
move
(
path
))
{}
~
Elf
();
void
set_base
(
std
::
size_t
base
);
std
::
size_t
find_symbol_address_by_name
(
std
::
string_view
name
);
std
::
size_t
get_entry
();
std
::
size_t
get_func_size
(
std
::
size_t
address
);
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_
;
std
::
size_t
base_
=
0
;
const
void
*
base_
=
nullptr
;
std
::
size_t
memory_length_
=
0
;
unsigned
char
*
memory_
=
nullptr
;
Elf64_Ehdr
*
ehdr_
=
nullptr
;
...
...
inject/main.cpp
View file @
ebdd7244
#include <dlfcn.h>
#include <cstring>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
#include "elf.h"
#include "process
_old
.h"
#include "process.h"
void
do_libc_dlopen_mode
();
void
do_libc_dlopen_mode
(
Process
&
process
,
const
void
*
address
,
std
::
string_view
path
);
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
!=
3
)
{
...
...
@@ -21,26 +25,36 @@ int main(int argc, char *argv[])
// find libc.so in target process
std
::
cout
<<
"[*] find libc.so in target process
\n
"
;
auto
[
libc_path
,
libc_base
]
=
process
.
find_libc
();
std
::
cout
<<
"[+] libc: "
<<
libc_path
<<
" 0x"
<<
std
::
hex
<<
libc_base
<<
std
::
endl
;
std
::
cout
<<
"[+] libc: "
<<
libc_path
<<
" 0x"
<<
std
::
hex
<<
reinterpret_cast
<
std
::
size_t
>
(
libc_base
)
<<
std
::
endl
;
// find __libc_dlopen_mode in libc.so
std
::
cout
<<
"[*] find __libc_dlopen_mode in "
<<
libc_path
<<
std
::
endl
;
Elf
libc
(
libc_path
);
libc
.
set_base
(
libc_base
);
auto
libc_dlopen_mode
=
libc
.
find_symbol_address_by_name
(
"__libc_dlopen_mode"
);
std
::
cout
<<
"[+] __libc_dlopen_mode: 0x"
<<
libc_dlopen_mode
<<
std
::
endl
;
std
::
cout
<<
"[+] __libc_dlopen_mode: 0x"
<<
reinterpret_cast
<
std
::
size_t
>
(
libc_dlopen_mode
)
<<
std
::
endl
;
// call __libc_dlopen_mode in target process
std
::
cout
<<
"[*] get shellcode in current process
\n
"
;
auto
do_libc_dlopen_mode_addr
=
reinterpret_cast
<
unsigned
char
*>
(
&
do_libc_dlopen_mode
);
auto
do_libc_dlopen_mode_size
=
Elf
(
argv
[
0
]).
get_func_size
(
reinterpret_cast
<
std
::
size_t
>
(
do_libc_dlopen_mode_addr
));
std
::
cout
<<
"[+] shellcode: 0x"
<<
reinterpret_cast
<
std
::
size_t
>
(
do_libc_dlopen_mode_addr
)
<<
" "
<<
std
::
dec
<<
do_libc_dlopen_mode_size
<<
std
::
endl
;
std
::
cout
<<
"[*] execute shellcode in target process
\n
"
;
process
.
call_shellcode
(
std
::
vector
(
do_libc_dlopen_mode_addr
,
do_libc_dlopen_mode_addr
+
do_libc_dlopen_mode_size
));
std
::
cout
<<
"[*] call __libc_dlopen_mode in target process
\n
"
;
do_libc_dlopen_mode
(
process
,
libc_dlopen_mode
,
argv
[
2
]);
std
::
cout
<<
"[+] injected
\n
"
;
return
0
;
}
void
do_libc_dlopen_mode
()
{}
void
do_libc_dlopen_mode
(
Process
&
process
,
const
void
*
address
,
std
::
string_view
path
)
{
std
::
vector
<
unsigned
char
>
data
(
path
.
data
(),
path
.
data
()
+
path
.
size
()
+
1
);
while
(
data
.
size
()
%
sizeof
(
void
*
)
!=
0
)
data
.
emplace_back
(
0x00
);
process
.
attach
();
auto
path_addr
=
process
.
find_r_area
();
auto
original_data
=
process
.
read
(
path_addr
,
data
.
size
());
process
.
write
(
path_addr
,
data
);
auto
flags
=
RTLD_LAZY
;
process
.
call_func
(
address
,
{
path_addr
,
reinterpret_cast
<
const
void
*>
(
flags
),
nullptr
,
nullptr
,
nullptr
,
nullptr
});
process
.
write
(
path_addr
,
original_data
);
process
.
detach
();
}
inject/process.cpp
View file @
ebdd7244
...
...
@@ -12,7 +12,7 @@ Process::~Process()
detach
();
}
std
::
pair
<
std
::
string
,
void
*>
Process
::
find_libc
()
std
::
pair
<
std
::
string
,
const
void
*>
Process
::
find_libc
()
{
std
::
string
filename
(
"/proc/"
);
filename
+=
std
::
to_string
(
pid_
);
...
...
@@ -24,12 +24,12 @@ std::pair<std::string, void *> Process::find_libc()
while
(
std
::
getline
(
file
,
line
))
{
if
(
std
::
regex_search
(
line
,
result
,
pattern
))
return
{
result
[
1
].
str
(),
reinterpret_cast
<
void
*>
(
std
::
stoul
(
line
,
nullptr
,
16
))};
return
{
result
[
1
].
str
(),
reinterpret_cast
<
unsigned
char
*>
(
std
::
stoul
(
line
,
nullptr
,
16
))};
}
throw
std
::
runtime_error
(
"libc.so not found in "
+
filename
);
}
unsigned
char
*
Process
::
find_rx_area
()
const
void
*
Process
::
find_rx_area
()
{
std
::
string
filename
(
"/proc/"
);
filename
+=
std
::
to_string
(
pid_
);
...
...
@@ -44,19 +44,15 @@ unsigned char *Process::find_rx_area()
throw
std
::
runtime_error
(
"rx area not found in "
+
filename
);
}
unsigned
char
*
Process
::
find_rw
_area
()
const
void
*
Process
::
find_r
_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
(
" rw"
)
!=
std
::
string
::
npos
)
return
reinterpret_cast
<
unsigned
char
*>
(
std
::
stoul
(
line
,
nullptr
,
16
));
}
throw
std
::
runtime_error
(
"rw area not found in "
+
filename
);
file
>>
line
;
return
reinterpret_cast
<
unsigned
char
*>
(
std
::
stoul
(
line
,
nullptr
,
16
));
}
void
Process
::
attach
()
...
...
@@ -76,41 +72,43 @@ void Process::detach()
attached_
=
false
;
}
void
Process
::
write
(
unsigned
char
*
address
,
std
::
vector
<
unsigned
char
>
&
data
)
void
Process
::
write
(
const
void
*
address
,
const
std
::
vector
<
unsigned
char
>
&
data
)
{
check_for_attached
();
check_for_read_write_size
(
data
.
size
());
auto
address_
=
static_cast
<
const
char
*>
(
address
);
auto
data_ptr
=
data
.
data
();
std
::
size_t
total_wrote
=
0
;
while
(
total_wrote
!=
data
.
size
())
{
void
*
data_to_write
=
nullptr
;
std
::
memcpy
(
&
data_to_write
,
data_ptr
,
sizeof
(
data_to_write
));
if
(
ptrace
(
PTRACE_POKETEXT
,
pid_
,
address
,
data_to_write
)
==
-
1
)
if
(
ptrace
(
PTRACE_POKETEXT
,
pid_
,
address
_
,
data_to_write
)
==
-
1
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
address
+=
sizeof
(
data_to_write
);
address
_
+=
sizeof
(
data_to_write
);
data_ptr
+=
sizeof
(
data_to_write
);
total_wrote
+=
sizeof
(
data_to_write
);
}
}
std
::
vector
<
unsigned
char
>
Process
::
read
(
unsigned
char
*
address
,
std
::
size_t
size
)
std
::
vector
<
unsigned
char
>
Process
::
read
(
const
void
*
address
,
std
::
size_t
size
)
{
check_for_attached
();
std
::
vector
<
unsigned
char
>
data
(
size
%
sizeof
(
void
*
)
==
0
?
size
:
size
+
(
size
-
size
%
sizeof
(
void
*
)));
check_for_read_write_size
(
size
);
auto
address_
=
static_cast
<
const
char
*>
(
address
);
std
::
vector
<
unsigned
char
>
data
(
size
);
auto
data_ptr
=
data
.
data
();
std
::
size_t
total_read
=
0
;
while
(
total_read
!=
size
)
{
auto
data_read
=
ptrace
(
PTRACE_PEEKTEXT
,
pid_
,
address
,
nullptr
);
auto
data_read
=
ptrace
(
PTRACE_PEEKTEXT
,
pid_
,
address
_
,
nullptr
);
if
(
data_read
==
-
1
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
auto
size_to_copy
=
size
-
total_read
>
sizeof
(
data_read
)
?
sizeof
(
data_read
)
:
size
-
total_read
;
std
::
memcpy
(
data_ptr
,
&
data_read
,
size_to_copy
);
address
+=
size_to_copy
;
data_ptr
+=
size_to_copy
;
total_read
+=
size_to_copy
;
std
::
memcpy
(
data_ptr
,
&
data_read
,
sizeof
(
data_read
));
address_
+=
sizeof
(
data_read
);
data_ptr
+=
sizeof
(
data_read
);
total_read
+=
sizeof
(
data_read
);
}
data
.
resize
(
size
);
return
data
;
}
...
...
@@ -126,11 +124,11 @@ user_regs_struct Process::get_registers()
void
Process
::
set_registers
(
const
user_regs_struct
&
registers
)
{
check_for_attached
();
if
(
ptrace
(
PTRACE_SETREGS
,
pid_
,
nullptr
,
&
registers
))
if
(
ptrace
(
PTRACE_SETREGS
,
pid_
,
nullptr
,
&
registers
)
==
-
1
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
}
void
Process
::
call_func
(
void
*
address
,
std
::
array
<
void
*
,
6
>
args
)
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
...
...
@@ -138,13 +136,16 @@ void Process::call_func(void *address, std::array<void *, 6> args)
// c: cc int3
std
::
vector
<
unsigned
char
>
shellcode
=
{
0x48
,
0xbb
,
0xef
,
0xbe
,
0xad
,
0xde
,
0xef
,
0xbe
,
0xad
,
0xde
,
0xff
,
0xd3
,
0xcc
};
while
(
shellcode
.
size
()
%
sizeof
(
void
*
)
!=
0
)
shellcode
.
emplace_back
(
0x90
);
std
::
memcpy
(
shellcode
.
data
()
+
2
,
&
address
,
sizeof
(
address
));
auto
rx_addr
=
find_rx_area
();
auto
original_code
=
read
(
rx_addr
,
shellcode
.
size
());
auto
rx_area
=
find_rx_area
();
auto
original_code
=
read
(
rx_area
,
shellcode
.
size
());
write
(
rx_area
,
shellcode
);
auto
original_registers
=
get_registers
();
write
(
rx_addr
,
shellcode
);
auto
registers
=
original_registers
;
registers
.
rip
=
reinterpret_cast
<
decltype
(
registers
.
rip
)
>
(
rx_addr
);
// TODO why +0x2
registers
.
rip
=
reinterpret_cast
<
decltype
(
registers
.
rip
)
>
(
rx_area
)
+
0x2
;
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
]);
...
...
@@ -153,7 +154,7 @@ void Process::call_func(void *address, std::array<void *, 6> args)
registers
.
r9
=
reinterpret_cast
<
decltype
(
registers
.
rdi
)
>
(
args
[
5
]);
set_registers
(
registers
);
continue_and_wait_for_trap
();
write
(
rx_a
ddr
,
original_code
);
write
(
rx_a
rea
,
original_code
);
set_registers
(
original_registers
);
}
...
...
@@ -163,6 +164,12 @@ void Process::check_for_attached()
throw
std
::
runtime_error
(
"process must be attach first"
);
}
void
Process
::
check_for_read_write_size
(
std
::
size_t
size
)
{
if
(
size
%
sizeof
(
void
*
)
!=
0
)
throw
std
::
runtime_error
(
"size % sizeof(void *) != 0"
);
}
void
Process
::
continue_and_wait_for_trap
()
{
check_for_attached
();
...
...
@@ -171,5 +178,5 @@ void Process::continue_and_wait_for_trap()
int
status
;
wait
(
&
status
);
if
(
WSTOPSIG
(
status
)
!=
SIGTRAP
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
)
);
throw
std
::
runtime_error
(
"unknown sig"
);
}
inject/process.h
View file @
ebdd7244
...
...
@@ -13,22 +13,23 @@ class Process final
public
:
explicit
Process
(
pid_t
pid
)
:
pid_
(
pid
),
attached_
(
false
)
{}
~
Process
();
std
::
pair
<
std
::
string
,
void
*>
find_libc
();
unsigned
char
*
find_rx_area
();
unsigned
char
*
find_rw
_area
();
std
::
pair
<
std
::
string
,
const
void
*>
find_libc
();
const
void
*
find_rx_area
();
const
void
*
find_r
_area
();
void
attach
();
void
detach
();
void
write
(
unsigned
char
*
address
,
std
::
vector
<
unsigned
char
>
&
data
);
std
::
vector
<
unsigned
char
>
read
(
unsigned
char
*
address
,
std
::
size_t
size
);
void
write
(
const
void
*
address
,
const
std
::
vector
<
unsigned
char
>
&
data
);
std
::
vector
<
unsigned
char
>
read
(
const
void
*
address
,
std
::
size_t
size
);
user_regs_struct
get_registers
();
void
set_registers
(
const
user_regs_struct
&
registers
);
void
call_func
(
void
*
address
,
std
::
array
<
void
*
,
6
>
args
);
void
call_func
(
const
void
*
address
,
std
::
array
<
const
void
*
,
6
>
args
);
private
:
pid_t
pid_
;
bool
attached_
;
void
check_for_attached
();
static
void
check_for_read_write_size
(
std
::
size_t
size
);
void
continue_and_wait_for_trap
();
};
...
...
inject/process_old.cpp
deleted
100644 → 0
View file @
c630fe56
#include "process_old.h"
#include <sys/wait.h>
#include <unistd.h>
#include <cstring>
#include <fstream>
#include <iostream>
#include <regex>
#include "elf.h"
std
::
pair
<
std
::
string
,
std
::
size_t
>
Process
::
find_libc
()
{
std
::
string
filename
(
"/proc/"
);
filename
+=
std
::
to_string
(
pid_
);
filename
+=
"/maps"
;
std
::
ifstream
file
(
filename
);
std
::
regex
pattern
(
R"(^([0-9a-h]+)\-.*?(/.*libc\-[0-9\.]*?\.so)$)"
);
std
::
string
line
;
std
::
smatch
result
;
while
(
std
::
getline
(
file
,
line
))
{
if
(
std
::
regex_search
(
line
,
result
,
pattern
))
return
{
result
[
2
].
str
(),
std
::
stoul
(
result
[
1
].
str
(),
nullptr
,
16
)};
}
throw
std
::
runtime_error
(
"libc.so not found in "
+
filename
);
}
std
::
size_t
Process
::
get_base
()
{
std
::
string
filename
(
"/proc/"
);
filename
+=
std
::
to_string
(
pid_
);
filename
+=
"/maps"
;
std
::
ifstream
file
(
filename
);
std
::
string
line
;
file
>>
line
;
return
std
::
stoul
(
line
,
nullptr
,
16
);
}
std
::
string
Process
::
get_execute
()
{
std
::
string
filename
(
"/proc/"
);
filename
+=
std
::
to_string
(
pid_
);
filename
+=
"/exe"
;
char
execute
[
1024
]
=
{
0
};
if
(
readlink
(
filename
.
c_str
(),
execute
,
1023
)
!=
-
1
)
return
execute
;
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
}
std
::
size_t
Process
::
get_entry_point
()
{
Elf
elf
(
get_execute
());
elf
.
set_base
(
get_base
());
return
elf
.
get_entry
();
}
void
Process
::
call_shellcode
(
std
::
vector
<
unsigned
char
>
shellcode
)
{
std
::
cout
<<
"[*] get target process's entry point
\n
"
;
auto
entry_point
=
get_entry_point
();
// replace `ret` with `int3`
if
(
shellcode
[
shellcode
.
size
()
-
1
]
==
0xc3
)
shellcode
[
shellcode
.
size
()
-
1
]
=
0xcc
;
// align
while
(
shellcode
.
size
()
%
sizeof
(
void
*
)
!=
0
)
shellcode
.
emplace_back
(
0x90
);
std
::
cout
<<
"[*] attach to target process
\n
"
;
attach
();
std
::
cout
<<
"[*] backup original code
\n
"
;
auto
original_code
=
read_memory
(
entry_point
,
shellcode
.
size
());
std
::
cout
<<
"[*] backup original registers
\n
"
;
auto
original_registers
=
get_registers
();
std
::
cout
<<
"[*] write shellcode to target process's entry point
\n
"
;
write_memory
(
entry_point
,
shellcode
);
auto
registers
=
original_registers
;
registers
.
rip
=
entry_point
;
std
::
cout
<<
"[*] set %rip to target process's entry point
\n
"
;
set_registers
(
registers
);
std
::
cout
<<
"[*] continue and wait for trap
\n
"
;
continue_and_wait_for_trap
();
std
::
cout
<<
"[*] restore original code
\n
"
;
write_memory
(
entry_point
,
original_code
);
std
::
cout
<<
"[*] restore original registers
\n
"
;
set_registers
(
original_registers
);
std
::
cout
<<
"[*] detach target process
\n
"
;
detach
();
}
void
Process
::
attach
()
{
if
(
ptrace
(
PTRACE_ATTACH
,
pid_
,
nullptr
,
nullptr
)
==
-
1
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
wait
(
nullptr
);
}
void
Process
::
detach
()
{
if
(
ptrace
(
PTRACE_DETACH
,
pid_
,
nullptr
,
nullptr
)
==
-
1
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
wait
(
nullptr
);
}
std
::
vector
<
unsigned
char
>
Process
::
read_memory
(
std
::
size_t
address
,
std
::
size_t
size
)
{
std
::
vector
<
unsigned
char
>
data
;
data
.
resize
(
size
);
auto
ptr
=
data
.
data
();
std
::
size_t
n
=
0
;
while
(
n
!=
size
)
{
auto
word
=
ptrace
(
PTRACE_PEEKTEXT
,
pid_
,
address
,
nullptr
);
if
(
word
==
-
1
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
auto
to_copy
=
size
-
n
>
sizeof
(
void
*
)
?
sizeof
(
void
*
)
:
size
-
n
;
std
::
memcpy
(
ptr
,
&
word
,
to_copy
);
ptr
+=
to_copy
;
n
+=
to_copy
;
address
+=
sizeof
(
void
*
);
}
return
data
;
}
void
Process
::
write_memory
(
std
::
size_t
address
,
std
::
vector
<
unsigned
char
>
data
)
{
auto
ptr
=
data
.
data
();
std
::
size_t
n
=
0
;
while
(
n
!=
data
.
size
())
{
void
*
to_write
=
nullptr
;
std
::
memcpy
(
&
to_write
,
ptr
,
sizeof
(
to_write
));
if
(
ptrace
(
PTRACE_POKETEXT
,
pid_
,
address
,
to_write
)
==
-
1
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
address
+=
sizeof
(
to_write
);
ptr
+=
sizeof
(
to_write
);
n
+=
sizeof
(
to_write
);
}
}
user_regs_struct
Process
::
get_registers
()
{
user_regs_struct
registers
=
{
0
};
if
(
ptrace
(
PTRACE_GETREGS
,
pid_
,
nullptr
,
&
registers
)
==
-
1
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
return
registers
;
}
void
Process
::
set_registers
(
const
user_regs_struct
&
registers
)
{
if
(
ptrace
(
PTRACE_SETREGS
,
pid_
,
nullptr
,
&
registers
))
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
}
void
Process
::
continue_and_wait_for_trap
()
{
if
(
ptrace
(
PTRACE_CONT
,
pid_
,
nullptr
,
nullptr
)
==
-
1
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
int
status
;
wait
(
&
status
);
if
(
WSTOPSIG
(
status
)
!=
SIGTRAP
)
throw
std
::
runtime_error
(
std
::
strerror
(
errno
));
}
inject/process_old.h
deleted
100644 → 0
View file @
c630fe56
#ifndef LINUX_LIBRARY_INJECT_PROCESS_OLD_H
#define LINUX_LIBRARY_INJECT_PROCESS_OLD_H
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/user.h>
#include <string>
#include <utility>
#include <vector>
class
Process
final
{
public
:
explicit
Process
(
pid_t
pid
)
:
pid_
(
pid
)
{}
std
::
pair
<
std
::
string
,
std
::
size_t
>
find_libc
();
std
::
size_t
get_entry_point
();
void
call_shellcode
(
std
::
vector
<
unsigned
char
>
shellcode
);
private
:
pid_t
pid_
;
std
::
size_t
get_base
();
std
::
string
get_execute
();
void
attach
();
void
detach
();
std
::
vector
<
unsigned
char
>
read_memory
(
std
::
size_t
address
,
std
::
size_t
size
);
void
write_memory
(
std
::
size_t
address
,
std
::
vector
<
unsigned
char
>
data
);
user_regs_struct
get_registers
();
void
set_registers
(
const
user_regs_struct
&
registers
);
void
continue_and_wait_for_trap
();
};
#endif // LINUX_LIBRARY_INJECT_PROCESS_OLD_H
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