Is there some kind of secret to hooking both 64bit & 32bit process on a 64bit system?
In an application that I'm currently writing I need to be able to hook 64bit processes. Hooking 32bit processes works just fine on 64 & 32bit systems but, no messages are received when trying to hook 64bit applications.
Before anyone tells me that I shouldn't be doing something like this let me explain that this is a very necessary thing for me to do.. Without setting global system hooks my application would be useless/pointless.
This application is written in C#/WPF but, using a C++ dll to do the actual hooking. I've tried compiling the dll for 64bit systems although it still isn't doing what it's supposed to do. When compiled for and running on 32bit systems it works exactly as it should.
*Edit:: I am talking about hooking window messages - WH_CBT & WH_SHELL messages
In order to hook both 32-bit and 64-bit processes you need to make sure that:
You have 32-bit DLL to hook 32-bit processes and 64-bit DLL to hook 64-bit processes
SetWindowsHookEx() is invoked from 32-bit code to hook 32-bit processes and from 64-bit code to hook 64-bit processes.
The latter basically means that you have to create both 32-bit and 64-bit executable that both call SetWindowsHookEx(), providing 32-bit and 64-bit DLL respectively as an hMod parameter.
If you application is 32-bit, you will have to spawn 64-bit process that will call SetWindowsHookEx() and probably do nothing else until you unhook. Note that Windows will automatically unset hook when/if this process exits/terminates, so it has to remain alive all the time you need the hooks, probably, the whole lifetime you your application - in this case you can make your 64-bit process WaitForSingleObject() until your main application process exits/terminates and unhook and exit after WaitForSingleObject() completes.
Related
I'm a long-time user of Cygwin. I'm running Win7/x64, but my Cygwin installation is 32-bit. At the time I installed it, 64-bit version was considered experimental. Now the Cygwin website lists 32-bit and 64-bit versions on their website without any special mentions or recommendations on which one to use.
As a programmer, my experience is: unless specifically designed for capabilities of 64-bit CPUs, very few applications can get any gains by being recompiled for a 64-bit CPU. They might use more memory, though, since each memory pointer now uses 8 bytes rather than 4.
So, my question is: is there any benefit to choose 64-bit Cygwin over 32-bit ones? Should I upgrade my 32-bit installation sooner or later?
Performance/memory benchmark results for common usage patterns (e.g. running common UNIX commands, particular shell scripts etc.) would be very welcome.
If you've upgraded your 32-bit Cygwin to 64-bit, please tell your story - was the upgrade worth it?
EDIT: I've been using 64-bit Cygwin for a while now, and haven't really noticed any differences - good or bad - from the 32-bit version.
After running 32-bit Cygwin at work for a number of years, I recently upgraded to 64-bit. It was quite painless as you can run the two installations side-by-side. For me, there was no noticeable difference in performance though I did not run any benchmarks. The biggest gain for me in upgrading was starting with a new fresh install without any of the cruft that built up over the last few years.
The one disadvantage that I had when running 32-bit Cygwin was that the WoW64 subsystem filesystem redirector silently redirects 32-bit applications. This has the result that running ls /cygdrive/c/Windows/System32/ in 32-bit Cygwin doesn’t actually display the contents of %WINDIR%\System32, but instead %WINDIR%\SysWOW64. Attempts to access files in the %WINDIR%\System32 directory, e.g., ls /cygdrive/c/Windows/System32/nbtstat.exe fail with the error message:
ls: cannot access /cygdrive/c/Windows/System32/nbtstat.exe: No such file or directory
This means that Windows commands installed in %WINDIR%\System32 such as nbtstat and dnscmd aren’t available without modifying the PATH. The work-around for accessing 64-bit Windows files was that the %SystemRoot%\sysnative pseudo-directory had to be used, e.g., to run the nbtstat command, use /cygdrive/c/Windows/Sysnative/nbtstat.
32-bit applications on 64-bit Windows
WoW64 (Windows 32-bit on Windows 64-bit) is a subsystem capable of running 32-bit applications. It is included on all 64-bit versions of Windows and creates a 32-bit environment to run unmodified 32-bit applications on a 64-bit system using DLLs to provide the necessary interfaces.
Windows uses the %SystemRoot%\system32 directory for its 64-bit library and executable files. This is done for backward compatibility reasons, as many legacy applications are hardcoded to use that path. When executing 32-bit applications, WoW64 transparently redirects 32-bit DLLs to SystemRoot%\SysWoW64, which contains 32-bit libraries and executables.
32-bit applications are generally not aware that they are running on a 64-bit operating system. 32-bit applications can access %SystemRoot%\System32 through the pseudo directory %SystemRoot%\sysnative.
For 64-bit applications (such as Windows Command Prompt, cmd.exe) there’s no filesystem redirection:
See also: File System Redirection
I ran one I/O heavy benchmark, but even for this the noticeable performance gain is well worth it.
On a cygwin bash shell on Windows 7, I ran a find of many patterns piped to grep and then redirected to a file on the same hard drive in 32 and 64 bit:
32 bit
real 1m58.57s 68% more time
user 0m11.95s 41% more time
sys 0m40.83s 23% more time
64 bit
real 1m10.36s
user 0m8.50s
sys 0m33.05s
I have two Linux C/C++ programs that communicate using shared memory (shm_open, mmap, etc.) with mutex (pthread_mutex_*) and conditional variables (pthread_cond_*) in that shared memory. If both programs are compiled (using gcc) and run in 32-bit Linux (RHEL) machines, they communicate successfully. If, on the other hand, one process is compiled in 64-bit machine, the other is still compiled in 32-bit machine (due to legacy code), and both are run in a 64-bit machine, pthread_cond_wait in the 32-bit process waits forever even after the 64-bit process does pthread_cond_signal. What am I missing here. Or is it impossible to use conditional variables and mutex between a 32-bit and a 64-bit application?
I know about several projects for cross compiling between linux and Windows.
The Wine project is great for running windows application inside Linux.
andLinux is a linux running inside Windows.
My question is, can we compile a complete linux OS with a Windows compiler (like mingw32, visual studio , ...) in order to get a linux system which is fully compatible with the Windows PE executable format ?
As wine demonstrates, the PE format isn't really the problem with compatibility.
PE only defines how the program is pieced together at load time. Under windows, RUNDLL interprets it, loads all the program sections to memory, loads all the supporting dlls to memory and patches up the function pointers so that there is a program sitting in memory ready to go. (See http://msdn.microsoft.com/en-us/library/ms809762.aspx for more details. Its a good read!)
There is little stopping you writing a kernel module to do all of this. With the details in the page linked above it may not be to hard and someone may already have done it.
The real issue is the fundamentals of the operating system. Even if linux could load a PE, there would be problems around the fundamental difference in file names (\ or /) as well as the permissions model which is different and the windows registry which doesn't exist under linux. That's before you get into the different windowing model for GUIs.
Therefore the task of getting a windows program to run under linux is less about the program loader and much more about emulating all of the windows DLLs under Linux. As i understand it, this is the main heart of wine.
Can a COM 32 bit out of process server be used for GDI drawing on a 64 bit process?
Yes it can. For GDI object HANDLEs and window HANDLES, it's guaranteed that only the low 32-bits will be used in 64-bit mode, so it should be safe to pass these between 32-bit and 64-bit. Of course, the COM server must be out of process.
Quoting from this page
On 64-bit Windows, an out-of-process 32-bit COM server can communicate with a 64-bit client, and an out-of-process 64-bit COM server can communicate with a 32-bit client. Therefore, if you have a 32-bit DLL that is not COM-aware, you can wrap it in an out-of-process COM server and use COM to marshal calls to and from a 64-bit process.
Similarly, from this page
64-bit versions of Windows use 32-bit handles for interoperability. When sharing a handle between 32-bit and 64-bit applications, only the lower 32 bits are significant, so it is safe to truncate the handle (when passing it from 64-bit to 32-bit) or sign-extend the handle (when passing it from 32-bit to 64-bit). Handles that can be shared include handles to user objects such as windows (HWND), handles to GDI objects such as pens and brushes (HBRUSH and HPEN), and handles to named objects such as mutexes, semaphores, and file handles.
I'm trying to debug an application for an ARM processor from my x86 box. I some followed instructions from someone that came before on getting a development environment setup. I've got a version of gdbserver that has been cross-compiled for the ARM processor and appears to allow me to connect to it via my ARM-aware gdb on my box.
I'm expecting that when the process I've got gdb attached to crashes (from a SIGSEGV or similar) it will break so that I can check out the call stack.
Is that a poor assumption? I'm new to the ARM world and cross-compiling things, is there possibly a good resource to get started on this stuff that I'm missing?
It depends on the target system (the one which uses an ARM processor). Some embedded systems detect invalid memory accesses (e.g. dereferencing NULL) but react with unconditional, uncatchable system termination (I have done development on such a system). What kind of OS is the target system running ?
So i assume that the gdb client is able to connect to gdbserver and you are able to put the break point on the running process right?
If all the above steps are successful then you should put the break point before the instruction which crashes, lets say if you dont know where is it crashing then i would say once the application is crashed, the core will be generated, take that core from the board. Then compile the source code again with debug option using -g option(if binaries are stripped) and do the offline ananlysis of core. something like below
gdb binary-name core_file
Then once you get gdb prompt ,give below commands
gdb thread apply all bt
The above command will give you the complete backtrace of all the threads, remember that binaries should not be stripped and the proper path of all the source code and shared lib should be available.
you can switch between threads using below command on gdb prompt
gdb thread thread_number
If the core file is not getting generated on the board then try below command on board before executing the application
ulimit -c unlimited