加密SO文件中自定义的section
前言
加密已知so文件中的某一section,在运行时解密。执行里面的代码!
0×1
libsyc.so里有一个.textsection,里面有一个方法返回一个字符串!
生成未加密的libsyc.so的代码:
然后java代码中调用returnString这个方法
System.out.println(returnString());
生成libsyc.so
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
//SO---------------加密----------------------
#include <sys/types.h>
#include <elf.h>
#include <sys/mman.h>
//注意上面说解密算法里面的断.mytext就是这里,
//这里把getKey进行了加密,这样对方拿不到你的密钥都没法破解你的dll了
int
getKey
(
)
__attribute__
(
(
section
(
".mytext"
)
)
)
;
int
getKey
(
)
{
return
2048
;
}
;
//这里就是.so初始化的时候,这里进行mytext断的解密工作
void
init_getKey
(
)
__attribute__
(
(
constructor
)
)
;
unsigned
long
getLibAddr
(
)
;
void
init_getKey
(
)
{
char
name
[
15
]
;
unsigned
int
nblock
;
unsigned
int
nsize
;
unsigned
long
base
;
unsigned
long
text_addr
;
unsigned
int
i
;
Elf32_Ehdr *
ehdr
;
Elf32_Shdr *
shdr
;
base
=
getLibAddr
(
)
;
ehdr
=
(
Elf32_Ehdr *
)
base
;
text_addr
=
ehdr
->
e_shoff
+
base
;
nblock
=
ehdr
->
e_entry
>>
16
;
nsize
=
ehdr
->
e_entry
&
0xffff
;
g_message
(
"momo: nblock = %d\n"
,
nblock
)
;
if
(
mprotect
(
(
void
*
)
base
,
4096
*
nsize
,
PROT_READ
|
PROT_EXEC
|
PROT_WRITE
)
!=
0
)
{
g_message
(
"momo: mem privilege change failed"
)
;
}
//注意这里就是解密算法, 要和加密算法完全逆向才行不然就解不开了。
for
(
i
=
0
;
i
<
nblock
;
i
++
)
{
char
*
addr
=
(
char
*
)
(
text_addr
+
i
)
;
*
addr
=
~
(
*
addr
)
;
}
if
(
mprotect
(
(
void
*
)
base
,
4096
*
nsize
,
PROT_READ
|
PROT_EXEC
)
!=
0
)
{
g_message
(
"momo: mem privilege change failed"
)
;
}
g_message
(
"momo: Decrypt success"
)
;
}
unsigned
long
getLibAddr
(
)
{
unsigned
long
ret
=
0
;
char
name
[
]
=
"libmono.so"
;
char
buf
[
4096
]
,
*
temp
;
int
pid
;
FILE *
fp
;
pid
=
getpid
(
)
;
sprintf
(
buf
,
"/proc/%d/maps"
,
pid
)
;
fp
=
fopen
(
buf
,
"r"
)
;
if
(
fp
==
NULL
)
{
g_message
(
"momo: open failed"
)
;
goto
_error
;
}
while
(
fgets
(
buf
,
sizeof
(
buf
)
,
fp
)
)
{
if
(
strstr
(
buf
,
name
)
)
{
temp
=
strtok
(
buf
,
"-"
)
;
ret
=
strtoul
(
temp
,
NULL
,
16
)
;
break
;
}
}
_error
:
fclose
(
fp
)
;
return
ret
;
}
|
0×2
加密代码
加密的流程:
打开so文件,读取elf头部数据,根据e.shoff定位到section header
读取section header的数据,根据sh_offset定位到string table的位置
遍历string table,根据section的名称找到需要加密的section
找到之后,根据sh_offset和sh_size读取section里的数据到变量中
加密
加密之后的数据覆盖原位置的数据
编译
执行加密
结果:
0×3
加密前后对照
此section的数据已经被加密了!
0×4
在so文件初始化代码中添加解密函数,解密已经被加密的section
将init_getstring函数加入init_array段中~
生成包含解密代码的so。
0×5
用IDA打开上面生成的so文件
定位到init_array段可以看到
进入init_getString函数
0×6
到此,对so文件某一section的加密就结束了。
0×7
原文地址:http://bbs.pediy.com/showthread.php?t=191649
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
//SO---------------加密----------------------
#include <sys/types.h>
#include <elf.h>
#include <sys/mman.h>
//注意上面说解密算法里面的断.mytext就是这里,
//这里把getKey进行了加密,这样对方拿不到你的密钥都没法破解你的dll了
int
getKey
(
)
__attribute__
(
(
section
(
".mytext"
)
)
)
;
int
getKey
(
)
{
return
2048
;
}
;
//这里就是.so初始化的时候,这里进行mytext断的解密工作
void
init_getKey
(
)
__attribute__
(
(
constructor
)
)
;
unsigned
long
getLibAddr
(
)
;
void
init_getKey
(
)
{
char
name
[
15
]
;
unsigned
int
nblock
;
unsigned
int
nsize
;
unsigned
long
base
;
unsigned
long
text_addr
;
unsigned
int
i
;
Elf32_Ehdr *
ehdr
;
Elf32_Shdr *
shdr
;
base
=
getLibAddr
(
)
;
ehdr
=
(
Elf32_Ehdr *
)
base
;
text_addr
=
ehdr
->
e_shoff
+
base
;
nblock
=
ehdr
->
e_entry
>>
16
;
nsize
=
ehdr
->
e_entry
&
0xffff
;
g_message
(
"momo: nblock = %d\n"
,
nblock
)
;
if
(
mprotect
(
(
void
*
)
base
,
4096
*
nsize
,
PROT_READ
|
PROT_EXEC
|
PROT_WRITE
)
!=
0
)
{
g_message
(
"momo: mem privilege change failed"
)
;
}
//注意这里就是解密算法, 要和加密算法完全逆向才行不然就解不开了。
for
(
i
=
0
;
i
<
nblock
;
i
++
)
{
char
*
addr
=
(
char
*
)
(
text_addr
+
i
)
;
*
addr
=
~
(
*
addr
)
;
}
if
(
mprotect
(
(
void
*
)
base
,
4096
*
nsize
,
PROT_READ
|
PROT_EXEC
)
!=
0
)
{
g_message
(
"momo: mem privilege change failed"
)
;
}
g_message
(
"momo: Decrypt success"
)
;
}
unsigned
long
getLibAddr
(
)
{
unsigned
long
ret
=
0
;
char
name
[
]
=
"libmono.so"
;
char
buf
[
4096
]
,
*
temp
;
int
pid
;
FILE *
fp
;
pid
=
getpid
(
)
;
sprintf
(
buf
,
"/proc/%d/maps"
,
pid
)
;
fp
=
fopen
(
buf
,
"r"
)
;
if
(
fp
==
NULL
)
{
g_message
(
"momo: open failed"
)
;
goto
_error
;
}
while
(
fgets
(
buf
,
sizeof
(
buf
)
,
fp
)
)
{
if
(
strstr
(
buf
,
name
)
)
{
temp
=
strtok
(
buf
,
"-"
)
;
ret
=
strtoul
(
temp
,
NULL
,
16
)
;
break
;
}
}
_error
:
fclose
(
fp
)
;
return
ret
;
}
|