Syscall args via get_param( ) gone wrong?

46 views
Skip to first unread message

ByteCrew

unread,
Jul 18, 2022, 10:38:09 AM7/18/22
to DynamoRIO Users
Hi,
I'm trying to access the actual values of syscalls via dr_syscall extension. I don't understand how can 

dr_syscall_get_param() 

be useful for this purpose. If I use this function to access syscall parameters in pre_syscall event I got addresses (which are from the addr space of the process under instrumentation) but I don't understand why the functions gives me also values that are not arguments of the current syscall. For example in my test binary I actually see the NtClose syscall and according to ntinternals this api only takes one argument but if I try to print 8 positions with 

dr_syscall_get_param(drcontext, 1) 
dr_syscall_get_param(drcontext, ...) 
dr_syscall_get_param(drcontext, 8) 

I get

NtClose
ARGS 0, 1, 0, 1, 7ff9e2365b1f, 7ffe0301, 1, 7ff9e2789877

can actually see different addresses that should not be involved in the syscall? Right? 
If I call get_param(...) for the current syscall should I get only the syscall arguments or am I using this api in the wrong way?

sharma...@google.com

unread,
Jul 18, 2022, 10:46:17 AM7/18/22
to DynamoRIO Users
Hi,

> I don't understand how can dr_syscall_get_param() be useful for this purpose.

dr_syscall_get_param is indeed how you get the syscall parameters in the pre-syscall event.

>  I don't understand why the functions gives me also values that are not arguments of the current syscall.

As noted in the documentation for dr_syscall_get_param, "It is up to the caller to ensure that reading this parameter is safe: this routine does not know the number of parameters for each system call, ". So your implementation needs to know the number of args accepted by the syscall and not pass a param_num that's higher than that.

Hope this helps,
Abhinav
Message has been deleted

ByteCrew

unread,
Jul 18, 2022, 11:15:59 AM7/18/22
to DynamoRIO Users
Thank you!
Ok, understood. But what am I reading exactly? Registers? Other process' memory areas? 
For example: let's take once more NtClose. If I call get_param(drcontext, 1) then it means that I'm going to get the zero in bold from the first post, but how can it be a valid value for the handle (NtClose takes only the process handle)? Does the position argument of get_param( ) refer to CPU registers?
What is the difference with  drsys_iterate_args( )? It seems more useful for this purpose, is it so?

sharma...@google.com

unread,
Jul 19, 2022, 9:44:13 AM7/19/22
to DynamoRIO Users
Hi,
The drsys_iterate_args API is available only in drmemory, unlike dr_syscall_get_param which is available to all DynamoRIO clients.

To get the first syscall parameter, you'd use param_num = 0 in dr_syscall_get_param(drcontext, param_num). I believe the zero you highlighted in your first post was a result of dr_syscall_get_param(drcontext, 1)?

See this if you're interested in the implementation.

Abhinav

ByteCrew

unread,
Jul 19, 2022, 10:35:30 AM7/19/22
to DynamoRIO Users
Nope, the highlighted zero was from  dr_syscall_get_param(drcontext, 0). But it is also true that the undocumented ntdll api like NtClose may have changed since the last available ntinternals.net - unofficial documentation - description. 
Yes, I know that  drsys_iterate_args is available only in drmemory, I was trying to use it to accomplish my goal but I don't understand much about its logic, there aren't examples of implementation anywhere unfortunately and the callback/user_data parameters passed as arguments are not so clear. Since dr_syscall_get_param does not know how much parameters there are in a syscall should I use drsys_iterate_args instead to read safely ALL the syscall parameters? 

Derek Bruening

unread,
Jul 19, 2022, 1:08:01 PM7/19/22
to ByteCrew, DynamoRIO Users
It is not likely that DR got the parameter value wrong: if it's getting syscall parameters wrong it wouldn't work at all as it has to deal with syscalls for its own purposes.  Are you sure the 0 passed to NtClose is not accurate?  You've given just that one instance without context: it is not uncommon to have incorrect or invalid arguments in real applications or to have system calls fail.  If you see 1000 NtClose calls with valid handles and one with 0 that does not look suspect in my experience.  If you are really skeptical, run in the debugger at that point and see what the value is and paste that result here.

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dynamorio-users/9a0bc2d0-c29e-472f-94e2-32179a9fbeb4n%40googlegroups.com.

ByteCrew

unread,
Jul 20, 2022, 4:22:07 AM7/20/22
to DynamoRIO Users
Yes I understand that, I was only trying to figure out what am I lookin at. Speaking of which I have a couple of questions: 

- after taking a look at this snippet I've noticed that sys_param_addr( ) refers to five registers (rdi, rsi, rdx, r10, r9, r8). Does dr_syscall_get_param(drcontext, param_num) use this function to read the value of the parameter? What if I want to read also other register's value?

And, from my previous post 

>  Since dr_syscall_get_param does not know how much parameters there are in a syscall should I use drsys_iterate_args instead to read safely ALL the syscall parameters?

For the NtClose matter I understood what you said, in fact, over a few calls I can see just a couple of zeros: 

NtClose
ARGS e4, 0, 1, 0, 1, 7ff9e2365b1f, 7ffe0301, 1
NtClose
ARGS ec, 0, 244aa0d0801, 0, 1, 7ff9e2365b49, 7ffe0301, 1
NtClose
ARGS 80, 0, 0, 0, 0, 7ff9e09973c9, 60138ed000, 242a9ec47e0
NtClose
ARGS 64, 0, 0, 242a9ed0630, 0, 7ff9e0510d32, 1, 1
NtClose
ARGS 0, 0, 0, 0, 7ff9e0500069, 7ff9eb5107a3, 0, 0
NtClose
ARGS 7c, 0, 0, 1, 7ff9e0504a00, 7ff9e05337cc, 1, 0
NtClose
ARGS 0, 0, 0, 1, 7ff9e05009f0, 7ff9e05107cc, 0, 0
NtClose
ARGS 6e, 0, 1, 1, 7ff9e050c000, 7ff9e05107cc, 0, 1

Thank you guys.

Derek Bruening

unread,
Jul 20, 2022, 11:01:32 AM7/20/22
to ByteCrew, DynamoRIO Users
On Wed, Jul 20, 2022 at 4:22 AM ByteCrew <strozz...@gmail.com> wrote:
Yes I understand that, I was only trying to figure out what am I lookin at. Speaking of which I have a couple of questions: 

- after taking a look at this snippet I've noticed that sys_param_addr( ) refers to five registers (rdi, rsi, rdx, r10, r9, r8).

On Linux x86_64, but it's different elsewhere.  There are precise interfaces between user and kernel specifying which syscall args are where depending on the platform.  Some are in stack slots on some platforms.
 
Does dr_syscall_get_param(drcontext, param_num) use this function to read the value of the parameter? What if I want to read also other register's value?


And, from my previous post 

>  Since dr_syscall_get_param does not know how much parameters there are in a syscall should I use drsys_iterate_args instead to read safely ALL the syscall parameters?

For the NtClose matter I understood what you said, in fact, over a few calls I can see just a couple of zeros: 

NtClose
ARGS e4, 0, 1, 0, 1, 7ff9e2365b1f, 7ffe0301, 1
NtClose
ARGS ec, 0, 244aa0d0801, 0, 1, 7ff9e2365b49, 7ffe0301, 1
NtClose
ARGS 80, 0, 0, 0, 0, 7ff9e09973c9, 60138ed000, 242a9ec47e0
NtClose
ARGS 64, 0, 0, 242a9ed0630, 0, 7ff9e0510d32, 1, 1
NtClose
ARGS 0, 0, 0, 0, 7ff9e0500069, 7ff9eb5107a3, 0, 0
NtClose
ARGS 7c, 0, 0, 1, 7ff9e0504a00, 7ff9e05337cc, 1, 0
NtClose
ARGS 0, 0, 0, 1, 7ff9e05009f0, 7ff9e05107cc, 0, 0
NtClose
ARGS 6e, 0, 1, 1, 7ff9e050c000, 7ff9e05107cc, 0, 1

Thank you guys.

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.

ByteCrew

unread,
Jul 20, 2022, 11:08:26 AM7/20/22
to DynamoRIO Users
On Linux x86_64, but it's different elsewhere.  There are precise interfaces between user and kernel specifying which syscall args are where depending on the platform.  Some are in stack slots on some platforms

Oh, ok. So if I'm on Windows dr_syscall_get_params( ) automatically follows the right calling convention?
 

And, from my previous post 

>  Since dr_syscall_get_param does not know how much parameters there are in a syscall should I use drsys_iterate_args instead to read safely ALL the syscall parameters?

For the NtClose matter I understood what you said, in fact, over a few calls I can see just a couple of zeros: 

NtClose
ARGS e4, 0, 1, 0, 1, 7ff9e2365b1f, 7ffe0301, 1
NtClose
ARGS ec, 0, 244aa0d0801, 0, 1, 7ff9e2365b49, 7ffe0301, 1
NtClose
ARGS 80, 0, 0, 0, 0, 7ff9e09973c9, 60138ed000, 242a9ec47e0
NtClose
ARGS 64, 0, 0, 242a9ed0630, 0, 7ff9e0510d32, 1, 1
NtClose
ARGS 0, 0, 0, 0, 7ff9e0500069, 7ff9eb5107a3, 0, 0
NtClose
ARGS 7c, 0, 0, 1, 7ff9e0504a00, 7ff9e05337cc, 1, 0
NtClose
ARGS 0, 0, 0, 1, 7ff9e05009f0, 7ff9e05107cc, 0, 0
NtClose
ARGS 6e, 0, 1, 1, 7ff9e050c000, 7ff9e05107cc, 0, 1

Thank you guys.

I think that something is missing here (?) you just quoted the question but there is no further info.

Derek Bruening

unread,
Jul 21, 2022, 1:08:29 PM7/21/22
to ByteCrew, DynamoRIO Users
On Wed, Jul 20, 2022 at 11:08 AM ByteCrew <strozz...@gmail.com> wrote:
On Linux x86_64, but it's different elsewhere.  There are precise interfaces between user and kernel specifying which syscall args are where depending on the platform.  Some are in stack slots on some platforms

Oh, ok. So if I'm on Windows dr_syscall_get_params( ) automatically follows the right calling convention?

Yes, how else would it work?
 
 

And, from my previous post 

>  Since dr_syscall_get_param does not know how much parameters there are in a syscall should I use drsys_iterate_args instead to read safely ALL the syscall parameters?

For the NtClose matter I understood what you said, in fact, over a few calls I can see just a couple of zeros: 

NtClose
ARGS e4, 0, 1, 0, 1, 7ff9e2365b1f, 7ffe0301, 1
NtClose
ARGS ec, 0, 244aa0d0801, 0, 1, 7ff9e2365b49, 7ffe0301, 1
NtClose
ARGS 80, 0, 0, 0, 0, 7ff9e09973c9, 60138ed000, 242a9ec47e0
NtClose
ARGS 64, 0, 0, 242a9ed0630, 0, 7ff9e0510d32, 1, 1
NtClose
ARGS 0, 0, 0, 0, 7ff9e0500069, 7ff9eb5107a3, 0, 0
NtClose
ARGS 7c, 0, 0, 1, 7ff9e0504a00, 7ff9e05337cc, 1, 0
NtClose
ARGS 0, 0, 0, 1, 7ff9e05009f0, 7ff9e05107cc, 0, 0
NtClose
ARGS 6e, 0, 1, 1, 7ff9e050c000, 7ff9e05107cc, 0, 1

Thank you guys.

I think that something is missing here (?) you just quoted the question but there is no further info.

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.
Message has been deleted

ByteCrew

unread,
Jul 25, 2022, 5:50:21 AM7/25/22
to DynamoRIO Users
Thank you.

One more thing: is it possibile, using DynamoRIO obv, to intercept syscalls BEFORE they reach the Ntdll layer? 

By looking at STDERR after the execution I can only see Nt syscalls. Can I also intercept for example CreateProcess (before it gets transalted into Nt "equivalent"), or GetFileAttributes, etc?

Derek Bruening

unread,
Jul 25, 2022, 11:35:19 AM7/25/22
to ByteCrew, DynamoRIO Users
Your client will see all the code after takeover, so yes.  If you mean, is there a convenience library to make it easier, yes there is a function wrapping library: https://dynamorio.org/page_drwrap.html

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages