Skip to content

Commit

Permalink
posts: Add release notes for 16.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
oleavr committed Feb 17, 2024
1 parent fe0c8de commit df2aad3
Showing 1 changed file with 183 additions and 0 deletions.
183 changes: 183 additions & 0 deletions _i18n/en/_posts/2024-02-16-frida-16-2-0-released.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
---
layout: news_item
title: 'Frida 16.2.0 Released'
date: 2024-02-16 13:45:43 +0100
author: oleavr
version: 16.2.0
categories: [release]
---

Lots of exciting new things this time around. Let's dive right in.

## Thread Names

The Process.enumerateThreads() API now also exposes thread names when available:

{% highlight sh %}
$ frida -U -F
[Pixel 6 Pro::com.google.android.calculator ]-> Process.enumerateThreads()[1]
{
"id": 9579,
"name": "Signal Catcher",
"state": "waiting",
"context": { … }
}
[Pixel 6 Pro::com.google.android.calculator ]->
{% endhighlight %}

Kudos to [@Hexploitable][] for the awesome pull-request that got this ball
rolling 🙌

## Memory Protection Queries

Sometimes it's essential to quickly determine the current protection of a page
in memory. Thanks to [@mrmacete][], now you can:

{% highlight sh %}
$ frida -p 0
[Local::SystemSession ]-> Memory.queryProtection(Module.getExportByName(null, 'open'))
"r-x"
[Local::SystemSession ]->
{% endhighlight %}

## QuickJS 2024-01-13

This release also contains the latest QuickJS, released last month. This means
there's almost complete ES2023 support, and even some features from the upcoming
ES2024 specification. Plus, quite a few bug-fixes as well. It's also worth
mentioning that top-level await is now supported, making it easier to write
portable scripts that work on both of our JavaScript runtimes.

## Cloaking

Frida keeps track of its own memory ranges, threads, etc., to keep you from
seeing yourself during process introspection. Introspection APIs such as
Process.enumerateThreads() ensure that Frida's own resources are hidden, and
things appear as if you were not inside the process being instrumented.

For those of you using Stalker, or other things that expose you to raw memory
locations, you might see code not belonging to any loaded module, and wonder
where it came from. For example, if you use Stalker.follow() to follow execution
into or out of a hooked function, it's going to execute some trampoline code
generated by Interceptor.

Agents using Gum's C APIs could already query whether a given memory address,
thread, etc., is owned by Frida, but this hadn't yet been exposed to our
JavaScript bindings. But now, thanks to another awesome contribution by
[@mrmacete][], this is now supported. For example:

{% highlight sh %}
$ frida -p 0
[Local::SystemSession ]-> open = Module.getExportByName(null, 'open')
"0x7f929a325840"
[Local::SystemSession ]-> Interceptor.attach(open, () => {})
{}
[Local::SystemSession ]-> Instruction.parse(open).toString()
"jmp 0x7f928940c408"
[Local::SystemSession ]-> Cloak.hasRangeContaining(ptr('0x7f928940c408'))
true
[Local::SystemSession ]-> pointInsideOpen = open.add(16)
"0x7f929a325850"
[Local::SystemSession ]-> Instruction.parse(pointInsideOpen).toString()
"push rbx"
[Local::SystemSession ]-> Cloak.hasRangeContaining(pointInsideOpen)
false
[Local::SystemSession ]->
{% endhighlight %}

## Fast Interceptor

One little known and fairly recent feature, now also available from JavaScript,
is Interceptor.replaceFast(). What's different about it is that the target is
modified to vector directly to your replacement, which means there is less
overhead compared to Interceptor.replace(). This also means that you need to
use the returned pointer if you want to call the original implementation. It is
also not possible to combine it with Interceptor.attach() for the same target.
However, if you're dealing with a hot target it's definitely something you want
to have in your toolbox, especially when combined with CModule.

## ELF Exports Regression

We discovered way late that Frida 16.1.0 broke Module#enumerateExports() on some
ELF binaries, and this is now finally fixed. It turned out to be a bug in the
bounds-checking that I added when making Gum.ElfModule a cross-platform API,
when it got support for offline use-cases like that of our Barebone backend.
(Where we use it to dynamically inject Rust code into OS kernels and bare-metal
targets.)

## ELF Import Slots

Those of you using Frida on Apple platforms may have noticed that
Module#enumerateImports() provides you with import objects that always have a
*slot* property. One way you can use this is to write a new pointer to that
address, letting you rebind imports on a per-module basis. Super-handy if
Interceptor is unable to hook a function, or for scenarios where you want to
avoid inline hooks.

As of this release, we now provide the *slot* property on ELF-based platforms
too, so you can also use this feature on Linux, Android, FreeBSD, and QNX. Yay!

## Android Stability

Avid users on recent versions of Android may have experienced "soft-loops",
where Frida randomly crashes Zygote and causes a big chunk of user-space to
restart. This turned out to be caused by the runtime preparing itself to
fork() by polling /proc/self/stat while waiting for the thread count to drop
to one, i.e. waiting for the process to become single-threaded.

This has now been solved by subtracting the threads owned by Frida, which we
determine by internally using the Cloak API, touched upon earlier in this post.
We also make use of the new ELF Import Slots feature, so we can hook read() only
for callers in libart.so. Inserting an inline hook in libc.so's read() is
not a great idea in this case, as the process we're in might use it for a
blocking read that blocks indefinitely. This becomes a challenge when wanting to
unload, and getting stuck waiting for the chance to roll back our inline hook.

Anyway, quite an interesting bug. Shout-out to [@enovella_][] for reporting and
helping track this one down 🙌

While on the topic of Android, this release also improves Java hooking on
Android 14, where a new ART quick entrypoint is being used in case of
*--enable-optimizations*. Kudos to [@cr4zyserb][] for this neat contribution.

## Better iOS 16 support

If you ever got hit by `Service cannot load in requested session` when trying
to install Frida on iOS, this is now finally fixed. Kudos to [@as0ler][] for the
assist on fixing this.

## Jailbroken tvOS

Another exciting development is that we now support jailbroken tvOS, and you
can grab a .deb straight from our repo at https://build.frida.re/. Special
thanks to [@tmm1][] for the pull-requests that made this happen.

## Misc

This release also has a lot more to offer. The remaining changes are:

- symbolutil-libdwarf: Fix handling of *DW_AT_ranges* in DWARF 5. This means the
DebugSymbol API works properly on binaries built by newer toolchains.
- elf-module: Fix relocation address when online.
- interceptor: Check module prefix when claiming grafts on arm64, for
compatibility with Xcode's new libLogRedirect.dylib interposing on iOS 17.
Thanks [@mrmacete][]!
- interceptor: Cloak thunks on arm64. Thanks [@mrmacete][]!
- windows: Ensure that the MSVC source-charset is set to UTF-8, so embedded
JavaScript can be parsed correctly at runtime. Thanks [@Qfrost911][]!
- freebsd: Improve allocate-near strategy.
- gumjs: Plug leak during QJS load() w/ ESM.
- objc: Ensure block structure is writable in implementation setter. Thanks
[@mrmacete][]!
- compiler: Bump @types/frida-gum to 18.6.0.

Enjoy!


[@Hexploitable]: https://twitter.com/Hexploitable
[@mrmacete]: https://twitter.com/bezjaje
[@enovella_]: https://twitter.com/enovella_
[@cr4zyserb]: https://github.com/cr4zyserb
[@as0ler]: https://twitter.com/as0ler
[@tmm1]: https://twitter.com/tmm1
[@Qfrost911]: https://github.com/Qfrost911

0 comments on commit df2aad3

Please sign in to comment.