
Originally Posted by
theholyone
Where does it all start?
You have a function called SendInput in the Windows API (https://msdn.microsoft.com/en-us/lib...v=vs.85).aspx). This function is a UserMode function and when invoked, it sends the parameters to your mouse driver telling it where to move. The mouse driver tells the kernel where the mouse should be and everything else is irrelevant from there on.
How is SendInput invoked from MoveMouse? Well things are invoked by instructions (Assembly/Machine Language). SendInput has the following signature:
C Code:
UINT __stdcall SendInput(UINT nInputs, LPINPUT pInputs, int cbSize);
So what you have to do is (push each parameter onto the stack in reverse order first via assembly instructions/machine instructions and invoke the call instruction):
ASM Code:
mov rax, inputs ;Inputs is the address of a structure (LPINPUT aka Long-Pointer to Input Structure). It moves into a register which is pushed later on.
push cbSize
push rax
push nInputs
call SendInput
This is how a function is called at the lowest possible level. This is "Machine instructions". Your CPU sees this and executes each one. No explanation of how is needed because that's irrelevant (but just incase, it's interpreted in voltages).
Samba developers know this so what they do is they parse the MoveMouse function. Store each parameter in a stack (the structure, not the memory). For each parameter on the stack they pop it off and write a push instruction for it. When the stack gets empty (no more parameters), they write a call instruction and make the memory executable with VirtualProtect (Windows) or MMap (OSX/Linux). This will execute the actual SendInput function and voila. Your mouse has moved.
Nowadays no one likes to write assembly/machine language, so a library called LibFFI (https://en.wikipedia.org/wiki/Libffi) does it all for you and does most of it in C (A higher-level human readable language). This library handles the calling conventions like STDCALL, FASTCALL, THISCALL, CDECL, PASCAL, etc.. This means that the library knows what order to push the instructions (STDCALL for reverse order) or whether or not the function belongs to a class (THISCALL), etc.. It also handles x86 and ARM instructions (different CPU architectures).
With this library it's simple. Samba does: Invoke(&SendInput, ....) where ... are the parameters to SendInput and may or may not be a variadic parameter pack (a function accepting any amount parameters).
With this, the developer does not have to know anything about the CPU or Assembly. The developer only needs to know the calling convention, the name of the function to be called (or address of it) and the parameters.
From there on, everything is trivial.