Linking fails for GetSaveFileName when cross compiling with MinGW [duplicate] - mingw-w64

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 4 years ago.
I'm trying to compile a modified version of UniLogger on Ubuntu 18.04 using mingw. I'm getting the following link error:
undefined reference to '_imp__GetSaveFileNameW#4'
I found this post on the MinGW mailing list saying one needs to explicitly link to comdlg32 so I tried that also:
i686-w64-mingw32-g++ -municode -o unilogger.exe -lcomdlg32 Source.cpp
But still got the same error, as did the person asking in the post. He and I both verified the presence of the function in the lib file:
nm /usr/i686-w64-mingw32/lib/libcomdlg32.a
libcomdlg32s00012.o:
00000000 b .bss
00000000 d .data
00000000 T _GetSaveFileNameW#4
U __head_lib32_libcomdlg32_a
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 I __imp__GetSaveFileNameW#4
00000000 t .text
libcomdlg32s00011.o:
00000000 b .bss
00000000 d .data
00000000 T _GetSaveFileNameA#4
U __head_lib32_libcomdlg32_a
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 I __imp__GetSaveFileNameA#4
00000000 t .text
I'm at a bit of a loss at this point.

OK, figured out what the problem was - order of arguements on the command line:
i686-w64-mingw32-g++ -lcomdlg32 -municode -o unilogger.exe
gives the link error, however
i686-w64-mingw32-g++ -municode -o unilogger.exe -lcomdlg32
Compiles just fine. Actually think I've run into this problem before with gcc now that I think of it...

Related

How do you get plain text from binary where the plaintext is formatted by itself?

Desired output of something like "xxd -b file":
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
..etc
then followed by
plaintext here
Actual output:
00000000 00000000 00000000 00000000 plai
00000000 00000000 00000000 00000000 n te
00000000 00000000 00000000 00000000 xt h
Hopefully communicates what I'm getting at. This is just a minor issue I encountered doing a beginner CTF, but it felt very off and sloppy to copy paste just one line at a time, since highlighting treats the actual information I want in the right column as just part the array of text. I've tried a few different flags with xxd and read the man page, but I have not found an option that outputs the plaintext by itself or in a manner that is more readable. Is there another tool I should be using, ideally one that is common on most linux distros?
Process the file twice, once by xxd, once by cat. Use cut to remove the plaintext from the xxd output:
xxd -b file | cut -d' ' -f1-8 ; cat file
Use 2-8 if you aren't interested in the positions.

/proc/<pid>/map shows more shared library than ldd for busybox

Why /proc/<pid>/maps shows more shared library than ldd program?
Here's an example:
# ------------ Embedded Linux side ------------
# ps
.....
28 root [jffs2_gcd_mtd2]
132 root -/bin/sh ---> the target to show
155 root [kworker/0:2]
# # Note: -/bin/sh is actually /bin/busybox
# cat /proc/132/maps
00400000-004bc000 r-xp 00000000 1f:02 34 /bin/busybox
004cc000-004cd000 rw-p 000bc000 1f:02 34 /bin/busybox
004cd000-004ee000 rw-p 00000000 00:00 0 [heap]
775bb000-775cb000 rw-p 00000000 00:00 0
775cb000-775d6000 r-xp 00000000 1f:02 397 /lib/libnss_files-2.22.so
775d6000-775e5000 ---p 0000b000 1f:02 397 /lib/libnss_files-2.22.so
775e5000-775e6000 r--p 0000a000 1f:02 397 /lib/libnss_files-2.22.so
775e6000-775e7000 rw-p 0000b000 1f:02 397 /lib/libnss_files-2.22.so
775e7000-775ed000 rw-p 00000000 00:00 0
775ed000-7775a000 r-xp 00000000 1f:02 382 /lib/libc-2.22.so
7775a000-7776a000 ---p 0016d000 1f:02 382 /lib/libc-2.22.so
7776a000-7776d000 r--p 0016d000 1f:02 382 /lib/libc-2.22.so
7776d000-77770000 rw-p 00170000 1f:02 382 /lib/libc-2.22.so
77770000-77772000 rw-p 00000000 00:00 0
77772000-77795000 r-xp 00000000 1f:02 374 /lib/ld-2.22.so
777a1000-777a2000 rw-p 00000000 00:00 0
777a3000-777a4000 rw-p 00000000 00:00 0
777a4000-777a5000 r--p 00022000 1f:02 374 /lib/ld-2.22.so
777a5000-777a6000 rw-p 00023000 1f:02 374 /lib/ld-2.22.so
7fb42000-7fb63000 rwxp 00000000 00:00 0 [stack]
7fff7000-7fff8000 r-xp 00000000 00:00 0 [vdso]
# cksum /bin/busybox
698740119 773496 /bin/busybox
#---------- Then on the PC side ----------------
$ cksum ./busybox
698740119 773496 bin/busybox
$ /usr/local/bin/mips-linux-gnu-ldd bin/busybox
checking sub-depends for 'not found'
libc.so.6 => not found (0x00000000)
/lib/ld.so.1 => /lib/ld.so.1 (0x00000000)
cksum is used to check if the files are the same.
From PC side ldd cross-tool, it shows busybox depends on libc and ld only.
However, in the real run-time environment, /proc/132/maps shows one more shared library, /lib/libnss_files-2.22.so.
To confirm if we have indirect dependency:
$ /usr/local/bin/mips-linux-gnu-ldd lib/libc.so.6
/lib/ld.so.1 => /lib/ld.so.1 (0x00000000)
$ /usr/local/bin/mips-linux-gnu-ldd lib/ld.so.1
not a dynamic executable
No. ldd show that libc depends on ld, which is already one of busybox's dependency.
One process can dlopen(3) a shared object and load it in its address space without the need of linking it to it. This means a shared object doesn't need to appear in the ldd(1) output for it to appear in the running instance of the program.
I'm not saying that this is the case, but you can develop shared objects with the only purpose of adding (unknown) functionality to a program that had open design to incorporate libraries on demand.
Normally, those programs don't appear in the ldd output.
libnss_files is a component of libc. It's loaded on demand, and is used to perform name lookups in static files, like /etc/passwd and /etc/hosts. (There's also libnss_dns for DNS lookups.)
For more information, see the libc documentation for NSS (Name Service Switch).

Why is vdso appearing during execution of static binaries? [duplicate]

This question already has answers here:
What are vdso and vsyscall?
(2 answers)
Closed 7 years ago.
Here is a quick sample program. (This will basically get the procmap associated with the process)
> cat sample.c
#include<stdio.h>
int main()
{
char buffer[1000];
sprintf(buffer, "cat /proc/%d/maps\n", getpid());
int status = system(buffer);
return 1;
}
Preparing it statically
> gcc -static -o sample sample.c
> file sample
sample: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=9bb9f33e867df8f2d56ffb4bfb5d348c544b1050, not stripped
Executing the binary
> ./sample
00400000-004c0000 r-xp 00000000 08:01 12337398 /home/admin/sample
006bf000-006c2000 rw-p 000bf000 08:01 12337398 /home/admin/sample
006c2000-006c5000 rw-p 00000000 00:00 0
0107c000-0109f000 rw-p 00000000 00:00 0 [heap]
7ffdb3d78000-7ffdb3d99000 rw-p 00000000 00:00 0 [stack]
7ffdb3de7000-7ffdb3de9000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
I googled about vDSO but did not understand properly. Wikipedia says "these are ways in which kernel routines can be accessed from user space". My question is why are these shared objects appearing in execution of static binaries?
My question is why are these shared objects appearing in execution of static binaries?
They appear because your kernel "injects" them into every process.
Read more about them here and here.

Get pages attribute by system call in Linux

Is there any system call or function that can get page attribute like readable, writable, executable by page address?
I know we can use mprotect to set pages attribute, but I have no idea if we can get pages attribute. Any comment is appreciated.
There isn't. You need to use the proc interface, which contains lots of information about each process in various files. The information you're looking for is in plaintext, in /proc/<pid>/maps. You can take a look at it for your current process by running:
$ cat /proc/$$/maps
You can find some more information in man 5 proc.
The example given at the above link is:
address perms offset dev inode pathname
08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm
08056000-08058000 rw-p 0000d000 03:0c 64593 /usr/sbin/gpm
08058000-0805b000 rwxp 00000000 00:00 0
40000000-40013000 r-xp 00000000 03:0c 4165 /lib/ld-2.2.4.so
40013000-40015000 rw-p 00012000 03:0c 4165 /lib/ld-2.2.4.so
4001f000-40135000 r-xp 00000000 03:0c 45494 /lib/libc-2.2.4.so
40135000-4013e000 rw-p 00115000 03:0c 45494 /lib/libc-2.2.4.so
4013e000-40142000 rw-p 00000000 00:00 0
bffff000-c0000000 rwxp 00000000 00:00 0
As you can see, the permissions are the second (space-delimited) field there. So from a program (like in C, since you mentioned mprotect(), you could open up /proc/$$/maps with fopen(), then use fgets() or scanf() to pull the data out. You're just looking for that perms field of the range where your page lies.

What do the "---p" permissions in /proc/self/maps mean?

I understand the meaning of rwxps bits. r-xp is for .text. rw-p is for .data/.bss/heap/stack. What is the use of just ---p pages?
For example see this output of cat /proc/self/maps
00400000-0040b000 r-xp 00000000 08:03 827490 /bin/cat
0060b000-0060c000 rw-p 0000b000 08:03 827490 /bin/cat
0060c000-0062d000 rw-p 00000000 00:00 0 [heap]
3819a00000-3819a1e000 r-xp 00000000 08:03 532487 /lib64 ld-2.11.2.so
3819c1d000-3819c1e000 r--p 0001d000 08:03 532487 /lib64/ld-2.11.2.so
3819c1e000-3819c1f000 rw-p 0001e000 08:03 532487 /lib64/ld-2.11.2.so
3819c1f000-3819c20000 rw-p 00000000 00:00 0
3819e00000-3819f70000 r-xp 00000000 08:03 532490 /lib64/libc-2.11.2.so
3819f70000-381a16f000 ---p 00170000 08:03 532490 /lib64/libc-2.11.2.so
381a16f000-381a173000 r--p 0016f000 08:03 532490 /lib64/libc-2.11.2.so
381a173000-381a174000 rw-p 00173000 08:03 532490 /lib64/libc-2.11.2.so
381a174000-381a179000 rw-p 00000000 00:00 0
7fb859c49000-7fb85fa7a000 r--p 00000000 08:03 192261 /usr/lib/locale/locale-archive
7fb85fa7a000-7fb85fa7d000 rw-p 00000000 00:00 0
7fb85fa95000-7fb85fa96000 rw-p 00000000 00:00 0
7fff64894000-7fff648a9000 rw-p 00000000 00:00 0 [stack]
7fff649ff000-7fff64a00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
According to the man page, it means private (copy on write). No idea what the usefulness of such a mapping is without being able to read/write/execute anything in it, though.
Possibly it is private to libc, allowing it to modify the permissions to access it without a user program accidentally mucking it up.
This is something I've wondered about the specifics of too. It didn't appear until sometime in the last few years, but I'm unsure whether GNU binutils or the glibc dynamic linker (ld-linux.so.2) is responsible for the change.
At first I thought it was a sort of guard region created by the dynamic linker to protect against out of bounds access to a library's data segment, but it makes no sense for it to be so large. It's possible that it's a complete map of the while library file so that the dynamic linker can make it readable again at some time in the future (perhaps during dlopen or dlsym calls) to access ELF metadata that doesn't normally need to be mapped.
In any case, it's nasty bloat, especially on 32-bit machines where virtual address space is a precious resource. It also bloats the kernel page tables, increasing the kernelspace resources used by a process.
P.S. Sorry this isn't really an answer. I know it's just random bits and pieces that might help lead to an answer, but it was way too long for a comment.
Private mapping (MAP_PRIVATE): Modifications to the contents of the mapping are not visible to other processes.
For file mapping they are not carried through to the underlying file. Changes to the contents of the mapping are nevertheless private to each process.
The kernel accomplishes this by using the copy-on-write technique. This means that whenever a process attempts to modify the contents of a page, the kernel first creates a new, separate copy of that page for the process (and adjusts the process’s page tables).
For this reason, a MAP_PRIVATE mapping is sometimes referred to as a private, copy-on-write mapping. (Source: The Linux Programming Interface book)

Resources