From 51a4aaa27d280bae24c8fbdeb056fb01a6d5e940 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 16 Jun 2024 08:51:04 +0100 Subject: win32: detect Actually Portable Executable binaries Check for the signature of Actually Portable Executable binaries and treat them as executable. Adds 40-64 bytes. (GitHub issue #424) --- win32/mingw.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/win32/mingw.c b/win32/mingw.c index f96b5b49a..26b046f1a 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -472,22 +472,30 @@ static int has_exec_format(const char *name) * Poke about in file to see if it's a PE binary. I've just copied * the magic from the file command. */ - if (buf[0] == 'M' && buf[1] == 'Z' && n > 0x3f) { - offset = (buf[0x19] << 8) + buf[0x18]; - if (offset > 0x3f) { - offset = (buf[0x3f] << 24) + (buf[0x3e] << 16) + - (buf[0x3d] << 8) + buf[0x3c]; - if (offset < sizeof(buf)-100) { - if (memcmp(buf+offset, "PE\0\0", 4) == 0) { - sig = (buf[offset+25] << 8) + buf[offset+24]; - if (sig == 0x10b || sig == 0x20b) { - sig = (buf[offset+23] << 8) + buf[offset+22]; - if ((sig & 0x2000) != 0) { - /* DLL */ - return 0; + if (buf[0] == 'M' && buf[1] == 'Z') { + /* Actually Portable Executable */ + /* See ape/ape.S at https://github.com/jart/cosmopolitan */ + if (n > 9 && memcmp(buf + 2, "qFpD='\n", 7) == 0) + return 1; + + if (n > 0x3f) { + offset = (buf[0x19] << 8) + buf[0x18]; + if (offset > 0x3f) { + offset = (buf[0x3f] << 24) + (buf[0x3e] << 16) + + (buf[0x3d] << 8) + buf[0x3c]; + if (offset < sizeof(buf)-100) { + if (memcmp(buf+offset, "PE\0\0", 4) == 0) { + sig = (buf[offset+25] << 8) + buf[offset+24]; + if (sig == 0x10b || sig == 0x20b) { + sig = (buf[offset+23] << 8) + buf[offset+22]; + if ((sig & 0x2000) != 0) { + /* DLL */ + return 0; + } + sig = buf[offset+92]; + return (sig == 1 || sig == 2 || sig == 3 + || sig == 7); } - sig = buf[offset+92]; - return (sig == 1 || sig == 2 || sig == 3 || sig == 7); } } } -- cgit v1.2.3-55-g6feb