Remote Call

Remote Call Dialog
This dialog allows you to make call inside any hooked process.

   - General
   - Parameter syntax
   - Buffer Overrun protection in action

   - Examples
       1) Simple Call
       2) Value passed by reference
       3) Buffer
       4) Output Buffer
       5) Struct
       6) Pointer on Struct
       7) double/float
       8) double*/float*
       9) Exe_Internal
       10) ASM

General

Dll Name
Enter the name (or full path for not system dll) of the dll inside which you want to make your call.
By the way in the screenshot this is "user32.dll".

Using the same syntax as monitoring file, by specifying a virtual address, you can make a call of a not exported function inside an exe or inside a dll.
For an EXE :
EXE_INTERNAL@0xAddress,EXE_INTERNAL_RVA@0xRelativeAddress,
EXE_INTERNAL_POINTER@0xAddress,EXE_INTERNAL_RVA_POINTER@0xRelativeAddress
where RelativeAddress is the relative address from Base Address of the exe

For a DLL :
DLL_INTERNAL@0xRelativeAddress DLL_INTERNAL_POINTER@0xRelativeAddress for a dll.
where RelativeAddress is the relative address from Base Address of the dll (see monitoring files).

Function call
Enter the name of the function followed by parameters : Beep(500,0x3e8)

Show after call registers and floating result
Use this option to force the result window to show after call details including after call registers and floating result.

Do call inside specified threadt
Use this function to do a call inside a specified thread (specify a thread ID only if necessary as a thread context switching is required). It as been introduce for functions using local thread storage (and so some COM method).

Call Timeout
Max time for function to execute.

Registers
Enter the state of registers as you want they are filled just before function call

Make Call inside the selected process
Select the process into wish you want to make the call.


Parameters syntax :
Notice : more examples are given below

   - Direct value : 500, 0x12, -45

   - Pointer to value : &500, &0x12, &-45
You can use &OutValue for reference value that don't require initialisation GetWindowThreadProcessId(0x1234,&OutValue)

   - String : "string" for ansi string and L"string" for unicode string. Notice: this syntax allow you standard escape sequence \b, \f, \r, \n, \\, \t, \', \"

   - Buffer : &Buffer= followed by a byte array. Warning buffer has length of provided byte array. Make sure it is enough for function call
MessageBoxA(0,&Buffer=46 6F 6F 00,&Buffer=46 00,0)

   - Out Buffer &OutBuffer[N] where N is the size. Like GetTempPathA(255,&OutBuffer[255])

   - Structures : Buffer= followed by a byte array used for direct structure parameters.
To pass a POINT pt {200,300} (or {0xC8,0x12C}in hexa) structure like for ChildWindowFromPoint(HWND hWndParent,POINT Point) function,
Use Buffer=C8 00 00 00 2C 01 00 00

   - double : double= followed by value ex: double=0.5

   - pointer to double : &double= followed by value ex: &double=0.5

   - float : float= followed by value ex: float=0.5

   - pointer to float : &float= followed by value ex: &float=0.5

   - variants : The following keywords are supported : VT_EMPTY, VT_NULL, VT_I1, VT_I2, VT_I4, VT_I8, VT_INT, VT_UI1, VT_UI2, VT_UI4, VT_UI8, VT_UINT, VT_BOOL, VT_ERROR, VT_R4, VT_R8, VT_CY, VT_DATE, VT_DISPATCH, VT_UNKNOWN, VT_BSTR
You can pass some value as reference by adding the _BYREF suffix (like VT_I1_BYREF=0x500000). In this case (like for VT_BSTR), the provided value must be the address of pointer in remote process.
To allocate such memory in remote process, get pointer on it, and read/write value, just use the WinAPIOverride memory window
ex: VT_I1=7, VT_BSTR=0x12345, VT_UI2_BYREF=0x23456

   - pointer to variants : add an & prefix to the previously defined keywords. &VT_EMPTY, &VT_NULL, &VT_I1, &VT_I2....
ex : VariantCopy(&VT_EMPTY,&VT_I2=78)




As soon as one of you parameter is passed as reference, a detail window is shown to display parameter values,
after call registers and floating results. Else only a MessageBox containing the function return will appear.

The result window don't parse parameters, as no monitoring is requiered to do a remote call. So there's no way to know the types of parameters.

You can log your own calls (take care of modules filters as calls are made by apioverride.dll, you need to temporary uncheck "Only Base Module" and "Use list" inside the "Modules Filters" group in the WinApiOverride main dialog)

Remote call provides 3 protections to avoid hooked process to crash :
   - Call is done inside a try{} catch() block
   - Buffer overrun protection
   - A stack protection is done: if you forgot someparameters they are set to 0.
By the way if you call the Add(int,int) function of TargetSample with "Add()" the result is
But even with these protections, providing a bad pointer can still make process crash.

Use the String Hex dialog for string to bytes buffer conversion

All values can be entered as decimal or hexadecimal (Use "0x" as prefix for hex values)

Multiple instances of this dialog can be launched


If you want to log your remote call, you have to disable the module filter defined for the apioveride.dll (See modules filters)
Temporary uncheck "Only Base Module" and "Use list" inside the "Modules Filters" group in the WinApiOverride main dialog)

Due to .Net framework exception handling way, you musn't call .NET functions throwing exceptions (even if exceptions are catched in .NET code)



Buffer overrun protection

By the way if you are doing the following call GetTempPathA(260,&OutBuffer[20])
You can quickly see that first parameter (supposed to be the size of buffer) does'nt match.
Doing such call in real life will do a buffer overrun and can crash your process.
But with buffer protection introduced in version 6.0, you will get the following result
Parameter index reported in buffer overrun message is 1 based parameter index

Buffer overrun report for parameter 2
Result after buffer overrun report
In previous case we can see that value return by GetTempPathA (0x24 = 36) is the size of the provided buffer (OutBuffer[20]) + the size of the overrun 16.




Examples :

1) Simple Call

For functions requiering simple parameters like the Beep function, write it like you do in your one code
Beep(500,1000)
Add(-12,14)
This work for any 4 bytes or less types (int,DWORD, long, char, BYTE, short....)


2) Value passed by reference

Just preceed value by an '&'
GetSystemTimeAdjustment(&0,&46,&78)
For out only value we can use the &OutValue key word which will act like an &0
As we use reference values, the remote call result will popup automatically displaying the results of the function call


3) Buffer

In the following example we are going to display a messagebox with "Foo" as text and "F" as caption.
We need an ASCII string buffer so we use the String Hex dialog to convert text to byte array.
As "Foo" is 46 6F 6F 00 and "F" 46 00, we do the following
That's good : the result is the expected one
Notice: since WinAPIOverride 4.0 strings can be written directly like MessageBoxA(0,"Foo","F",2)

4) Out Buffer

We are going to make a call to GetTempPathA function. It require a quite big buffer, so instead of doing &Buffer=000.....0000
we use the &OutBuffer[255] which provides a quite speedest way
With Param2= 433A5C444F43554D457E315C4D59555345527E315C4C4F43414C537E315C54656D705C000000000...
and using the String Hex dialog to convert bytes to an ascii string we get the following:
C:\DOCUME~1\MYUSER~1\LOCALS~1\Temp\


5) Struct

Structures are considered as memory buffer. So to use them , you have to use the same representation that your computer use.

By the way for a structure defined by
typedef struct{
DWORD dw1;
DWORD dw2;
DWORD dw3;
}Foo;

It's memory representation is LittleEndian(dw1)LittleEndian(dw2)LittleEndian(dw3)
So with dw1=1, dw2=2 and dw3=3 we got the following 12 bytes buffer for the struct representation:
01 00 00 00 02 00 00 00 03 00 00 00
So a func f(Foo) will be called by f(Buffer= 01 00 00 00 02 00 00 00 03 00 00 00)

Notice : it's the easiest way because structure is already 4 bytes aligned.

As memory representation depends of alignment, you have to take care of structures using not 4 bytes multiple types :
( see the #pragma pack preprocessor help for more information)
Example with point struct {0xC8,0x12C}


6) Struct*

With the same Foo struct and same condition defined in 5), the only differency is the '&'
So function f2(Foo*) will be called by f2(&Buffer= 01 00 00 00 02 00 00 00 03 00 00 00)


7) double/float

You have to put keyword before the use of these types.
Don't forget to check the "Show after call registers ans floating result" if function return a float or a double
double=0.5
float=0.5


8) double*/float*

You have to mark the reference by '&' and use the same keywords defined in 7)
&double=0.5
&float=0.5


9) Exe_Internal

With the TargetSample.exe provided for tutorials (Notice : can be found at "Overriding Dll SDK\API\ExeInternal (with target sample)\ReleaseUnicode")
The function add(int,int) is at address 0x401000
So with the following parameters we can call the Add function of TargetSample.exe by doing the following

Easy isn't it ?


10) ASM

To check asm call, we will use another exe provide for tutorial : Target32.exe (Notice : can be found at "Overriding Dll SDK\ASM\AsmExeInternal (with asm target sample)\x86 example\Asm Target32").
The RotateRegisters function address is at 0x4010A0.
Don't forget to check the "Show after call registers ans floating result" option.
The function RotateRegisters just do the following :
edx=eax
ecx=edx
ebx=ecx
eax=ebx
The registers result
And if you make a logging during the same time, the details view will show the following :
We find our data in the "Registers Before Call" row and the result in the "Registers After Call" row.
All is OK.