.NET Hooking


   - General information
   - Auto Monitoring
   - Static Monitoring & Monitoring Files Syntax
   - Overriding, or Adding Pre/Post call hooks
   - .NET Options
   - .NET Tools

   - Advanced information


General information

To enable .Net hooking, click the toolbar button on the main window before starting the application to hook.
Next you can attach application at startup or after launching it.
With default options you don't need to do anything else.


.NET hooking is an extension to API hooking.
That means all processes, modules, monitoring and overriding filters work as the classical API way.
Monitoring files too support the same functions and parameter flags.

Auto monitoring

According to your .NET options, as soon as "Enable .NET auto monitoring" is checked, every jitted function is being to be monitored.
This is the more lazy way.
Even if "Enable .NET auto monitoring" is not checked, when your target application is running, you can ask to monitor / unmonitor a specified function with the .NET Tools


Static Monitoring & Monitoring Files Syntax

As for api, you can do your own monitoring files.
I encourage you to use MonitoringFileBuilder which quickly generate them for you, and then adjust the resulting file, specifing particular options on some functions, according to you wish.

the syntax is the following :
.NET@AssmblyName@FunctionToken| [ReturnType] FuncName( ParamType [paramName] ) [;]
where assembly name is the name of the .NET exe or dll, FunctionToken is the token of the function in the assembly;
Other types are like standard options defined in monitoring file basic and advanced syntax
To get function token use MonitoringFileBuilder to generate a monitoring file (all token will be provided),
or the Microsoft IL DASM (use "View" / "Show Token Value" and double click on the function you needs in the treeview)

Example :
   .NET@Network Stuff.exe@0x06000014|NET_STRING easy_socket.hexa_convert::hexa_to_string(NET_STRING string)
   .NET@Network Stuff.exe@0x0600040B|VOID Network_Stuff.FormScan.udp_scan::set_time_out(PVOID pObject,INT)

To allow you to spy .NET string, you have to use NET_STRING as parameter type


Overriding

As API .Net functions can be override.
With currently used method, we directly change generated code, that means .NET code is override by cpp code.
To override .Net code,like API, you have to write a single dll.
You can define faking array or pre/post callback to the function as API. See Overriding dll for more information
The only difference with API overriding is the library name which uses the same syntax as .NET monitoring file : .NET@AssmblyName@FunctionToken
where assembly name is the name of the .NET exe or dll and FunctionToken is the token of the function in the assembly.
To get function token use MonitoringFileBuilder to generate a monitoring file (all token will be provided),
or the Microsoft IL DASM (use "View" / "Show Token Value" and double click on the function you needs in the treeview)


Pre and Post hook can as monitoring make your target crash, according to options, due to Framework security,
but overriding won't and this is really nice as you don't have to use the slow "Enable framework hooking" to make it works
See .Net options for more information.

Overriding example :
Notice : Example is located in the "Overriding Dll SDK\NET" directory.
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // fake API array. Redirection are defined here
  3. ///////////////////////////////////////////////////////////////////////////////
  4. STRUCT_FAKE_API pArrayFakeAPI[]=
  5. {
  6. // library name ,function name, function handler, stack size (required to allocate enough stack space), FirstBytesCanExecuteAnywhereSize
  7. // stack size= sum(StackSizeOf(ParameterType)) Same as monitoring file keyword
  8. {_T(".NET@NET_Target.exe@0x06000005"),_T("NET_Target.Form1::button_Click"),(FARPROC)mButton_Click,4,0},
  9. {_T(""),_T(""),NULL,0,0}// last element for ending loops
  10. };
  11.  
  12. ///////////////////////////////////////////////////////////////////////////////
  13. // Before API call array. Redirection are defined here
  14. ///////////////////////////////////////////////////////////////////////////////
  15. STRUCT_FAKE_API_WITH_USERPARAM pArrayBeforeAPICall[]=
  16. {
  17. // library name ,function name, function handler, stack size (required to allocate enough stack space), FirstBytesCanExecuteAnywhereSize
  18. // stack size= sum(StackSizeOf(ParameterType)) Same as monitoring file keyword
  19. {_T(".NET@NET_Target.exe@0x06000005"),_T("NET_Target.Form1::button_Click"),(FARPROC)m1BeforeButton_Click,4,0},
  20. {_T(".NET@NET_Target.exe@0x06000005"),_T("NET_Target.Form1::button_Click"),(FARPROC)m2BeforeButton_Click,4,0},
  21. {_T(""),_T(""),NULL,0,0,0}// last element for ending loops
  22. };
  23.  
  24. ///////////////////////////////////////////////////////////////////////////////
  25. // After API call array. Redirection are defined here
  26. ///////////////////////////////////////////////////////////////////////////////
  27. STRUCT_FAKE_API_WITH_USERPARAM pArrayAfterAPICall[]=
  28. {
  29. // library name ,function name, function handler, stack size (required to allocate enough stack space), FirstBytesCanExecuteAnywhereSize
  30. // stack size= sum(StackSizeOf(ParameterType)) Same as monitoring file keyword
  31. {_T(".NET@NET_Target.exe@0x06000005"),_T("NET_Target.Form1::button_Click"),(FARPROC)m1AfterButton_Click,4,0},
  32. {_T(".NET@NET_Target.exe@0x06000005"),_T("NET_Target.Form1::button_Click"),(FARPROC)m2AfterButton_Click,4,0},
  33. {_T(""),_T(""),NULL,0,0,0}// last element for ending loops
  34. };
  35.  
  36. ///////////////////////////////////////////////////////////////////////////////
  37. ///////////////////////////// NEW API DEFINITION //////////////////////////////
  38. /////////////////////// You don't need to export these functions //////////////
  39. ///////////////////////////////////////////////////////////////////////////////
  40.  
  41. // TAKE CARE OF X86 .NET __FASTCALL IMPLEMENTATION !!!
  42. // see MS Common Language Infrastructure (CLI) PARTITION II 15.5.6.1 Standard 80x86 calling convention
  43. void __fastcall mButton_Click(PVOID pObject,PVOID sender,PVOID e)
  44. {
  45. MessageBox(0,_T("Overrided Button Click"),0,MB_ICONINFORMATION);
  46. return;
  47. }
  48.  
  49. BOOL __stdcall m1BeforeButton_Click(PBYTE pEspArgs,REGISTERS* pBeforeCallRegisters,PRE_POST_API_CALL_HOOK_INFOS* pHookInfos,PVOID UserParam)
  50. // return FALSE to stop pre api call chain functions
  51. {
  52. MessageBox(0,_T("Before Button Click 1"),0,MB_ICONINFORMATION);
  53. return TRUE;
  54. }
  55. BOOL __stdcall m2BeforeButton_Click(PBYTE pEspArgs,REGISTERS* pBeforeCallRegisters,PRE_POST_API_CALL_HOOK_INFOS* pHookInfos,PVOID UserParam)
  56. // return FALSE to stop pre api call chain functions
  57. {
  58. MessageBox(0,_T("Before Button Click 2"),0,MB_ICONINFORMATION);
  59. return TRUE;
  60. }
  61. BOOL __stdcall m1AfterButton_Click(PBYTE pEspArgs,REGISTERS* pBeforeCallRegisters,PRE_POST_API_CALL_HOOK_INFOS* pHookInfos,PVOID UserParam)
  62. // return FALSE to stop pre api call chain functions
  63. {
  64. MessageBox(0,_T("After Button Click 1"),0,MB_ICONINFORMATION);
  65. return TRUE;
  66. }
  67. BOOL __stdcall m2AfterButton_Click(PBYTE pEspArgs,REGISTERS* pBeforeCallRegisters,PRE_POST_API_CALL_HOOK_INFOS* pHookInfos,PVOID UserParam)
  68. // return FALSE to stop pre api call chain functions
  69. {
  70. MessageBox(0,_T("After Button Click 2"),0,MB_ICONINFORMATION);
  71. return TRUE;
  72. }
For overriding TAKE CARE OF X86 .NET __FASTCALL IMPLEMENTATION.
see MS Common Language Infrastructure (CLI) PARTITION II 15.5.6.1 Standard 80x86 calling convention for more information.

In the previous example, "void __fastcall mButton_Click(PVOID pObject,PVOID sender,PVOID e)"
don't provide troubles as "pObject" and "sender" are passed through ecx and edx registers, and only e is pushed on stack.
If more than 1 parameter is passed through stack, stack parameters are in reverse order.