A good start is a disassembler such as Objdump, HopperApp, or IDA Pro. The last of them automatically determines the parameters for non-specific cases.
If you want to understand for yourself how this works, I would consider various “calling conventions” (wikipedia is a good start).
Example for __stdcall: let's say you have the x86.so library, and something like this happens in binary format:
push 3 push 2 push 1 call func ; void func(int a, int b, int c) where a=1, b=2 and c=3
Arguments are pushed onto the stack in reverse order. EAX, ECX and EDX can be used inside the function (stored by the calling party), other registers must be explicitly saved from the function itself (stored by the called party). This says nothing about the data type of the argument. This requires some more reversal, which must be solved.
Even IDA Pro does not automatically detect every information, because it depends on many factors and can be very complex :)
source share