frida / frida-core

Frida core library intended for static linking into bindings
https://frida.re
Other
618 stars 198 forks source link

Bug in the detect_linker_flavor Function #528

Open AmesianX opened 6 months ago

AmesianX commented 6 months ago

I built a binary for Frida from the source code, but I wasted a lot of time because of some ridiculous bugs. For most people who try to build Frida natively in a Windows environment, the build process will be almost impossible.

The reason why developers maintaining Frida's source code did not notice this bug was likely because the build was cached. Developers who modified the source code probably did so after several builds. If you generate incorrect code after one or more successful builds, your changes will not be reflected due to cache issues.

Developers should take this into account when modifying the build scripts. To check if I had written the code incorrectly, I confirmed that it was not applied even after using the "ninja -t clean" command to clear the cache.

When modifying the build scripts, you must retrieve the source code from scratch and then test it. This ensures that no cached builds interfere with the changes and that the build process works correctly for everyone.

I opened an x64 build environment console window for msbuild to build in a 64-bit environment, but it is not being applied. It is being recognized as x86, and parsing is not working properly.

If the user reading this post is not an English speaker, they should enter the command "chcp 65001" before starting the build.

C:\frida\frida-core\build>ninja -j4
[20/124] Generating compat/arch-support with a custom command
FAILED: compat/arch-support.bundle compat/frida-helper.exe compat/frida-agent.dll compat/frida-gadget.dll
"C:\Python311\python.exe" "../compat/build.py" "compile" "compat/arch-support.bundle.p" "gASVHgMAAAAAAACMCF9fbWFpbl9flIwFU3RhdGWUk5QpgZR9lCiMBHJvbGWUjAdwcm9qZWN0lIwIYnVpbGRkaXKUjAdwYXRobGlilIwLV2luZG93c1BhdGiUk5QojANDOlyUjAVmcmlkYZSMCmZyaWRhLWNvcmWUjAVidWlsZJSMBmNvbXBhdJR0lFKUjAx0b3BfYnVpbGRkaXKUaAoojANDOlyUaAxoDWgOdJRSlIwNZnJpZGFfdmVyc2lvbpSMBjE2LjIuNZSMB2hvc3Rfb3OUjAd3aW5kb3dzlIwLaG9zdF9jb25maWeUjAJtdJSMEWFsbG93ZWRfcHJlYnVpbGRzlI+UKIwIc2RrOmhvc3SUjAl0b29sY2hhaW6UjAlzZGs6YnVpbGSUkIwHb3V0cHV0c5SMC2NvbGxlY3Rpb25zlIwLT3JkZXJlZERpY3SUk5QpUpQoaACMC091dHB1dEdyb3VwlJOUKYGUfZQojARhcmNolE6MB3RyaXBsZXSUTowNZXh0cmFfZW52aXJvbpR9lHViXZRoAIwGT3V0cHV0lJOUKYGUfZQojAppZGVudGlmaWVylIwTYXJjaF9zdXBwb3J0X2J1bmRsZZSMBG5hbWWUjBNhcmNoLXN1cHBvcnQuYnVuZGxllIwEZmlsZZRoCmgPhZRSlIwGdGFyZ2V0lIwAlHViYWgnKYGUfZQoaCqMA3g4NpRoK05oLH2UdWJdlChoMCmBlH2UKGgzjA1oZWxwZXJfbGVnYWN5lGg1jBBmcmlkYS1oZWxwZXIuZXhllGg3aAqMA3NyY5RoRIaUUpRoOowMZnJpZGEtaGVscGVylHViaDApgZR9lChoM4wMYWdlbnRfbGVnYWN5lGg1jA9mcmlkYS1hZ2VudC5kbGyUaDdoCowDbGlilIwFYWdlbnSUaEyHlFKUaDqMC2ZyaWRhLWFnZW50lHViaDApgZR9lChoM4wNZ2FkZ2V0X2xlZ2FjeZRoNYwQZnJpZGEtZ2FkZ2V0LmRsbJRoN2gKaE2MBmdhZGdldJRoVYeUUpRoOowMZnJpZGEtZ2FkZ2V0lHViZXV1Yi4="
[+] ==========>>> Detected compiler path: ['C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.39.33519\\bin\\Hostx86\\x86\\cl.exe']
[+] -------------> ['C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.39.33519\\bin\\Hostx86\\x86\\cl.exe']
[+] -------------> x86 Microsoft (R) C/C++ ȭ Ϸ  19.39.33523
Copyright (c) Microsoft Corporation. All rights reserved.

cl :  error D8021 : '/Wl,--version'  μ ߸Ǿ��ϴ.

Traceback (most recent call last):
  File "C:\frida\frida-core\compat\build.py", line 621, in <module>
    main(sys.argv)
  File "C:\frida\frida-core\compat\build.py", line 65, in main
    args.func(args)
  File "C:\frida\frida-core\compat\build.py", line 60, in <lambda>
    command.set_defaults(func=lambda args: compile(args.privdir, pickle.loads(base64.b64decode(args.state))))
                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\frida\frida-core\compat\build.py", line 398, in compile
    configure(sourcedir=REPO_ROOT,
  File "C:\frida\frida-core\releng\meson_configure.py", line 203, in configure
    env.generate_machine_configs(build_machine,
  File "C:\frida\frida-core\releng\env.py", line 81, in generate_machine_configs
    generate_machine_config(build_machine,
  File "C:\frida\frida-core\releng\env.py", line 145, in generate_machine_config
    impl.init_machine_config(machine,
  File "C:\frida\frida-core\releng\env_generic.py", line 167, in init_machine_config
    linker_flavor = detect_linker_flavor(cc)
                    ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\frida\frida-core\releng\env_generic.py", line 277, in detect_linker_flavor
    raise LinkerDetectionError(f"unknown linker: '{excerpt}'")
releng.env_generic.LinkerDetectionError: unknown linker: 'x86 Microsoft (R) C/C++ ȭ Ϸ  19.39.33523'
[22/124] Copying file tests/labrats/simple-agent-windows-x86_64.dll
ninja: build stopped: interrupted by user.

source code : frida-core\releng\env_generic.py


if cc is None:
        if machine.os == "windows":
            detect_tool_path = lambda name: winenv.detect_msvs_tool_path(machine, build_machine, name, toolchain_prefix)

            cc = [str(detect_tool_path("cl.exe"))]          
            lib = [str(detect_tool_path("lib.exe"))]
            link = [str(detect_tool_path("link.exe"))]
            assembler_name = MSVC_ASSEMBLER_NAMES[machine.arch]
            assembler_tool = [str(detect_tool_path(assembler_name + ".exe"))]

            raw_cc = strv_to_meson(cc) + " + common_flags"
            binaries["c"] = raw_cc
            binaries["cpp"] = raw_cc
            binaries["lib"] = strv_to_meson(lib) + " + common_flags"
            binaries["link"] = strv_to_meson(link) + " + common_flags"
            binaries[assembler_name] = strv_to_meson(assembler_tool) + " + common_flags"

            runtime_dirs = winenv.detect_msvs_runtime_path(machine, build_machine, toolchain_prefix)
            outpath.extend(runtime_dirs)

            vs_dir = winenv.detect_msvs_installation_dir(toolchain_prefix)
            outenv["VSINSTALLDIR"] = str(vs_dir) + "\\"
            outenv["VCINSTALLDIR"] = str(vs_dir / "VC") + "\\"
            outenv["Platform"] = machine.msvc_platform
            outenv["INCLUDE"] = ";".join([str(path) for path in winenv.detect_msvs_include_path(toolchain_prefix)])
            outenv["LIB"] = ";".join([str(path) for path in winenv.detect_msvs_library_path(machine, toolchain_prefix)])
        elif machine != build_machine \
                and "CC" not in environ \
                and "CFLAGS" not in environ \
                and machine.os == build_machine.os \
                and machine.os == "linux" \
                and machine.pointer_size == 4 \
                and build_machine.pointer_size == 8:
            try:
                cc, gcc_binaries = resolve_gcc_binaries()
                binaries.update(gcc_binaries)
                common_flags += ["-m32"]
            except CompilerNotFoundError:
                pass

    print(f"[+] ==========>>> Detected compiler path: {cc}") 

    if cc is None:
        suffix = ":\n" + diagnostics if diagnostics is not None else ""
        raise CompilerNotFoundError("no C compiler found" + suffix)

    if "cpp" not in binaries:
        raise CompilerNotFoundError("no C++ compiler found")

source code : frida-core\releng\env_generic.py


def detect_linker_flavor(cc: list[str]) -> str:
    print(f"[+] -------------> {cc}")
    linker_version = subprocess.run(cc + ["-Wl,--version"],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT,
                                    encoding="utf-8").stdout
    if linker_version.startswith("Microsoft "):
        return "msvc"
    if "GNU ld " in linker_version:
        return "gnu-ld"
    if "GNU gold " in linker_version:
        return "gnu-gold"
    if linker_version.startswith("LLD "):
        return "lld"
    if linker_version.startswith("ld: "):
        return "apple"
    print(f"[+] -------------> {cc}")
    excerpt = linker_version.split("\n")[0].rstrip()
    raise LinkerDetectionError(f"unknown linker: '{excerpt}'")

I was able to build it temporarily by hard-coding it like this: (Additionally, when hardcoding, make sure to match the SDK version number to your version. Also, ensure that you are building in a way that matches your environment, such as building x64 on an x64 host.)

source code : frida-core\releng\env_generic.py

    if linker_flavor is None:
        linker = [f"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.39.33519\\bin\\Hostx64\\x64\\cl.exe"]
        linker_flavor = detect_linker_flavor(linker)
        # linker_flavor = detect_linker_flavor(cc)

P.S: FYI, using Pickle from a computer security perspective is a very poor coding practice.

s0nlxaftrsh0ck commented 1 month ago

Adding that I too am running into this issue on Ubuntu 22.04 despite me trying

./config --host=linux-X86_64

I get an error saying I don't have a C compiler but when I type gcc it is very much there

`/home/s0nlx/tools/frida/deps/sdk-linux-x86_64/share/vala/vapi']", '-Dbuild.vala_link_args=[]', '-Dfrida-python:build.c_std=none', '-Dfrida-tools:build.c_std=none', PosixPath('/home/s0nlx/tools/frida/build/subprojects/frida-core/compat/arch-support.bundle.p/x86')]' returned non-zero exit status 1. Output: The Meson build system Version: 1.4.99 Source dir: /home/s0nlx/tools/frida/subprojects/frida-core Build dir: /home/s0nlx/tools/frida/build/subprojects/frida-core/compat/arch-support.bundle.p/x86 Build type: cross build Program python3 found: YES (/usr/bin/python3) Project name: frida-core Project version: 16.5.3-dev.8 C compiler for the host machine: /usr/bin/cc -m32 -march=pentium4 (gcc 11.4.0 "cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0") C linker for the host machine: /usr/bin/cc -m32 -march=pentium4 ld.bfd 2.38
meson.build:1:0: ERROR: Compiler /usr/bin/c++ -m32 -march=pentium4 cannot compile programs.
A full log can be found at /home/s0nlx/tools/frida/build/subprojects/frida-core/compat/arch-support.bundle.p/x86/meson-logs/meson-log.txt

[122/302] Generating subprojects/frida...js/gumjs-runtime with a custom command ninja: build stopped: subcommand failed. Trying gcc on it's own... gcc gcc: fatal error: no input files compilation terminated.`