pouët.net

Running/emulating a Win32 DLL on linux/Mac OSX

category: general [glöplog]
 
Ok, this is a little OT but it seemed skunk works enough to post here..

I have a third-party win32 .DLL that contains a disassembler routine that I use in my homebrew DSP debugger. I would like to run my debugger on Linux or Mac OSX and the only thing stopping me ATM is this DLL. Writing my own disassembler is not worth it -- it will take too much time.

Therefore, I want to try to use QEMU or some other CPU emulator to "run" the DLL on non-win32 operating systems. There are no OS calls in this DLL, except for malloc, free and various printf functions. Has anyone tried this (or any other) approach?

added on the 2009-12-17 15:02:18 by trc_wm trc_wm
tried wine?
I had thought about wine. It seems overly bloated for my purpose. I would need to patch it so that I can communicate with my DLL from outside wine. This is probably easier to do with QEMU than with wine.
added on the 2009-12-17 15:13:13 by trc_wm trc_wm
tried windows?
added on the 2009-12-17 15:43:41 by leGend leGend
Is it really that hard to write a disassembler? At least for most processors I could write one in an afternoon...
added on the 2009-12-17 16:02:54 by xeron xeron
ok long posting got lost because of session timeout :/

short version: use winelib or write your own disasm ;)

Quote:
you're free to use a linux syscall to do whatever you want, including forking the process and exec'ing the linux program. That's the beauty of wine. You have win32 *and* linux APIs available at the same time


(from http://wiki.jswindle.com/index.php/WineLib#Calling_Linux_API)
added on the 2009-12-17 18:49:03 by xyz xyz
@xeron: for most processors, writing a disassembler is straight-forward because the bitfields of the instructions are easy to decode. On this DSP however, things are terrible. So I'd rather not write my own code if I already have something that works (.. on Win32 that is).

@hermes: thanks for the URL. According to the winelib website, the easiest way would be to make a winlib-based app, run that as a separate process and do IPC. Dirty, but it works, I guess :)
added on the 2009-12-18 14:54:24 by trc_wm trc_wm
You certainly don't need QEMU for this.

If Wine is too heavyweight, then just load the PE yourself (a bit of trivial header parsing and a couple of mmap calls). Since Windows and Linux x86 calling conventions are basically the same, after the mmap, you really only need to write the addresses of malloc/free/etc. into the import address table. If you can't load the DLL at its preferred load address, you'll need to handle relocations too, but that's also straightforward.

All in all, we're talking about maybe 250-300 lines of straightforward C code here, not including the various structs for EXE/PE header fields that you should be able to copy&paste from windows.h with a few typedefs.
added on the 2009-12-18 15:40:19 by ryg ryg
2) disassemble the desired function, blindly copypaste that code as inline assembly in your favourite c source code, fix the label mess, recompile, forget, done.
added on the 2009-12-18 17:02:41 by rmeht rmeht
@rmeht: that sounds like the easiest way to get it working. Thanks!

@ryg: I might try that, if I can't get rmeht's method to work.

BTW, the bo2k sources contain custom DLL loading functions which could be useful.
added on the 2009-12-18 20:46:39 by trc_wm trc_wm
je bent weer lekker crossplatform bezig, niels!
added on the 2009-12-18 22:10:58 by maali maali
ja, dat krijg je als je in een bedrijf werkt met MAC aanhangers.
added on the 2009-12-19 00:32:41 by trc_wm trc_wm
rmeht: not a bad idea at all but only works if there are no dependencies to win32 specific code/libs.
added on the 2009-12-19 00:56:21 by xyz xyz
hermes, trc already stated in the first post that there aren't.
added on the 2009-12-19 02:03:08 by ryg ryg
ryg: all right, that's true. must have overread it.
added on the 2009-12-19 02:06:21 by xyz xyz

login