How to uniquely identify computer (mainboard) using C#(.Net/Mono, local application)?
Edition. We can identify mainboard in .Net using something like this (see Get Unique System Identifiers in C#):
using System.Management;
...
ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_MotherboardDevice");
...
But unfortunately Mono does not support System.Management. How to do it under Mono for Linux? - I don't know :(
Write a function that takes a few unique hardware parameters as input and generates a hash out of them.
For example, Windows activation looks at the following hardware characteristics:
Display Adapter
SCSI Adapter
IDE Adapter (effectively the motherboard)
Network Adapter (NIC) and its MAC Address
RAM Amount Range (i.e., 0-64mb, 64-128mb, etc.)
Processor Type
Processor Serial Number
Hard Drive Device
Hard Drive Volume Serial Number (VSN)
CD-ROM / CD-RW / DVD-ROM
You can pick up a few of them to generate your unique computer identifier.
Please see: Get Unique System Identifiers in C#
You realistically have MotherboardID, CPUID, Disk Serial and MAC address, from experience none of them are 100%.
Our stats show
Disk serial Is missing 0.1 %
MAC Is missing 1.3 %
Motherboard ID Is missing 30 %
CPUID Is missing 99 %
0.04% of machines tested yielded no information, we couldn't even read the computer name. It maybe that these were some kind of virtual PC, HyperV or VMWare instance, or maybe just very locked down? In any case your design has to be able to cope with these cases.
Disk serial is the most reliable, but easy to change, mac can be changed and depending on the filtering applied when reading it can change if device drivers are added (hyperv, wireshark etc).
Motherboard and CPUID sometimes return values that are invalid "NONE", "AAAA..", "XXXX..." etc.
You should also note that these functions can be very slow to call (they may take a few seconds even on a fast PC), so it may be worth kicking them off on a background thread as early as possible, you ideally don't want to be blocking on them.
Try this:
http://carso-owen.blogspot.com/2007/02/how-to-get-my-motherboard-serial-number.html
Personally though, I'd go with hard drive serial number. If a mainboard dies and is replaced, that PC isn't valid any more. If the HDD drive is replaced, it doesn't matter too much because the software was on it.
Of course, on the other hand, if the HDD is just moved elsewhere, the information goes with it, so you might want to look at a combination of serial numbers, depending what you want it for.
How about the MAC address of the network card?
Related
I have an application that reads and sends data from/to 2/3 machines attached to the PC through keyspan USB to Serial adapter. Sending/receiving works well.
My problem is that on restart of the PC, the COM ports are assigned "at random", often swapped. That makes automatic processing of data impossible.
I tried to manually set the COMm ports in the Device Manager and with Keyspan assist software without success.
Questions:
how to fix COM ports on Windows so after restart they are always same?
How to assign COM ports with java/c#/powershell (get ports setting and save it(once configured), set on next restart from configuration file)?
Thank you in advance for any suggestions.
Roman
thank you very much for your help.
In the mean time I've slightly modified the solution from http://syswow.blogspot.ch/2013/03/change-device-com-port-via-powershell.html
Unfortunately my current keyspan device ID's are not stable (KEYSPAN*USA19HMAP\00_00 and KEYSPAN*USA19HMAP\01_00 and KEYSPAN*USA19HMAP\02_00), as noted before. These ID's can and often change in between restarts (I suppose as Windows is "registering" them).
I have swapped to another vendor and now I get stable ID's / COM's (FTDIBUS\VID_0403+PID_6001+FTH8ZL5AA\0000 and FTDIBUS\VID_0403+PID_6001+FTH919SZA\0000 etc.).
Thank you once again for your help.
Roman
It's not possible without special USB drivers from your vendor. I don't know who made the USB drivers for your keyspan USB, but you might send them an email asking if they offer something like this. We use Silabs CP210X drivers for usb drivers for our products and they offer a special one that makes it so the COM ports are assigned and don't change randomly when our devices are plugged in. You might try it and see, but no promises it will work with your USB.
In my experience, COM port names are stable in Windows. I suspect there is something weird about the way your USB-to-Serial adapters were implemented, or something weird about the Windows driver you are using with it.
However, given that the COM port names are not stable for you, I would suggest using libusbp. It's a USB abstraction libary written in C which can enumerate the USB devices on your system and tell you the names of their COM ports. What you would do is:
Get a list of devices using libusbp_list_connected_devices.
For each device, call libusbp_device_get_os_id. This will return a string that is something like USB\\VID_1234&PID_DA01\6&11A23516&18&0000. That string should be stable across reboots, so you would have a list of those strings in a configuration file for your software.
If you see a device whose ID matches what is in your configuration file, then use libusbp_serial_port_create and libusbp_serial_port_get_name to get the COM port name.
The library is in C, but it can compile to a Win32 DLL, and you can use PInvoke (FFI) to call functions in it from C# or Java. The library might have some minor compilation errors if you try to compile it in Visual Studio, since it is mainly used in MinGW/GCC/clang environments. You should be able to fix those errors and/or report them as issues on GitHub.
I have no idea if it is possible to calculate urban electric power Hz frequency, on PC without any external electric or electronic device.
I want to get electric power Hz through Os, power supply, motherboard or any other data source available in a normal PC, best practical code for me is C#.
Usually, in many countries, electric current is 50 or 60 Hz. Now I want to calculate it in my code, on my computer, without any external device, and best case is that code be so harmless to run on remote server, internet server without need for any special permission. In CMOS, BIOS and windows registry there are many hidden data, may be one usefull for this.
Any help is welcomed.
EDIT No, don't miss understand, I don't need to know countries current Hz, I want to know Hz of power that my Pc is using, Here
(local place) power Hz and at the present time
This looks promising:
http://wutils.com/wmi/root/cimv2/power/ms_409/win32_powersupply/
This is WMI, and should be doable through C# assuming it actually works and gives you what you need
http://wutils.com/wmi/root/cimv2/power/ms_409/properties/range1inputfrequencyhigh.html
Dim wmiObject
Set wmiObject = GetObject( _
"WINMGMTS:\\.\ROOT\CIMV2\power\ms_409:" + _
"Win32_PowerSupply.CreationClassName=""Value"",DeviceID=""Value"",SystemCreationClassName=""Value"",SystemName=""Value""")
Wscript.Echo wmiObject.Range1InputFrequencyHigh
It looks like you may be able to use the sound card and microphone to detect the mains power supply frequency
see the section on System frequency-response analysis
http://www.techmind.org/audio/
Unless you have a very special equipment, the power supply doesn't tell anything to the Motherboard (and so to the OS). It's perhaps possible to query the Motherboard about the DC current it receives, but it would be useless for what you are trying to do.
As always, if no one has done it before you, there are two possibilities: you are a genius or it can't be done. Normally sadly it is the second one :-)
I want to prevent executable being copied to another PC and thus i need to somehow save information inside my EXE file about that it was already used somewhere else on another PC.
Can i embed small piece of information like user's hard drive number into my EXE file so this information would be available when this EXE is copied to another PC?
I thought maybe there is a way to read and write to some resource file embedded in an EXE file but i presume that resource file is read only and if so is there is a place inside EXE file where i could keep information which i need?
You're fighting an uphill battle this way. It's possible to create a home-grown licensing scheme but be prepared to do a lot of work (I did it, so I speak from first-hand experience). Just some problems to solve:
If the hard drive fails and needs to be replaced, your user won't be able to use the program. Every time this happens, you'll get a support call with an angry user.
If the user runs your program inside a virtual machine, the hard drive serial number won't be unique - anyone can clone the virtual machine and now your program can be run on another machine.
Hard drive serial numbers can be changed - they don't come directly from the hardware.
What if the hard drive is a removable drive? Your user can run your program from a removable drive and then keep moving it to different machines.
Even if you get it done, how do you protect the license information from being modified?
If you really want to license your product, look at existing licensing products - they're not cheap but they already did the (considerable amount of) work that's necessary to have any kind of reliability.
Even if you only want to have minimal protection, consider this: you'll have to do a lot of work to get even minimal security of your secret token (whatever that is). If its security is minimal, then what's the point of you even doing all that work? If all you do is force people to put in a meaningless serial number, you'll just annoy your honest customers. If anyone wants to steal something that's not well protected, they will steal it. All a 'simple' protection scheme does is annoys your users and gives you a false sense of protection.
I ended up using Reprise RLM - I'm not associated with this company but I had a good experience with their sales and support people and their product worked well in the testing scenarios.
Ok, I analyzed all the variants that were proposed and decided that in my case it will be better to develop my own copy-protection system, due to the reason that I am an indie developer and not going to work with extra large applications.
Just in case, somebody faces to the same issue - here is the algorithm (well, one of them):
User starts APP1.EXE
APP1.EXE reads itself to some variable and adds HDD serial number to the end of it, e.g. HDD serial number - when you add something to the end it does not break EXE file and you do not have to worry about PE headers
Unfortunately, EXE cannot save itself in runtime so it saves its copy called APP2.EXE with the information about HDD
When APP2.EXE is saved APP1.EXE starts it as a separate process via Process.Start() and terminates itself
Now APP2.EXE is running and has the same content as APP1.EXE + HDD serial number so we simply write all bytes from APP2.EXE back to APP1.EXE, close current process and start APP1.EXE again
From now on APP1.EXE is running and have all needed information about current HDD so each time user starts APP1.EXE it compares HDD number at the end of its content with the actual one on user's PC, if they differ - terminate the process
Delete APP2.EXE so that user would not realize how these files exchange information about his HDD.
Useful info about self-deleting EXE can be found here :
http://www.catch22.net/tuts/self-deleting-executables
http://buffernow.com/selfdelete-executable-in-c/
P. S. I know that it is like a huge hole of security (I will not mention all of them) but implementation of this algorithm took just 20 lines of code in C# and was moved to a separate DLL which I can use everywhere and it works. There is NO any registration in the algorithm above and user can simply take this app and use it and I am sure that ~ 80% of them will not realize how this app is protected from copying.
Link to implementation : https://bitbucket.org/artemiusgreat/examples/src/ef7b60142277?at=master
I want to make a program and sell it, so I was thinking to make some kind of licensing system. What I've found on google is this:
http://www.codeproject.com/Articles/28678/Generating-Unique-Key-Finger-Print-for-a-Computer
I am running Windows 7 (32 bit) in VirtualBox from Ubuntu. I get the same UID, but when I restart my Windows, I get a new UID. I am just thinking that some people will buy my program and they may run it from VirtualBox, so it would be a problem.
Do you guys have any suggestions?
Even if it's an easier way, but something that won't change even if I restart my VBox.
You need to not get so bogged down in the whole DRM process, there are always smarter people out there and someone will work out how to circumvent it.
If you're really concerned:
Set up an online license server to hold your users licenses
Prevent the application from doing anything until the user enters a valid license
This licence would be validated over the internet by your service
You could restrict the number of "active" applications using your service that way
Think along the lines of how iTunes allows you to authorise up to 5 computers to access your media library.
Even if a lot of time has passed, I want to add a possible solution to this question, pointing out something that happened to me trying to generate a fingerprint with exactly that code and facing the same problem.
The identifier function retrieves only the first not-empty value of wmiProperty for each wmiClass. The first important thing you should be aware of is this: what is returned for every wmiClass might not belong to the same ManagementObject. Hence, if something changes to "not the first object", this might affect also your fingerprint.
Be advised that using Win32_DiskDrive as wmiClass is dangerous since plugging in a USB device often results in this device being recognized as the first one (instead of your hard drive), changing the fingerprint as you plug-in or out your device. Even if this doesn't happen, still one of the wmiProperty could be taken from your USB device if your main drive has it empty (e.g. the disk signature, which happened to me).
A possible solution to that would be excluding all USB devices by checking InterfaceType and excluding all those who match "USB", or at least that's what I did.
I have a requirement to implement a feature (in C#) to lock a folder on a USB drive. After locking, in any PC without my software, this folder is inaccessible (or better invisible). I have tried using ACL (Access Control List) but it does not work on USB.
My original requirement is that "Do not allow people to see the content of a folder on a USB drive without my software. When the user logs into my software, this folder is accessible and when the user logs out, my software has to do something to make sure this folder becomes inaccessible on other PCs". This leads me to think about locking the USB folder.
I already tried a work around to zip the folder (not compress) with a password but zipping takes time (about 2 minutes for 1 Gb). So if I have a large amount of data (100 GB) it takes too long to process (The software has to process this when doing logging out).
For the data to be inaccessible, you would need to create an encrypted container which your program would represent as a virtual folder on existing disk or a virtual disk (drive letter). The first is possible with Pismo File Mount, the second - with our product (Solid File System OS edition). Both approaches require installation of the kernel-mode driver to the system. This is not an application requirement but OS architecture requirement.
From technical point of view our approach is more robust because Pismo File Mount uses a filter driver, while SolFS uses a file system driver and filter drivers are more complicated and more prone to compatibility issues (we have filter-based product as well, so I have experience with both approaches).
(Note: TrueCrypt has nothing to do with C#. So that isn't applicable here.)
Have you had a look at TrueCrypt?
In general you shouldn't try to reinvent the wheel, especially with security requirements. This is a heavy topic and messing around with the file system on your own should be the last option to consider.
TrueCrypt uses two different modes of operation:
File-hosted (container)
Partition/device-hosted
Note: In addition to creating the above types of virtual volumes,
TrueCrypt can encrypt a physical
partition/drive where Windows is
installed (for more information, see
the chapter System Encryption).
A TrueCrypt file-hosted volume is a
normal file, which can reside on any
type of storage device. It contains
(hosts) a completely independent
encrypted virtual disk device.
A TrueCrypt partition is a hard disk
partition encrypted using TrueCrypt.
You can also encrypt entire hard
disks, USB hard disks, USB memory
sticks, and other types of storage
devices.
I have used this software before, which is open source, so you might get something out of it.
http://www.truecrypt.org/
However, I think it works at the partition level rather than the drive level (I think it formats the partition using its own file system).