【加壳脱壳-webassembly-1.使用ollvm和wasi-sdk混淆】此文章归类为:加壳脱壳。
标签: webassembly混淆
webassmebly作为新型平台越来越受到重视,其中WASM的混淆也尤为重要。本文介绍一种简单的混淆方法在ubuntu22.04下使用,并且使用wasi-sdk的类C库,混淆的WASM程序可以使用C库函数实现类似功能。
原始的ollvm版本已经年久失修,跟不上新版本的开发,如果使用会遇到很多bug,这里我采用一个修改版的ollvm,
github地址:[Pluto-Obfuscator][1]
下载:
git clone
下载好以后需要编译安装,
进入项目目录,直接执行
bash build.sh
就可以编译安装ollvm了(确保机器中有编译工具,cmake,ninja-build,g++等),这里build.sh我已经修改好了,编译安装以后的ollvm支持编译C代码到WASM。

在/Pluto-Obfuscator/build/bin文件夹下就是编译好的工具。
进入此目录,使用编译好的clang将C文件编译为wasm,以下是编译命令:
|
1
2
3
|
/
root
/
Pluto
-
Obfuscator
/
build
/
bin
/
clang \
-
-
target
=
wasm32
-
nostdlib
-
Wl,
-
-
no
-
entry\
-
Wl,
-
-
export
-
all
-
g
-
O0 loop.c
-
o loop.wasm
|
这个时候会出现以下错误:
|
1
2
|
clang
-
12
: error: unable to execute command: Executable
"wasm-ld"
doesn't exist!
clang
-
12
: error: linker command failed with exit code
1
(use
-
v to see invocation)
|
我们使用wasi-sdk中的clang编译此文件并且看看链接部分的命令是什么。
下载wasi-sdk:
|
1
2
|
wget https:
/
/
github.com
/
WebAssembly
/
wasi
-
sdk
/
releases
/
download
/
wasi
-
sdk
-
21
/
wasi
-
sdk
-
21.0
-
linux.tar.gz
tar
-
xzvf wasi
-
sdk
-
21.0
-
linux.tar.gz
|
loop.c内容如下:
|
1
2
3
4
5
6
7
8
9
10
|
int
main(){
int
n1
=
10
;
int
n2
=
20
;
if
(n1 >
0
){
for
(
int
i
=
0
; i < n2; i
+
+
){
n1
+
=
n2;
}
}
return
n1;
}
|
(其实函数名是不是main没有关系)
使用wasi-sdk中的clang和相同的命令编译loop.c,但是加上-v选项。
|
1
2
3
|
/
root
/
wasi
-
sdk
-
21.0
/
bin
/
clang
-
v \
-
-
target
=
wasm32
-
nostdlib
-
Wl,
-
-
no
-
entry\
-
Wl,
-
-
export
-
all
-
g
-
O0 loop.c
-
o loop.wasm
|
运行后得到如下输出:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
root@localhost:~
# /root/wasi-sdk-21.0/bin/clang -v --target=wasm32 -nostdlib -Wl,--no-entry -Wl,--export-all -g -O0 loop.c -o loop.wasm
clang version
17.0
.
6
Target: wasm32
Thread model: posix
InstalledDir:
/
root
/
wasi
-
sdk
-
21.0
/
bin
"/root/wasi-sdk-21.0/bin/clang-17"
-
cc1
-
triple wasm32
-
emit
-
obj
-
mrelax
-
all
-
dumpdir loop.wasm
-
-
disable
-
free
-
clear
-
ast
-
before
-
backend
-
disable
-
llvm
-
verifier
-
discard
-
value
-
names
-
main
-
file
-
name loop.c
-
mrelocation
-
model static
-
mframe
-
pointer
=
none
-
ffp
-
contract
=
on
-
fno
-
rounding
-
math
-
mconstructor
-
aliases
-
target
-
cpu generic
-
fvisibility
=
hidden
-
debug
-
info
-
kind
=
constructor
-
dwarf
-
version
=
4
-
debugger
-
tuning
=
gdb
-
v
-
fcoverage
-
compilation
-
dir
=
/
root
-
resource
-
dir
/
root
/
wasi
-
sdk
-
21.0
/
lib
/
clang
/
17
-
isysroot
/
root
/
wasi
-
sdk
-
21.0
/
bin
/
..
/
share
/
wasi
-
sysroot
-
internal
-
isystem
/
root
/
wasi
-
sdk
-
21.0
/
lib
/
clang
/
17
/
include
-
internal
-
isystem
/
root
/
wasi
-
sdk
-
21.0
/
bin
/
..
/
share
/
wasi
-
sysroot
/
include
-
O0
-
fdebug
-
compilation
-
dir
=
/
root
-
ferror
-
limit
19
-
fgnuc
-
version
=
4.2
.
1
-
fcolor
-
diagnostics
-
o
/
tmp
/
loop
-
34b990
.o
-
x c loop.c
clang
-
cc1 version
17.0
.
6
based upon LLVM
17.0
.
6
default target wasm32
-
wasi
#include "..." search starts here:
#include <...> search starts here:
/
root
/
wasi
-
sdk
-
21.0
/
lib
/
clang
/
17
/
include
/
root
/
wasi
-
sdk
-
21.0
/
bin
/
..
/
share
/
wasi
-
sysroot
/
include
End of search
list
.
"/root/wasi-sdk-21.0/bin/wasm-ld"
-
m wasm32
-
L
/
root
/
wasi
-
sdk
-
21.0
/
bin
/
..
/
share
/
wasi
-
sysroot
/
lib
-
-
no
-
entry
-
-
export
-
all
/
tmp
/
loop
-
34b990
.o
-
o loop.wasm
|
注意到这条命令就是链接命令:
|
1
|
"/root/wasi-sdk-21.0/bin/wasm-ld"
-
m wasm32
-
L
/
root
/
wasi
-
sdk
-
21.0
/
bin
/
..
/
share
/
wasi
-
sysroot
/
lib
-
-
no
-
entry
-
-
export
-
all
/
tmp
/
loop
-
34b990
.o
-
o loop.wasm
|
因为编译安装的clang中没有设置wasm-ld的地址,所以clang找不到链接器,一种办法是设置环境变量,一种办法是直接使用wasi-sdk中的链接器,有一些版本的clang可能会提示找不到wasm-ld-14,wasm-ld-13等等,考虑到这种情况设置环境变量可能不太好,直接独立使用sdk中的wasm-ld会更好。
所以我们修改一下链接命令得到如下:
|
1
|
"/root/wasi-sdk-21.0/bin/wasm-ld"
-
m wasm32
-
L
/
root
/
wasi
-
sdk
-
21.0
/
bin
/
..
/
share
/
wasi
-
sysroot
/
lib
-
-
no
-
entry
-
-
export
-
all
/
root
/
loop.o
-
o
/
root
/
loop.wasm
|
|
1
2
3
|
/
root
/
Pluto
-
Obfuscator
/
build
/
bin
/
clang \
-
-
target
=
wasm32
-
nostdlib
-
Wl,
-
-
no
-
entry\
-
Wl,
-
-
export
-
all
-
g
-
O0 loop.c
-
c
-
o loop.o
|
整合到一起就能编译loop.c到loop.wasm了。
使用runtime运行loop.wasm, 得不到任何结果,因为我们没有一些输出信息, 但是加入标准库以后clang会提示找不到c库。
|
1
2
|
root@localhost:~
/
wasmtime
-
v17.
0.1
-
x86_64
-
linux
# ./wasmtime /root/loop.wasm
root@localhost:~
/
wasmtime
-
v17.
0.1
-
x86_64
-
linux
#
|
在loop.c中加入打印代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <stdio.h>
int
main(){
printf(
"hello world\n"
);
int
n1
=
10
;
int
n2
=
20
;
if
(n1 >
0
){
for
(
int
i
=
0
; i < n2; i
+
+
){
n1
+
=
n2;
}
}
return
0
;
}
|
编译这个C文件需要指定C库的地址,使用wasi-sdk中的clang编译文件命令如下:
|
1
|
root@localhost:~
/
wasi
-
sdk
-
21.0
/
bin
# ./clang -O0 --target=wasm32-wasi --sysroot=/root/wasi-sdk-21.0/share/wasi-sysroot/ /root/loop.c -o /root/loop.wasm
|
同上我们使用-v选项查看整个链接过程,得到如下信息:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
root@localhost:~
/
wasi
-
sdk
-
21.0
/
bin
# ./clang -v -O0 --target=wasm32-wasi --sysroot=/root/wasi-sdk-21.0/share/wasi-sysroot/ /root/loop.c -o /root/loop.wasm
clang version
17.0
.
6
Target: wasm32
-
unknown
-
wasi
Thread model: posix
InstalledDir:
/
root
/
wasi
-
sdk
-
21.0
/
bin
/
.
"/root/wasi-sdk-21.0/bin/clang-17"
-
cc1
-
triple wasm32
-
unknown
-
wasi
-
emit
-
obj
-
mrelax
-
all
-
dumpdir
/
root
/
loop.wasm
-
-
disable
-
free
-
clear
-
ast
-
before
-
backend
-
disable
-
llvm
-
verifier
-
discard
-
value
-
names
-
main
-
file
-
name loop.c
-
mrelocation
-
model static
-
mframe
-
pointer
=
none
-
ffp
-
contract
=
on
-
fno
-
rounding
-
math
-
mconstructor
-
aliases
-
target
-
cpu generic
-
fvisibility
=
hidden
-
debugger
-
tuning
=
gdb
-
v
-
fcoverage
-
compilation
-
dir
=
/
root
/
wasi
-
sdk
-
21.0
/
bin
-
resource
-
dir
/
root
/
wasi
-
sdk
-
21.0
/
lib
/
clang
/
17
-
isysroot
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
-
internal
-
isystem
/
root
/
wasi
-
sdk
-
21.0
/
lib
/
clang
/
17
/
include
-
internal
-
isystem
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
/
include
/
wasm32
-
wasi
-
internal
-
isystem
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
/
include
-
fdebug
-
compilation
-
dir
=
/
root
/
wasi
-
sdk
-
21.0
/
bin
-
ferror
-
limit
19
-
fgnuc
-
version
=
4.2
.
1
-
fcolor
-
diagnostics
-
o
/
tmp
/
loop
-
c1b686.o
-
x c
/
root
/
loop.c
clang
-
cc1 version
17.0
.
6
based upon LLVM
17.0
.
6
default target wasm32
-
wasi
ignoring nonexistent directory
"/root/wasi-sdk-21.0/share/wasi-sysroot//include/wasm32-wasi"
#include "..." search starts here:
#include <...> search starts here:
/
root
/
wasi
-
sdk
-
21.0
/
lib
/
clang
/
17
/
include
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
/
include
End of search
list
.
"/root/wasi-sdk-21.0/bin/./wasm-ld"
-
m wasm32
-
L
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
/
lib
/
wasm32
-
wasi
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
/
lib
/
wasm32
-
wasi
/
crt1
-
command.o
/
tmp
/
loop
-
c1b686.o
-
lc
/
root
/
wasi
-
sdk
-
21.0
/
lib
/
clang
/
17
/
lib
/
wasi
/
libclang_rt.builtins
-
wasm32.a
-
o
/
root
/
loop.wasm
|
使用ollvm中的clang先将文件编译为。o文件,然后链接为wasm文件。
|
1
2
3
|
/
root
/
Pluto
-
Obfuscator
/
build
/
bin
/
clang
-
O0
-
-
target
=
wasm32
-
wasi
-
-
sysroot
=
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
loop.c
-
c
-
o loop.o
"/root/wasi-sdk-21.0/bin/./wasm-ld"
-
m wasm32
-
L
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
/
lib
/
wasm32
-
wasi
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
/
lib
/
wasm32
-
wasi
/
crt1
-
command.o
/
root
/
loop.o
-
lc
/
root
/
wasi
-
sdk
-
21.0
/
lib
/
clang
/
17
/
lib
/
wasi
/
libclang_rt.builtins
-
wasm32.a
-
o
/
root
/
loop.wasm
|
使用wasmtime运行如下:
|
1
2
|
root@localhost:~
/
wasmtime
-
v17.
0.1
-
x86_64
-
linux
# ./wasmtime /root/loop.wasm
hello world
|
这样我们就可以开启ollvm flattning混淆了,命令如下:
|
1
|
/
root
/
Pluto
-
Obfuscator
/
build
/
bin
/
clang
-
mllvm
-
fla
-
O0
-
-
target
=
wasm32
-
wasi
-
-
sysroot
=
/
root
/
wasi
-
sdk
-
21.0
/
share
/
wasi
-
sysroot
/
loop.c
-
c
-
o loop.o
|
混淆前的loop.wasm和混淆后的loop_fla.wasm在ghidra中对比效果:
loop.wasm(未混淆):

loop_fla.wasm(已混淆):

ollvm中有许多其他混淆选项也可以试试~
[1]:
更多【加壳脱壳-webassembly-1.使用ollvm和wasi-sdk混淆】相关视频教程:www.yxfzedu.com