ld.exe: unrecognized option '-z' - gcc

I followed this Buffer Overflow Exploit tutorial and wrote a small application to compile with gcc in my mingw32.exe. However, when I did, I got the following errors:
Liu.D.H#DESKTOP-KA8TQF4 MINGW32 ~
$ gcc vuln.c -o vuln -fno-stack-protector -m32 -z execstack
C:/msys32/mingw32/bin/../lib/gcc/i686-w64-mingw32/7.3.0/../../../../i686-w64-mingw32/bin/ld.exe: unrecognized option '-z'
C:/msys32/mingw32/bin/../lib/gcc/i686-w64-mingw32/7.3.0/../../../../i686-w64-mingw32/bin/ld.exe: use the --help option for usage information
collect2.exe: error: ld returned 1 exit status
Liu.D.H#DESKTOP-KA8TQF4 MINGW32 ~
$ gcc -c vuln.c -o vuln -fno-stack-protector -m32 -z execstack
Liu.D.H#DESKTOP-KA8TQF4 MINGW32 ~
$ ld -z execstack vuln.o -o vuln
C:\msys32\mingw32\bin\ld.exe: unrecognized option '-z'
C:\msys32\mingw32\bin\ld.exe: use the --help option for usage information
Liu.D.H#DESKTOP-KA8TQF4 MINGW32 ~
$ ld -v
GNU ld (GNU Binutils) 2.30
Liu.D.H#DESKTOP-KA8TQF4 MINGW32 ~
$ C:/msys32/mingw32/bin/../lib/gcc/i686-w64-mingw32/7.3.0/../../../../i686-w64-mingw32/bin/ld.exe -v
GNU ld (GNU Binutils) 2.30
Liu.D.H#DESKTOP-KA8TQF4 MINGW32 ~
$
I could find the execstack options in man ld and the version matched above.

The -z options are just not supported for Windows versions of ld. Check with ld --help. For Cygwin, it should not list -z options that are present when running the same command on a Linux system. I believe this is because options here are really only meaningful on Linux.
The -z execstack option (not the Linux tool of the same name) tells the Linux version of ld to turn off Data Execution Prevention (DEP) on the executable. This is done with flags in the ELF.
Windows DEP policy, on the other hand, is built into the OS nowadays. Here are some options to manage this yourself:
For individual programs on Windows 10:
Look for "Adjust the appearance and performance of Windows" in the Start Menu. (You can type "performance" and it will appear). This gives you a new dialog box.
Go to the third tab, "Data Execution Prevention".
Add/remove exceptions here
Call the WinAPI's SetProcessDEPPolicy depending on the OS's DEP setting. However, this has to be done in the program itself.
Use bcdedit via CMD to globally turn on/off DEP, but this is a bad idea. To quote the article:
Important DEP is a highly effective security feature that should not be disabled unless you have no alternative.
In short, when following tutorials for exploit exercises, often these are meant to be done on Linux machines. Run it on the proper OS, or for extra safety, run it on a VM. The same exploits can't be expected to work on Windows in the same way.
More on Windows DEP policy: See
How to make my program DEP-compatible?

Related

How can I automagically obtain a detailed script equivalent to a complex `gcc` invocation?

It is my understanding that, under the hood, a simple gcc invocation such as this:
% gcc -o hello hello.c
— May actually invoke several separate executables, perhaps hidden inside gcc installation. These may be:
The linker ld.
The assembler as.
An obscure executable cc1 that is actually a compiler.
An obscure executable collect2 with functionality that I find difficult to summarize.
Any number of other commands.
All of them will be invoked with an outrageous amount of command line parameters and environment variables. However, it is my understanding that the gcc executable does nothing by itself, that is, the whole run of gcc is completely described by the commands it runs, so any single invocation of gcc is equivalent to some shell script.
It is sometimes desirable to locate individual commands performed during a run of gcc, either to alter and perform them separately, trace a bug in the build process, or simply to document the particulars of a build. Furthermore, it is sometimes demanded that such effort is performed across several build configurations, target architectures, optimization parameters and so on.
A log of operation may be obtained from gcc by supplying a parameter -v, and redirecting to a file:
% gcc -o hello hello.c 2> gcc.log
Unfortunately, this method by itself does not provide a script that can readily be executed, altered, version controlled and so on. Rather, the log generated will contain a mixture of actual commands and arbitrary commentary, such as gcc version, all in a uniform list. It is then on the operator to manually mark the commentary as such or remove it altogether, in order to, hopefully, obtain a runnable shell script.
How can I (make ghc to) automagically generate such a script?
First of all note that command-line invocations alone are not sufficient - GCC passes additional options via environment variables (COMPILER_PATH, COLLECT_GCC_OPTIONS, etc.) and via temp files which contain compiler options inside them (the latter is AFAIK only used in LTO compilations).
You can easily extract compilation commands via sed:
$ gcc tmp.c -### 2>&1
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/6.4.0/lto-wrapper.exe
Target: x86_64-pc-cygwin
Configured with: ...
Thread model: posix
gcc version 6.4.0 (GCC)
COLLECT_GCC_OPTIONS='-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-pc-cygwin/6.4.0/cc1.exe -quiet -Dunix -idirafter /usr/lib/gcc/x86_64-pc-cygwin/6.4.0/../../../../lib/../include/w32api -idirafter /usr/lib/gcc/x86_64-pc-cygwin/6.4.0/../../../../x86_64-pc-cygwin/lib/../lib/../../include/w32api tmp.c -quiet -dumpbase tmp.c "-mtune=generic" "-march=x86-64" -auxbase tmp -o /tmp/cco2cExb.s
...
$ gcc tmp.c -### 2>&1 | sed -ne '/^[A-Z_0-9]\+=/{ s/^\([^=]\+\)=\(.*\)/export \1="\2"/; s/'\''//g; p}; /^ /{p}'
export COLLECT_GCC="gcc"
export COLLECT_LTO_WRAPPER="/usr/lib/gcc/x86_64-pc-cygwin/6.4.0/lto-wrapper.exe"
export COLLECT_GCC_OPTIONS="-mtune=generic -march=x86-64"
/usr/lib/gcc/x86_64-pc-cygwin/6.4.0/cc1.exe -quiet -Dunix -idirafter /usr/lib/gcc/x86_64-pc-cygwin/6.4.0/../../../../lib/../include/w32api -idirafter /usr/lib/gcc/x86_64-pc-cygwin/6.4.0/../../../../x86_64-pc-cygwin/lib/../lib/../../include/w32api tmp.c -quiet -dumpbase tmp.c "-mtune=generic" "-march=x86-64" -auxbase tmp -o /tmp/ccZSUbZx.s
...

GCC error when installing ncurses on OS X 10.8

I'm trying to install ncurses 5.9 on OS X 10.8 with GCC 4.9 installed. No errors or warnings show up when I run ./configure in the ncurses directory, but when I run make, I get gcc: error: unrecognized command line option ‘-no-cpp-precomp’. Upon googling the issue (and trying it out), I found that --no-cpp-precomp (with two dashes, i.e in long flag form) is a valid command.
I'm not sure what was prompting GCC to run the invalid command – whether it was make, or if it was a command specified in ncurses itself.
Is there any way to fix this? If so, how?
EDIT: I tried changing the reference in the ./configure file from -no-cpp-precomp to --no-cpp-precomp manually, using a text editor, and was met with this, despite GCC seemingly accepting the --no-cpp-precomp option. After that, I tried running autoreconf, and got this:
configure:6558: error: possibly undefined macro: AC_DIVERT_HELP
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
autoreconf: /opt/local/bin/autoconf failed with exit status: 1
After running it with the m4_pattern_allow option:
autoreconf: 'configure.ac' or 'configure.in' is required
After running ./configure && make anyway:
cd man && make DESTDIR="" all
sh ./MKterminfo.sh ./terminfo.head ./../include/Caps ./terminfo.tail >terminfo.5
cd include && make DESTDIR="" all
cat curses.head >curses.h
AWK=gawk sh ./MKkey_defs.sh ./Caps >>curses.h
sh -c 'if test "chtype" = "cchar_t" ; then cat ./curses.wide >>curses.h ; fi'
cat ./curses.tail >>curses.h
gawk -f MKterm.h.awk ./Caps > term.h
sh ./edit_cfg.sh ../include/ncurses_cfg.h term.h
** edit: HAVE_TCGETATTR 1
** edit: HAVE_TERMIOS_H 1
** edit: HAVE_TERMIO_H 0
** edit: BROKEN_LINKER 0
cd ncurses && make DESTDIR="" all
gcc -o make_hash -DHAVE_CONFIG_H -I../ncurses -I. -I./../include -I../include -DUSE_BUILD_CC -DHAVE_CONFIG_H -I../ncurses -I. -D_DARWIN_C_SOURCE -DNDEBUG -I. -I../include -I/usr/local/include/ncurses -O2 --param max-inline-insns-single=1200 --no-cpp-precomp ./tinfo/make_hash.c -Wl,-search_paths_first
gcc: error: unrecognized command line option ‘--no-cpp-precomp’
make[1]: *** [make_hash] Error 1
make: *** [all] Error 2
It looks like this has been fixed in the latest patches to ncurses 5.9
The 5.9 source can be found here: ftp://invisible-island.net/ncurses/ncurses-5.9.tar.gz
The latest patches are here: ftp://invisible-island.net/ncurses/5.9/ but the latest rollup patch appears to have the fix: ftp://invisible-island.net/ncurses/5.9/patch-5.9-20130504.sh.gz
To apply the patch, get the 2 files above then:
$ tar xvf ncurses-5.9.tar.gz
$ cd ncurses-5.9
$ gzip -dc ../patch-5.9-20130504.sh.gz | sh
--no-cpp-precomp is an obsolete Apple GCC option it should generate a warnning not an error but if -Werror flag is passed to the compiler it will fail on warnings, either way, you will have to remove it manually from the build scripts and then run autoreconf or you could just remove it from the configure script directly.
I realize this is very old now, but since I'm running into the same issue (need to build on Mac Yosemite 10.10 with GCC 4.9), maybe it'll help someone else too. It looks like the configure script is detecting that it's a Mac and assuming clang is used, even though the 'gcc' from the PATH is GNU. Seems they fixed the detection logic in newer versions. I've found the same issue in Boost 1.37 and it was fixed (somewhere before) Boost 1.55.

Can't output anything using cygwin 1.7 gcc under windows

I just installed cygwin 1.7, and wrote a simple Hello world in test.c
but when I complie, nothing happens, even no error messages
gcc-4 -o test.exe test.c
And there's nothing generated under my folder.
I have included C:\cygwin;C:\cygwin\bin in my PATH
Did I miss something?
EDIT:
for more information, I installed Qt4, tortoiseHg, and mingw before.
Now I had removed mingw. but still got Qt4 and tortoiseHg, is this a problem?
Try doing this from the Cygwin Terminal, not cmd.exe:
$ cd `cygpath -u "$USERPROFILE"`/Desktop/UT
$ gcc -o foo foo.c
$ ls -l foo
-rwxr-xr-x+ 1 yourlogin None 19618 May 10 05:15 foo*
If that works, there's some bogus remnant lying around.
You'll find that the Cygwin experience is generally better running under Bash, in a MinTTY terminal anyway. cmd.exe doesn't understand Cygwinisms, and is a DOS throwback besides.
Note that you don't need to say gcc-4 to get GCC 4.x. gcc is GCC 4.x on Cygwin, and has been for quite some time now.
Also note that you don't need to include .exe in the GCC -o flag, because Cygwin GCC knows to add that already.

Force gcc to use one linker over another

Lately I have been working on OS X. Things were going pretty peachy for a while until somehow ld got on my system and now gcc won't use dyld. Furthermore, all of my shared libraries are in *.dylib format, and ld is stubornly ignoring there existance. If I mv ld from PATH, gcc just complains it cant find ld.
Please help me to get gcc back on track and using what it should.
You can try some gcc options. From the man page:
-c Compile or assemble the source files, but do not link. The linking
stage simply is not done. The ultimate output is in the form of an
object file for each source file.
You could then link explicitly using whatever linker you want.
Does it help to symlink ld to dyld?
mv /usr/bin/ld /usr/bin/ld.old
ln -s /usr/bin/dyld /usr/bin/ld
Edit: fixed ld params order
This isn't your exact question, but I had a need to switch to ld.gold, and for that, the -fuse-ld=gold option to gcc was very useful.
look at -Xlinker option
I got it from man gcc
you can double check using some verbose options like -v

gcc -print-prog-name=??? doesn't work as I would expect

if I understand the gcc manuals right than the option -print-prog-name should print the name of the program used.
But it seems that this option only echoes the given argument
Examples:
gcc -print-prog-name=ld
--> ld
gcc -print-prog-name=xxxsome-funny-name
--> xxxsome-funny-name
Is this the expected behaviour? I think it should print something like
gcc -print-prog-name=ld
--> /usr/bin/ld
gcc -print-prog-name=xxxsome-funny-name
--> unknown program
EDIT: testing on Debian Lenny 64bit with gcc v4.2.4
Meanwhile I found another reason for the behaviour of
gcc -print-prog-name=ld
The ld command is not invoked directly by gcc.
gcc invokes collect. And it is collect which in turn invokes ld.
I think the -print-prog-name option only applies to a small set of tools that GCC
uses internally. For example,
$ gcc -print-prog-name=cc1
/usr/libexec/gcc/x86_64-redhat-linux/3.4.5/cc1
$ ls -L /usr/libexec/gcc/x86_64-redhat-linux/3.4.5/
cc1 cc1plus collect2 f771 jc1 jvgenmain
$ gcc -print-prog-name=f771
/usr/libexec/gcc/x86_64-redhat-linux/3.4.5/f771
So gcc -print-prog-name is aware of the tools that live in that directory. But:
$ gcc -print-prog-name=ld
ld
My guess is that if gcc -print-prog-name returns an absolute path, it's configured
to use that version of the program, no matter what's on your $PATH -- otherwise
it just echoes back what you gave it without resolving it to an absolute pathname.

Resources