Enable building libpng on CI without using GUI (#3110)

* Fixing windows ci build in justfile. harness.cc modified for cl.exe. Additions to README.

* More precise compiler check for noinline definition.

---------

Co-authored-by: dkoch <dkoch@vigilantsys.com>
This commit is contained in:
dkoch144 2025-03-26 17:16:06 -04:00 committed by GitHub
parent 58bb64fac4
commit f700aac911
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 77 additions and 8 deletions

View File

@ -25,8 +25,30 @@ harness: lib
clang++ -O3 harness.o libpng-1.6.37/.libs/libpng16.a -shared -lz -o libpng-harness.so clang++ -O3 harness.o libpng-1.6.37/.libs/libpng16.a -shared -lz -o libpng-harness.so
[windows] [windows]
harness: zlib:
cl /c harness_win.cpp && link harness_win.obj /dll powershell -Command Invoke-WebRequest -OutFile zlib-1.2.11.tar.gz https://zlib.net/fossils/zlib-1.2.11.tar.gz
tar -xvf zlib-1.2.11.tar.gz
del /q zlib-1.2.11.tar.gz
move zlib-1.2.11 zlib
[windows]
lib: zlib
cd zlib && cmake -A x64 -DCMAKE_CXX_COMPILER=cl . && cmake --build . --config Release
[windows]
libpng:
powershell -Command Invoke-WebRequest -OutFile libpng-1.6.37.tar.gz https://github.com/glennrp/libpng/archive/refs/tags/v1.6.37.tar.gz
tar -xvf libpng-1.6.37.tar.gz
del /q libpng-1.6.37.tar.gz
[windows]
lib2: libpng
cd libpng-1.6.37 && cmake -A x64 -DCMAKE_CXX_COMPILER=cl -DZLIB_ROOT=..\zlib -DZLIB_LIBRARY=..\zlib\Release\zlib.lib . && cmake --build . --config Release
[windows]
harness: lib lib2
copy libpng-1.6.37\Release\libpng16.lib . && copy libpng-1.6.37\Release\libpng16.dll . && copy zlib\Release\zlib.lib . && copy zlib\Release\zlib.dll . && copy target\release\frida_fuzzer.exe .
cl /O2 /c /I .\libpng-1.6.37 harness.cc /Fo:harness.obj && link /DLL /OUT:libpng-harness.dll harness.obj libpng16.lib zlib.lib
[unix] [unix]
[windows] [windows]
@ -39,7 +61,7 @@ run: build harness
[windows] [windows]
run: build harness run: build harness
{{TARGET_DIR}}\{{PROFILE}}\{{FUZZER_NAME_WIN}} -F LLVMFuzzerTestOneInput -H .\harness_win.dll -l .\harness_win.dll --cores=0 {{TARGET_DIR}}\{{PROFILE}}\{{FUZZER_NAME_WIN}} -F LLVMFuzzerTestOneInput -H .\libpng-harness.dll -l .\libpng-harness.dll -l .\zlib.dll -l .\libpng16.dll --cores=0
[unix] [unix]
test: build harness test: build harness
@ -57,7 +79,7 @@ test: build harness
[windows] [windows]
[script("cmd.exe", "/c")] [script("cmd.exe", "/c")]
test: build harness test: build harness
start "" "{{TARGET_DIR}}\{{PROFILE}}\{{FUZZER_NAME_WIN}}" -F LLVMFuzzerTestOneInput -H .\harness_win.dll -l .\harness_win.dll --cores=0 start "" "{{TARGET_DIR}}\{{PROFILE}}\{{FUZZER_NAME_WIN}}" -F LLVMFuzzerTestOneInput -H .\libpng-harness.dll -l .\libpng-harness.dll -l .\zlib.dll -l .\libpng16.dll --cores=0
ping -n 10 127.0.0.1>NUL && taskkill /im frida_fuzzer.exe /F ping -n 10 127.0.0.1>NUL && taskkill /im frida_fuzzer.exe /F
dir /a-d corpus_discovered && (echo Files exist) || (exit /b 1337) dir /a-d corpus_discovered && (echo Files exist) || (exit /b 1337)

View File

@ -63,3 +63,44 @@ clang++ -L.\zlib.dll .\harness.o .\libpng16.lib -lzlib -shared -o .\libpng-harne
./frida_fuzzer.exe ./libpng-harness.dll LLVMFuzzerTestOneInput ./libpng-harness.dll ./frida_fuzzer.exe ./libpng-harness.dll LLVMFuzzerTestOneInput ./libpng-harness.dll
``` ```
### To build it with visual studio for ci (no gui)
Assumes that the fuzzer is already built with `cargo build --release`
1. download and build zlib in this directory
```
powershell -Command Invoke-WebRequest -OutFile zlib-1.2.11.tar.gz https://zlib.net/fossils/zlib-1.2.11.tar.gz
tar -xvf zlib-1.2.11.tar.gz
del /q zlib-1.2.11.tar.gz
move zlib-1.2.11 zlib
cd zlib
cmake -A x64 -DCMAKE_CXX_COMPILER=cl .
cmake --build . --config Release
```
2. download and build libpng in this directory
```
powershell -Command Invoke-WebRequest -OutFile libpng-1.6.37.tar.gz https://github.com/glennrp/libpng/archive/refs/tags/v1.6.37.tar.gz
tar -xvf libpng-1.6.37.tar.gz
del /q libpng-1.6.37.tar.gz
cd libpng-1.6.37
cmake -A x64 -DCMAKE_CXX_COMPILER=cl -DZLIB_ROOT=..\zlib -DZLIB_LIBRARY=..\zlib\Release\zlib.lib .
cmake --build . --config Release
```
3. copy libraries from zlib and libpng and use to build harness
```
copy libpng-1.6.37\Release\libpng16.lib .
copy libpng-1.6.37\Release\libpng16.dll .
copy zlib\Release\zlib.lib .
copy zlib\Release\zlib.dll .
copy target\release\frida_fuzzer.exe .
cl /O2 /c /I .\libpng-1.6.37 harness.cc /Fo:harness.obj
link /DLL /OUT:libpng-harness.dll harness.obj libpng16.lib zlib.lib
```
4. start fuzzing
```
.\frida_fuzzer.exe -F LLVMFuzzerTestOneInput -H .\libpng-harness.dll -l .\libpng-harness.dll -l .\zlib.dll -l .\libpng16.dll --cores 0
```
OR
1. Run `just test`

View File

@ -85,7 +85,13 @@ extern "C" int afl_libfuzzer_init() {
static char *allocation = NULL; static char *allocation = NULL;
__attribute__((noinline)) void func3(char *alloc) { #ifdef _MSC_VER
#define NOINLINE __declspec(noinline)
#else
#define NOINLINE __attribute__((noinline))
#endif
NOINLINE void func3(char *alloc) {
// printf("func3\n"); // printf("func3\n");
#ifdef _WIN32 #ifdef _WIN32
if ((rand() % 2) == 0) { if ((rand() % 2) == 0) {
@ -99,12 +105,12 @@ __attribute__((noinline)) void func3(char *alloc) {
} }
#endif #endif
} }
__attribute__((noinline)) void func2() { NOINLINE void func2() {
allocation = (char *)malloc(0xff); allocation = (char *)malloc(0xff);
// printf("func2\n"); // printf("func2\n");
func3(allocation); func3(allocation);
} }
__attribute__((noinline)) void func1() { NOINLINE void func1() {
// printf("func1\n"); // printf("func1\n");
func2(); func2();
} }
@ -119,7 +125,7 @@ __attribute__((noinline)) void func1() {
// Entry point for LibFuzzer. // Entry point for LibFuzzer.
// Roughly follows the libpng book example: // Roughly follows the libpng book example:
// http://www.libpng.org/pub/png/book/chapter13.html // http://www.libpng.org/pub/png/book/chapter13.html
HARNESS_EXPORTS extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, extern "C" HARNESS_EXPORTS int LLVMFuzzerTestOneInput(const uint8_t *data,
size_t size) { size_t size) {
if (size >= 8 && *(uint64_t *)data == 0xABCDEFAA8F1324AA) { abort(); } if (size >= 8 && *(uint64_t *)data == 0xABCDEFAA8F1324AA) { abort(); }
if (size < kPngHeaderSize) { return 0; } if (size < kPngHeaderSize) { return 0; }