Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return Values #3

Open
pmurley opened this issue Sep 11, 2020 · 11 comments
Open

Return Values #3

pmurley opened this issue Sep 11, 2020 · 11 comments
Labels
help wanted Extra attention is needed

Comments

@pmurley
Copy link

pmurley commented Sep 11, 2020

Hi @jueckstock, hope all is well. I've been enjoying using this tool over the past few months. I'm wondering if you've considered modifying the instrumentation such that it logs simple return values as well. I think this would apply to get and call methods most clearly, right? I guess it's probably impractical to log any arbitrary return type, but how difficult do you think it would be just to grab and ints or strings that are returned? Is this functionality already there and I've just been missing it?

Sidenote as well: Do you plan to continue pushing updated patches for newer versions of Chromium at all?

Thanks!

@jueckstock
Copy link
Collaborator

Glad you like it. What do you find it useful for, if you don't mind sharing?

W.r.t. logging return values, it should not be hard to log such values using the existing vv8 JS object serialization code.

Repositioning the instrumentation to capture return values or retrieved property values would be straightforward in some cases and potentially tricky in others (esp. property access bytecode injection). Definitely possible, just a question of pain points.

The capabality would, of course, be useful! As I have opportunity, I will look into it.

W.r.t. patch updates: I am aware of more up to date patches created by other researchers using vv8 and am working to get those updates pulled back into this repository. Hopefully soon.

@pmurley
Copy link
Author

pmurley commented Sep 16, 2020

I'm looking at various applications, including seeing what advantages there are for fingerprinting detection (over something extension-based like OpenWPM), studying obfuscated JavaScript code (looking forward to reading your IMC paper :) ), and doing some general script and site clustering by applying some ML to the generated traces. I'm also working on combining the trace output with data from the DevTools network and debugger domains to get more fine-grained, complete provenance on script and resource loads.

Glad to hear you think return values are (mostly) pretty straightforward -- I think it would be a welcome addition for several applications.

If you're interested/available, I'd love to do a call sometime just to pick your brain a little bit about some of these possibilities and your thoughts about the future of the tool. I know sometimes research projects like this tend to be one-and-done-type things, but I think it's a valuable capability that still has a lot of untapped potential, and I'd be thrilled to collaborate if we can find a project where it makes sense.

@fhertz
Copy link

fhertz commented Jan 2, 2023

hi @jueckstock @pmurley , i think getting the return value will be great if it's string or int , i think the Graal is to have the possibility to get and hook the returned value, like Frida , we can hook a function, and when it's called we can return a value, or just log the function call or play with arguments.

kapravel added a commit that referenced this issue Mar 16, 2023
@L3thal14
Copy link

Any updates on this?

@Niek
Copy link

Niek commented Mar 19, 2024

Another +1 for this

@packman80
Copy link

great idea!

@sohomdatta1
Copy link
Collaborator

I was playing around with this for a while today (just for fun), and based on a bit of testing, it appears that in the latest version of Chrome, you could just potentially hook into

HandleApiCallHelper(
    Isolate* isolate, Handle<HeapObject> new_target,
    Handle<FunctionTemplateInfo> fun_data, Handle<Object> receiver,
    Address* argv, int argc) {
    ....
}

in src/builtins/builtins-api.cc to intercept the return value of a JavaScript API and then use VisibleV8 logging API to dump that info to the log.

That being said, we (at the lab) don't have a specific usecase for this feature yet, but if any one of y'all are still interested in adding it, I'll be happy to help out and provide a code review/walk you through some of our modifications.

@sohomdatta1 sohomdatta1 added the help wanted Extra attention is needed label Jun 19, 2024
@Ghxst
Copy link

Ghxst commented Jun 27, 2024

Still very much interested in this! Interesting find.

@naifmeh
Copy link

naifmeh commented Aug 12, 2024

Hi @sohomdatta1,
I would be very interested by a walk through to do this, if possible.
Thanks :)

@sohomdatta1
Copy link
Collaborator

sohomdatta1 commented Aug 14, 2024

Hi @naifmeh
Sorry it took me a while to get back,
The return value of the function

HandleApiCallHelper(
    Isolate* isolate, Handle<HeapObject> new_target,
    Handle<FunctionTemplateInfo> fun_data, Handle<Object> receiver,
    Address* argv, int argc) {
    ....
}

should in theory be the return value that will eventually passed to our Javascript API function. The idea I had back then was to add a few lines of CPP to intercept the return value and then call a new function that logs return values using the VisibleV8 logger. While we don't have a function that explicitly log return values at the moment, it should be mostly easy to create one based on the functions we use to log function calls (Most of the code can be copypasted minus the constructor checks and the argument printing, in its place you need to add code to print a single return value)

@naifmeh
Copy link

naifmeh commented Aug 16, 2024

Thanks for the instructions @sohomdatta1!

I managed to add something that prints the expected returns of the function by adding the following call logs starting from here:

if (fun_data->has_callback(isolate)) {
    FunctionCallbackArguments custom(isolate, *fun_data, raw_holder,
                                     *new_target, argv, argc);
    Handle<Object> result = custom.Call(*fun_data);

    RETURN_EXCEPTION_IF_EXCEPTION(isolate);
    if (result.is_null()) {
      if (is_construct) {
        v8::internal::visv8_log_api_call_result(isolate, *fun_data, *receiver, argv, argc, *js_receiver);
        return js_receiver;
      }
      return isolate->factory()->undefined_value();
    }
    // Rebox the result.
    {
      DisallowGarbageCollection no_gc;
      Tagged<Object> raw_result = *result;
      v8::internal::visv8_log_api_call_result(isolate, *fun_data, *receiver, argv, argc, raw_result);
      DCHECK(IsApiCallResultType(raw_result));
      if (!is_construct || IsJSReceiver(raw_result)) 
        return handle(raw_result, isolate);
    }
  }

  v8::internal::visv8_log_api_call_result(isolate, *fun_data, *receiver, argv, argc, *js_receiver);
  return js_receiver;

But it doesn't exactly log the value, but rather the returned type. I get logs that look like this:

c363:%get userAgentData:{665335,Navigator}
g377:{102492,NavigatorUAData}:"getHighEntropyValues"
a473:?:{120346,Window} => {665335,Navigator}
...
g10946:{968892,HTMLCanvasElement}:"toDataURL"
c10946:%toDataURL:{968892,HTMLCanvasElement}
n11056:%Image
a11056:?:{556311,Image} => {556311,Image}
...
g12551:{120346,Window}:"matchMedia"
c12551:%matchMedia:{120346,Window}:"( color-gamut\: srgb )"
a12551:?:? => {60987,MediaQueryList}
...

Maybe I'm doing something wrong, so I'Il keep looking. But if you have any idea in the meantime, it would be really helpful :)

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

9 participants