FAQ - How to log structs or arrays ? - How to build a monitoring file ? - What is the difference between monitoring, overriding, pre and post hooks ? - How to do parameter filtering ? - Where can I find more monitoring files ? - My monitoring file make my targeted software crash. What can I do ? - How to change a parameter value ? - Where is located the return value ? - How to change a function return ? - How to build an overriding dll ? - How to find the address for an EXE_INTERNAL or DLL_INTERNAL monitoring ? - How to get first functions bytes without a dissassembler - Where is located the "this" pointer at function call ? - Where are passed parameters - What is caller address and how is it computed ? - Why must I use internal dumper of WinAPIOverride to dump hooked processes ? - What is VA, RVA and RAW ? - Can I use multiple instance of WinAPIOverride32 ? - Can I load Ansi monitoring files or overriding dll from the WinAPIOverride32 Unicode version ? - Can I load Unicode monitoring files or overriding dll from the WinAPIOverride32 Ansi version ? - I get an "A monitoring hook is already defined..." message (or Multiple hook definitions for the same function). What does it mean? How to log structs or arrays ? Use ":DataSize=" and ":PointedDataSize=" parameter options defined in Monitoring Files : Advanced Syntax Where can I find more monitoring files ? Monitoring files can be found at http://jacquelin.potier.free.fr/winapioverride32/monitoringfiles.php All updates will be post at this address.
My monitoring file make my targeted software crash. What can I do ? First check all hooked functions with Monitoring File Builder (as explained here), and comment function definition for which a warning was reported. It should solve your trouble in 99% of case. If your application still crash with the modified monitoring file, you have to manually identify the hook responsible of the crash. For this, inside the Option dialog, check the "Monitoring File Debug Mode" option : all modules filters will be by passed, and each api will be logged before and after it's call. Once application has crash, look at Global stats dialog, and the api with an odd count is the responsible of the crash. If this not working, you have to manual find it by doing multiple tests, by enabling functions one by one (or by group) and let the other disabled Multiple hook definitions for the same function When you get a strange message like |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
that means the function is already monitored by the specified file, so hook won't be install once again. The ownership allows to specify when the hook will be removed : at the first file unload or when you unload the new file.
If you say that new file takes the ownership, you'll get another strange message : |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
If you reply No, all Logging, breaking and failing conditions defined in the first loaded file are trashed, and only the new options are used. If you reply Yes, the old conditions are kept, and the new ones are added Example : First monitoring file : lib.dll | Add(int x:LogValue=0x12,int y:BreakValue=14) | BreakBeforeCall Second monitoring file lib.dll | Add(int x:LogValue=0x15,int y) If second monitoring files takes the hook and don't keep old configuration, it is equivalent to lib.dll | Add(int x:LogValue=0x15,int y) else, as previous conditions are kept, the result is simailar to the following definition lib.dll | Add(int x:LogValue=0x12:LogValue=0x15,int y:BreakValue=14) | BreakBeforeCall How to find the address for an EXE_INTERNAL or DLL_INTERNAL monitoring ? Notice : the following doesn't apply to .NET application. For .Net applications, use Monitoring File Builder If you still get the sources of the project, New way since 5.0 (works only if your compiler generates pdb files like Visual Studio) once you have built your target, use Debug Info Viewer and select functions you want to monitor. This software will generate the monitoring file for you, and it can display generated function asm code. Warning : You have to regenerate the monitoring file each time you do a build (as function code start address may change due to build). Old Way : put a break point on at begin of the function you want to hook. Start your project with your IDE in the same configuration as you want to make monitoring file. It's important as Debug and Release version don't generate the same code, and so the address of function will differ. When your breakpoint is reached, use the IDE asm display. You get the address of the function. Avoid to do a change your code adding a MessageBox or printf call to display your function address. Adding or modifying code will probaly generate a different address, so the address you'll get by this way is absolutly no use. Example with TargetSample in Release configuration
If you have LOST YOUR source code, you have to identify function address using an advanced disassember like IDA Since 6.2 version Monitoring File Builder can use generated IDA map file to create monitoring files Get first functions bytes without a dissassembler If you want to know the first bytes of one of your function, or an API function, you don't need a disassembler. First put a break point at the place you do the call to the api or function (Make a small exe project if necessary). Once done, run your code. When the break point is reached, go to the asm view and do step by step until begin of function is reached. In Visual studio assume that the "Show Code Bytes" options is checked (right click under asm view) By the way for MessageBox function |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Do "Step Over" until you reach the line "004457EB call dword ptr [__imp__MessageBoxA@16 (4A9B9Ch)]". Next use the "Step Into" |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
You got it. Notice : when the software uses redirection table, the begin of function is not at the first "Step Into". To be sure you are at the good location, for dll, you can check the address with the microsoft Depends software. If dll is not rebased, function address = dll Prefered Base + Entry Point. By the way for my version of User32.dll, and the MessageBoxA function using Depends we get |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
So if dll is not rebased, function address should be at 0x77D10000 + 0x2ADD7 =
0x77D3ADD7 : the location we jump with the "Step Into". By displaying codes bytes, this allow us to see that for this version of dll, the first instruction bytes are 83 3D C4 D3 D6 77 00. As the "cmp" asm instruction can be done anywhere, for this dll version we can use the option |FirstBytesCanExecuteAnywhere=7 Where is located the return value ? (32-Bit Compilers only) The following table shows you where the return value is located in registers according to it's type
Where is located the "this" pointer at function call ? The following table shows you how the this pointer is passed according calling convention and compiler
Where are passed parameters ? From Wikipedia
What is caller address and how is it computed ? When a function is called, return address is pushed on stack. So WinApiOverride tries to get caller address from this return address. It disassemble instuctions before return address to find a call. If a call is found the caller address is supposed to be the call one. If nothing is found, the return address is let unchanged (even if reported as caller address in logs). This works in more than 95% of case but for the other case caller address can be fully wrong. Take a look at the following pseudo asm code to see a case where such analysis can fail : As you can see WinApioverride will detect the "call api" instruction as caller address even if call comes from "jmp api". Why must I use internal dumper of WinAPIOverride to dump hooked processes ? You HAVE TO use the WinAPIOverride dump dialog for hooked modules. All other dumper will produce you a crashing code. The reason is very easy : To hook functions, we modify first bytes of functions. Only WinAPIOverride knows which bytes are modified. As external dumpers don't know which functions are hooked and which are the originals bytes, they will save the modified bytes. So you can't get a valid dump. To create a dump, WinAPIOverride suspend process, removes the hooks and restore original bytes, do the dump, restores the hooks, and then resume process. But external dumper can dump all not hooked modules. So if you exactly know which modules are hooked or not, you can use them. What is VA, RVA and RAW ? VA (Virtual Address) : address at which instruction is when module is loaded (when module is not rebased). Address seen in your favorite disassembler RVA (Relative Virtual Address) : address at which instruction is when module is loaded relative to module address begin. VA = RVA + module address Raw : address of instruction in the binary file (when you open file with your favorite hex editor) Can I use multiple instance of WinAPIOverride32 ? Yes, but you can't target the same process. Each process can be hooked only once. Only one instance of WinAPIOverride32 can use the "Attach to all new process" option. Can I load Ansi monitoring files or Ansi overriding dll from the WinAPIOverride32 Unicode version ? Yes, you don't need to do anything. WinAPIOverride support both Ansi and Unicode monitoring files and overriding dll Can I load Unicode monitoring files or Unicode overriding dll from the WinAPIOverride32 Ansi version ? Yes, since version 2.0 you don't need to do anything. WinAPIOverride support both Ansi and Unicode monitoring files and overriding dll |