How do I open OLEDB Prompt for 32-bit from x64 - c#

Good day everyone,
I am writing a C# application that will allow users to dynamically set the database they want to connect to (I'll work a bit with the database data and such, but that's not important). The important part is that I'm allowing my users to connect to data-stores from OLEDB using the code below.
ADODB.Connection connection;
MSDASC.DataLinks instance = new MSDASC.DataLinksClass();
if( (connection = instance.PromptNew() as ADODB.Connection) == null ) return;
This will open the very same Dialog that windows opens for *.udl files, and that's exactly what I want.
However, I hit a interesting problem to which your brightness could come in handy: some customer WILL have to browse for x86 drivers, and the vast majority will certainly use x64.
I know you can open x86 UDL files with the following command-line:
"C:\Windows\syswow64\rundll32.exe" "C:\Program Files (x86)\Common Files\System\Ole DB\oledb32.dll",OpenDSLFile "C:\myConnectionFile.udl"
When the default (64 bit) command is:
"C:\Program Files\Common Files\System\Ole DB\oledb32.dll",OpenDSLFile "C:\myConnectionFile.udl"
In other words: windows' allowing users to create entries in both fashion. I would like to do the same in my app, using the API.
I have considered the option of creating a temp UDL file and opening from the command-line above, which made my conversation with my technical lead rather unpleasant, so that's not an option.
All suggestions are welcome. I will not dismiss unsafe coding nor the thought of building wrapper in C++ if we get to that (although my C++ is inconveniently rusty nowadays).
Thank you all in advance and happy coding...

Good day fellow developers,
After a tedious and lengthy research process I have around the answer I was looking for.
In order to use OLEDB providers for both 32 and 64 bit platform from one single C# 64bit app I'll need to create an Out-of-Process Wrapper to the 32bit call, and make the call over IPC (Internal Process Calls). Because the amount of functionalities I'm exposing is moderate, the hindrance was just re-creating some method calls on the wrapper.
This blog helped me put the parts together, and now I'm able to determine what type of OLEDB connection I'll allow my user create, and I'm also able to perform all operations I need regardless of the Provider Architecture.
I hope this will benefit other people who might be having the issue.
If time (and NDA) allows, I'll get the code here for people to copy and try it later.
These links were also very useful on my research
http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/
Registering the DLL Server for Surrogate Activation
https: // msdn.microsoft.com/en-us/library/windows/desktop/ms686606(v=vs.85).aspx)
Writing Serviced Component
https: // msdn.microsoft.com/en-us/library/3x7357ez(VS.80).aspx)
How to: Create Serviced Component
https: // msdn.microsoft.com/en-us/library/ty17dz7h(VS.80).aspx)
Create Out-Of-Process COM in C#/.Net?http: // stackoverflow.com/questions/446417/create-out-of-process-com-in-c-net
Thanks everyone
D

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.

How to test whether a given functional code unit (C#) does NOT create/write any files to disk?

Imagine there's a mission-critical process that'll be used in a business which handles sensitive information (think of Credit Card, social security, patient records...etc). I would think this unit ideally should do whatever it has to do on-the-fly, meaning it won't intentionally write files to disk containing sensitive information. The idea here is that if the computer that runs this process is compromised, no sensitive information can be leaked, at least not by means of files.
What approaches could be taken to, say, come up with a unit test that will fail if the unit under test tries to write any file to disk?
There is the FileSystemWatcher (http://www.c-sharpcorner.com/uploadfile/puranindia/filesystemwatcher-in-C-Sharp/) however this requires you to know a specific directory. In your case this probably isn't very helpful since the program could write anything to disk any where. This introduces a unique problem. However, I have also found something called Detours from Microsoft. This appears to intercept all native win32 api calls. http://research.microsoft.com/en-us/projects/detours/ The issue with this is that its kind of hard to test, and integrating it into unit testing will be a challenge.
When you have to treat your software as "untrusted" in the sense that you need to prove it doesn't do something, testing becomes a complex task that requires you to run them on very controlled environments. When hooking in to the Win32 API, you will be deluged with API calls that need to be processed quickly. This can result in unintentional side effects because the application is not running in a truly native environment.
My suggestion to you (having worked several years doing software testing for Pharma automation to the exacting standards of the FDA) is to create a controlled environment, eg a virtual machine, that has a known starting state. This can be accomplished by never actually saving vmdk changes to disk. You have to take a snapshot of the file system. You can do this by writing a C# app to enumerate all files on the virtual drive, getting their size, some timestamps and maybe even a hash of the file. This can be time consuming so you may want (or be able) to skip the hashing. Create some sort of report, easiest would be by dropping them in a CSV or XML export. You then run your software under normal circumstances for a set period of time. Once this is complete, you run a file system analysis again and compare the results. There are some good apps out there for comparing file contents (like WinMerge). When taking these snap shots, the best way to do it would be to mount the vmdk as a drive in the host OS. This will bypass any file locks the guest OS might have.
This method is time intensive but quite thorough. If you don't need something of this depth, you can use something like Process Monitor and write the output to a file and run a report against that. However in my work I would have to prove that Process Monitor shows all IO before I could use it which can be just as hard as the method I spoke of above.
Just my 2 cents.
UPDATE:
I've been thinking about it, and you might be able to achieve fairly reliable results if you remove all references to System.IO from your code. Write a library to wrap around System.IO that either does not implement a write method, or only implements one that also writes to a log file. In this case, you simply have to validate that every time a write occurs using your library, it gets logged. Then validate using reflection that you don't reference System.IO outside of this new wrapper library. Your tests can then simply look at this log file to make sure only approved writes are occurring. You could make use of a SQL Database instead of a flat log file to help avoid cases of tampering or contaminated results. This should be much easier to validate than trying to script a virtual machine setup like I described above. This, of course, all requires you to access to the source code of the "untrusted" application, although since you are unit testing it, I assume you do.
1st option:
Maybe you could use Code Access Security, but the "Deny" is obsolete in .NET 4 (but should works in previous version):
[FileIOPermission(SecurityAction.Deny)]
public class MyClass
{
...
}
You may reactivate this behavior in .NET 4 using NetFx40_LegacySecurityPolicy
2nd option:
reducing the level of privilege may also works, as I know that downloaded app can't write on the disk and must use a special storage area.
3rd option:
Remove any reference to System.IO and replace by an interface that your code must use to write data to disk.
Then write an implementation that use System.IO (in a separate project)
In the nunit test, mock this interface and throw an exception when a method id called.
Problem is to ensure any developers will not call System.IO anymore. You can try to do this by enforcing coding rules using FxCop (or other similar tools)

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.

Categories