0

I am working on a personal C# project where I want to redirect console streams to different inputs/outputs for different object instances. So for example I have a class User that I do not have source access to. I have multiple instances of User, and I would like to separate the console I/O of the Users (like for instance 1 and 2, output it in the console and for users 2 and 3, write to a file).

For example, User calls Console.WriteLine. I already figured out how to hook that call at runtime using some dangerous IL manipulation. But now I am stuck: how would I find out what was the User instance that called Console.WriteLine?

  • I cannot use a field like UID or Name, since the technique should also work on other objects that use Console.WriteLine
  • It needs to be done at runtime (also no altering of the assembly that contains User).
  • I have no source access to User
  • I have no issues with using unsafe or in other ways dangerous code

To my understanding, the object reference needs to be stored on the stack as the first parameter to the last frame, but I do not know how I get a pointer to the reference (nor to the last frame). But the information needs to exist somewhere, since the program needs to deconstruct the frame after it leaves the function, right? I kind of remember that whenever a new frame is pushed onto the stack, at the end of the stack before the new frame is added it puts a frame pointer that points to the top of the frame, so If I get to the top of the current frame using the current frame pointer and then read the last frame pointer before it, then go to there and find the parameter I could get the reference, right?

My Question: How would I "climb up" the stack in practice? Is there any other way to get the reference?

(And yes, I know doing this was not intended nor is it good practice, but I really enjoy exactly this aspect of programming.)

Jakob Tinhofer
  • 313
  • 3
  • 16
  • The exact details of how you would do this will be platform-specific, but you're right that if a non-static class method calls `Console.WriteLine`, then that method will have access to its `this` pointer. That is typically held in a caller-preserved register, so it should not be hard to get at in your hook from asm, but the details... – 500 - Internal Server Error Jul 05 '23 at 00:16
  • Related: [How do I get the executing object for a stackframe?](https://stackoverflow.com/q/889310). The consensus there was that it's impossible using .NET code, but might be possible using assembly code. On the other hand [this answer](https://stackoverflow.com/a/75297) by Lars Truijens to [Obtain parameter values from a stack frame in .NET?](https://stackoverflow.com/q/75076) suggests writing your own debugger or profiler, and links to the open-source [Mdbg](https://stackoverflow.com/q/2791459). – dbc Jul 05 '23 at 20:46

0 Answers0