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 16, 2024
1 parent fe0c8de commit a7e62db
Showing 1 changed file with 180 additions and 0 deletions.
180 changes: 180 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,180 @@
---
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 *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
*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.

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
[@cr4zyserb]: https://github.com/cr4zyserb
[@as0ler]: https://twitter.com/as0ler
[@tmm1]: https://twitter.com/tmm1
[@Qfrost911]: https://github.com/Qfrost911

0 comments on commit a7e62db

Please sign in to comment.