import
lief
def
read_sleb128(content, offset):
value
=
0
len
=
0
shift
=
0
while
1
:
a_byte
=
content[offset]
offset
+
=
1
value
+
=
(a_byte &
0x7f
) << shift
shift
+
=
7
len
+
=
1
if
a_byte <
128
:
break
return
(value,
len
)
def
encode_leb128(value):
if
value
=
=
0
:
return
[
0
]
ret
=
[]
while
value !
=
0
:
a_byte
=
value &
0x7F
value >>
=
7
if
value >
0
:
a_byte |
=
0x80
ret.append(a_byte)
return
ret
def
add_library_for_androidso(target_path, libname):
output_path
=
target_path
+
".injected.so"
sofile
=
lief.parse(target_path)
if
sofile.
type
=
=
sofile.
type
.CLASS32:
addr_size
=
4
else
:
addr_size
=
8
sofile.add_library(libname)
sofile.write(output_path)
seg_relr
=
sofile.get_section(
".relr.dyn"
)
seg_relro
=
sofile.get_section(
".data.rel.ro"
)
sofile.patch_address(seg_relr.virtual_address, seg_relro.virtual_address, addr_size)
sofile.patch_address(seg_relro.virtual_address, seg_relro.virtual_address, addr_size)
seg_got
=
sofile.get_section(
".got"
)
seg_rel
=
None
if
sofile.
type
=
=
sofile.
type
.CLASS32:
seg_rel
=
sofile.get_section(
".rel.dyn"
)
else
:
seg_rel
=
sofile.get_section(
".rela.dyn"
)
content
=
seg_rel.content
current_pos
=
4
for
i
in
range
(
4
):
tmp_value,
len
=
read_sleb128(content, current_pos)
current_pos
+
=
len
encoded_gotaddr
=
encode_leb128(seg_got.virtual_address)
sofile.patch_address(seg_rel.virtual_address
+
current_pos, encoded_gotaddr)
for
e
in
sofile.dynamic_entries:
if
e.tag.value
=
=
0x6000000f
:
e.value
=
seg_rel.virtual_address
elif
e.tag.value
=
=
0x24
:
e.value
=
seg_relr.virtual_address
elif
e.tag.value
=
=
0x60000011
:
e.value
=
seg_rel.virtual_address
sofile.write(output_path)