Trick - 借助 zig cc 做交叉编译
2022-9-2 22:55:7 Author: 0x4d5a(查看原文) 阅读量:532 收藏

0. TL; DR

zig[1] 是一门新的底层语言,去年已经有安全人员公开用 zig 开发的攻防项目,大家应该都有所耳闻。

但很多人不知道的是,zig 还自带了一套完整的 cc / c++ 编译链,并且具备强大的交叉编译能力,可以无缝替代 gcc / clang。

zig cc 可以用来交叉编译原生 C / C++,或是依赖 cc 编译链的其它语言。

1. 举个例子

Golang 的一大特点是交叉编译,但一旦用到 CGO,交叉编译就会麻烦很多。以 HackBrowserData 举例,其解析浏览器本地数据存储时依赖 sqlite3,而 Golang 最流行的 sqlite3 库 go-sqlite3[2] 是一个典型的 CGO 项目。

> GOOS=windows GOARCH=amd64 CGO_ENABLED=1 go build# runtime/cgogcc_libinit_windows.c:8:10: fatal error: 'windows.h' file not found
> GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build# runtime/cgolinux_syscall.c:67:13: error: implicit declaration of function 'setresgid' is invalid in C99 [-Werror,-Wimplicit-function-declaration]linux_syscall.c:67:13: note: did you mean 'setregid'?/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:593:6: note: 'setregid' declared herelinux_syscall.c:73:13: error: implicit declaration of function 'setresuid' is invalid in C99 [-Werror,-Wimplicit-function-declaration]linux_syscall.c:73:13: note: did you mean 'setreuid'?/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:595:6: note: 'setreuid' declared here

因为 CGO 默认会用当前系统的 cc 编译链,所以这种情况的解决办法是安装对应架构的编译链,比如 MinGW:

> CC="x86_64-w64-mingw32-gcc" CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build
> file hack-browser-data.exehack-browser-data.exe: PE32+ executable (console) x86-64, for MS Windows

需要交叉编译到多少架构,就需要安装多少编译链。

2. zig cc

使用 zig cc 的话,只需要:

> CC="zig cc -target x86_64-linux-musl" CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build> file hack-browser-datahack-browser-data: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, Go BuildID=BAyS6mMhA1gWvDMsJucZ/Ezu43jyXvCI5lsSn4DrY/uwy290WsjU7IqN0A-Jhn/6Ubko4EhzpMvTPLH4NgH, with debug_info, not stripped
> CC="zig cc -target aarch64-linux-musl" CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build> file hack-browser-datahack-browser-data: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, Go BuildID=uhoy_ughFoJ1WKdpH5RQ/BxRyuA71TrSWu4TV56MJ/NRIUpm74LYrbhaGlltMr/LjXFS_iq2QS0Wbi-MCUj, with debug_info, not stripped
> CC="zig cc -target x86_64-windows" CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build> file hack-browser-data.exehack-browser-data.exe: PE32+ executable (console) x86-64, for MS Windows
> CC="zig cc -target i386-windows" CGO_ENABLED=1 GOOS=windows GOARCH=386 go build> file hack-browser-data.exehack-browser-data.exe: PE32 executable (console) Intel 80386, for MS Windows
> CC="zig cc -target aarch64-windows" CGO_ENABLED=1 GOOS=windows GOARCH=arm64 go build> file hack-browser-data.exehack-browser-data.exe: PE32+ executable (console) Aarch64, for MS Windows

相比安装多种架构的 cc 编译链,zig 只需要下载一个 45 MB 的单压缩文件,无需任何依赖和配置。

zig 编译器具体做了哪些工作可以阅读开发组的文章 zig cc: a Powerful Drop-In Replacement for GCC/Clang[3]

至于稳定性,zig cc 并不是从头做起,而是建立在 clang 之上的。并且 Uber 已经将 zig cc 用作编译 C/C++ 代码 How Uber Uses Zig[4],对于普遍规模较小的安全工具来说,基本不用担心稳定性的问题。

References

[1] zig: https://ziglang.org/
[2] go-sqlite3: https://github.com/mattn/go-sqlite3
[3] zig cc: a Powerful Drop-In Replacement for GCC/Clang: https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html
[4] How Uber Uses Zig: https://jakstys.lt/2022/how-uber-uses-zig/


文章来源: http://mp.weixin.qq.com/s?__biz=Mzg5MjU2NTc1Mg==&mid=2247483772&idx=1&sn=d11f71d313359f73391f568a06ec44af&chksm=c03d60ebf74ae9fd46c58bf3b2c32aa449c6c11dcc354c3dedf0d1dac337b514a907c5339183#rd
如有侵权请联系:admin#unsafe.sh