NOTIFYICONDATA - GUID problem - system-tray

According to the description for the guidItem member of the NOTIFYICONDATA structure at http://msdn.microsoft.com/en-us/library/bb773352(v=vs.85).aspx programs that make use of the Windows system tray need to identify their icon with a valid GUID on Windows 7. I did this, but I'm running into a problem. If my application is running in directory A and then the user at some point decides to move it and run it in directory B, when the program makes the call to Shell_NotifyIcon it fails (returns 0) with GetLastError set to 1460 (ERROR_TIMEOUT).
If you read further down at the very bottom of that MSDN article to troubleshooting point 2, it basically describes that programs identifying their system tray icon with a GUID cannot change paths or this will happen. It also then has this interesting little blurb in it:
If the path must be changed, the application should remove any GUID
information that was added when the existing icon was registered.
Does anyone know of a Win32 API call or a way to do this? Presumably this would be a function taking the GUID that I want to remove, and calling it would remove any settings for any exe that windows identified as using this GUID. If so, I could setup my program to attempt to call Shell_NotifyIcon, and then if it fails, I'll call a function to clear everything out and try again.
The only other option I can think of to allow a program that has the potential for needing to be run in multiple locations (not at the same time) to use the same GUID for its system tray icon is to brute force modify the settings in the registry according to this article: http://deployment.xtremeconsulting.com/2011/07/08/windows-7-notification-area-automation-falling-back-down-the-binary-registry-rabbit-hole/ I would like to avoid this approach if possible, for obvious reasons.
Any help on this issue will be greatly appreciated.

Here's a complete list of possibilities that I'm aware of:
sign your EXE with a valid certificate;
do not ever move the EXE (precludes portable programs);
do not assign a GUID to your notify icon,
the hacky approach you linked to,
generate a GUID based on your application path.
Let's take a look at that last idea, in particular. Windows wants a unique GUID for every path. We just want a GUID that doesn't change for as long as the path is fixed. That's actually trivial to achieve. Here's an outline:
generate a random GUID using a service like make a guid
obtain your executable path
hash your path with a hash function that outputs at least 128 bits, like MD5 or SHA-1
XOR your GUID with the path hash, truncating to 128 bits
use the result as the tray icon GUID
This comes with a gotcha: the application path is not necessarily unique. But this shouldn't be a major problem because firstly, most of the time it's unique, and secondly, the worst that will happen if run via an alternative path is that the user will have to reposition the tray icon once.

Related

GetFileInformationByHandleEx/FileIdInfo vs DeviceIoControl/FSCTL_CREATE_OR_GET_OBJECT_ID for OpenFileById

Recently I've stumbled upon "If you want to use GUIDs to identify your files, then nobody's stopping you" article by Raymond Chen and wanted to implement this method. But then I found that there is another way to get file ID and this is GetFileInformationByHandleEx with FILE_INFO_BY_HANDLE_CLASS::FileIdInfo and using the FileId field (128 bit).
I tried both, both methods works as expected but I have a few questions I cannot find any answers to:
These methods return different IDs (and the id from GetFileInformationByHandleEx seems to use only the low 64 bit leaving the high part as zero). What each of them represent? Are they essentially the same thing or just two independent mechanisms to achieve the same goal?
Edit: Actually I've just found some information. So the ObjectID from DeviceIoControl is NTFS object ID but what is the other ID then? How do they relate (if at all)? Are both methods available only on NTFS or at least one of them will work on FAT16/32, exFAT, etc?
Documentation for FILE_INFO_BY_HANDLE_CLASS::FileIdInfo doesn't tell us that the ID may not exist unlike FSCTL_CREATE_OR_GET_OBJECT_ID where I need to explicitly state that I want the ID to be created if there isn't one already. Will it have any bad consequences if I'd just blindly request creation of object IDs for any file I'll be working with?
I found a comment for this question that these IDs remain unchanged if a file is moved to another volume (logical or physical). I did test only the DeviceIoControl method but they indeed don't chnage across drives but if I do move the file I'm required to supply OpenFileById with the destination volume handle, otherwise it won't open the file. So, is there a way to make OpenFileById find a file without keeping the volume reference?
I'm thinking of enumerating all connected volumes to try to open the file by ID for each until it succeed but I'm not sure how reliable is this. Could it be that there could exist two equal IDs that reference different files on different volumes?
How fast it is to ask system to get (or create) an ID? Will it hurt performance if I add the ID query to regular file enumeration procedures or I'd better to do that only on demand when I really need this?

Is there any way to determine if a program uses a specific Windows API functions?

Ok, it may be a bit difficult to explain:
Suppose someone creates a Windows application (using C# or any other language) that uses the GetDesktopWindow() function on the user32.dll to capture a Screenshot and then sends this image to any online service.
Since it's custom made application, no anti-virus software will be able to determine that it's a virus because it's still an unknown application for it. Also, there are legitimate uses for such API, so it's not necessarily a virus, it can be a harmless window capture tool or some kind of espionage tool.
What I want to know is: Is there any way to see what a specific EXE file does regarding the Windows functions? Can I know if "myapp.exe" uses GetDesktopWindow() of user32.dll?
This is only one example. There are plenty other Windows endpoints that I would like to know when they're used by any application.
Is there a way to do that?
It depends to what lengths you want to go doing that. It's essentially a game of cat and mouse - bad actors will attempt to find new ways to circumvent your detection by jumping through some obscure hoops, you will add more sophisticated detection methods for those tricks, they will think of new tricks, and so on.
Also, it depends on whether you want to statically or dynamically determine that, and whether you actually want to know if GetDesktopWindow is called or if "the program gets a handle to the desktop window" (which can be achieved in other ways as well).
Here is a non-exhaustive list of ideas:
You could statically determine whether the function is imported by looking at the import directory. Research the PE file structure to find out more. This article may help.
This method of detection can be easily circumvented by dynamically importing the function using LoadLibrary and GetProcAddress.
You could scan the file for the string GetDesktopWindow to detect possible usage for dynamic import.
This method of detection can be easily circumvented by packing, encrypting or otherwise obfuscating the name of the dynamically imported function.
You could dynamically observe whether the GetDesktopWindow function gets called by registering an AppInit_DLL or a global hook which is injected into every new process and hook the GetDesktopWindow function from inside the process by overwriting its first bytes with a jump to your own code, notifying your detection component somehow, executing the original bytes and jumping back. (Microsoft Detours can help there.)
This method of detection can be circumvented if the target notices the hook and removes it before calling, since its in its own process space. (You could also do some tricks with acting like a debugger and setting a hardware breakpoint on the first instruction of GetDesktopWindow, but yet again there would be ways to detect or circumvent that since the target could also modify the debug registers.)
You could build a driver that does this from kernel-mode instead, but now we are getting really deep.
Note that until now we focused on the actual GetDesktopWindow function from user32.dll. But what if the target will just use a different way to achieve its goal of getting a desktop window handle?
The desktop window handle for the current thread is stored in the TIB (thread information block) which is accessible via fs:[18] from user mode. You can see this in the GetDesktopWindow source code of ReactOS which is pretty accurate compared to Microsoft's actual implementation (which you can verify by looking at it in a debugger). The target could therefore just access the TIB and extract this value, without even calling GetDesktopWindow at all.
The target could just take a known top-level window such as the shell's hidden compatibility window which you'll get via GetShellWindow() or - to avoid detection of GetShellWindow too - for example FindWindow(NULL, "Program Manager") (or even a newly created window!) and call GetAncestor(hWnd, GA_PARENT) on it to get the desktop window handle.
I'm sure, with some creativity, your adversaries will come up with more clever ideas than these.
Also, if we take this one step further and take a look at the ultimate goal of taking a screenshot, there as well exist other ways to achieve that. First example coming to mind: They could use keybd_event to emulate pressing the PrnSc key and then read the screenshot out of the clipboard data.
So it's all a matter of how far you want to take this.
By the way, you may find the drltrace project interesting - it is a library call tracer.

Store the state inside golang binary

I am Developing an onpremise solution for a client without any control and internet connection on the machine.
The solution is to be monetized based on number of allowed requests(REST API calls) for a bought license. So currently we store the request count in an encrypted file on the file system itself. But this solution is not perfect as the file can be copied somewhere and then replaced when the requests quota is over. Also if the file is deleted then there's manual intervention needed from support.
I'm looking for a solution to store the state/data in binary and update it runtime (consider usage count that updates in binary itself)
Looking for a better approach.
Also binary should start from the previous stored State
Is there a way to do it?
P.S. I know writing to binary won't solve the issue but I think it'll increase the difficulty by increasing number of permutation and combinations for places where the state can be stored and since it's not a common knowledge that you can change the executable that would be the last place to look for the state if someone's trying to mess with the system (security by obscurity)
Is there a way to do it?
No.
(At least no official, portable way. Of course you can modify a binary and change e.g. the data or BSS segment, but this is hard, OS-dependent and does not solve your problem as it has the same problem like an external file: You can just keep the original executable and start over with that one. Some things simply cannot be solved technically.)
If your rest API is within your control and is the part that you are monetizing surely this is the point at which you would be filtering the licensed perhaps some kind of certificate authentication or key to the API and then you can keep then count on the API side that you can control and then it wont matter if it is in a flat file or a DB etc, because you control it.
Here is a solution to what you are trying to do (not to writing to the executable which) that will defeat casual copying of files.
A possible approach is to regularly write the request count and the current system time to file. This file does not even have to be encrypted - you just need to generate a hash of the data (eg using SHA2) and sign it with a private key then append to the file.
Then when you (re)start the service read and verify the file using your public key and check that it has not been too long since the time that was written to the file. Note that some initial file will have to be written on installation and your service will need to be running continually - only allowing for brief restarts. You also would probably verify that the time is not in the future as this would indicate an attempt to circumvent the system.
Of course this approach has problems such as the client fiddling with the system time or even debugging your code to find the private key and probably others. Hopefully these are hard enough to act as a deterrent. Also if the service or system is shut down for an extended period of time then some sort of manual intervention would be required.

Could DigitalProductId and InstallDate ever change?

I have a software activation logic which relies on thre parameters:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallDate
Id of system volume
I'm interested in question: could these parameters ever change under any conditions except manual modification of registry values (for 1, 2) in single OS installation?
System volume id, as far as i know, can change only when the volume is formated.
Both DigitalProductId and InstalLDate also should be constant in single OS as they identify a license (concrete windows installation) and the date the OS was initially installes respectively. So according to this logic they shouldn't ever change.
I want to find any documentation that proves these points. Unfortunately my searching for such a documentation didn't give me enough as all that i've found are articles like this http://technet.microsoft.com/en-us/library/cc709644(v=ws.10).aspx which contain inderect information on the topic.
Also i've looked through this great post: http://siginetsoftware.com/forum/showthread.php?596-Investigating-the-Microsoft-Digital-ProductID-(DPID)
It partially proves my points but doesn't give a 100% guarantee
I repeat a question here once again:
Could parameters 1-3 ever change in single Windows installation?
Thanks in advance
My research has shown that independently of windows updates, service packs and other software, these keys remain the same.

Get Windows hardlink count without GetFileInformationByHandle()

Is there a way to get a file hardlinks count on Windows without using GetFileInformationByHandle()?
MSDN says:
Depending on the underlying network features of the operating system and the type of server connected to, the GetFileInformationByHandle function may fail, return partial information, or full information for the given file.
In practice, retrieving the link count on a network share, whatever the Windows version at both ends, always return 1. The only case where it works is when accessing a samba share. Looks like they forgot to duplicate Windows bug/limitation. Also, the "partial results" without telling you they are partial is pretty nice for an API call.
It seems a little strange but what about GetFileInformationByHandleEx. It doesn't contain the waiver that you quoted above, so perhaps has the smarts built into it to handle some of the problems that GetFileInformationByHandle can have.
For that you can try FindFirstFileNameW and FindNextFileNameW.
It isn't good option to enumerate stuff to get count but it is another way.

Resources