WineLib app error

Open forum for end-user questions about Wine. Before asking questions, check out the Wiki as a first step.
Forum Rules
Locked
Jean-Claude Gervais

WineLib app error

Post by Jean-Claude Gervais »

Hello everyone!

Operating system:
Linux 2.6.32-gentoo-r5 #1 SMP x86_64 Intel(R) Core(TM)2 Quad CPU Q6600 @
2.40GHz GenuineIntel GNU/Linux

Version of Wine:
wine-1.1.40

I am trying to run an application I wrote which compiles and runs fine
using MinGW but when I try to make a WineLib version of it I get the
error -
wine: Bad EXE format for P:\CMS\cms.exe

Here is a transcript of the session.


First I build a DLL the application needs:

$ make
wrc -r -Iinc -I/usr/include/wine/windows -o resource.o resource.rc
wineg++ -O2 -fno-strength-reduce -fno-strict-aliasing -g -Iinc
-I../include -I/usr/include/wine/windows -Dlinux -D__amd64__
-D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE
-D_SVID_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -c -o
src/tis.o src/tis.cpp
+ wineg++ -o ./libdbgtrace.so.~ -shared --dll dbgtrace.spec
-Wl,-soname,libdbgtrace.so. resource.o src/tis.o

$ file libdbgtrace.so.~.so
libdbgtrace.so.~.so: ELF 32-bit LSB shared object, Intel 80386, version
1 (SYSV), dynamically linked, not stripped


This apparently works OK.
Then I build the application:


$ make
wrc -r -I./inc -I/usr/include/wine/windows -DWINELIB -D_REENTRANT
-DDEBUG -o resource.res resource.rc
wineg++ -O2 -fno-strength-reduce -fno-strict-aliasing -g -mwindows
-std=c++0x -Wall -I. -Iinc -I../include -I/usr/include/wine/windows
-Dlinux -D__amd64__ -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE
-D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -DWINELIB -D_REENTRANT -DDEBUG -c -o src/main.o
src/main.cpp
rm -f cms
wineg++ -o cms -O2 -fno-strength-reduce -fno-strict-aliasing -g
-L/usr/lib32/wine resource.res src/main.o -lws2_32 -lcomctl32
-L../dbgtrace -ldbgtrace.so.~

$ file cms.exe.so
cms.exe.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV),
dynamically linked, not stripped

This also appears to work, but when I run the app by changing to the
shared object's folder and invoke the .exe (which is really a shell
script), I get the following:

$ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH wine ../CMS/cms.exe
wine: Bad EXE format for P:\CMS\cms.exe

I'm sure I've done something wrong, forgotten a flag or something...
Anyone know what is wrong?

J
Thunderbird
Level 5
Level 5
Posts: 336
Joined: Mon Nov 24, 2008 8:10 am

Post by Thunderbird »

You can directly invoke the '.exe' file which is just a script to launch your app. Or if you want to use wine yourself use: 'wine appname.exe.so'.
Jean-Claude Gervais

WineLib app error

Post by Jean-Claude Gervais »

Thank you, Thunderbird.
It is wineg++ that creates the script. I thought it was safer to use it.

If I invoke the .so file directly, I get this:

LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH wine ../CMS/cms.exe.so
wine: Module not found
wine: Bad EXE format for P:\CMS\cms.exe.so

I *think* this may mean that it is not able to find the .so I built? Not
sure...

Is there a tool like depends.exe for *nix? It would be very useful to
know which module is not found.

Thank you for your help!

J

On Thu, 2010-04-01 at 17:08 -0500, Thunderbird wrote:
You can directly invoke the '.exe' file which is just a script to launch your app. Or if you want to use wine yourself use: 'wine appname.exe.so'.



Thunderbird
Level 5
Level 5
Posts: 336
Joined: Mon Nov 24, 2008 8:10 am

Post by Thunderbird »

I would try again from scratch using a basic hello world app and see if you can get that working.
hellork
Level 3
Level 3
Posts: 82
Joined: Thu Mar 27, 2008 7:13 pm

Re: WineLib app error

Post by hellork »

I've heard that LD_PRELOAD doesn't work with wine, but after reading the man page for dlopen() it started working for me, although I'm not sure why. :)

As a test, I'll use the simple password challenge from http://neworder.box.sk/newsread.php?newsid=13857

To make things more readable for my tired eyes, I'll use the C code "pythonizer" from http://thenerdshow.com/pysces.html

Code: Select all

/*
 * pass.p.c password challenge
 */
#include <stdio.h>
#include <string.h>

int main  int argc, char **argv
    char passwd[] = "wine"
    if  argc < 2
        printf  "usage: %s <password>\n", argv[0]
        return 0
    if  !strcmp(passwd, argv[1])
        printf  "PASS\n"
        return 1
    printf  "FAIL\n"
    return 0

Code: Select all

#hijack.spec
@ stdcall strcmp(str str)

Code: Select all

/* 
 * hijack.p.c ALL YOUR STRING ARE BELONG TO US!
 */
#include <stdio.h>
#include <string.h>
#include <limits.h>
int strcmp  const char *s1, const char *s2
/* The if statement suppresses a lot of output for this test */
/* Remove it and see how often Wine uses this function! */
    if  !strncmp(s1,"wine",5)
        printf  "S1 = '%s'\n", s1
        printf  "S2 = '%s'\n", s2
    return strncmp  s1,s2,UINT_MAX

Compiling for both Winelib and Linux
(-m32 produces 32 bit binaries on 64 bit linux):

Code: Select all

pycc gcc pass.p.c -o pass -m32
pycc gcc -fPIC -shared -m32 hijack.p.c -o hijack.so
pycc winegcc pass.p.c -o pass -m32
pycc winegcc -fPIC -shared -m32 hijack.p.c -o hijack.dll.so hijack.spec
And testing...

Code: Select all

wine pass.exe.so
usage: pass.exe.so <password>
./pass huh???
FAIL
Notice that there is no difference between hijack.so and hijack.dll.so. Both behave like and are loaded like Linux shared objects because they are Linux shared objects! As far as ld is concerned, they are interchangeable! The only apparent difference is the "Winelib" shared object compiled with winegcc is 75K in size...
So what's so special about the Winelib shared object? Somebody help me out here. I'm guessing it has extra code so wine can treat it like a regular windows DLL within the wine environment.

Code: Select all

# Preloading Wine shared object with wine binary
LD_PRELOAD=$(pwd)/hijack.dll.so wine pass.exe.so wrongpassword
S1 = 'wine'
S2 = 'wrongpassword'
FAIL
# Preloading Linux shared object works with wine binary!
LD_PRELOAD=$(pwd)/hijack.so wine pass.exe.so wrongpassword
S1 = 'wine'
S2 = 'wrongpassword'
FAIL
Since we hijacked strcmp to tell us the password, we can now gain entry.

Code: Select all

./pass wine
PASS
Thunderbird
Level 5
Level 5
Posts: 336
Joined: Mon Nov 24, 2008 8:10 am

Post by Thunderbird »

The reason you have to compile using winegcc/wineg++ is that it injects special Wine voodoo. Wine can't be used as a normal set of libraries since we need a Windows-environment (file system, windows memory layout, registry, kernel==wineserver, ..).
Jean-Claude Gervais

WineLib app error

Post by Jean-Claude Gervais »

OK, I did that and I have come to the conclusion that linking the DLL
(shared object lib) that I wrote is DEFINITELY causing the error.

This is strange, because when I comment out all of its calls and run

nm cms.exe.so

to verify that it is NOT linking any of the lib's functions it will
still give the error.

If I remove the mention of the lib from the link options, then the app
loads and runs.

So it is something to do with the construction of the .so file...

It has to be a missing or incorrect flag...

I added -fPIC but that doesn't seem to help.

On Fri, 2010-04-02 at 03:05 -0500, Thunderbird wrote:
I would try again from scratch using a basic hello world app and see if you can get that working.



Thunderbird
Level 5
Level 5
Posts: 336
Joined: Mon Nov 24, 2008 8:10 am

Post by Thunderbird »

I would get rid of a lot of unneeded CFLAGS, some might not work for winelib purposes (winegcc is just a wrapper).
Jean-Claude Gervais

WineLib app error

Post by Jean-Claude Gervais »

OK, got it!

Turns out that there is a discrepancy caused by the makefile generation
kit I am using (Imake) and the expected name of the .so file.

The last line when building the shared object (the link step) does two
different things:

- It physically names the output file ( -o ./libdbgtrace.so.~.so )
- It passes a linker option setting the shared-object name
( -soname,libdbgtrace.so. )

These two things do NOT match

Using ldd on the application

ldd cms.exe.so

showed me that one of the shared-libs needed to run the app was not
found and more importantly, its expected NAME ( libdbgtrace.so. )

I simply renamed the shared-object and now the app runs and behaves
exactly as its MinGW-compiled twin does, which was the goal.

Thanks, Thunderbird (and others!), you've helped me see more clearly.

Happy Easter to all and a big chocolate bunny!

J


On Fri, 2010-04-02 at 16:57 -0500, Thunderbird wrote:
I would get rid of a lot of unneeded CFLAGS, some might not work for winelib purposes (winegcc is just a wrapper).
Locked