def msvs_tool_path(host, tool): if host == "windows-x86_64": return os.path.join(winenv.get_msvc_tool_dir(), "bin", "HostX86", "x64", tool) else: return os.path.join(winenv.get_msvc_tool_dir(), "bin", "HostX86", "x86", tool)
def generate_meson_env(arch: str, config: str, runtime: str) -> MesonEnv: prefix = get_prefix_path(arch, config, runtime) env_dir = get_tmp_path(arch, config, runtime) env_dir.mkdir(parents=True, exist_ok=True) vc_dir = Path(winenv.get_msvs_installation_dir()) / "VC" vc_install_dir = str(vc_dir) + "\\" msvc_platform = msvc_platform_from_arch(arch) msvc_dir = Path(winenv.get_msvc_tool_dir()) msvc_bin_dir = msvc_dir / "bin" / ( "Host" + msvc_platform_from_arch(build_arch)) / msvc_platform msvc_dll_dirs = [] if arch != build_arch: build_msvc_platform = msvc_platform_from_arch(build_arch) msvc_dll_dirs.append(msvc_dir / "bin" / ("Host" + build_msvc_platform) / build_msvc_platform) (winxp_sdk_dir, winxp_sdk_version) = winenv.get_winxp_sdk() winxp_sdk_dir = Path(winxp_sdk_dir) if arch == 'x86': winxp_bin_dir = winxp_sdk_dir / "Bin" winxp_lib_dir = winxp_sdk_dir / "Lib" else: winxp_bin_dir = winxp_sdk_dir / "Bin" / msvc_platform winxp_lib_dir = winxp_sdk_dir / "Lib" / msvc_platform clflags = "/D" + " /D".join([ "_USING_V110_SDK71_", "_UNICODE", "UNICODE", ]) platform_cflags = [] if arch == 'x86': platform_cflags += ["/arch:SSE2"] cflags = " ".join(platform_cflags) cxxflags = " ".join(platform_cflags + [ # Relax C++11 compliance for XP compatibility. "/Zc:threadSafeInit-", ]) (win10_sdk_dir, win10_sdk_version) = winenv.get_win10_sdk() win10_sdk_dir = Path(win10_sdk_dir) m4_path = BOOTSTRAP_TOOLCHAIN_DIR / "bin" / "m4.exe" bison_pkgdatadir = BOOTSTRAP_TOOLCHAIN_DIR / "share" / "bison" vala_flags = "--target-glib=" + detect_target_glib() exe_path = ";".join([ str(path) for path in [ prefix / "bin", env_dir, BOOTSTRAP_TOOLCHAIN_DIR / "bin", winxp_bin_dir, msvc_bin_dir, ] + msvc_dll_dirs ]) include_path = ";".join([ str(path) for path in [ msvc_dir / "include", msvc_dir / "atlmfc" / "include", vc_dir / "Auxiliary" / "VS" / "include", win10_sdk_dir / "Include" / win10_sdk_version / "ucrt", winxp_sdk_dir / "Include", ] ]) library_path = ";".join([ str(path) for path in [ msvc_dir / "lib" / msvc_platform, msvc_dir / "atlmfc" / "lib" / msvc_platform, vc_dir / "Auxiliary" / "VS" / "lib" / msvc_platform, win10_sdk_dir / "Lib" / win10_sdk_version / "ucrt" / msvc_platform, winxp_lib_dir, ] ]) env_path = env_dir / "env.bat" env_path.write_text("""@ECHO OFF set PATH={exe_path};%PATH% set INCLUDE={include_path} set LIB={library_path} set CL={clflags} set CFLAGS={cflags} set CXXFLAGS={cxxflags} set VCINSTALLDIR={vc_install_dir} set Platform={platform} set VALA={valac} set VALAFLAGS={vala_flags} set DEPOT_TOOLS_WIN_TOOLCHAIN=0 """.format( exe_path=exe_path, include_path=include_path, library_path=library_path, clflags=clflags, cflags=cflags, cxxflags=cxxflags, vc_install_dir=vc_install_dir, platform=msvc_platform, valac=detect_bootstrap_valac(), vala_flags=vala_flags, ), encoding='utf-8') rc_path = winxp_bin_dir / "rc.exe" rc_wrapper_path = env_dir / "rc.bat" rc_wrapper_path.write_text("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 "{rc_path}" {flags} %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(rc_path=rc_path, flags=clflags), encoding='utf-8') (env_dir / "meson.bat").write_text("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 py -3 "{meson_path}" %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(meson_path=MESON), encoding='utf-8') pkgconfig_path = BOOTSTRAP_TOOLCHAIN_DIR / "bin" / "pkg-config.exe" pkgconfig_lib_dir = prefix / "lib" / "pkgconfig" pkgconfig_wrapper_path = env_dir / "pkg-config.bat" pkgconfig_wrapper_path.write_text("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 SET PKG_CONFIG_PATH={pkgconfig_lib_dir} "{pkgconfig_path}" --static %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format( pkgconfig_path=pkgconfig_path, pkgconfig_lib_dir=pkgconfig_lib_dir, ), encoding='utf-8') flex_path = BOOTSTRAP_TOOLCHAIN_DIR / "bin" / "flex.exe" flex_wrapper_path = env_dir / "flex.py" (env_dir / "flex.bat").write_text("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 py -3 "{wrapper_path}" %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(wrapper_path=flex_wrapper_path), encoding='utf-8') flex_wrapper_path.write_text("""import subprocess import sys args = [arg.replace("/", "\\\\") for arg in sys.argv[1:]] sys.exit(subprocess.call([r"{flex_path}"] + args)) """.format(flex_path=flex_path), encoding='utf-8') bison_path = BOOTSTRAP_TOOLCHAIN_DIR / "bin" / "bison.exe" bison_wrapper_path = env_dir / "bison.py" (env_dir / "bison.bat").write_text("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 py -3 "{wrapper_path}" %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(wrapper_path=bison_wrapper_path), encoding='utf-8') bison_wrapper_path.write_text("""\ import os import subprocess import sys os.environ["BISON_PKGDATADIR"] = r"{bison_pkgdatadir}" os.environ["M4"] = r"{m4_path}" args = [arg.replace("/", "\\\\") for arg in sys.argv[1:]] sys.exit(subprocess.call([r"{bison_path}"] + args)) """.format(bison_path=bison_path, bison_pkgdatadir=bison_pkgdatadir, m4_path=m4_path), encoding='utf-8') shell_env = {} shell_env.update(os.environ) shell_env["PATH"] = exe_path + ";" + shell_env["PATH"] shell_env["INCLUDE"] = include_path shell_env["LIB"] = library_path shell_env["CL"] = clflags shell_env["CFLAGS"] = cflags shell_env["CXXFLAGS"] = cxxflags shell_env["VCINSTALLDIR"] = vc_install_dir shell_env["Platform"] = msvc_platform shell_env["VALAC"] = detect_bootstrap_valac() shell_env["VALAFLAGS"] = vala_flags return MesonEnv(env_dir, shell_env)
def generate_meson_env(platform, configuration, runtime): prefix = get_prefix_path(platform, configuration, runtime) env_dir = get_tmp_path(platform, configuration, runtime) if not os.path.exists(env_dir): os.makedirs(env_dir) vc_dir = os.path.join(winenv.get_msvs_installation_dir(), "VC") vc_install_dir = vc_dir + "\\" msvc_platform = platform_to_msvc(platform) msvc_dir = winenv.get_msvc_tool_dir() msvc_bin_dir = os.path.join(msvc_dir, "bin", "Host" + platform_to_msvc(build_platform), msvc_platform) msvc_dll_dirs = [] if platform != build_platform: build_msvc_platform = platform_to_msvc(build_platform) msvc_dll_dirs.append( os.path.join(msvc_dir, "bin", "Host" + build_msvc_platform, build_msvc_platform)) (winxp_sdk_dir, winxp_sdk_version) = winenv.get_winxp_sdk() if platform == 'x86': winxp_bin_dir = os.path.join(winxp_sdk_dir, "Bin") winxp_lib_dir = os.path.join(winxp_sdk_dir, "Lib") else: winxp_bin_dir = os.path.join(winxp_sdk_dir, "Bin", msvc_platform) winxp_lib_dir = os.path.join(winxp_sdk_dir, "Lib", msvc_platform) clflags = "/D" + " /D".join([ "_USING_V110_SDK71_", "_UNICODE", "UNICODE", ]) platform_cflags = [] if platform == 'x86': platform_cflags += ["/arch:SSE2"] cflags = " ".join(platform_cflags) cxxflags = " ".join(platform_cflags + [ # Relax C++11 compliance for XP compatibility. "/Zc:threadSafeInit-", ]) (win10_sdk_dir, win10_sdk_version) = winenv.get_win10_sdk() m4_path = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin", "m4.exe") bison_pkgdatadir = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "share", "bison") vala_flags = "--target-glib=" + VALA_TARGET_GLIB exe_path = ";".join([ os.path.join(prefix, "bin"), env_dir, os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin"), winxp_bin_dir, msvc_bin_dir, ] + msvc_dll_dirs) include_path = ";".join([ os.path.join(msvc_dir, "include"), os.path.join(msvc_dir, "atlmfc", "include"), os.path.join(vc_dir, "Auxiliary", "VS", "include"), os.path.join(win10_sdk_dir, "Include", win10_sdk_version, "ucrt"), os.path.join(winxp_sdk_dir, "Include"), ]) library_path = ";".join([ os.path.join(msvc_dir, "lib", msvc_platform), os.path.join(msvc_dir, "atlmfc", "lib", msvc_platform), os.path.join(vc_dir, "Auxiliary", "VS", "lib", msvc_platform), os.path.join(win10_sdk_dir, "Lib", win10_sdk_version, "ucrt", msvc_platform), winxp_lib_dir, ]) env_path = os.path.join(env_dir, "env.bat") with open(env_path, "w", encoding='utf-8') as f: f.write("""@ECHO OFF set PATH={exe_path};%PATH% set INCLUDE={include_path} set LIB={library_path} set CL={clflags} set CFLAGS={cflags} set CXXFLAGS={cxxflags} set VCINSTALLDIR={vc_install_dir} set Platform={platform} set VALA={valac} set VALAFLAGS={vala_flags} set DEPOT_TOOLS_WIN_TOOLCHAIN=0 """.format(exe_path=exe_path, include_path=include_path, library_path=library_path, clflags=clflags, cflags=cflags, cxxflags=cxxflags, vc_install_dir=vc_install_dir, platform=msvc_platform, valac=BOOTSTRAP_VALAC, vala_flags=vala_flags)) rc_path = os.path.join(winxp_bin_dir, "rc.exe") rc_wrapper_path = os.path.join(env_dir, "rc.bat") with open(rc_wrapper_path, "w", encoding='utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 "{rc_path}" {flags} %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(rc_path=rc_path, flags=clflags)) with open(os.path.join(env_dir, "meson.bat"), "w", encoding='utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 py -3 "{meson_path}" %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(meson_path=MESON)) pkgconfig_path = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin", "pkg-config.exe") pkgconfig_lib_dir = os.path.join(prefix, "lib", "pkgconfig") pkgconfig_wrapper_path = os.path.join(env_dir, "pkg-config.bat") with open(pkgconfig_wrapper_path, "w", encoding='utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 SET PKG_CONFIG_PATH={pkgconfig_lib_dir} "{pkgconfig_path}" --static %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(pkgconfig_path=pkgconfig_path, pkgconfig_lib_dir=pkgconfig_lib_dir)) flex_path = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin", "flex.exe") flex_wrapper_path = os.path.join(env_dir, "flex.py") with open(os.path.join(env_dir, "flex.bat"), "w", encoding='utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 py -3 "{wrapper_path}" %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(wrapper_path=flex_wrapper_path)) with open(flex_wrapper_path, "w", encoding='utf-8') as f: f.write("""import subprocess import sys args = [arg.replace("/", "\\\\") for arg in sys.argv[1:]] sys.exit(subprocess.call([r"{flex_path}"] + args)) """.format(flex_path=flex_path)) bison_path = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin", "bison.exe") bison_wrapper_path = os.path.join(env_dir, "bison.py") with open(os.path.join(env_dir, "bison.bat"), "w", encoding='utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 py -3 "{wrapper_path}" %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(wrapper_path=bison_wrapper_path)) with open(bison_wrapper_path, "w", encoding='utf-8') as f: f.write("""\ import os import subprocess import sys os.environ["BISON_PKGDATADIR"] = r"{bison_pkgdatadir}" os.environ["M4"] = r"{m4_path}" args = [arg.replace("/", "\\\\") for arg in sys.argv[1:]] sys.exit(subprocess.call([r"{bison_path}"] + args)) """.format(bison_path=bison_path, bison_pkgdatadir=bison_pkgdatadir, m4_path=m4_path)) shell_env = {} shell_env.update(os.environ) shell_env["PATH"] = exe_path + ";" + shell_env["PATH"] shell_env["INCLUDE"] = include_path shell_env["LIB"] = library_path shell_env["CL"] = clflags shell_env["CFLAGS"] = cflags shell_env["CXXFLAGS"] = cxxflags shell_env["VCINSTALLDIR"] = vc_install_dir shell_env["Platform"] = msvc_platform shell_env["VALAC"] = BOOTSTRAP_VALAC shell_env["VALAFLAGS"] = vala_flags return MesonEnv(env_dir, shell_env)
def generate_header(package, frida_root, host, kit, flavor, umbrella_header_path, thirdparty_symbol_mappings): if platform.system() == 'Windows': (win10_sdk_dir, win10_sdk_version) = winenv.get_win10_sdk() include_dirs = [ os.path.join(winenv.get_msvc_tool_dir(), "include"), os.path.join(win10_sdk_dir, "Include", win10_sdk_version, "ucrt"), os.path.join(frida_root, "build", "sdk-windows", msvs_arch_config(host), "lib", "glib-2.0", "include"), os.path.join(frida_root, "build", "sdk-windows", msvs_arch_config(host), "include", "glib-2.0"), os.path.join(frida_root, "build", "sdk-windows", msvs_arch_config(host), "include", "json-glib-1.0"), os.path.join(frida_root, "build", "sdk-windows", msvs_arch_config(host), "include", "capstone"), internal_include_path("gum", frida_root, host), os.path.join(frida_root, "frida-gum"), os.path.join(frida_root, "frida-gum", "bindings") ] includes = ["/I" + include_dir for include_dir in include_dirs] preprocessor = subprocess.Popen( [msvs_cl_exe(host), "/nologo", "/E", umbrella_header_path] + includes, cwd=msvs_runtime_path(host), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = preprocessor.communicate() if preprocessor.returncode != 0: raise Exception("Failed to spawn preprocessor: " + stderr.decode('utf-8')) lines = stdout.decode('utf-8').split('\n') mapping_prefix = "#line " header_refs = [ line[line.index("\"") + 1:line.rindex("\"")].replace("\\\\", "/") for line in lines if line.startswith(mapping_prefix) ] header_files = deduplicate(header_refs) frida_root_slashed = frida_root.replace("\\", "/") header_files = [ header_file for header_file in header_files if bool(re.match('^' + frida_root_slashed, header_file, re.I)) ] else: rc = env_rc(frida_root, host, flavor) header_dependencies = subprocess.check_output([ "(. \"{rc}\" && $CPP $CFLAGS -M $($PKG_CONFIG --cflags {package}) \"{header}\")" .format(rc=rc, package=package, header=umbrella_header_path) ], shell=True).decode( 'utf-8') header_lines = header_dependencies.strip().split("\n")[1:] header_files = [line.rstrip("\\").strip() for line in header_lines] header_files = [ header_file for header_file in header_files if header_file.startswith(frida_root) and "/ndk-" not in header_file[len(frida_root):] ] devkit_header_lines = [] umbrella_header = header_files[0] processed_header_files = set([umbrella_header]) ingest_header(umbrella_header, header_files, processed_header_files, devkit_header_lines) if kit == "frida-gumjs": inspector_server_header = os.path.join( os.path.dirname(umbrella_header_path), "guminspectorserver.h") ingest_header(inspector_server_header, header_files, processed_header_files, devkit_header_lines) if kit == "frida-core" and host.startswith("android-"): selinux_header = os.path.join(os.path.dirname(umbrella_header_path), "frida-selinux.h") ingest_header(selinux_header, header_files, processed_header_files, devkit_header_lines) devkit_header = u"".join(devkit_header_lines) if package.startswith("frida-gum"): config = """#ifndef GUM_STATIC # define GUM_STATIC #endif """ else: config = "" if platform.system() == 'Windows': deps = ["dnsapi", "iphlpapi", "psapi", "winmm", "ws2_32"] if package == "frida-core-1.0": deps.extend([ "advapi32", "crypt32", "gdi32", "kernel32", "ole32", "secur32", "shell32", "shlwapi", "user32" ]) deps.sort() frida_pragmas = "#pragma comment(lib, \"{}\")".format( compute_library_filename(kit)) dep_pragmas = "\n".join( ["#pragma comment(lib, \"{}.lib\")".format(dep) for dep in deps]) config += frida_pragmas + "\n\n" + dep_pragmas + "\n\n" if len(thirdparty_symbol_mappings) > 0: public_mappings = [] for original, renamed in extract_public_thirdparty_symbol_mappings( thirdparty_symbol_mappings): public_mappings.append((original, renamed)) if "define {0}".format( original) not in devkit_header and "define {0}".format( original) not in devkit_header: continue def fixup_macro(match): prefix = match.group(1) suffix = re.sub(r"\b{0}\b".format(original), renamed, match.group(2)) return "#undef {0}\n".format( original) + prefix + original + suffix devkit_header = re.sub( r"^([ \t]*#[ \t]*define[ \t]*){0}\b((.*\\\n)*.*)$".format( original), fixup_macro, devkit_header, flags=re.MULTILINE) config += "#ifndef __FRIDA_SYMBOL_MAPPINGS__\n" config += "#define __FRIDA_SYMBOL_MAPPINGS__\n\n" config += "\n".join([ "#define {0} {1}".format(original, renamed) for original, renamed in public_mappings ]) + "\n\n" config += "#endif\n\n" return (config + devkit_header).replace("\r\n", "\n")
def msvs_runtime_path(host): return os.path.join(winenv.get_msvc_tool_dir(), "bin", "HostX86", "x86")
def generate_meson_env(platform, configuration, runtime): prefix = get_prefix_path(platform, configuration, runtime) env_dir = get_tmp_path(platform, configuration, runtime) if not os.path.exists(env_dir): os.makedirs(env_dir) vc_dir = os.path.join(winenv.get_msvs_installation_dir(), "VC") vc_install_dir = vc_dir + "\\" msvc_platform = platform_to_msvc(platform) msvc_dir = winenv.get_msvc_tool_dir() msvc_bin_dir = os.path.join(msvc_dir, "bin", "Host" + platform_to_msvc(build_platform), msvc_platform) msvc_dll_dirs = [] if platform != build_platform: build_msvc_platform = platform_to_msvc(build_platform) msvc_dll_dirs.append(os.path.join(msvc_dir, "bin", "Host" + build_msvc_platform, build_msvc_platform)) (winxp_sdk_dir, winxp_sdk_version) = winenv.get_winxp_sdk() if platform == 'x86': winxp_bin_dir = os.path.join(winxp_sdk_dir, "Bin") winxp_lib_dir = os.path.join(winxp_sdk_dir, "Lib") else: winxp_bin_dir = os.path.join(winxp_sdk_dir, "Bin", msvc_platform) winxp_lib_dir = os.path.join(winxp_sdk_dir, "Lib", msvc_platform) clflags = "/D" + " /D".join([ "_USING_V110_SDK71_", "_UNICODE", "UNICODE", ]) platform_cflags = [] if platform == 'x86': platform_cflags += ["/arch:SSE2"] cflags = " ".join(platform_cflags) cxxflags = " ".join(platform_cflags + [ # Relax C++11 compliance for XP compatibility. "/Zc:threadSafeInit-", ]) (win10_sdk_dir, win10_sdk_version) = winenv.get_win10_sdk() m4_path = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin", "m4.exe") bison_pkgdatadir = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "share", "bison") vala_flags = "--target-glib=" + VALA_TARGET_GLIB exe_path = ";".join([ os.path.join(prefix, "bin"), env_dir, os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin"), winxp_bin_dir, msvc_bin_dir, ] + msvc_dll_dirs) include_path = ";".join([ os.path.join(msvc_dir, "include"), os.path.join(msvc_dir, "atlmfc", "include"), os.path.join(vc_dir, "Auxiliary", "VS", "include"), os.path.join(win10_sdk_dir, "Include", win10_sdk_version, "ucrt"), os.path.join(winxp_sdk_dir, "Include"), ]) library_path = ";".join([ os.path.join(msvc_dir, "lib", msvc_platform), os.path.join(msvc_dir, "atlmfc", "lib", msvc_platform), os.path.join(vc_dir, "Auxiliary", "VS", "lib", msvc_platform), os.path.join(win10_sdk_dir, "Lib", win10_sdk_version, "ucrt", msvc_platform), winxp_lib_dir, ]) env_path = os.path.join(env_dir, "env.bat") with codecs.open(env_path, "w", 'utf-8') as f: f.write("""@ECHO OFF set PATH={exe_path};%PATH% set INCLUDE={include_path} set LIB={library_path} set CL={clflags} set CFLAGS={cflags} set CXXFLAGS={cxxflags} set VCINSTALLDIR={vc_install_dir} set Platform={platform} set VALA={valac} set VALAFLAGS={vala_flags} set DEPOT_TOOLS_WIN_TOOLCHAIN=0 """.format( exe_path=exe_path, include_path=include_path, library_path=library_path, clflags=clflags, cflags=cflags, cxxflags=cxxflags, vc_install_dir=vc_install_dir, platform=msvc_platform, valac=BOOTSTRAP_VALAC, vala_flags=vala_flags )) rc_path = os.path.join(winxp_bin_dir, "rc.exe") rc_wrapper_path = os.path.join(env_dir, "rc.bat") with codecs.open(rc_wrapper_path, "w", 'utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 "{rc_path}" {flags} %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(rc_path=rc_path, flags=clflags)) with codecs.open(os.path.join(env_dir, "meson.bat"), "w", 'utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 py -3 "{meson_path}" %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(meson_path=MESON)) pkgconfig_path = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin", "pkg-config.exe") pkgconfig_lib_dir = os.path.join(prefix, "lib", "pkgconfig") pkgconfig_wrapper_path = os.path.join(env_dir, "pkg-config.bat") with codecs.open(pkgconfig_wrapper_path, "w", 'utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 SET PKG_CONFIG_PATH={pkgconfig_lib_dir} "{pkgconfig_path}" --static %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(pkgconfig_path=pkgconfig_path, pkgconfig_lib_dir=pkgconfig_lib_dir)) flex_path = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin", "flex.exe") flex_wrapper_path = os.path.join(env_dir, "flex.py") with codecs.open(os.path.join(env_dir, "flex.bat"), "w", 'utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 py -3 "{wrapper_path}" %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(wrapper_path=flex_wrapper_path)) with codecs.open(flex_wrapper_path, "w", 'utf-8') as f: f.write("""import subprocess import sys args = [arg.replace("/", "\\\\") for arg in sys.argv[1:]] sys.exit(subprocess.call([r"{flex_path}"] + args)) """.format(flex_path=flex_path)) bison_path = os.path.join(BOOTSTRAP_TOOLCHAIN_DIR, "bin", "bison.exe") bison_wrapper_path = os.path.join(env_dir, "bison.py") with codecs.open(os.path.join(env_dir, "bison.bat"), "w", 'utf-8') as f: f.write("""@ECHO OFF SETLOCAL EnableExtensions SET _res=0 py -3 "{wrapper_path}" %* || SET _res=1 ENDLOCAL & SET _res=%_res% EXIT /B %_res%""".format(wrapper_path=bison_wrapper_path)) with codecs.open(bison_wrapper_path, "w", 'utf-8') as f: f.write("""\ import os import subprocess import sys os.environ["BISON_PKGDATADIR"] = r"{bison_pkgdatadir}" os.environ["M4"] = r"{m4_path}" args = [arg.replace("/", "\\\\") for arg in sys.argv[1:]] sys.exit(subprocess.call([r"{bison_path}"] + args)) """.format( bison_path=bison_path, bison_pkgdatadir=bison_pkgdatadir, m4_path=m4_path )) shell_env = {} shell_env.update(os.environ) shell_env["PATH"] = exe_path + ";" + shell_env["PATH"] shell_env["INCLUDE"] = include_path shell_env["LIB"] = library_path shell_env["CL"] = clflags shell_env["CFLAGS"] = cflags shell_env["CXXFLAGS"] = cxxflags shell_env["VCINSTALLDIR"] = vc_install_dir shell_env["Platform"] = msvc_platform shell_env["VALAC"] = BOOTSTRAP_VALAC shell_env["VALAFLAGS"] = vala_flags return MesonEnv(env_dir, shell_env)
def generate_header(package, frida_root, host, kit, umbrella_header_path, thirdparty_symbol_mappings): if platform.system() == 'Windows': (win10_sdk_dir, win10_sdk_version) = winenv.get_win10_sdk() include_dirs = [ os.path.join(winenv.get_msvc_tool_dir(), "include"), os.path.join(win10_sdk_dir, "Include", win10_sdk_version, "ucrt"), os.path.join(frida_root, "build", "sdk-windows", msvs_arch_config(host), "lib", "glib-2.0", "include"), os.path.join(frida_root, "build", "sdk-windows", msvs_arch_config(host), "include", "glib-2.0"), os.path.join(frida_root, "build", "sdk-windows", msvs_arch_config(host), "include", "glib-2.0"), os.path.join(frida_root, "build", "sdk-windows", msvs_arch_config(host), "include", "json-glib-1.0"), os.path.join(frida_root, "capstone", "include", "capstone"), os.path.join(frida_root, "frida-gum"), os.path.join(frida_root, "frida-gum", "bindings") ] includes = ["/I" + include_dir for include_dir in include_dirs] preprocessor = subprocess.Popen( [msvs_cl_exe(host), "/nologo", "/E", umbrella_header_path] + includes, cwd=msvs_runtime_path(host), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = preprocessor.communicate() if preprocessor.returncode != 0: raise Exception("Failed to spawn preprocessor: " + stderr.decode('utf-8')) lines = stdout.decode('utf-8').split('\n') mapping_prefix = "#line " header_refs = [line[line.index("\"") + 1:line.rindex("\"")].replace("\\\\", "/") for line in lines if line.startswith(mapping_prefix)] header_files = deduplicate(header_refs) frida_root_slashed = frida_root.replace("\\", "/") header_files = [header_file for header_file in header_files if bool(re.match('^' + frida_root_slashed, header_file, re.I))] else: rc = env_rc(frida_root, host) header_dependencies = subprocess.check_output( ["(. \"{rc}\" && $CPP $CFLAGS -M $($PKG_CONFIG --cflags {package}) \"{header}\")".format(rc=rc, package=package, header=umbrella_header_path)], shell=True).decode('utf-8') header_lines = header_dependencies.strip().split("\n")[1:] header_files = [line.rstrip("\\").strip() for line in header_lines] header_files = [header_file for header_file in header_files if header_file.startswith(frida_root) and "/ndk-" not in header_file[len(frida_root):] ] devkit_header_lines = [] umbrella_header = header_files[0] processed_header_files = set([umbrella_header]) ingest_header(umbrella_header, header_files, processed_header_files, devkit_header_lines) if kit == "frida-gumjs": inspector_server_header = os.path.join(os.path.dirname(umbrella_header_path), "guminspectorserver.h") ingest_header(inspector_server_header, header_files, processed_header_files, devkit_header_lines) if kit == "frida-core" and host.startswith("android-"): selinux_header = os.path.join(os.path.dirname(umbrella_header_path), "frida-selinux.h") ingest_header(selinux_header, header_files, processed_header_files, devkit_header_lines) devkit_header = u"".join(devkit_header_lines) if package.startswith("frida-gum"): config = """#ifndef GUM_STATIC # define GUM_STATIC #endif """ else: config = "" if platform.system() == 'Windows': deps = ["dnsapi", "iphlpapi", "psapi", "winmm", "ws2_32"] if package == "frida-core-1.0": deps.extend(["advapi32", "gdi32", "kernel32", "ole32", "shell32", "shlwapi", "user32"]) deps.sort() frida_pragmas = "#pragma comment(lib, \"{}\")".format(compute_library_filename(kit)) dep_pragmas = "\n".join(["#pragma comment(lib, \"{}.lib\")".format(dep) for dep in deps]) config += frida_pragmas + "\n\n" + dep_pragmas + "\n\n" if len(thirdparty_symbol_mappings) > 0: public_mappings = [] for original, renamed in extract_public_thirdparty_symbol_mappings(thirdparty_symbol_mappings): public_mappings.append((original, renamed)) if not "define {0}".format(original) in devkit_header: continue def fixup_macro(match): prefix = match.group(1) suffix = re.sub(r"\b{0}\b".format(original), renamed, match.group(2)) return "#undef {0}\n".format(original) + prefix + original + suffix devkit_header = re.sub(r"^([ \t]*#[ \t]*define[ \t]*){0}\b((.*\\\n)*.*)$".format(original), fixup_macro, devkit_header, flags=re.MULTILINE) config += "#ifndef __FRIDA_SYMBOL_MAPPINGS__\n" config += "#define __FRIDA_SYMBOL_MAPPINGS__\n\n" config += "\n".join(["#define {0} {1}".format(original, renamed) for original, renamed in public_mappings]) + "\n\n" config += "#endif\n\n" return (config + devkit_header).replace("\r\n", "\n")