I know I read all about surrogate process, and I was able to create a surrogate COM but it either all works in 32bit or all works in 64bit.
What would be the correct structure?
1) 32.dll <- 64.com <- 64.exe
2) 32.dll <- 32.com <- 64.exe
I tried both of the above but I did not succeed to call the 32.dll?
I'm not too informed about the surrogate COM you refer to but I've solved this problem (Using a 32bit dll from a 64bit exe) by introducing a COM object in the middle:
32.dll <-> 32bit-out-of-process-com-server.exe <-> 64.exe.
Sorry this might be what you mean by 32.com, not sure, but make sure the intermediate COM object lives in an .exe (out of process) and not in a dll. This is for the same reason you can't load the original 32.dll into the 64 bit process.
This is defenetly what you want:
32.dll <- 32.com <- 64.exe
If it does not work, show more details HOW it does not work.
Also, if you are not doing much calls, you may communicate via sockets (just a backup plan).
Related
I've been filling myself up with notes trying to successfully create my first program on Windows 7 with NASM, but with a few self imposed stipulations (until I'm ready to move forward). In creating this first program, however, I have a ton of questions.
.
The stipulations for now are that:
I'm running Window 7 SP1 - 64-bit
I do not wish to use DOSBox so Interrupts 0x21-24 are likely not applicable
I do not wish to rely on C so this is all NASM
I would really like to avoid downloading Visual Studio or associated WDK tools if I can (this depends on whether or not I NEED to interact with the Windows API and relates to Question 2 below)
I've downloaded and installed MinGW
I'm writing my code in Notepad++ and saving as *.asm
I am linking using "ld" for now, but from what I've read, most seem to recommend "GoLink" (and Alink hasn't been updated in years?). I'll probably migrate to GoLink after I've assured myself that "ld" may be too limiting
I want to know if printing is possible without the use of the Windows API or C because of the code below?
.
The only code example that has worked for me in some capacity can be found here.
nasm is not executing file in Windows 8
.
;FILE: main.asm
[section] .text
global _main
_main:
mov eax, 6
ret ; returns eax (exits)
Linked:
c:\Users\James\Desktop>nasm -fwin32 main.asm
c:\Users\James\Desktop>ld -e _main main.obj -o main.exe
c:\Users\James\Desktop>main.exe
c:\Users\James\Desktop>echo %errorlevel%
6
.
My questions (a ton):
The fact that in the code above "ret" by itself gives output, although it just returns whatever is in EAX, is there a way to use it (or another directive outside of the Windows API) to return the contents of a variable (hopefully a string variable)? I tried to use ret with DOS calls, but as noted above, that definitely doesn't work because I'm on a 64-bit system.
In case I absolutely must use the Windows API, is the only way to interact with it by using the WDK tools? Is there some other way because that last time I downloaded Visual Studio and associated WDK tools it took up a ton of memory and massively slowed down my computer. Is there another way to make programs give output or print to the screen either by using internal commands or some other method to use API calls? One thread I admittedly skimmed (amidst 40 more tabs I have open) mentions "Russinovich's Windows Internals" but not a direct answer. At current every time I use code with the extern commands "ld" tells me that the references to commands like WinMain/WinMain#16 are undefined. In the same vein is there a table I can consult containing accurate calls to the API (i.e. _ExitProcess#4 vs. ExitProcess). I found this link to what think may be the NT API but I'm not sure it applies given my stipulations, but in reality, I'm just kind of confused:
http://j00ru.vexillium.org/ntapi/
In bits of code I've encountered I've seen directives for [Bit 16], [Bit 32], and [Bit 64]. [Bit 16] is likely ignorable, but I'm confused by the [Bit 32] and [Bit 64] for the following reasons which may not even be related: Via the code above I'm using the command, "nasm -fwin32 main.asm", then I'm linking it successfully and going on to receive output. For some reason - though I have not read the full "ld" documentation yet - when I use the command "nasm -fwin64 main.asm" and link it in the same way I receive an error saying "main.obj: File not recognized: File format not recognized". I don't understand why differentiating between 32 and 64 while I'm on a native 64-bit machine causes an error although this probably is just unique to ld.
.
In the meantime I'll be reading this question and will post an update it if helps: Executable isn't compatible with 64 bits processor
I can't answer some parts in great detail, so I expect somebody either putting up better answer, or feel free to edit this one.
you are linking against default clib, so your _main is called after Clib is initialized, the ret with value in eax is like return 6; in C++. Then Clib correctly destructs everything and calls windows exit process with exit code 6. You can return only int from _main, and I'm not even sure if full int is propagated to exit process call, or only 8 bit value is used. So you can return single char in ASCII encoding, if you treat that number as char.
You must call Windows API, if you want to display something in console/window, or write something into file, ie. do any output (and of course also for input). There's no peripheral available to win32/64 executable directly, like in DOS CGA/EGA/VGA text modes accessible trough int 10h or video ram at B800:0000. Any try to access some I/O peripheral directly should result into access violation. Only Win API should be legal for user-level application code.
How much of WDK you need I have no idea, haven't developed anything for windows for years. I think it's even possible to create executable without WDK, which would provide correct externs and dependencies on kernel32.dll and similar, but the amount of effort is way beyond simply using proper parts of WDK or clib from MinGW.
I think your linker is set to default to 32b executable, you have to figure out what kind of object format is produced by nasm for -fwin64 and how link that one with ld.
Why the difference. The 64b OS can run 32b binaries. But you can't mix 32/64 in single executable so easily (if at all). So you are either producing 32b or 64b binary, and you have to adjust everything to it (asm instructions used, directives and options, and WinAPI calls).
A very strange, presumably meant to be helpfull behaviour of Visual Studio 2012.
When I enter a double in vb.net like:
Dim myD as Double = 1.4
When I hit enter of move my focus another way, the formatting kicks in and changes the above to:
Dim myD as Double = 1.39999999999999998
or 1.6 as
Dim myD as Double = 1.6000000000000001
This behaviour does not appear to happen for all doubles. 1.3, 1.5, 1.7 and 1.8
See this youtube movie for the behaviour in action:
http://youtu.be/afw4jg58-aU
Why, and more important, how can I prevent this?
Edit:
Extensions installed are:
Second Edit
The behaviour seems to have gone away. I do not know what has caused this so for future reference this is useless to anyone, but for now, I'm happy that I don't have to go troubleshooting as suggested.
The exact same issue is also reported in this question. Which applied to VS2010, otherwise without a usable answer.
This is an environmental problem, code is getting loaded into Visual Studio that messes with the FPU control word on your machine. It is a processor register that determines how floating point operations work, it looks like this:
The Rounding Control bits are a good source of trouble like this, they determine how the internal 80-bits precision floating point value is truncated to 64-bits. Options are round-up, round-down and round-to-nearest. The Precision Control bits are also a good candidate, options are full 64-bit precision, 53 and 24 bits.
Both VS2012 and the .NET Framework rely on the operating system default, with the expectation that this will not change afterwards. Pretty hard to diagnose trouble arises when code actually does change it, your observation strongly fits the pattern. The most common troublemakers are:
code that uses DirectX without the D3DCREATE_FPU_PRESERVE option. DirectX reprograms the precision and rounding control bits to squeeze out a bit more perf.
code that was written in an older Borland language product. Its runtime library initializes the FPU control word in a non-standard way. Otherwise a generic problem with software that relies on old runtime library or an old legacy initialization that was carried through in later releases.
in general, any code that uses a media codec or media api. Such code tends to reprogram the FPU to squeeze out perf for the same reasons that DirectX does. Especially notorious in a product I worked on which uses such codecs heavily. The codebase was peppered with calls that reset the FPU control word after making a call into external code.
Finding and eliminating such code can be very difficult. DLLs get injected into another process by a large variety of well-intended malware. The SysInternals' Autoruns utility can be very useful, it shows all the possible ways code can be injected with an easy way to disable it. Be prepared to be shocked at what you see and readily disable stuff that doesn't carry a Microsoft copyright.
For dynamic injection, you'll need a debugger to see what is loaded into VS. Start VS again and use Tools + Attach to Process to attach to the first one, selecting the unmanaged debugger. Debug + Windows + Modules shows you what DLLs are loaded. Do beware that the DLL can be transient, a shell dialog like File + Open + File will dynamically load shell extensions into VS and unload them again afterwards. Good luck with it, you'll need it and sometimes the only fix is a rather drastic one.
I had the exact same issue with Visual Studio 2012.
The "solution" if it happens to you is:
write your number in your code
let VS screw it up, e.g. when you move to another line
CTRL-Z to revert VS mess
continue writing your code
I'm trying to recreate a program that uses javascript to open a connection to a PLC and then display all sorts of information on a web page. I'd rather have it in a form in MS Access for various reasons, and have spent forever trying to find the right dll to use (Jet32X.dll, if anyone is curious). I finally tracked the CLSID called out in the javascript back to a registered class for the PLC, and I'm trying to create that object in VB code. It won't get any further than the Dim As New line, however, throwing runtime error 429: "Active X Component Cannot Create Object." Really wish I had some more information about why.
I know the class is registered, since that's how I found it in the first place. I know the DLL file isn't corrupted, since the program runs fine from the JS version. I have a sneaky suspicion that there's some sort of incompatibility going on here, since the PLC and supporting software is pretty old, and I'm working in Microsoft Access 2013 (and its associated VBA). I can't really think of a good way to verify this, however. Does anyone have any other ideas? Could anything else be causing this problem?
Figured it out; in case anyone else runs into this sort of issue:
32bit COM dlls will not run in 64bit applications. If you don't want to go back and reinstall 32bit versions of whichever application you're using, one of the easiest workarounds is using dllhost.exe as a surrogate.
You can read a little about it here, but I found this tutorial easier to follow.
I send a new reply just to recap the information and avoid anyone that stumbles in the same problem again after me wasting precious time. All the steps involved assume that you already correctly registered the dll you are trying to use.
How to make a 32bit COM Dll work in a 64bit application
The "easy" solutions involve using the Dll Surrogate method, which runs dllhost.exe and as an intermediary process in 64bit to expose the underlying 32bit dll. When done correctly this works seamlessly without any special measure needing to be taken in neither in the 32bit dll nor in the 64bit application.
There are two main approaches to this:
Using Oleview.exe (i.e. using a GUI)
Oleview can be obtained downloading the Window 10 SDK.
In order to use Oleview it you have to:
Download the Window 10 SDK at the following link:
https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
Go to C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86 to find the 32bit version of oleview.exe
ONLY THE FIRST TIME: run it as administrator to avoid see the message related to the impossibility to load iviewer.dll
In the left pane, Object Classes -> All Objects and find your dll name.
WARNING: you may find many entries for your dll. In particular each class has got its own entry such as YourProjectName.YourClassName
In the right pane, go to Implementation -> Inproc Server, and tick Use Surrogate Process. Leave the Path to Custom Surrogate empty to use the system default surrogate, that is dllhost.exe.
You can check the procedure went correctly by returning to the Registry tab, always in the right pane of the Oleviewer and make sure that now under CLSID = {yourAppIdHere} [DllSurrogate] = is listed among the entries.
Edit manually the Windows Registry
The Oleview method is recommended, but the manual method may be ok if you need to do this only once. The tutorial that NickGlowsinDark mentions was moved to https://techtalk.gfi.com/32bit-object-64bit-environment/ .
In order to avoid problems in the future with the page going offline I copy and paste here the most important steps involved. All credit goes to Emmanuel Carabott that is the original author of the tutorial, I added the first two steps in order to facilitate you in the process.
Open the Registry Editor (Windows+R -> regedit), and follow the following steps:
You first need to find your dll GUIDs. You will probably have many GUIDs, one for each of the classes that your dll exports. I find it's easier to find the GUIDs if you go to HKEY_CLASSES_ROOT\YourProjectName.YouClassName. It is the (Default) String Value you find under the Clsid key.
I recommend you find all the GUIDs first and make a note of them in order to have an easier time with the steps after this one.
Then, as Emmanuel Carabott kindly explains in his article, you have to do the following for each of the GUIDs you found:
Locate your COM object GUID under the HKey_Classes_Root\Wow6432Node\CLSID\[GUID]
Once located add a new REG_SZ (string) Value. Name should be AppID and data should be the same COM object GUID you have just searched for.
Add a new key under HKey_Classes_Root\Wow6432Node\AppID\
The new key should be called the same as the com object GUID
Under the new key you just added, add a new REG_SZ (string) Value, and call it DllSurrogate. Leave the value empty.
Create a new Key under HKey_Local_Machine\Software\Classes\AppID\
Again the new key should be called the same as the COM object’s GUID. No values are necessary to be added under this key.
That’s it, your COM Object should now be accessible from a 64bit environment and can be used like a regular COM Object.
The default base address for an .exe built in Visual Studio is 0x00400000.
The default base address for d3dx9_30.dll and odbcint.dll (which both live in %windir%\system32) is also 0x00400000. So by default, exes that link to either of these dlls will have a runtime address collision. The OS automatically relocates the dll to a different base addresses and fixes up pointers as needed, and I can see this happening when I attach the VS debugger: The relocated module gets an exclamation icon overlay.
Rebasing system DLLs is a really bad idea, not to mention nearly impossible to do on user systems. So I have decided to rebase my exes to prevent this address collision and thus prevent runtime rebasing.
If I change my client EXE to a different base address to move it out of d3dx9_30.dll's way, it works fine: no address collision, no relocation, no fixups.
But if I change my server EXEs to a different base address to move them out of odbcint.dll's way, it does not work.
odbcint.dll is 0x17000 bytes in memory and prefers base address 0x00400000. I tried basing my EXEs at 0x00420000, then at 0x00660000. Still odbcint.dll gets relocated at runtime. I profiled with depends.exe, which showed that there is no other module attempting to claim this address before odbcint.dll loads.
Does anyone have a theory explaining why I can't get odbcint.dll to load at its preferred address?
Update:
vadump shows that by the time I enter main() the memory at 0x00400000-0x00470000 is claimed as 'UNKNOWN_MAPPED'. I have been unable to find more information about what exactly this means. I presume that some system dll is reserving this memory at load time; my debugging-fu is not strong enough to discover which, why, or precisely when.
If you download VADump (available in the Windows Resource Kit:), you can see exactly what module is hitting those pages and causing it to miss its address. (Run vadump -op pid.)
You didn't say what OS you're working on, but on Vista/2K8+ you should also know about ASLR.
Sometimes, a customer (or tester) needs a patch on an installation of the product I work on. Sometimes, I brew him a dll containing the fix, so that he can test it. He overwrites the old dll with the new version and restarts the app.
Every now and then, it appears that the 'new' dll isn't actually used, although I'm absolutely positive that my brand new sparkling bytes were copied over the old dll.
To make things worse, after the first 'hotfixed' run, when restarting the application, the new functionality clearly is loaded..., and the old behaviour is never to be seen again.
Has anyone observed this behaviour? Would it be possible that the XP loader sort of 'caches' recently used dlls?
(Note: this happens on XP SP2)
Yes, this is possible. Windows does not let you delete files which are in use, but strangely enough (for Windows at least) you can rename a DLL while it is still in use. If your tester uses something along
rename dll to dll.orig
copy new dll
restart application
it can happen, that the dll.orig version is still used if it has not been completely unloaded (because some still started app still has a reference to it).
This has bitten me a few times, too. I therefore usually change some behavior (mostly something of the header of the log-file) so that I can be sure that something has not been happened.
To workaround is simply: close all programs that use this DLL. Sysinternals Process Explorer helps to find the applications that use it.