Foreword
Not long ago, in order to get the OpenRASP for linux aarch64 version, the most critical thing in the middle is Chromium’s open source v8 engine (commonly known as libv8), which is introduced in the form of a static library (libv8_monolith.a). The official precompiled version is 7.8.279.19
, relatively old. I tried to compile this version from V8 official source code, but it always ran OOM (I don’t know if it was a problem with the compilation environment), so I gave up with tears~~~
The following is the error message during the process:
mvn install
gdb ../build64/java/libopenrasp_v8_java.so core.xxxxx # xxxxx is the process number of coredump
Later, after repeated attempts (the articles on the Internet were really short, but in the end they all pointed to failure, asking for help with GPT was basically nonsense, which made me take many detours), I found the 8.6.395.17
version. hello-world can run normally, so the follow-up work of OpenRASP update will be carried out based on this version.
This article will talk about the three methods of obtaining the libv8_monolith.a static library that I have explored in the past three weeks for readers’ reference.
Method 1: Use Libv8 official code
- Advantages: Native code, clean; the generated library is small in size and easy to configure parameters.
- Disadvantages: It requires a ladder to access, the tool chain is huge, and the compilation environment is very slow to set up.
- Reference: https://github.com/tanjelly/openrasp-v8/blob/master/vendors/build-libv8.sh
PS: I didn’t know there was this script in the project at first, so I took a lot of detours! ! !
Installing the system
- Ubuntu22.04 X86_64
Install necessary components
sed -i 's#/archive.ubuntu.com#/mirrors.ustc.edu.cn#g' /etc/apt/sources.list sed -i 's#/security.ubuntu.com#/mirrors.ustc.edu.cn#g' /etc/apt/sources.list apt-get update apt-get upgrade apt-get install vim git python2 python3 python3-pip ninja-build clang-14 apt-get install pkg-config libglib2.0-dev ln -s /usr/bin/python2 /usr/bin/python export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/share/pkgconfig:/usr/lib/$(uname -p)-linux-gnu/pkgconfig
Pull and compile libv8 related code
cd /opt/ # Pull compilation tools git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git export PATH=/opt/depot_tools:$PATH # Initialize the compilation environment (if there is an error, it needs to be handled according to the error) python3 /opt/depot_tools/gclient.py # Pull v8 code fetch v8 # Pull related dependencies (long wait...) cd v8 git checkout 8.6.395.17 gclient sync -v # Or execute python3 /opt/depot_tools/gclient.py sync -v
Install aarch64 compilation environment
cd /opt/v8/ python build/linux/sysroot_scripts/install-sysroot.py --arch=arm64
Build
cd /opt/v8/ # Build configuration mkdir -p out/arm64.release cat > out/arm64.release/args.gn <<EOF is_debug = false target_cpu = "arm64" symbol_level = 0 is_component_build = false treat_warnings_as_errors = false use_custom_libcxx = false libcxx_abi_unstable = false v8_embedder_string = " <OpenRASP>" v8_monolithic = true v8_enable_i18n_support = false v8_use_snapshot = true v8_use_external_startup_data = false v8_enable_shared_ro_heap = true EOF # Generate build-related files (the libcxx_abi_unstable problem may be prompted during the process, ignore it directly) gn gen out/arm64.release # Build (16 is the number of CPUs) /usr/bin/ninja -C out/arm64.release -j 16 v8_monolith #The final generated library file (size is about 40M) out/arm64.release/obj/libv8_monolith.a
The generation method of other versions of libv8_monolith.a is basically the same as the aarch64 version. You only need to modify the target_cpu
parameter in the args.gn
file to x64
(compilation is successful) ) or x86
(cross compilation failed, you may need to compile in the i386 system environment).
Method 2: Use Nodejs official code
- Advantages: You can use the system’s default compilation environment, saving a lot of time in pulling the tool chain.
- Disadvantages: It is not easy to customize. I have not thoroughly studied how to adjust parameters. The final generated file is also larger than [Method 1] (about 70M +)
- Reference: https://github.com/rubyjs/libv8-node/blob/master/libexec/build-libv8
Install and start the system
- CentOS 7.9 Aarch64
Install necessary components
yum update -y yum -y install cmake git wget vim python2 centos-release-scl yum makecache
Install compilation tools
yum -y install devtoolset-10 scl enable devtoolset-10 bash
Pull Nodejs code
wget https://nodejs.org/dist/v15.14.0/node-v15.14.0.tar.gz tar -xf node-v15.14.0.tar.xz
Compile Nodejs
cd node-v15.10.0/ CPUS=`cat /proc/cpuinfo | grep processor | wc -l` #Configuration ./configure --openssl-no-asm --without-npm --shared --without-intl --without-siphash sed -i "56i \ 'v8_embedder_string': ' <OpenRASP>'," config.gypi # compile make -j$CPUS
Packaging libv8_monolith.a
First create a script build-monolith.sh containing the following content in the nodejs source code root directory (refer to the node-v8-monolith project)
#!/bin/sh BASEDIR=$(pwd) BUILDTYPE=${BUILDTYPE:-Release} cd out/${BUILDTYPE}/obj.target if [ "$(uname)" = "SunOS" ]; then /usr/xpg4/bin/find . -path "**/*v8*/**/*.o" | xargs ar cqs libv8_monolith.a /usr/xpg4/bin/find . -path "**/*icu*/**/*.o" | xargs ar cqs libv8_monolith.a elif [ "$(uname)" = "Linux" ]; then for lib in `find . -path './tools/v8_gypfiles/*.a'`; do ar -t $lib | xargs ar -q libv8_monolith.a; done; for lib in `find . -path './tools/icu/*.a'`; do ar -t $lib | xargs ar -q libv8_monolith.a; done; else echo "Unsupported Platform" exit fi mv libv8_monolith.a $BASEDIR/out/${BUILDTYPE}
Then execute the script to generate the file:
bash ./build-monolith.sh # Generated library file location out/Release/libv8_monolith.a
Method 3: Use libv8-node precompiled library
- Advantages: This method is the most trouble-free and saves a lot of time fussing with the libv8 library.
- Disadvantages: The file is a bit large and cannot be customized.
Download libv8-node
# I originally wanted to find a version consistent with method 2, but found that it was not officially provided. wget https://rubygems.org/downloads/libv8-node-15.14.0.1-aarch64-linux.gem
Use 7zip to extract the following files from the downloaded package:
data.tar.gz/data.tar/vendor/v8/include data.tar.gz/data.tar/vendor/v8/out.gn/libv8/obj/libv8_monolith.a
Summary
From a comprehensive comparison, it is better to use [Method 1] if conditions permit among the three methods. If you want to save time, [Method 3] is a good choice. [Method 2] Suitable for students who have a certain foundation in parameter adjustment.
Reference
1: https://github.com/sqreen/node-v8-monolith
2: https://github.com/tanjelly/openrasp-v8
3: https://v8.dev/docs/compile-arm64
4: https://rubygems.org/gems/libv8-node/versions/15.14.0.1-aarch64-linux
5: https://nodejs.org/