Closed hasherezade closed 2 years ago
The reason of this behavior is, the tags (including the called function name) are produced by the function _SaveTransitions
:
https://github.com/hasherezade/tiny_tracer/blob/ae72aa302a018d2f219ed8ffdb3d7ae2d47051a9/TinyTracer.cpp#L98
which takes as an argument EIP from where the function was called. This EIP is then checked against the list of the traced shellcodes. If the EIP is within the traced area, the call is logged.
On the other hand, the arguments trace is produced by the function LogFunctionArgs
called by:
https://github.com/hasherezade/tiny_tracer/blob/ae72aa302a018d2f219ed8ffdb3d7ae2d47051a9/TinyTracer.cpp#L398-L427
where not the call EIP is passed, but the return EIP:
RTN_InsertCall(funcRtn, IPOINT_BEFORE, AFUNPTR(LogFunctionArgs),
IARG_RETURN_IP,
IARG_ADDRINT, fName,
The inserted function will be used as a callback when the execution entered into the monitored function. Pin provides no way to pass the EIP of the line that executed the call, only the EIP where it will return.
So, in the situation where the call was made not from the EIP that is within the trace shellcode, but yet it returns to the traced shellcode, the parameters will be logged, but not the origin.
Example:
> cbe3000+704;called: ?? [cbdc000+9b0]
> cbdc000+9b0;wininet.InternetOpenA
RET: cbe3000 + 709
It happens because the call is implemented by CALL-JMP:
0CBE3704 | E8 A792FFFF | call <JMP.&InternetOpenA> |
and the jump table is in another allocated region:
0CBDC9B0 | FF25 CC72BE0C | jmp dword ptr ds:[<&InternetOpenA>] | JMP.&InternetOpenA
After the changes, if the call is done from an untraced shellcode, but it returns to the traced area, the return will be logged. Example:
6a78;ntdll.NtdllDefWindowProc_A
1ee5b;user32.[CallNextHookEx+b1]*
> cbf3000+ff1;RET from: [cbe6000+610] -> user32.GetMessageA
> cbf3000+709;RET from: [cbec000+9b0] -> wininet.InternetOpenA
Arg[0] = ptr 0x0cbf37c4 -> "lVali"
Arg[1] = 0x00000004 = 4
Arg[2] = 0
> cbf3000+72c;RET from: [cbec000+9b8] -> wininet.InternetOpenUrlA
Arg[0] = ptr 0x00cc0004 -> {\x00\x00\x00\x00\x00\x00\x00\x00}
Arg[1] = ptr 0x0dee2a3c -> "https://[removed]"
Arg[2] = 0
Arg[3] = 0
> cbf3000+76b;RET from: [cbec000+9a0] -> wininet.HttpQueryInfoA
Arg[0] = ptr 0x00cc000c -> {\x00\x00\x00\x00\x00\x00\x00\x00}
Arg[1] = 0x00000013 = 19
Arg[2] = ptr 0x0cbf6a14 -> {\x00\x00\x00\x00\x00\x00\x00\x00}
Arg[3] = ptr 0x0cbf6c1c -> {\x01\x02\x00\x00\x00\x00\x00\x00}
> cbf3000+7b3;RET from: [cbec000+9a8] -> wininet.InternetCloseHandle
> cbf3000+7be;RET from: [cbec000+9a8] -> wininet.InternetCloseHandle
> cbf3000+a63;RET from: [cbec000+9b0] -> wininet.InternetOpenA
Arg[0] = ptr 0x0cbf3b4c -> "aswe"
Arg[1] = 0
Arg[2] = 0
If we enable tracing all the shellcodes (i.e. FOLLOW_SHELLCODES=3
), and now the calling element will be among the traced shellcodes, the call will be logged as before:
> cbe1000+304;kernel32.VirtualFree
> cbec000+9b0;wininet.InternetOpenA
Arg[0] = ptr 0x0cbf37c4 -> "lVali"
Arg[1] = 0x00000004 = 4
Arg[2] = 0
> cbec000+9b8;wininet.InternetOpenUrlA
Arg[0] = ptr 0x00cc0004 -> {\x00\x00\x00\x00\x00\x00\x00\x00}
Arg[1] = ptr 0x0d982a3c -> "https://[removed]"
Arg[2] = 0
Arg[3] = 0
> cbec000+9a0;wininet.HttpQueryInfoA
Arg[0] = ptr 0x00cc000c -> {\x00\x00\x00\x00\x00\x00\x00\x00}
Arg[1] = 0x00000013 = 19
Arg[2] = ptr 0x0cbf6a14 -> {\x00\x00\x00\x00\x00\x00\x00\x00}
Arg[3] = ptr 0x0cbf6c1c -> {\x01\x02\x00\x00\x00\x00\x00\x00}
> cbec000+9a8;wininet.InternetCloseHandle
> cbec000+9a8;wininet.InternetCloseHandle
> cbec000+9b0;wininet.InternetOpenA
Arg[0] = ptr 0x0cbf3b4c -> "aswe"
Arg[1] = 0
Arg[2] = 0
In case if a function has parameter tracking enabled, but it is called from a shellcode that is not traced, its parameters are reported, but not the name.
Example:
Used settings: TinyTracer.ini
params.txt
Sample: