3 ms·
Hi oleavr Sorry, I'm at work so I don't have much time to investigate, but how does it know what the arguments of the functions are? Is it just walking the sta
by mattchamb 13y ago
Hi oleavr
Sorry, I'm at work so I don't have much time to investigate, but how does it know what the arguments of the functions are? Is it just walking the stack until it finds something that looks like a return address, then assume everything before that is an argument?
Also, what kind of hooking does it support? I am only really familiar with windows DLLs, but is it able to hook the Import Address Table? How does this work with statically linked binaries when it can't just walk the IAT?
This stuff can probably be answered by looking at the source, but my curiosity currently is overruled by deadlines.
- oleavr 13y agoNo worries, the Frida website could definitely have explained things better! Regarding the number of function arguments it doesn't know that, so that's something you need to know at the higher level. It is however safe to access arguments out of bounds, just expect "garbage" values if you access values beyond the Nth argument of an N argument function. Also, using Frida's Memory API (Memory.readUtf8String() for example) you'll get a JS exception thrown if you attempt to access an invalid address. As for IAT, Frida is agnostic as far as hooking goes, it only needs the address of the function in memory (which you can obtain through for example Module.enumerateExports("kernel32.dll", ...)). How it works is that it dynamically rewrites/relocates the start of the function with a JMP to a trampoline that executes your JS hook, then the overwritten instruction(s) and finally jumps back to the next instruction after the overwritten ones. Regarding functions in static libraries you can use Process.enumerateRanges() or Module.enumerateRanges() and Memory.scan() together to find the functions you're interested in, and then just Interceptor.attach() to them. Hope this makes things a bit clearer!
- mattchamb 13y agoAwesome, thanks for the answer. That makes sense to just leave indexing the stack up to the user. Same with letting the user do some legwork to find the address of the function. Have you considered the (sort of edge) case when arguments are passed in registers? For example (in the VC compiler, as far as I remember) the "this" pointer is generally passed in the register ECX instead of being pushed onto the stack. In those cases it might be useful to have access to the register contents inside the JS callback. Along a similar line, the EAX register is generally used for return values. It might be useful to provide access to that as well (through another callback?), although that would probably require changing how your trampoline works so that it replaces the return address in the stack... (i miss working with low level things sometimes). Keep up the awesome work :D
- oleavr 13y agoAhh yes, exposing registers is planned and very trivial to implement, as it's available at the C code level, just needs to be exposed to the script runtime (V8). Future versions may also allow specifying an ABI, so args[0] maps to ecx for thiscall in 32-bit mode. My explanation of the hooking was a bit oversimplified, there is indeed support for hooking the return. Just implement onLeave(retval) in addition to onEnter(args), and you'll have access to the return value (coming from EAX/RAX). Feedback is most appreciated, so please let me know if there's any issues. :)