open-obfuscator / o-mvll

:electron: O-MVLL is a LLVM-based obfuscator for native code (Android & iOS)
https://obfuscator.re/omvll
Apache License 2.0
574 stars 62 forks source link

Prebuilt LLVM needs X86 MC backend for JIT execution #26

Open junknet opened 11 months ago

junknet commented 11 months ago

OS: Linux manjaro 6.1.38-1-MANJARO #1 SMP PREEMPT_DYNAMIC Wed Jul 5 23:49:30 UTC 2023 x86_64 GNU/Linux Dokcer build libOMVLL.so.

export OMVLL_CONFIG=/home/junknet/Desktop/test.py
export OMVLL_PYTHONPATH=/home/junknet/Downloads/Python-3.10.7/Lib 
cd  /home/junknet/Downloads/android-ndk-r25c-linux/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin
./aarch64-linux-android21-clang  -fpass-plugin=/home/junknet/Desktop/o-mvll/src/build_ndk_r25/libOMVLL.so /home/junknet/Desktop/kankanshili/src/qwe.cpp -o main

out: /home/junknet/Downloads/android-ndk-r25c-linux/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/clang-14 -S -emit-llvm -std=c++17 -o /tmp/omvll-x86_64-unknown-linux-gnu-b682cc.cpp.ll /tmp/omvll-x86_64-unknown-linux-gnu-b682cc.cpp /home/junknet/Downloads/android-ndk-r25c-linux/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/clang-14 -S -emit-llvm -target aarch64-unknown-linux-android21 -std=c++17 -o /tmp/omvll-aarch64-unknown-linux-android21-f4f132.cpp.ll /tmp/omvll-aarch64-unknown-linux-android21-f4f132.cpp No available targets are compatible with triple "x86_64-unknown-linux-gnu"

romainthomas commented 11 months ago

As mentioned in the documentation Currently, it only supports AArch64 but there is on-going work to support more architectures.

junknet commented 11 months ago

As mentioned in the documentation Currently, it only supports AArch64 but there is on-going work to support more architectures.

I don't quite understand what you mean, are you saying that my development platform also needs to be aarch64 architecture? I use the ./aarch64-linux-android21-clang compiler. Isn't the target platform aarch64?

romainthomas commented 11 months ago

I don't quite understand what you mean, are you saying that my development platform also needs to be aarch64 architecture?

Nop but look at your triple in /tmp/omvll-aarch64-unknown-linux-android21-f4f132.cpp.ll

junknet commented 11 months ago

I don't quite understand what you mean, are you saying that my development platform also needs to be aarch64 architecture?

Nop but look at your triple in /tmp/omvll-aarch64-unknown-linux-android21-f4f132.cpp.ll

cat omvll-aarch64-unknown-linux-android21-4b8419.cpp.ll

; ModuleID = '/tmp/omvll-aarch64-unknown-linux-android21-4b8419.cpp' source_filename = "/tmp/omvll-aarch64-unknown-linux-android21-4b8419.cpp" target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64-unknown-linux-android21"

; Function Attrs: mustprogress noinline nounwind optnone uwtable define dso_local void @encode(i8 noundef %0, i8 noundef %1, i64 noundef %2, i32 noundef %3) #0 { %5 = alloca i8, align 8 %6 = alloca i8, align 8 %7 = alloca i64, align 8 %8 = alloca i32, align 4 %9 = alloca i8, align 8 %10 = alloca i32, align 4 store i8 %0, i8 %5, align 8 store i8* %1, i8* %6, align 8 store i64 %2, i64 %7, align 8 store i32 %3, i32 %8, align 4 %11 = bitcast i64 %7 to i8 store i8 %11, i8 %9, align 8 store i32 0, i32* %10, align 4 br label %12

12: ; preds = %36, %4 %13 = load i32, i32 %10, align 4 %14 = load i32, i32 %8, align 4 %15 = icmp slt i32 %13, %14 br i1 %15, label %16, label %39

16: ; preds = %12 %17 = load i8*, i8 %6, align 8 %18 = load i32, i32 %10, align 4 %19 = sext i32 %18 to i64 %20 = getelementptr inbounds i8, i8 %17, i64 %19 %21 = load i8, i8 %20, align 1 %22 = zext i8 %21 to i32 %23 = load i8, i8 %9, align 8 %24 = load i32, i32 %10, align 4 %25 = sext i32 %24 to i64 %26 = urem i64 %25, 8 %27 = getelementptr inbounds i8, i8 %23, i64 %26 %28 = load i8, i8 %27, align 1 %29 = zext i8 %28 to i32 %30 = xor i32 %22, %29 %31 = trunc i32 %30 to i8 %32 = load i8, i8* %5, align 8 %33 = load i32, i32 %10, align 4 %34 = sext i32 %33 to i64 %35 = getelementptr inbounds i8, i8 %32, i64 %34 store i8 %31, i8 %35, align 1 br label %36

36: ; preds = %16 %37 = load i32, i32 %10, align 4 %38 = add nsw i32 %37, 1 store i32 %38, i32 %10, align 4 br label %12, !llvm.loop !10

39: ; preds = %12 ret void }

; Function Attrs: mustprogress noinline nounwind optnone uwtable define dso_local void @decode(i8 noundef %0, i8 noundef %1, i64 noundef %2, i32 noundef %3) #0 { %5 = alloca i8, align 8 %6 = alloca i8, align 8 %7 = alloca i64, align 8 %8 = alloca i32, align 4 %9 = alloca i8, align 8 %10 = alloca i32, align 4 store i8 %0, i8 %5, align 8 store i8* %1, i8* %6, align 8 store i64 %2, i64 %7, align 8 store i32 %3, i32 %8, align 4 %11 = bitcast i64 %7 to i8 store i8 %11, i8 %9, align 8 store i32 0, i32* %10, align 4 br label %12

12: ; preds = %36, %4 %13 = load i32, i32 %10, align 4 %14 = load i32, i32 %8, align 4 %15 = icmp slt i32 %13, %14 br i1 %15, label %16, label %39

16: ; preds = %12 %17 = load i8*, i8 %6, align 8 %18 = load i32, i32 %10, align 4 %19 = sext i32 %18 to i64 %20 = getelementptr inbounds i8, i8 %17, i64 %19 %21 = load i8, i8 %20, align 1 %22 = zext i8 %21 to i32 %23 = load i8, i8 %9, align 8 %24 = load i32, i32 %10, align 4 %25 = sext i32 %24 to i64 %26 = urem i64 %25, 8 %27 = getelementptr inbounds i8, i8 %23, i64 %26 %28 = load i8, i8 %27, align 1 %29 = zext i8 %28 to i32 %30 = xor i32 %22, %29 %31 = trunc i32 %30 to i8 %32 = load i8, i8* %5, align 8 %33 = load i32, i32 %10, align 4 %34 = sext i32 %33 to i64 %35 = getelementptr inbounds i8, i8 %32, i64 %34 store i8 %31, i8 %35, align 1 br label %36

36: ; preds = %16 %37 = load i32, i32 %10, align 4 %38 = add nsw i32 %37, 1 store i32 %38, i32 %10, align 4 br label %12, !llvm.loop !12

39: ; preds = %12 ret void }

attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fix-cortex-a53-835769,+neon,+outline-atomics,+v8a" }

!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8} !llvm.ident = !{!9}

!0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 8, !"branch-target-enforcement", i32 0} !2 = !{i32 8, !"sign-return-address", i32 0} !3 = !{i32 8, !"sign-return-address-all", i32 0} !4 = !{i32 8, !"sign-return-address-with-bkey", i32 0} !5 = !{i32 7, !"PIC Level", i32 2} !6 = !{i32 7, !"PIE Level", i32 2} !7 = !{i32 7, !"uwtable", i32 1} !8 = !{i32 7, !"frame-pointer", i32 1} !9 = !{!"Android (9352603, based on r450784d1) clang version 14.0.7 (https://android.googlesource.com/toolchain/llvm-project 4c603efb0cca074e9238af8b4106c30add4418f6)"} !10 = distinct !{!10, !11} !11 = !{!"llvm.loop.mustprogress"} !12 = distinct !{!12, !11}

junknet commented 11 months ago

It's only appears in string obfuscation.

weliveindetail commented 11 months ago

Yes, StringEncOpt.* has two parts:

That's why in the LLVM libraries we link against, we need the MC backend for the host platform. @junknet Do you have this issue with the prebuilt dependencies package from https://data.romainthomas.fr/omvll-deps-ndk-r25.tar ?

junknet commented 11 months ago

Yes, StringEncOpt.* has two parts:

* `decode()` is compiled for the target device and injected into the module

* `encode()` is compiled for the host machine and executed on-the-fly at compile-time of the module

That's why in the LLVM libraries we link against, we need the MC backend for the host platform. @junknet Do you have this issue with the prebuilt dependencies package from https://data.romainthomas.fr/omvll-deps-ndk-r25.tar ?

Yeah. I use the following command to build.


$ docker pull openobfuscator/omvll-ndk
$ git clone https://github.com/open-obfuscator/o-mvll.git

$ curl -LO https://data.romainthomas.fr/omvll-deps-ndk-r25.tar
$ mkdir -p ./third-party
$ tar xvf omvll-deps-ndk-r25.tar -C ./third-party
$ docker run --rm                           \
         -v $(pwd)/o-mvll:/o-mvll           \
         -v $(pwd)/third-party:/third-party \
         openobfuscator/omvll-ndk sh /o-mvll/scripts/docker/ndk_r25_compile.sh
weliveindetail commented 11 months ago

Interesting, looking at the script here suggests that the existing package has the X86 backend already: https://github.com/open-obfuscator/o-mvll/blob/main/scripts/docker/deps/compile_llvm_r25.sh#L1

Can you confirm that @romainthomas ? If so, this must be an issue with target registration in LLVM

romainthomas commented 11 months ago

Yes I confirm that pre-built LLVM has both architectures

antoniofrighetto commented 4 months ago

Hey @junknet, would you mind trying the latest release and see if it solves your issue?