64 bit & 32 bit Registry issue in Windows (Programming in c#) - c#

I'm trying to get data from the registry of windows to my software but there is one thing i'm having trouble with it:
if my software runs on a 64 bit system the registry path will be :
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\AVAST Software\Avast ProgramFolder
and if my software runs on 32 bit system the registry path will be :
HKEY_LOCAL_MACHINE\SOFTWARE\AVAST Software\Avast ProgramFolder
What can i do ? to double check every time ?
maybe i will check only the second option(without the \Wow6432Node\) and when the software runs on 64 bit it will automatically add to the path the \Wow6432Node\ ?
What is the best solution for this issue ?

Before you do anything further, you should have a good read of the documentation of the registry redirector. It's really important that you have a clear understanding of what it does.
OK, now that you understand the registry redirector, let's look at how to tackle your problem. You have a few options. The simplest is build your program to target x86, and access HKEY_LOCAL_MACHINE\SOFTWARE\AVAST Software\Avast ProgramFolder no matter what bitness system you run on. That way your code will always run in a 32 bit process and so always see the 32 bit view of the registry. The registry redirector will handle the mapping onto the true physical Wow6432Node transparently.
Alternatively, if you must use AnyCPU, and must cater for running inside a 64 bit process, you need to use the RegistryView enumeration. This allows you to read from the 32 bit view of the registry, even from a 64 bit process. But again you access HKEY_LOCAL_MACHINE\SOFTWARE\AVAST Software\Avast ProgramFolder but ask for that key with respect to the 32 bit view of the registry.
The golden rule with the registry redirector is that you must not hard code Wow6432Node into your paths. The documentation says it like this:
Redirected keys are mapped to physical locations under Wow6432Node. For example, HKEY_LOCAL_MACHINE\Software is redirected to HKEY_LOCAL_MACHINE\Software\Wow6432Node. However, the physical location of redirected keys should be considered reserved by the system. Applications should not access a key's physical location directly, because this location may change.
Don't be tempted to break that rule. The system provides mechanisms to read from the 32 bit view in a supported manner.

You don't state which version of the framework you're using, but if you're using 4+ then you can use Environment.Is64BitOperatingSystem to determine the bitiness of the environment and therefore look/write to the correct place.

Related

Change hardcoded value in executable

A new game released has been provided with server files that do not currently have the option of configuring an IP Address/Port for binding. Unfortunately this limits the ability to run more than one instance of the application per machine as it is hard-coded to port "12345".
Many years ago I was using c++ and hex editors to change hard coded values like this and while that knowledge has long since been forgotten, would it be possible to improve this by writing a secondary application to change that value at runtime?
You still can use hex editor in order to change the hard coded constant.
Another way is to use debug api, provided by any decent OS. In Windows it is WriteProcessMemory function.
It looks following way - the launch application runs the modified application in debug mode. Changes needed constant and then runs it.
Of course, the modified application may use anti debugging techniques - in this case the solution is not trivial.
In both cases, you have to know where this value resides in the memory (executable file). This way some reverse engineering have to be provided.
Note, after the last question edits: All this answer is for native executable files. For managed code it probably is more complex.

Enable ODP.Net logging

Can anyone help me with enabling ODP.Net logging on a Windows XP machine? I googled and found following link but it did not work for me.
http://download.oracle.com/docs/html/E10927_01/featConfig.htm
I set the "TraceLevel" setting to "63" in registry but it did not help
Basically I want to capture all the database call happening from my C# code through the log.
I wish there was a tool like "SQL Profiler" for Oracle.
I had the same issues on certain machines when troubleshooting some issues with Oracle Support. I found that changing the path to the output file a couple of times and multiple restarts finally forced the ODP client to start logging. Make sure that the output file is to a directory that your calling application identity has access to.
Check the following things in the registry keys. Here is an example from my machine for .net4 and 11.2.
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\ODP.NET\4.112.2.0
32 or 64 bit (correct node)
Change the Trace Level to 8 (or 64 I think for complete logging)
Change the Trace Option = 1
Set a valid TraceFileName
Note that the trace will default to go in the root of the C drive. For Windows 7 and later, this requires administrator privilege or it will just fail silently. So either make sure your app is running as administrator or that you change the path of the file.
Also note, that if you want to trace ODP.NET fully managed, you need to put the settings inside the app or web config file, not the registry, AND the settings for TraceLevel are different (1 through 7).
And finally, when tracing unmanaged ODP.NET remember that there is a separate WOW registry node for 32 bit Windows. If your app is 32 bit, don't accidentally set it under the 64 bit portion of the registry.
You can also use AOP-based approach - generate proxy using library like Castle Dynamic Proxy, intercept the calls you're interested in and log the arguments like SQL and parameters. This is more powerful method in my opinion although it can somehow affect performance. See this Gist for sample implementation: https://gist.github.com/Buthrakaur/b1124c08f8521f39f8fd

How to make my program not run on other computers?

I have an assignment, and it has (amongst others) two demands:
make an installer
make it so that if it is installed on one computer, anyone trying to run the same files on another computer will fail.
I'm using VS9 (2008) express, I think I can do the installer part, but I'm not sure how to do the "security" part. I don't need any hard to crack safety, just a dumb condition that will stop most users from copying the files to another computer. (Like checking the MAC address).
Any ideas?
EDIT:
I would like to check the MAC address but I want the program finalized during installation. Meaning that after I install I can't move the program to another machine. It also does not have to be a very smart or difficult condition, just bare minimum. I just don't know how to do it in the installation.
EDIT:
It's sad I don't have the complete VS then I would be able to do it easily.
If you're looking for some way to mark the first computer as the "authorized" computer, then you need some external service you can ask for permission to launch.
The first person to ask permission would be allowed, the rest would be prevented.
You'll also need to come up with some way of identifying a particular instance of your application that's different for every install.
If your app needs to be authorized for the machine, then you will need to calculate some fingerprint for the machine it can use each time (eg across installs).
[Edit]
This approach is useful when you're worried about copies of the installer being distributed as well. You did specify that its ok to install on multiple machines, so in that case MasterMind's approach is superior. It will work, and does not requires a 3rd party server
[Edit 2]
If you're looking for info on how to build a custom installer, try here
First of all, come up with some function to generate a unique PC signature, like Windows does for activation.
Your installer will be creating this signature and writing it to a local file (better encrypted). You can create a simple console executable to generate this file and include that executable into your installer package, setting it up to run silently after the successful installation.
Your program when starting will be creating the signature again using the same algorithm and comparing it to the one created during installation. If the new signature is different from the original one or the signature file is missing, then exit without loading the UI.
ADDED: If you don't need it very complex, you can just choose a few unique values like the MAC address you suggested, maybe the hard drive serial number, mainboard serial number, concatenate them into a single string and generate the hash out of it.
This approach will allow for an unlimited number of copies to run (but each installation will only be workable on one single machine where it was installed). If you stick to the identification by hardware (or OS product key as well), then the application can run on various OS installations on the same machine.
This strategy, however, implies that you control all installations (or perform them yourself) or absolutely trust your client not to install additional copies elsewhere or distribute your installer. If you need that kind of protection as well, then you should consider product activation. It can be quite complicated if you do it yourself. There are however third party products to help you. Some offer product activation services: Google: activation service
Once you have a decent fingerprint, the rest is easy. Personally I'd take something like the MAC address and the windows product ID (at HKLM\Software\Microsoft\Windows\CurrentVersion\ProductId) and use a hashing algorithm to get something reasonably obscure.
edit:
Here's a question that shows you how to get your MAC address as a string:
Read MAC Address from network adapter in .NET
Then grab your windows product ID (in case they don't have a network adapter) from the above registry key. Concatenate both strings and do a GetHashCode() (or use your favorite hashing algorithm) on the result. This is a simple way to get a UID for a computer.
Write the hash to a file or to a registry entry when your installer is executing and check it when your program starts up.
Consider using two or more values that potentially identify the machine, e.g.
Windows product code
Volume serial number of the C: drive
MAC address of an ethernet interface
And if just one of these changes but the others match, update that one value in the registry and continue running normally. Hard drives get replaced (regularly), Windows gets upgraded (occasionally), Ethernet adapters get replaced (rarely but it does happen.) It can be very frustrating when old software stops working because of this.
Bare minimum answer, assuming the only requirement here is that the software should run if installed through the installer, and won't run if copied to another computer:
Write a simple key to the registry. Most likely your product's version number, incase they copy a newer version to the computer, it has a different number to check for.
In your software, just make sure this registry value exists.
For packaging installations, I enjoy using NSIS which has simple methods for writing to the registry.
I like the idea of checking the MAC address.
I have also seen product key/online activation combinations where you enter the product key and the software contacts a web service that logs the product key and # of installs.
This isn't the most secure option or anything but you did say it didn't have to be smart...
On install, you could set a program variable to be the machine name (or a hash of it if you like).
Like:
myProgram.Properties.Settings.Default.Machine = System.Environment.MachineName;
myProgram.Properties.Settings.Default.Save();
then check that on startup:
if (System.Environment.MachineName != myProgram.Properties.Settings.Default.Machine)
{
MessageBox.Show("Can't run on this computer");
this.Close();
}
To get the installer to only work for one machine, you'd pretty much have to build it for the target machine. I dont think it would be possible to make an installer that assumes the first machine it sees is it's mommy and is attached for life.
-1 for clinging to an antiquated license-restriction policy that is a poor practice in general. Hardware dongles and "device detection" are SO 1990.
People own more than one computer. They buy new computers. They upgrade their computers. Computers break, resulting in replacement of motherboards or network cards.
All of these, given your design, will result in honest, paying customers being locked out of what they've paid for and will have to call you for support to "reset" their activation.
And each time you do so, your overhead will increase by, very likely, more than the actual cost of a license.
I'm not suggesting you give up and just send your app off to the torrentverse, but you should think more creatively about how to allow customers the freedom to use what they paid for, keep your support costs low, and discourage pirates.
One creative solution would be to cache the user's settings on your server, keyed by their serial number, and synchronize them every time the application starts and is connected to the Net.
This will allow a user to install the app on, say, both a laptop and desktop, and will actually be a value-add for customers because their settings are synchronized between devices.
But it actively discourages users from sharing their license key, since doing so would mean they would be sharing their settings with every pirate user, or that they would have to remember to stay disconnected from the Interwebs when they open or close the app.

A different Approach for anti-virus . Am I going in the right direction?

I'm currently conceiving a system that works like an anti-virus, but also uses the White Listing i.e
Preventing Viruses from Running by having a database of Known legitimate Programs
Yes , there is the Windows UAC, but still many viruses "work around" it. I'm planning on a more reliable system.
My system has also a database of known threats (cryptographic hash).
Is this approach viable,
What are the possible loop holes in this approach
I understand that there has been a lot of attempts at this. But still I want to try it out.
I'm planning to use C# and .Net for a prototype may be i'll move on to C++ for performance later
Update:
Thank you all for your time and thoughts.
I decided to do some more research in this area before actually designing something
Espcially as pointd out below the Zeroday threat problem
What about DLLs used by executables? Do you hash them too? A virus can replace a DLL.
This has been brought up before, and there are products out there which do that. (Faronics Anti-Executable works like this)
There are two main problems with this approach:
A virus can embed itself into any file; not just EXEs. Programs can load DLLs and other bits of code(macros, scripts, etc), and programs can contain bugs(such as buffer overflows) which can be exploited by malicious documents and other files.
Every time you patch a system or otherwise legitimately modify the software, you also need to update the white list.
There is products like Appsense Application Manager that do this already. It was temporarily pitched as a security product but they changed tact and focused it on licensing. I think it's because it didn't work too well as a security product.
If you are planning to work with a limited set of applications and you can work with application developers you can use a code signing model. You can find a similar approach in most mobile operating systems. You have to sign all the executable modules including libraries and need to verify they have a valid signature and not modified using a root certificate.
If you are only planning to white list applications based on their hash value you need to make sure your white listed applications verify any modules they use before they load. Even if the applications/installation files are digitally signed it does not guarantee that a library will be modified later in a malicious way.
In reality, it is not even enough to only verify executables and libraries. For example, Xbox Linux hack utilizes a malicious save file. It is a specially prepared save file that causes a legitimate and signed application behave in unexpected ways. And, of course it is not possible to white list a save file based on its hash value.
Another problem with keeping a database is zero day attacks. You need to be ahead of the curve for creating hash values for new attacks and propagating these updates to your users otherwise they will be vulnerable all new attacks. Unless you only allow only white listed applications to be executed and that would be really restrictive.
IMHO, it is really difficult build such a system on open platfom. Good luck with it.

How do I store information in my executable in .Net

I'd like to bind a configuration file to my executable. I'd like to do this by storing an MD5 hash of the file inside the executable. This should keep anyone but the executable from modifying the file.
Essentially if someone modifies this file outside of the program the program should fail to load it again.
EDIT: The program processes credit card information so being able to change the configuration in any way could be a potential security risk. This software will be distributed to a large number of clients. Ideally client should have a configuration that is tied directly to the executable. This will hopefully keep a hacker from being able to get a fake configuration into place.
The configuration still needs to be editable though so compiling an individual copy for each customer is not an option.
It's important that this be dynamic. So that I can tie the hash to the configuration file as the configuration changes.
A better solution is to store the MD5 in the configuration file. But instead of the MD5 being just of the configuration file, also include some secret "key" value, like a fixed guid, in the MD5.
write(MD5(SecretKey + ConfigFileText));
Then you simply remove that MD5 and rehash the file (including your secret key). If the MD5's are the same, then no-one modified it. This prevents someone from modifying it and re-applying the MD5 since they don't know your secret key.
Keep in mind this is a fairly weak solution (as is the one you are suggesting) as they could easily track into your program to find the key or where the MD5 is stored.
A better solution would be to use a public key system and sign the configuration file. Again that is weak since that would require the private key to be stored on their local machine. Pretty much anything that is contained on their local PC can be bypassed with enough effort.
If you REALLY want to store the information in your executable (which I would discourage) then you can just try appending it at the end of the EXE. That is usually safe. Modifying executable programs is virus like behavior and most operating system security will try to stop you too. If your program is in the Program Files directory, and your configuration file is in the Application Data directory, and the user is logged in as a non-administrator (in XP or Vista), then you will be unable to update the EXE.
Update: I don't care if you are using Asymmetric encryption, RSA or Quantum cryptography, if you are storing your keys on the user's computer (which you must do unless you route it all through a web service) then the user can find your keys, even if it means inspecting the registers on the CPU at run time! You are only buying yourself a moderate level of security, so stick with something that is simple. To prevent modification the solution I suggested is the best. To prevent reading then encrypt it, and if you are storing your key locally then use AES Rijndael.
Update: The FixedGUID / SecretKey could alternatively be generated at install time and stored somewhere "secret" in the registry. Or you could generate it every time you use it from hardware configuration. Then you are getting more complicated. How you want to do this to allow for moderate levels of hardware changes would be to take 6 different signatures, and hash your configuration file 6 times - once with each. Combine each one with a 2nd secret value, like the GUID mentioned above (either global or generated at install). Then when you check you verify each hash separately. As long as they have 3 out of 6 (or whatever your tolerance is) then you accept it. Next time you write it you hash it with the new hardware configuration. This allows them to slowly swap out hardware over time and get a whole new system. . . Maybe that is a weakness. It all comes down to your tolerance. There are variations based on tighter tolerances.
UPDATE: For a Credit Card system you might want to consider some real security. You should retain the services of a security and cryptography consultant. More information needs to be exchanged. They need to analyze your specific needs and risks.
Also, if you want security with .NET you need to first start with a really good .NET obfuscator (just Google it). A .NET assembly is way to easy to disassemble and get at the source code and read all your secrets. Not to sound a like a broken record, but anything that depends on the security of your user's system is fundamentally flawed from the beginning.
Out of pure curiosity, what's your reasoning for never wanting to load the file if it's been changed?
Why not just keep all of the configuration information compiled in the executable? Why bother with an external file at all?
Edit
I just read your edit about this being a credit card info program. That poses a very interesting challenge.
I would think, for that level of security, some sort of pretty major encryption would be necessary but I don't know anything about handling that sort of thing in such a way that the cryptographic secrets can't just be extracted from the executable.
Is authenticating against some sort of online source a possibility?
I'd suggest you use a Assymmetric Key Encryption to encrypt your configuration file, wherever they are stored, inside the executable or not.
If I remember correctly, RSA is one the variants.
For the explanation of it, see Public-key cryptography on Wikipedia
Store the "reading" key in your executable and keep to yourself the "writing" key. So no one but you can modify the configuration.
This has the advantages of:
No-one can modify the configuration unless they have the "writing" key because any modification will corrupt it entirely, even if they know the "reading" key it would takes ages to compute the other key.
Modification guarantee.
It's not hard - there are plenty of libraries available these days. There're also a lot of key-generation programs that can generate really, really long keys.
Do take some research on how to properly implement them though.
just make a const string that holds the md5 hash and compile it into your app ... your app can then just refer to this const string when validating the configuration file

Categories