Can anyone explain how does one program hook into and modify behavior of other programs in Windows?
How is it even possible? Don't windows programs protect themselves from other programs going into their memory, etc? (I don't know the internals how it works so I just said "into their memory" -- I bet it's more complex than that.)
Also does modern Windows like Windows 7 still allow it?
Thanks, Boda Cydo
There are several different ways to hook into and modify the behavior of other programs.
For example, you can directly write to another program's memory (WriteProcessMemory) or you can inject a thread into another program's memory (CreateRemoteThread). This presumes you have some rights to control that other program.
You can also inject a window hook via SetWindowsHookEx. This presumes you are running in the user's session at the same or higher integrity level of the program you are injecting into.
This is still allowed for several reasons. Without a way to modify behavior of other programs you would not be able to implement a debugger. Windows hooks are used by testing programs, accessibility programs, programs that change the look and feel of Windows, etc.
Imagine an application that saves data to file X.txt
you can grab the x.txt contents, and attempt to find a difference in the saved x.txt against the current x.txt, once it changes you can have an event fire knowing that program X modified its x.txt file.
You can do this on a lower level but the concept remains the same, (monitor something for change).
Related
Is it possible to have certain code executed whenever a file of a certain type is opened? In my case, I want to "listen" for when video files (".avi, mp4, etc.") are opened (either via the windows file explorer shell, or maybe directly from a video player?), so that I can store a history of played videos.
An hour's worth of googling turned up nothing, so I turn to you stackoverflow. Please point me in the right direction.
Thanks.
The best (and only reasonable way) to capture file system events (open/read/write) from arbitrary processes is by writing a File System MiniFilter
If you're developing a commercial product, please refrain from "hooking" Usermode APIs like CreateFile. Doing so requires numerous, platform-specific hacks, and is a compatibility nightmare.
I wouldn't hook CreateFile for this job. Windows has mechanisms built-in to handle jobs like this much more cleanly.
The easy way to handle this would be with ReadDirectoryChangesW with the FILE_NOTIFY_CHANGE_LAST_ACCESS flag. Any time a file is opened, its last-access time will be updated, so this tells you any time the file was opened.
Although it's pretty rare, that can "miss" changes under rare circumstances1. If you must have 100% accuracy (instead of, say, 99.9%), you can read change journals instead, but it's a fair amount of extra work for an advantage you may not care about.
1. There is one circumstance that isn't (necessarily) rare that you might care about though: ReadDirectoryChangesW will only work when/if your program is running. Change journals will let you know about things that happened even when your code isn't running at all.
Ok i wrote and application that use Adobe ActiveX control for displaying PDF files.
Adobe ActiveX control load files only from file system. So i nead to feed a file path to this control.
Problem is that i don't want to store PDF files on file system. Event temporary! I wan't to store my PDF files only in memory, and i want to use Adobe ActiveX control.
So i nead:
1) A way to fake file on a file system. So this control would "think" that there is a file, but would load it from memory
2) A way to create file on file system that would be "visible" to only one application, so my PDF control could load it, and other users won't even see it..
3) Something else
PS: I'm not asking to "finish my home work", i'm just asking - is there a way to do this?
You can almost do it (means: no you can't, but you can do something that comes close).
Creating a file with FILE_ATTRIBUTE_TEMPORARY does in principle create a file, temporarily. However, as long as there is sufficient buffer cache (which is normally always the case unless your file is tens to hundreds of megabytes), the system will not write to disk. This is not just something that happens accidentially, but the actual specified behaviour of this flag.
Further, specifying 0 as share mode and FILE_FLAG_DELETE_ON_CLOSE will prevent any other process from opening your file for as long as you keep it open, even if someone knows it's there, and the file will "disappear" when you close it. Even if your application crashes, the OS will clean up behind you (if DRM is the reason). If you're in super paranoia mode and worried about the system bluescreening while your file exists, you can additionally schedule a pending move too. This will, in case of a system crash, remove the file during boot.
Lastly, given NTFS, you can create an alternate stream with a random, preferrably unique name (e.g. SHA1 of the document or a UUID) on any file or even directory. Alternate streams on directories are ... a kind of nasty hack, but entirely legal and they work just fine, and don't appear in Explorer. This will not really make your file invisible, but nearly so (in almost every practical aspect, anyway). If you're a good citizen, you will want to use the system temp folder for such a thing, not the program folder or some other place that you shouldn't write to.
Creating an alternate stream is dead easy too, just use the normal file or directory name and append a colon (:) and the name of the stream you want. No extra API needed.
Other than that, it gets kind of hard. You can of course always create something like a ramdisk (would be tough to hide it, though), or try to use one of the stream-from-memory functions to fool an application into reading from a memory buffer on the allegation of a file... but that's not trivial stuff.
If something needs to be on a file system to pass to another application, you can not hide it/limit it to certain processes. Anything your app can see, anything else at the same privilige level can also see/access. You may be able to lock it but how depends on why you want to protect against.
Remember that the user's PC is theirs, not yours so they have full access to everything on it.
You can create a virtual disk and limit access to it to only specific application. Do to this you would have to write a file system driver or a filesystem filter driver. Both work in kernel mode and are tricky to write and maintain. Our company offers components that let you avoid writing drivers yourself and write business logic in user-mode (we provide drivers in those products).
Your most obvious option is to get rid of Adobe Reader control and use some third-party component that displays PDFs and can load them from memory.
But in general a smart hacker would be able to capture your data unless you have (a) non-standard data format, and/or (b) stream the data from the server dynamically, not keeping the complete data on the computer. These are not bulletproof solutions either, but they make hacker's work much harder.
I have an application, which displays me some data. I need to attach to this app's process, find the data I need in memory (one single number, actually), and save it somewhere. This application doesn't seem to use standard windows controls, so things aren't going to be as simple as reading controls data using AutoIt or something similar.
Currently I'm a self-learner database guy and have quite shallow knowledge about windows apps debugging. Not even sure if I asked my question correctly enough.
So, can you give me some starter guidelines about, say, what should I read first, and general directions I should work on?
Thanks.
To read memory of other application you need to open the process with respect of OpenProcess with at least PROCESS_VM_READ access rights and then use ReadProcessMemory to read any memory address from the process. If you are an administrator or have debug privilege you will be able to open any process with maximal access rights, you need only to enable SeDebugPrivilege before (see for example http://support.microsoft.com/kb/131065).
If you don't know a much about the memory of the destination process you can just enumerate the memory blocks with respect of VirtualQueryEx (see How does one use VirtualAllocEx do make room for a code cave? as an example where I examine the program code. The program data you can examine in the same way).
The most practical problem which I see is that you ask your question in too general way. If you explain more what kind of the data you are looking for I could probably suggest you a better way. For example if you could see the data somewhere you could examine the corresponding windows and controls with respect of Spy++ (a part of Visual Studio Tools). The most important are the class of windows (or controls) and the messages which will be send at the moment when the most interesting window are displayed. You can also use Process Monitor to trace all file and registry access at the time when the windows with the interesting information will be displayed. At least at the beginning you should examine the memory of the process with ReadProcessMemory at the moment when the data which you are looking for are displayed on the window.
If you will have no success in your investigations I'd recommend you to insert in your question more information.
My primary advice is: try to find any other method of integration than this. Even if you succeed, you'll be hostage to any kinds of changes in the target process, and possibly in the Windows O/S. What you are describing is behaviour most virus scanners should flag and hinder: if not now, then in the future.
That said, you can take a look at DLL injection. However, it sounds as if you're going to have to debug the heck out of the target process at the disassembly level: otherwise, how are you going to know what memory address to read?
I used to know the windows debugging API but it's long lost memory. How about using ollydbg:
http://www.ollydbg.de/
And controlling that with both ollydbg script and autoit?
Sounds interesting... but very difficult. Since you say this is a 'one-off', what about something like this instead?
Take a screenshot of this application.
Run the screenshot through an OCR program
If you are able to read the text you are looking for in a predictable way, you're halfway there!
So now if you can read a OCR'd screenshot of your application, it is a simple matter of writing a program that does the following:
Scripts the steps to get the data on the screen
Creates a screenshot of the data in question
Runs it through an OCR program like Microsoft Office Document Imaging
Extracts the relevant text and does 'whatever' with it.
I have done something like this before with pretty good results, but I would say it is a fragile solution. If the application changes, it stops working. If the OCR can't read the text, it stops working. If the OCR reads the wrong text, it might do worse things than stop working...
As the other posters have said, reaching into memory and pulling out data is a pretty advanced topic... kudos to you if you can figure out a way to do that!
I know this may not be a popular answer, due to the nature of what this software is used for, but programs like CheatEngine and ArtMoney allow you to search through all the memory reserved by a process for a given value, then refine the results till you find the address of the value you're looking for.
I learned this initially while trying to learn how to better protect my games after coming across a trainer for one of them, but have found the technique occasionally useful when debugging.
Here is an example of the technique described above in use: https://www.youtube.com/watch?v=Nv04gYx2jMw&t=265
I wonder if it is possible to figure out what keys user was pressing while his Mac OS was starting up?
Any way will do. As far as I understand it there is no easy way to simply hook an app/script to start working and capturing keystrokes simultaneously along with the OS. But maybe there is a way to some kind of reverse engineer this? Maybe looking into a specific log file or something like that?
Any results will do. Basically what I'm interested in is in finding out, which key the user pressed/held during the OS startup. It may be string, a character code or a hex, doesn't really matter.
UPDATE: guided by Pekka's advice I've found a kernel extension that should do the job. And it, hopefully, will do it, after this follow-up question - Why this keyboard intercepting kernel extension doesn’t work? is answered. :)
I'm no OS guru, but I think very, very, very hardly. I don't suppose stuff like this is automatically recorded anywhere.
I guess you would have to look whether the part of the system that handles the startup keys is somehow accessible, and can be extended to invoke a command defined by you.
The second best thing that comes to mind is for you to write some sort of custom device driver or startup script that gets loaded at startup, and listens to keypress events.
How to approach this depends completely on what point in the boot process you want to check for keys.
If you want to check really early, your only choice is to play with the EFI (firmware) environment -- maybe you could modify rEFIt to do what you want?
After the firmware, control passes to boot.efi (BootX on PPC Macs). This could presumably be replaced/hacked, and I'd expect the source to be available from as part of Darwin, but I don't see it on a quick inspection.
After that, the kernel loads (you could build your own kernel) with a minimal set of cached drivers (you could write a driver, not sure how to get it to be cached, though).
After that, all sorts of things happen more or less at once. Normal drivers get loaded, /etc/rc.local gets run, launchd items in /System/Library/LaunchDaemons and Library/LaunchDaemons become active... If you're willing to wait until this phase of the boot process, you have many options.
It's not just not recorded anywhere, for quite a while during startup there is no keyboard driver. So from the point of view of software, during that interval the keyboard simply doesn't exist.
I would like to create events for certain resources that are used across various processes and access these events by name. The problem seems to be that the names of the events must be known to all applications referring to them.
Is there maybe a way to get a list of names events in the system?
I am aware that I might use some standard names, but it seems rather inflexible with regard to future extensibility (all application would require a recompile).
I'm afraid, I can't even consider ZwOpenDirectoryObject, because it is described as needing Windows XP or higher, so it is out of question. Thanks for the suggestion though.
I am a little unsure about shared memory, because I haven't tried it so far. Might do some reading in that area I guess. Configuration files and registry are a slight problem, because they do tend to fail with Vista due to access problems. I am a bit afraid, that shared memory will have the same problem.
The idea with ProcessExplorer sounds promising. Does anyone know an API that could be used for listing events for a process? And, does it work without administrative rights?
Thank you for the clarification.
There is not really a master process. It is more of a driver dll that is used from different processes and the events would be used to "lock" resources used by these processes.
I am thinking about setting up a central service that has sufficient access rights even under Vista. It will certainly complicate things, but it might be the only thing left facing the problems with security.
No, there is not any facility to enumerate named events. You could enumerate all objects in the respective object manager directory using ZwOpenDirectoryObject and then filter for events. But this routine is undocumented and therefore should not be used without good reason.
Why not use a separate mechanism to share the event names? You could list them in a configuration file, a registry key or maybe even in shared memory.
Do not mix up the user mode ZwOpenDirectoryObject with the kernel mode ZwOpenDirectoryObject -- the kernel mode API (http://msdn.microsoft.com/en-us/library/ms800966.aspx) indeed seems to available as of XP only, but the user mode version should be available at least since NT 4. Anyway, I would not recommend using ZwOpenDirectoryObject.
Why should configuration files and registry keys fail on Vista? Of course, you have to get the security settings right -- but you would have to do that for your named events as well -- so there should not be a big difference here. Maybe you should tell us some more details about the nature of your processes -- do they all run within the same logon session or do they run as different users even? And is there some master process or who creates the events in the first place?
Frankly, I tend to find the Process Explorer idea to be not a very good one. Despite the fact that you probably will not be able to accomplish that without using undocumented APIs and/or a device driver, I do not think that a process should be spelunking around in the handle table of another process just to find out the names of some kernel objects. And, of course, the same security issues apply again.
ProcessExplorer is able to enumerate all the named events held by some specific process. You could go over the entire process list and do something similar although I have now clue as to what API is used to get the list...