x64 x86 DLL AnyCPU - c#

I'm trying to hook a simple process using EasyHook. I'm programming/debugging in a x64 environment and compiling my DLL with AnyCpu config on Visual Studio C#.
The problem is that when trying to use this DLL (in another project, same Solution, compiling with AnyCpu too) in the inject library function:
RemoteHooking.Inject(TargetPID, "DivisionInject.dll", "DivisionInject.dll", ChannelName);
(2nd parameter is for 32-bit system. 3rd is for 64 bit.)
I don't know why this line is throwing an exception:
System.ArgumentException: the given 64-Bit library does not exist!
I thought that AnyCpu used to create my DLL, i could use the same file (DLL) in 32bits system and on 64 bits too. Is this wrong?
Thanks.

The AnyCpu setting basically means that the determination of how the process or library will be loaded or executed will be based at/on the point of execution/load. A library compiled as AnyCpu will be loadable by both a 32bit and a 64bit calling process. An executable compiled as AnyCpu will run a 64bit process on a 64bit machine and 32bit on a 32bit machine. See this thread for a discussion on the concept of the AnyCpu target.
If your caller is compiled as 64bit and set to AnyCpu, it will be attempting to load the 64bit library.

While it is now less common, it is possible to install Windows 32-bit on a 64-bit machine. In this case, only exe's built for 32-bit/AnyCpu will run. The converse is obvious. 32-bit machines can only run Windows 32-bit.
Thus the O/S bitness is the determining factor, not the hardware.
Windows 32-bit on a 64-bit machine was more common in enterprise shops, that didn't want to support both O/S's or 32-bit legacy applications running on Windows-64.

Related

Why am I Able to load x64 assembly into AnyCPU Prefer 32 bit executable?

I am working on a tool that loads different assemblies using System.Reflection's method Assembly.Load
Here is what i get
On a 64bit OS, if application configured with :
x64 loads x64 & AnyCPU Assembly
x86 loads x86 & AnyCPU Assembly
AnyCPU loads x64 & AnyCPU Assembly
Now when it's configured with AnyCPU Prefer 32 bit on 64 bit OS,it will be running on 32bit process as it said here
In .NET 4.5 and Visual Studio 11 the cheese has been moved. The
default for most .NET projects is again AnyCPU, but there is more than
one meaning to AnyCPU now. There is an additional sub-type of AnyCPU,
“Any CPU 32-bit preferred”, which is the new default (overall, there
are now five options for the /platform C# compiler switch: x86,
Itanium, x64, anycpu, and anycpu32bitpreferred). When using the
"Prefer 32-Bit" flavor of AnyCPU, the semantics are as follows:
If the process runs on a 32-bit Windows system, it runs as a 32-bit process. IL is compiled to x86 machine code.
If the process runs on a 64-bit Windows system, it runs as a 32-bit process. IL is compiled to x86 machine code.
If the process runs on an ARM Windows system, it runs as a 32-bit process. IL is compiled to ARM machine code.
The difference, then, between “Any CPU 32-bit preferred” and “x86” is
only this: a .NET application compiled to x86 will fail to run on an
ARM Windows system, but an “Any CPU 32-bit preferred” application will
run successfully.
My Question is : Why it loads x64 assembly without any problem? isn't that a strange behaviour?
I have seen this question ODP.NET x64 ANYCPU and Prefer 32-bit setting that support this proposition
.NET assemblies (exe and dll) don't contain x86/x64 assembly. They contain IL (intermediate language), which is architecture-independent. At runtime, the JIT turns the IL into x86/x64 machine code, as appropriate.
The "Any CPU" and "Prefer 32-bit" settings, etc, only change some bits in the header of the assembly, which tells the JIT what to emit at runtime. Only the bits in the header of the .exe matter: the exe dictates what the JIT will emit, and if the JIT is emitting e.g. x86 for the exe, it will do the same for all other assemblies which are loaded into that process.
Now, it might be a bad idea to load a dll which has the "x86" flag set into a process which the JIT is emitting x64 for: presumably that dll has a reason for specifying x86, and that's probably because it's invoking some native code which is compiled for x86. If you force it to run inside an x64 process, then it won't be able to invoke that x86 native code any more.
(Note that the landscape has moved since that quote you found: .NET Core now ignores "Prefer 32-bit", and AnyCPU defaults to x64).
The AnyCPU option allows the .NET virtual IL code in the executable binary file to be run on 32-bit as well as 64-bit computers.
AnyCPU prefers 32-bit indicates to run the process in 32-bit compatibility mode on x64 machines, unless of course some cause prevents that.
It is a parameter at runtime, not at compilation, as explained #canton7.
What is the purpose of the "Prefer 32-bit" setting in Visual Studio and how does it actually work?
If the application loads 64-bit DLLs, it means the code is executed (translated) in 64-bits native machine code, otherwise we would get a system error box.
Having a virtual assembly for a virtual OOP (single inheritance yet) computer is the purpose of DotNet.
If we look using any Task Manager we will see that the process is indeed x64 and not x32.
What is said in the following links about x32-x64 is valid for x64-x32:
Is it possible to load a 64-bit dll into a 32-bit process?
Calling 32bit Code from 64bit Process
Load 32bit DLL library in 64bit application
Process Interoperability
To be able to load a DLL of a different architecture than the highest one, we need certain things like creating a sandbox. For example, Renoise can run 32-bit VST while the DAW is 64-bit.

Will dll be loaded as 32bit or 64bit when exe is x86(32bit) on a 64bit machine?

In VS2008, for example, I have an exe built as x86(32bit) because I want it runs in 32bit even on 64bit machine. This exe will dynamically load other dlls through reflection and invoke.
Now my question is, if I build my dll as "All CPU", instead of x86, and when I run the exe host on a 64 bit machine, once my dll gets loaded, or called, the dll will be treated as 64bit or 32bit?
(My test shows it is treated as 32bit, but I want to confirm with you all. I think in general, 32bit cannot access 64bit. Since the exe is 32bit, so the dlls will be always loaded as 32bit?)
Thanks
Yes, you are correct. Unless you jump through some serious hoops, every part of the process (at least the user code parts) will be 32-bit.
If the DLL to be loaded it also marked as AnyCPU then there won't be any problems.
If you have an AnyCPU EXE (for example) which is running on a 64-bit computer (so it's an x64 process) which then attempts to load an x86 DLL (which is not marked as AnyCPU) then it will fail with a runtime exception (BadImageFormatException)

how to know which cpu to use in build (x86 x64 or AnyCpu)?

I'm using Windows 7 and x64 cpu.
Does it mean that I should always compile with "x64" option in Visual Studio? What about "dll", can I use x86 dll from x64 application? Probably there are other concerns?
This article contains a brief overview of each option.
Here's a small quote:
The default setting, Any CPU, means that the assembly will run
natively on the CPU is it currently running on. Meaning, it will run
as 64-bit on a 64-bit machine and 32-bit on a 32-bit machine. If the
assembly is called from a 64-bit application, it will perform as a
64-bit assembly and so on.
If the project is set to x86, this means the project is intended to
run only as a 32-bit process. A 64-bit process will be unable to call
into an assembly set as X86. Reasons to set your project as x86
include dependencies upon native DLLs that are only available in
32-bit or making native calls assuming 32-bit . Applications and
assemblies marked for x86 can still run on 64-bit Windows. However
they run under WOW64. Visual Studio itself runs under this emulation
mode since it is a 32-bit application.
Setting the project to x64 will specify that the assembly must run
under 64-bit Windows. Attempting to run the assembly on 32-bit
Windows or call the assembly from a 32-bit process will result in a
runtime error.
Generally speaking, you should use AnyCpu all the time.
If you have specific reasons to expect compatibility problems with that, then you'll need to choose x86 or x64 as appropriate.
As noted in the comments, dll's built against specific architectures can require you to build your assembly a certain way. This will be something you'll want to do when you need to, not otherwise.
No... the machine you write your code on/compile/build your software (EXE, DLL...) does not have anything to do with the question which target (x86 / x64 / Any).
IF you want the result of the build to run anywhere you use either x86 or AnyCPU. If you want the result to run on x64 only then you use x64.
There are some cases where you must use x86 or x64 - that is when you use some (3rd-party?) component/library/DLL/ActiveX etc. in your project which is 32 Bit only (then x86) or only 64 Bit only (then x64).
AnyCPU is what I generally recommend. You can see this issue discussed in depth at this SO post.
The only concern is that you cannot go backwards - you can't use an x64 assembly from a x86 application. AnyCPU alleviates this potential pitfall.

converting .net application 32 bit to 64 bit

I have got a .net application,
Class library (Target Platform set to Any CPU)
Winform Application (Target platform set to Any CPU)
Installer (Target Platform set to X86 and Detected dependencies set for .net framework(x86))
Now when I install this application through setup.exe on a 64-bit machine, it is installed in the Program Files [x86] folder; I guess this is WoW64 feature of emulating 32-bit environment on a 64-bit application.
Now when a client asks to convert it to 64-bit, why does it matter to him if the 32-bit version itself works fine through WoW64? would converting it to 64 bit result in performance benefits?
And when I try to convert it to 64-bit, do I need to change it for all, ie ,
Class Library (change Target platform to 64) (What if I skip this step?)
Winform Application (change target platform to 64) (What if I skip this too?)
Installer (change target platform to 64) [Detected dependencies listing doesn't show any .NET framework x64 option, why?]
Please suggest.
No conversion is necessary, your app already runs as a 64-bit process. Because you used AnyCPU on the EXE project. You installed it to the wrong folder but that doesn't matter much if no other process tries to start yours programmatically. That's exceedingly rare.
Verify this from TaskMgr.exe, Processes tab. A 32-bit process has *32 after its process name.
Make your client happy by changing the Setup project's TargetPlatform setting to x64 so it gets installed in c:\program files. Takes you a few minutes.
You can leave the .NET code projects on AnyCPU, however to install onto 64-bit without hitting the 32-bit WOW stuff you need to change the installer project property that you mention.
If you have custom actions in the installer, these may not work when you change to 64-bit. You might get a BadImageFormatException. To resolve this, you need to faff with the resulting MSI:
http://adamhouldsworth.blogspot.com/2010/10/64bit-custom-actions.html
It won't make much of a difference to the client if your application is standalone. There is no free performance benefit, other than access to more RAM, when going to 64-bit (though the JIT has different types of optimisations available).
The only situation I've seen where 64-bit is required is when you consume that DLL in another application, you cannot mix bit-ness in a single process.
Update: perhaps the lack of a 64-bit framework prerequisite is because you are using VS 2005?
http://social.msdn.microsoft.com/Forums/en-US/winformssetup/thread/7b00f4e9-64e3-4fb6-9906-880820ecda92
64 bit may or may not give performance differences. A 64 bit application can also utilize (way) more memory than a 32bit application.
If you launch an AnyCpu exe on a 64bit OS it should launch in 64bit (see in the task manager, 32bit processes are appended with *32 there). If you set the application to x64, the library must be either x64 or AnyCpu.
If you do not have native x64-only references you can leave your exe and dll as AnyCpu, but you will need to modify the setup to x64.
As for the framework, on an x64 machine (which is the only place an x64 app will run anyway), the framework always includes both 32 and 64 bit, found in C:\Windows\Microsoft.NET\Framework and Framework64 respectively.
Now when i install this application through setup.exe on a 64-bit machine, it is installed in the
Program Files [x86] folder; I guess this is WOW feature of emulating 32-bit environment on a 64-
bit application.
No, it has NOTHING to do with the program, only with the installer.
•Installer (Target Platform set to X86 and Detected dependencies set for .net framework(x86))
32 bit installer installes it in the 32 bit folder for programs, regarless whether the program is 32 or 64 bit.
Sadly you can not have one installer doing both - you need an installer for 32 and one for 64 bit in concept, by design.
This is totally a design decision on the MSI part and, again, has nothing to do with the program at all.

Convert 32 bit dll to 64 bit dll

I have the 32 bit compiled dll when I try to use it in 64 bit application it fails to load,
So I would like to convert the dll to 64 bit. Its working fine when the platform of the application changed from "Any CPU" or "x64" to "x86". But I want to use it under 64 bit, Since I am going to call the dll from ASP pages.
Please help me out with this.
Windows CAN NOT load a 32bit dll into a 64bit process - this is a limitation that you can not circumvent. This means that if your 32bit DLL does any P/Invokes to other 32bit DLLS (or uses any 32bit .Net DLLS) you will be entirely out of luck (you will need to run the entire website in 32bit).
You are not entirely clear on when it works and when it doesn't. Here are the explanations:
x86 - 32bit - Can not be loaded into a 64bit process.
x64 - 64bit - Can not be executed on a 32bit machine.
AnyCPU - dual - Can be loaded and executed in both environments.
In terms of AnyCPU:
64bit process on 64bit machine - DLL is loaded as 64bit.
32bit process on 32bit machine - DLL is loaded as 32bit.
32bit process on 64bit machine - DLL is loaded as 32bit.
In most cases it's fine to leave it as AnyCPU. However, as I said, if you are using any native or .Net 32bit DLLs you will need to make your entire application 32bit (and there is nothing you can, or Microsoft could, do about this).
x86 flag is usually set for a reason, so it may be bad idea to change it. But if you are absolutely sure, there's an utility, corflags.exe. I have it under C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin. Of course it will help with .net assemblies only.
If you want to load a pure C# DLL in both a 32 and 64 bit process, then the correct choice is AnyCPU. This will compile it the DLL as CPU agnostic and it will be loadable into either type of process.
I'm not 100% sure that's what you're asking though. If it's not can you clarify your question?
you can take a look at http://msdn.microsoft.com/en-us/library/ms164699%28VS.80%29.aspx

Categories