mirror of
https://github.com/frida/frida-core.git
synced 2026-11-09 01:59:34 -10:00
Compare commits
No files matched your search
@@ -1400,12 +1400,12 @@ namespace Frida.Agent {
|
||||
if (nb_api.unload_library == null)
|
||||
parameters.append ("|eternal|sticky");
|
||||
/*
|
||||
* Disable ExitMonitor to work around a bug in Android's libndk_translation.so on Android 11.
|
||||
* We need to avoid modifying libc.so ranges that the translator potentially depends on, to
|
||||
* avoid blowing up when Interceptor's CPU cache flush results in the translated code being
|
||||
* discarded, which seems like an edge-case the translator doesn't handle.
|
||||
* Disable Exceptor and ExitMonitor to work around a bug in Android's libndk_translation.so
|
||||
* on Android 11. We need to avoid modifying libc.so ranges that the translator potentially
|
||||
* depends on, to avoid blowing up when Interceptor's CPU cache flush results in the translated
|
||||
* code being discarded, which seems like an edge-case the translator doesn't handle.
|
||||
*/
|
||||
parameters.append ("|exit-monitor:off");
|
||||
parameters.append ("|exceptor:off|exit-monitor:off");
|
||||
|
||||
emulated_bridge_state = new BridgeState (parameters.str);
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "frida-base.h"
|
||||
|
||||
GBytes *
|
||||
frida_make_bytes_with_owner (GType t_type,
|
||||
GBoxedCopyFunc t_dup_func,
|
||||
GDestroyNotify t_destroy_func,
|
||||
void * data,
|
||||
gsize size,
|
||||
gpointer owner)
|
||||
{
|
||||
return g_bytes_new_with_free_func (data, size, t_destroy_func, owner);
|
||||
}
|
||||
+94
-32
@@ -356,10 +356,20 @@ namespace Frida {
|
||||
return *((int8 *) get_pointer (offset, sizeof (int8)));
|
||||
}
|
||||
|
||||
public unowned Buffer write_int8 (size_t offset, int8 val) {
|
||||
*((int8 *) get_pointer (offset, sizeof (int8))) = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public uint8 read_uint8 (size_t offset) {
|
||||
return *get_pointer (offset, sizeof (uint8));
|
||||
}
|
||||
|
||||
public unowned Buffer write_uint8 (size_t offset, uint8 val) {
|
||||
*((uint8 *) get_pointer (offset, sizeof (uint8))) = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int16 read_int16 (size_t offset) {
|
||||
int16 val = *((int16 *) get_pointer (offset, sizeof (int16)));
|
||||
return (byte_order == BIG_ENDIAN)
|
||||
@@ -367,6 +377,14 @@ namespace Frida {
|
||||
: int16.from_little_endian (val);
|
||||
}
|
||||
|
||||
public unowned Buffer write_int16 (size_t offset, int16 val) {
|
||||
int16 target_val = (byte_order == BIG_ENDIAN)
|
||||
? val.to_big_endian ()
|
||||
: val.to_little_endian ();
|
||||
*((int16 *) get_pointer (offset, sizeof (int16))) = target_val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public uint16 read_uint16 (size_t offset) {
|
||||
uint16 val = *((uint16 *) get_pointer (offset, sizeof (uint16)));
|
||||
return (byte_order == BIG_ENDIAN)
|
||||
@@ -374,6 +392,14 @@ namespace Frida {
|
||||
: uint16.from_little_endian (val);
|
||||
}
|
||||
|
||||
public unowned Buffer write_uint16 (size_t offset, uint16 val) {
|
||||
uint16 target_val = (byte_order == BIG_ENDIAN)
|
||||
? val.to_big_endian ()
|
||||
: val.to_little_endian ();
|
||||
*((uint16 *) get_pointer (offset, sizeof (uint16))) = target_val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int32 read_int32 (size_t offset) {
|
||||
int32 val = *((int32 *) get_pointer (offset, sizeof (int32)));
|
||||
return (byte_order == BIG_ENDIAN)
|
||||
@@ -381,6 +407,14 @@ namespace Frida {
|
||||
: int32.from_little_endian (val);
|
||||
}
|
||||
|
||||
public unowned Buffer write_int32 (size_t offset, int32 val) {
|
||||
int32 target_val = (byte_order == BIG_ENDIAN)
|
||||
? val.to_big_endian ()
|
||||
: val.to_little_endian ();
|
||||
*((int32 *) get_pointer (offset, sizeof (int32))) = target_val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public uint32 read_uint32 (size_t offset) {
|
||||
uint32 val = *((uint32 *) get_pointer (offset, sizeof (uint32)));
|
||||
return (byte_order == BIG_ENDIAN)
|
||||
@@ -403,6 +437,14 @@ namespace Frida {
|
||||
: int64.from_little_endian (val);
|
||||
}
|
||||
|
||||
public unowned Buffer write_int64 (size_t offset, int64 val) {
|
||||
int64 target_val = (byte_order == BIG_ENDIAN)
|
||||
? val.to_big_endian ()
|
||||
: val.to_little_endian ();
|
||||
*((int64 *) get_pointer (offset, sizeof (int64))) = target_val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public uint64 read_uint64 (size_t offset) {
|
||||
uint64 val = *((uint64 *) get_pointer (offset, sizeof (uint64)));
|
||||
return (byte_order == BIG_ENDIAN)
|
||||
@@ -446,7 +488,7 @@ namespace Frida {
|
||||
|
||||
public string read_fixed_string (size_t offset, size_t size) throws Error {
|
||||
string * start = (string *) get_pointer (offset, size);
|
||||
size_t max_length = size - offset;
|
||||
size_t max_length = size_t.min (size, this.size - offset);
|
||||
string * end = memchr (start, 0, max_length);
|
||||
size_t n;
|
||||
if (end != null)
|
||||
@@ -465,6 +507,18 @@ namespace Frida {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Bytes read_bytes (size_t offset, size_t size) {
|
||||
var data = new uint8[size + 1];
|
||||
Memory.copy (data, get_pointer (offset, size), size);
|
||||
return new Bytes.take ((owned) data);
|
||||
}
|
||||
|
||||
public unowned Buffer write_bytes (size_t offset, Bytes bytes) {
|
||||
size_t size = bytes.get_size ();
|
||||
Memory.copy (get_pointer (offset, size), bytes.get_data (), size);
|
||||
return this;
|
||||
}
|
||||
|
||||
private uint8 * get_pointer (size_t offset, size_t n) {
|
||||
size_t minimum_size = offset + n;
|
||||
assert (size >= minimum_size);
|
||||
@@ -474,14 +528,20 @@ namespace Frida {
|
||||
}
|
||||
|
||||
public sealed class BufferReader {
|
||||
public size_t offset {
|
||||
get {
|
||||
return _offset;
|
||||
}
|
||||
}
|
||||
|
||||
public size_t available {
|
||||
get {
|
||||
return buffer.bytes.get_size () - offset;
|
||||
return buffer.bytes.get_size () - _offset;
|
||||
}
|
||||
}
|
||||
|
||||
private Buffer buffer;
|
||||
private size_t offset = 0;
|
||||
private size_t _offset = 0;
|
||||
|
||||
public BufferReader (Buffer buf) {
|
||||
buffer = buf;
|
||||
@@ -490,105 +550,105 @@ namespace Frida {
|
||||
public uint64 read_pointer (size_t offset) throws Error {
|
||||
var pointer_size = buffer.pointer_size;
|
||||
check_available (pointer_size);
|
||||
var ptr = buffer.read_pointer (offset);
|
||||
offset += pointer_size;
|
||||
var ptr = buffer.read_pointer (_offset);
|
||||
_offset += pointer_size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
public int8 read_int8 () throws Error {
|
||||
check_available (sizeof (int8));
|
||||
var val = buffer.read_int8 (offset);
|
||||
offset += sizeof (int8);
|
||||
var val = buffer.read_int8 (_offset);
|
||||
_offset += sizeof (int8);
|
||||
return val;
|
||||
}
|
||||
|
||||
public uint8 read_uint8 () throws Error {
|
||||
check_available (sizeof (uint8));
|
||||
var val = buffer.read_uint8 (offset);
|
||||
offset += sizeof (uint8);
|
||||
var val = buffer.read_uint8 (_offset);
|
||||
_offset += sizeof (uint8);
|
||||
return val;
|
||||
}
|
||||
|
||||
public int16 read_int16 () throws Error {
|
||||
check_available (sizeof (int16));
|
||||
var val = buffer.read_int16 (offset);
|
||||
offset += sizeof (int16);
|
||||
var val = buffer.read_int16 (_offset);
|
||||
_offset += sizeof (int16);
|
||||
return val;
|
||||
}
|
||||
|
||||
public uint16 read_uint16 () throws Error {
|
||||
check_available (sizeof (uint16));
|
||||
var val = buffer.read_uint16 (offset);
|
||||
offset += sizeof (uint16);
|
||||
var val = buffer.read_uint16 (_offset);
|
||||
_offset += sizeof (uint16);
|
||||
return val;
|
||||
}
|
||||
|
||||
public int32 read_int32 () throws Error {
|
||||
check_available (sizeof (int32));
|
||||
var val = buffer.read_int32 (offset);
|
||||
offset += sizeof (int32);
|
||||
var val = buffer.read_int32 (_offset);
|
||||
_offset += sizeof (int32);
|
||||
return val;
|
||||
}
|
||||
|
||||
public uint32 read_uint32 () throws Error {
|
||||
check_available (sizeof (uint32));
|
||||
var val = buffer.read_uint32 (offset);
|
||||
offset += sizeof (uint32);
|
||||
var val = buffer.read_uint32 (_offset);
|
||||
_offset += sizeof (uint32);
|
||||
return val;
|
||||
}
|
||||
|
||||
public int64 read_int64 () throws Error {
|
||||
check_available (sizeof (int64));
|
||||
var val = buffer.read_int64 (offset);
|
||||
offset += sizeof (int64);
|
||||
var val = buffer.read_int64 (_offset);
|
||||
_offset += sizeof (int64);
|
||||
return val;
|
||||
}
|
||||
|
||||
public uint64 read_uint64 () throws Error {
|
||||
check_available (sizeof (uint64));
|
||||
var val = buffer.read_uint64 (offset);
|
||||
offset += sizeof (uint64);
|
||||
var val = buffer.read_uint64 (_offset);
|
||||
_offset += sizeof (uint64);
|
||||
return val;
|
||||
}
|
||||
|
||||
public float read_float () throws Error {
|
||||
check_available (sizeof (float));
|
||||
var val = buffer.read_float (offset);
|
||||
offset += sizeof (float);
|
||||
var val = buffer.read_float (_offset);
|
||||
_offset += sizeof (float);
|
||||
return val;
|
||||
}
|
||||
|
||||
public double read_double () throws Error {
|
||||
check_available (sizeof (double));
|
||||
var val = buffer.read_double (offset);
|
||||
offset += sizeof (double);
|
||||
var val = buffer.read_double (_offset);
|
||||
_offset += sizeof (double);
|
||||
return val;
|
||||
}
|
||||
|
||||
public string read_string () throws Error {
|
||||
check_available (1);
|
||||
var val = buffer.read_string (offset);
|
||||
offset += val.length + 1;
|
||||
var val = buffer.read_string (_offset);
|
||||
_offset += val.length + 1;
|
||||
return val;
|
||||
}
|
||||
|
||||
public string read_fixed_string (size_t size) throws Error {
|
||||
check_available (size);
|
||||
var val = buffer.read_fixed_string (offset, size);
|
||||
offset += size;
|
||||
var val = buffer.read_fixed_string (_offset, size);
|
||||
_offset += size;
|
||||
return val;
|
||||
}
|
||||
|
||||
public Bytes read_bytes (size_t size) throws Error {
|
||||
check_available (size);
|
||||
var val = buffer.bytes[offset:offset + size];
|
||||
offset += size;
|
||||
var val = buffer.bytes[_offset:_offset + size];
|
||||
_offset += size;
|
||||
return val;
|
||||
}
|
||||
|
||||
public unowned BufferReader skip (size_t n) throws Error {
|
||||
check_available (n);
|
||||
offset += n;
|
||||
_offset += n;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -597,4 +657,6 @@ namespace Frida {
|
||||
throw new Error.PROTOCOL ("Malformed buffer: truncated");
|
||||
}
|
||||
}
|
||||
|
||||
public extern Bytes make_bytes_with_owner<T> (void * data, size_t size, owned T? owner = null);
|
||||
}
|
||||
@@ -13,6 +13,7 @@ base_sources = [
|
||||
'socket.vala',
|
||||
'socket-glue.c',
|
||||
'buffer.vala',
|
||||
'buffer-glue.c',
|
||||
'value.vala',
|
||||
]
|
||||
|
||||
|
||||
+52
-12
@@ -46,7 +46,8 @@ namespace Frida {
|
||||
}
|
||||
private GLib.Error? _error;
|
||||
|
||||
private Gee.ArrayQueue<CompletionFuncEntry> on_complete;
|
||||
private Gee.ArrayQueue<CompletionFuncEntry>? on_complete;
|
||||
private Gee.ArrayQueue<ThenHandlerEntry<T>>? on_then;
|
||||
|
||||
public async T wait_async (Cancellable? cancellable) throws Frida.Error, IOError {
|
||||
if (_ready)
|
||||
@@ -74,7 +75,21 @@ namespace Frida {
|
||||
return get_result ();
|
||||
}
|
||||
|
||||
private T get_result () throws Frida.Error, IOError {
|
||||
public void then (owned FutureCompletionHandler<T> handler) {
|
||||
if (_ready) {
|
||||
schedule (() => {
|
||||
handler (this);
|
||||
return Source.REMOVE;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (on_then == null)
|
||||
on_then = new Gee.ArrayQueue<ThenHandlerEntry<T>> ();
|
||||
on_then.offer (new ThenHandlerEntry<T> ((owned) handler));
|
||||
}
|
||||
|
||||
public T get_result () throws Frida.Error, IOError {
|
||||
if (error != null) {
|
||||
if (error is Frida.Error)
|
||||
throw (Frida.Error) error;
|
||||
@@ -111,19 +126,32 @@ namespace Frida {
|
||||
internal void transition_to_ready () {
|
||||
_ready = true;
|
||||
|
||||
if (on_complete != null && !on_complete.is_empty) {
|
||||
var source = new IdleSource ();
|
||||
source.set_priority (Priority.HIGH);
|
||||
source.set_callback (() => {
|
||||
CompletionFuncEntry? entry;
|
||||
while ((entry = on_complete.poll ()) != null)
|
||||
entry.func ();
|
||||
on_complete = null;
|
||||
return false;
|
||||
if (on_complete != null || on_then != null) {
|
||||
schedule (() => {
|
||||
if (on_complete != null) {
|
||||
CompletionFuncEntry? entry;
|
||||
while ((entry = on_complete.poll ()) != null)
|
||||
entry.func ();
|
||||
on_complete = null;
|
||||
}
|
||||
|
||||
if (on_then != null) {
|
||||
ThenHandlerEntry? entry;
|
||||
while ((entry = on_then.poll ()) != null)
|
||||
entry.handler (this);
|
||||
on_then = null;
|
||||
}
|
||||
|
||||
return Source.REMOVE;
|
||||
});
|
||||
source.attach (MainContext.get_thread_default ());
|
||||
}
|
||||
}
|
||||
|
||||
private static void schedule (owned SourceFunc function) {
|
||||
var source = new IdleSource ();
|
||||
source.set_callback ((owned) function);
|
||||
source.attach (MainContext.get_thread_default ());
|
||||
}
|
||||
}
|
||||
|
||||
private class CompletionFuncEntry {
|
||||
@@ -133,6 +161,14 @@ namespace Frida {
|
||||
this.func = (owned) func;
|
||||
}
|
||||
}
|
||||
|
||||
private class ThenHandlerEntry<T> {
|
||||
public FutureCompletionHandler<T> handler;
|
||||
|
||||
public ThenHandlerEntry (owned FutureCompletionHandler<T> handler) {
|
||||
this.handler = (owned) handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface Future<T> : Object {
|
||||
@@ -140,5 +176,9 @@ namespace Frida {
|
||||
public abstract T? value { get; }
|
||||
public abstract GLib.Error? error { get; }
|
||||
public abstract async T wait_async (Cancellable? cancellable) throws Frida.Error, IOError;
|
||||
public abstract void then (owned FutureCompletionHandler<T> handler);
|
||||
public abstract T get_result () throws Frida.Error, IOError;
|
||||
}
|
||||
|
||||
public delegate void FutureCompletionHandler<T> (Future<T> future);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "frida-gadget.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <gum/gumdarwin.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <objc/runtime.h>
|
||||
#include <pthread.h>
|
||||
|
||||
@@ -51,3 +53,53 @@ frida_gadget_environment_set_thread_name (const gchar * name)
|
||||
/* For now only implemented on i/macOS as Fruity.Injector relies on it there. */
|
||||
pthread_setname_np (name);
|
||||
}
|
||||
|
||||
void
|
||||
frida_gadget_environment_detect_darwin_location_fields (GumAddress our_address, gchar ** executable_name, gchar ** our_path,
|
||||
GumMemoryRange ** our_range)
|
||||
{
|
||||
mach_port_t task;
|
||||
GumDarwinModuleResolver * resolver;
|
||||
GPtrArray * modules;
|
||||
guint i;
|
||||
|
||||
task = mach_task_self ();
|
||||
|
||||
resolver = gum_darwin_module_resolver_new (task, NULL);
|
||||
if (resolver == NULL)
|
||||
return;
|
||||
|
||||
gum_darwin_module_resolver_fetch_modules (resolver, &modules, NULL);
|
||||
|
||||
for (i = 0; i != modules->len; i++)
|
||||
{
|
||||
GumModule * module;
|
||||
const GumMemoryRange * range;
|
||||
|
||||
module = g_ptr_array_index (modules, i);
|
||||
range = gum_module_get_range (module);
|
||||
|
||||
if (*executable_name == NULL)
|
||||
{
|
||||
gum_mach_header_t * header = GSIZE_TO_POINTER (range->base_address);
|
||||
if (header->filetype == MH_EXECUTE)
|
||||
*executable_name = g_strdup (gum_module_get_name (module));
|
||||
}
|
||||
|
||||
if (our_address >= range->base_address && our_address < range->base_address + range->size)
|
||||
{
|
||||
if (*our_path == NULL)
|
||||
*our_path = g_strdup (gum_module_get_path (module));
|
||||
|
||||
if (*our_range == NULL)
|
||||
*our_range = gum_memory_range_copy (range);
|
||||
}
|
||||
|
||||
if (*executable_name != NULL && *our_path != NULL && *our_range != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
g_ptr_array_unref (modules);
|
||||
|
||||
g_object_unref (resolver);
|
||||
}
|
||||
+11
-83
@@ -24,12 +24,6 @@ namespace Frida.Gadget {
|
||||
default = Gum.CodeSigningPolicy.OPTIONAL;
|
||||
}
|
||||
|
||||
private ObjectClass klass = (ObjectClass) typeof (Config).class_ref ();
|
||||
|
||||
public Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
|
||||
return default_serialize_property (property_name, value, pspec);
|
||||
}
|
||||
|
||||
public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
|
||||
if (property_name == "interaction" && property_node.get_node_type () == Json.NodeType.OBJECT) {
|
||||
var interaction_node = property_node.get_object ();
|
||||
@@ -77,20 +71,6 @@ namespace Frida.Gadget {
|
||||
value = Value (pspec.value_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
public unowned ParamSpec? find_property (string name) {
|
||||
return klass.find_property (name);
|
||||
}
|
||||
|
||||
public new Value get_property (ParamSpec pspec) {
|
||||
var val = Value (pspec.value_type);
|
||||
base.get_property (pspec.name, ref val);
|
||||
return val;
|
||||
}
|
||||
|
||||
public new void set_property (ParamSpec pspec, Value value) {
|
||||
base.set_property (pspec.name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ScriptInteraction : Object, Json.Serializable {
|
||||
@@ -112,12 +92,6 @@ namespace Frida.Gadget {
|
||||
default = Script.ChangeBehavior.IGNORE;
|
||||
}
|
||||
|
||||
private ObjectClass klass = (ObjectClass) typeof (ScriptInteraction).class_ref ();
|
||||
|
||||
public Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
|
||||
return default_serialize_property (property_name, value, pspec);
|
||||
}
|
||||
|
||||
public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
|
||||
if (property_name == "parameters" && property_node.get_node_type () == Json.NodeType.OBJECT) {
|
||||
var v = Value (typeof (Json.Node));
|
||||
@@ -129,20 +103,6 @@ namespace Frida.Gadget {
|
||||
value = Value (pspec.value_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
public unowned ParamSpec? find_property (string name) {
|
||||
return klass.find_property (name);
|
||||
}
|
||||
|
||||
public new Value get_property (ParamSpec pspec) {
|
||||
var val = Value (pspec.value_type);
|
||||
base.get_property (pspec.name, ref val);
|
||||
return val;
|
||||
}
|
||||
|
||||
public new void set_property (ParamSpec pspec, Value value) {
|
||||
base.set_property (pspec.name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ScriptDirectoryInteraction : Object {
|
||||
@@ -183,12 +143,6 @@ namespace Frida.Gadget {
|
||||
default = Script.ChangeBehavior.IGNORE;
|
||||
}
|
||||
|
||||
private ObjectClass klass = (ObjectClass) typeof (ScriptConfig).class_ref ();
|
||||
|
||||
public Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
|
||||
return default_serialize_property (property_name, value, pspec);
|
||||
}
|
||||
|
||||
public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
|
||||
if (property_name == "parameters" && property_node.get_node_type () == Json.NodeType.OBJECT) {
|
||||
var v = Value (typeof (Json.Node));
|
||||
@@ -200,20 +154,6 @@ namespace Frida.Gadget {
|
||||
value = Value (pspec.value_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
public unowned ParamSpec? find_property (string name) {
|
||||
return klass.find_property (name);
|
||||
}
|
||||
|
||||
public new Value get_property (ParamSpec pspec) {
|
||||
var val = Value (pspec.value_type);
|
||||
base.get_property (pspec.name, ref val);
|
||||
return val;
|
||||
}
|
||||
|
||||
public new void set_property (ParamSpec pspec, Value value) {
|
||||
base.set_property (pspec.name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ProcessFilter : Object {
|
||||
@@ -299,8 +239,6 @@ namespace Frida.Gadget {
|
||||
default = make_empty_json_object ();
|
||||
}
|
||||
|
||||
private ObjectClass klass = (ObjectClass) typeof (ConnectInteraction).class_ref ();
|
||||
|
||||
public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
|
||||
if (property_name == "parameters" && property_node.get_node_type () == Json.NodeType.OBJECT) {
|
||||
var v = Value (typeof (Json.Node));
|
||||
@@ -312,20 +250,6 @@ namespace Frida.Gadget {
|
||||
value = Value (pspec.value_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
public unowned ParamSpec? find_property (string name) {
|
||||
return klass.find_property (name);
|
||||
}
|
||||
|
||||
public new Value get_property (ParamSpec pspec) {
|
||||
var val = Value (pspec.value_type);
|
||||
base.get_property (pspec.name, ref val);
|
||||
return val;
|
||||
}
|
||||
|
||||
public new void set_property (ParamSpec pspec, Value value) {
|
||||
base.set_property (pspec.name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class Location : Object {
|
||||
@@ -759,7 +683,7 @@ namespace Frida.Gadget {
|
||||
}
|
||||
|
||||
try {
|
||||
return Json.gobject_from_data (typeof (Config), config_data) as Config;
|
||||
return (Config) Json.gobject_from_data (typeof (Config), config_data);
|
||||
} catch (GLib.Error e) {
|
||||
throw new Error.INVALID_ARGUMENT ("Invalid config: %s", e.message);
|
||||
}
|
||||
@@ -767,7 +691,7 @@ namespace Frida.Gadget {
|
||||
|
||||
private Config parse_config (string config_data) throws Error {
|
||||
try {
|
||||
return Json.gobject_from_data (typeof (Config), config_data) as Config;
|
||||
return (Config) Json.gobject_from_data (typeof (Config), config_data);
|
||||
} catch (GLib.Error e) {
|
||||
throw new Error.INVALID_ARGUMENT ("Invalid config: %s", e.message);
|
||||
}
|
||||
@@ -775,21 +699,20 @@ namespace Frida.Gadget {
|
||||
|
||||
private Location detect_location (Gum.MemoryRange? mapped_range) {
|
||||
string? executable_name = null;
|
||||
string? executable_path = null;
|
||||
Gum.MemoryRange? executable_range = null;
|
||||
string? our_path = null;
|
||||
Gum.MemoryRange? our_range = mapped_range;
|
||||
|
||||
Gum.Address our_address = Gum.Address.from_pointer (Gum.strip_code_pointer ((void *) detect_location));
|
||||
|
||||
#if DARWIN
|
||||
Environment.detect_darwin_location_fields (our_address, ref executable_name, ref our_path, ref our_range);
|
||||
#else
|
||||
var index = 0;
|
||||
Gum.Process.enumerate_modules ((details) => {
|
||||
var range = details.range;
|
||||
|
||||
if (index == 0) {
|
||||
executable_name = details.name;
|
||||
executable_path = details.path;
|
||||
executable_range = details.range;
|
||||
}
|
||||
|
||||
if (mapped_range != null)
|
||||
@@ -805,6 +728,7 @@ namespace Frida.Gadget {
|
||||
|
||||
return true;
|
||||
});
|
||||
#endif
|
||||
|
||||
assert (our_range != null);
|
||||
|
||||
@@ -1234,7 +1158,7 @@ namespace Frida.Gadget {
|
||||
}
|
||||
|
||||
try {
|
||||
return Json.gobject_from_data (typeof (ScriptConfig), data) as ScriptConfig;
|
||||
return (ScriptConfig) Json.gobject_from_data (typeof (ScriptConfig), data);
|
||||
} catch (GLib.Error e) {
|
||||
throw new Error.INVALID_ARGUMENT ("Invalid config: %s", e.message);
|
||||
}
|
||||
@@ -2176,6 +2100,10 @@ namespace Frida.Gadget {
|
||||
private extern bool has_objc_class (string name);
|
||||
|
||||
private extern void set_thread_name (string name);
|
||||
#if DARWIN
|
||||
private extern void detect_darwin_location_fields (Gum.Address our_address, ref string? executable_name,
|
||||
ref string? our_path, ref Gum.MemoryRange? our_range);
|
||||
#endif
|
||||
}
|
||||
|
||||
private extern void log_info (string message);
|
||||
|
||||
+68
-33
@@ -44,11 +44,17 @@ namespace Frida {
|
||||
|
||||
#if ANDROID
|
||||
public sealed class ThreadCountCloaker : Object {
|
||||
private GetOsThreadStat * get_os_thread_stat_slot;
|
||||
private static GetOsThreadStat old_get_os_thread_stat_impl;
|
||||
|
||||
private ReadFunc * read_slot;
|
||||
private static ReadFunc old_read_impl;
|
||||
|
||||
private static string expected_magic = "%u (".printf (Posix.getpid ());
|
||||
|
||||
[CCode (has_target = false)]
|
||||
private delegate ssize_t GetOsThreadStat (Posix.pid_t tid, void * buf, size_t count);
|
||||
|
||||
[CCode (has_target = false)]
|
||||
private delegate ssize_t ReadFunc (int fd, void * buf, size_t count);
|
||||
|
||||
@@ -56,39 +62,64 @@ namespace Frida {
|
||||
var art = Gum.Process.find_module_by_name ("libart.so");
|
||||
if (art != null) {
|
||||
art.enumerate_imports (imp => {
|
||||
if (imp.name == "read") {
|
||||
if (imp.name == "_ZN3art15GetOsThreadStatEiPcm" || imp.name == "_ZN3art15GetOsThreadStatEiPcj") {
|
||||
get_os_thread_stat_slot = (GetOsThreadStat *) imp.slot;
|
||||
} else if (imp.name == "read") {
|
||||
read_slot = (ReadFunc *) imp.slot;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (read_slot != null)
|
||||
old_read_impl = update_read_slot (on_read);
|
||||
if (get_os_thread_stat_slot != null) {
|
||||
old_get_os_thread_stat_impl = (GetOsThreadStat) update_slot ((void **) get_os_thread_stat_slot,
|
||||
(void *) on_get_os_thread_stat);
|
||||
}
|
||||
if (read_slot != null) {
|
||||
old_read_impl = (ReadFunc) update_slot ((void **) read_slot, (void *) on_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~ThreadCountCloaker () {
|
||||
if (read_slot != null)
|
||||
update_read_slot (old_read_impl);
|
||||
public override void dispose () {
|
||||
if (get_os_thread_stat_slot != null) {
|
||||
update_slot ((void **) get_os_thread_stat_slot, (void *) old_get_os_thread_stat_impl);
|
||||
}
|
||||
if (read_slot != null) {
|
||||
update_slot ((void **) read_slot, (void *) old_read_impl);
|
||||
}
|
||||
|
||||
base.dispose ();
|
||||
}
|
||||
|
||||
private ReadFunc update_read_slot (ReadFunc new_impl) {
|
||||
private static void * update_slot (void ** orig, void * new_impl) {
|
||||
Gum.PageProtection old_prot = READ;
|
||||
Gum.Memory.query_protection (read_slot, out old_prot);
|
||||
Gum.Memory.query_protection (orig, out old_prot);
|
||||
|
||||
bool is_writable = (old_prot & Gum.PageProtection.WRITE) != 0;
|
||||
if (!is_writable)
|
||||
Gum.mprotect (read_slot, sizeof (void *), old_prot | WRITE);
|
||||
Gum.mprotect (orig, sizeof (void *), old_prot | WRITE);
|
||||
|
||||
ReadFunc old_impl = *read_slot;
|
||||
*read_slot = new_impl;
|
||||
void * old_impl = *orig;
|
||||
*orig = new_impl;
|
||||
|
||||
if (!is_writable)
|
||||
Gum.mprotect (read_slot, sizeof (void *), old_prot);
|
||||
Gum.mprotect (orig, sizeof (void *), old_prot);
|
||||
|
||||
return old_impl;
|
||||
}
|
||||
|
||||
private static ssize_t on_get_os_thread_stat (Posix.pid_t tid, void * buf, size_t count) {
|
||||
ssize_t n = old_get_os_thread_stat_impl (tid, buf, count);
|
||||
|
||||
if (tid == Posix.getpid ()) {
|
||||
try {
|
||||
n = adjust_thread_count (buf, n, count);
|
||||
} catch (FileError e) {
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
private static ssize_t on_read (int fd, void * buf, size_t count) {
|
||||
var n = old_read_impl (fd, buf, count);
|
||||
if (n <= 0)
|
||||
@@ -101,32 +132,36 @@ namespace Frida {
|
||||
if (!file_descriptor_is_proc_self_stat (fd))
|
||||
return n;
|
||||
|
||||
unowned string raw_str = (string) buf;
|
||||
string str = raw_str.substring (0, n);
|
||||
|
||||
MatchInfo info;
|
||||
if (!/^(\d+ \(.+\)(?: [^ ]+){17}) \d+ (.+)/s.match (str, 0, out info))
|
||||
return n;
|
||||
string fields_before = info.fetch (1);
|
||||
string fields_after = info.fetch (2);
|
||||
|
||||
// We cannot simply use the value we got from the kernel and subtract the number of cloaked threads,
|
||||
// as there's a chance the total may have changed in the last moment.
|
||||
uint num_uncloaked_threads = query_num_uncloaked_threads ();
|
||||
|
||||
string adjusted_str = "%s %u %s".printf (fields_before, num_uncloaked_threads, fields_after);
|
||||
|
||||
var adjusted_length = adjusted_str.length;
|
||||
if (adjusted_length > count)
|
||||
return n;
|
||||
Memory.copy (buf, adjusted_str, adjusted_length);
|
||||
n = adjusted_length;
|
||||
n = adjust_thread_count (buf, n, count);
|
||||
} catch (FileError e) {
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
private static ssize_t adjust_thread_count (void * buf, ssize_t n, size_t count) throws FileError {
|
||||
unowned string raw_str = (string) buf;
|
||||
string str = raw_str.substring (0, n);
|
||||
|
||||
MatchInfo info;
|
||||
if (!/^(\d+ \(.+\)(?: [^ ]+){17}) \d+ (.+)/s.match (str, 0, out info))
|
||||
return n;
|
||||
string fields_before = info.fetch (1);
|
||||
string fields_after = info.fetch (2);
|
||||
|
||||
// We cannot simply use the value we got from the kernel and subtract the number of cloaked threads,
|
||||
// as there's a chance the total may have changed in the last moment.
|
||||
uint num_uncloaked_threads = query_num_uncloaked_threads ();
|
||||
|
||||
string adjusted_str = "%s %u %s".printf (fields_before, num_uncloaked_threads, fields_after);
|
||||
|
||||
var adjusted_length = adjusted_str.length;
|
||||
if (adjusted_length > count)
|
||||
return n;
|
||||
Memory.copy (buf, adjusted_str, adjusted_length);
|
||||
return adjusted_length;
|
||||
}
|
||||
|
||||
private static bool file_content_might_be_from_proc_self_stat (void * content, ssize_t size) {
|
||||
if (size < expected_magic.length)
|
||||
return false;
|
||||
|
||||
+10
-5
@@ -12,9 +12,11 @@ if not meson.get_compiler('vala').version().endswith('-frida')
|
||||
error('''Incompatible Vala compiler detected.
|
||||
|
||||
Frida currently relies on features not yet upstream. Grab the Frida-optimized
|
||||
Vala compiler from:
|
||||
Vala sources from:
|
||||
|
||||
https://github.com/frida/vala''')
|
||||
https://github.com/frida/vala
|
||||
|
||||
and compile them with Meson.''')
|
||||
endif
|
||||
|
||||
c_languages = ['c', 'cpp']
|
||||
@@ -269,12 +271,14 @@ if host_os == 'linux'
|
||||
#endif
|
||||
'''
|
||||
if cc.compiles(glibc_src, name: 'compiling for glibc')
|
||||
cdata.set('HAVE_GLIBC', 1)
|
||||
libc = 'glibc'
|
||||
elif cc.compiles(uclibc_src, name: 'compiling for uClibc')
|
||||
cdata.set('HAVE_UCLIBC', 1)
|
||||
libc = 'uclibc'
|
||||
else
|
||||
cdata.set('HAVE_MUSL', 1)
|
||||
libc = 'musl'
|
||||
endif
|
||||
cdata.set('HAVE_' + libc.to_upper(), 1)
|
||||
vala_flags += '--define=' + libc.to_upper()
|
||||
endif
|
||||
|
||||
if get_option('b_sanitize') == 'address'
|
||||
@@ -654,6 +658,7 @@ if get_option('devkits').length() != 0
|
||||
mkdevkit = [python, releng / 'mkdevkit.py']
|
||||
uninstalled_dir = meson.global_build_root() / 'meson-uninstalled'
|
||||
devkit_options = [
|
||||
'--dep-symbol-scope', get_option('devkit_symbol_scope'),
|
||||
'--cc', '>>>', cc.cmd_array(), '<<<',
|
||||
'--c-args', '>>>', get_option('c_args'), '<<<',
|
||||
'--pkg-config', '>>>', find_program('pkg-config'), '<<<',
|
||||
|
||||
@@ -150,6 +150,15 @@ option('devkits',
|
||||
description: 'Devkits to build'
|
||||
)
|
||||
|
||||
option('devkit_symbol_scope',
|
||||
type: 'combo',
|
||||
choices: ['prefixed', 'original'],
|
||||
value: 'prefixed',
|
||||
description : 'How devkit generation treats third-party symbols:\n'
|
||||
+ ' - prefixed: add the \'_frida_\' prefix\n'
|
||||
+ ' - original: keep symbols exactly as upstream\n'
|
||||
)
|
||||
|
||||
option('tests',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
|
||||
+1
-1
Submodule releng updated: e10baa39a2...38daa4fd6a.
+99
-23
@@ -14,59 +14,79 @@ namespace Frida.Barebone {
|
||||
get;
|
||||
}
|
||||
|
||||
public abstract size_t size {
|
||||
get;
|
||||
}
|
||||
|
||||
public abstract async void deallocate (Cancellable? cancellable) throws Error, IOError;
|
||||
}
|
||||
|
||||
public sealed class SimpleAllocator : Object, Allocator {
|
||||
public sealed class NullAllocator : Object, Allocator {
|
||||
public size_t page_size {
|
||||
get { return _page_size; }
|
||||
get {
|
||||
return _page_size;
|
||||
}
|
||||
}
|
||||
|
||||
private size_t _page_size;
|
||||
|
||||
public NullAllocator (size_t page_size) {
|
||||
this._page_size = page_size;
|
||||
}
|
||||
|
||||
public async Allocation allocate (size_t size, size_t alignment, Cancellable? cancellable) throws Error, IOError {
|
||||
throw new Error.NOT_SUPPORTED ("To enable this feature, specify an allocator in your FRIDA_BAREBONE_CONFIG");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class PhysicalAllocator : Object, Allocator {
|
||||
public size_t page_size {
|
||||
get {
|
||||
return _page_size;
|
||||
}
|
||||
}
|
||||
|
||||
private Machine machine;
|
||||
private size_t _page_size;
|
||||
private uint64 base_pa;
|
||||
|
||||
private uint64 cursor;
|
||||
|
||||
public SimpleAllocator (Machine machine, size_t page_size, uint64 base_pa) {
|
||||
public PhysicalAllocator (Machine machine, size_t page_size, PhysicalAllocatorConfig config) {
|
||||
this.machine = machine;
|
||||
this._page_size = page_size;
|
||||
this.base_pa = base_pa;
|
||||
this.cursor = base_pa;
|
||||
this.cursor = config.physical_base;
|
||||
}
|
||||
|
||||
public async Allocation allocate (size_t size, size_t alignment, Cancellable? cancellable) throws Error, IOError {
|
||||
if (base_pa == 0) {
|
||||
uint64 example_base;
|
||||
if ("corellium" in machine.gdb.features)
|
||||
example_base = 0x0800000000 + ((2048 - 3) * 1024 * 1024);
|
||||
else
|
||||
example_base = 0x0040000000 + (128 * 1024 * 1024);
|
||||
throw new Error.NOT_SUPPORTED ("To enable this feature, set FRIDA_BAREBONE_HEAP_BASE to the physical " +
|
||||
"base address to use, e.g. 0x%" + uint64.FORMAT_MODIFIER + "x", example_base);
|
||||
}
|
||||
|
||||
uint64 address_pa = cursor;
|
||||
|
||||
size_t vm_size = round_size_up (size, page_size);
|
||||
size_t vm_size = round_size_up (size, _page_size);
|
||||
cursor += vm_size;
|
||||
|
||||
uint num_pages = (uint) (vm_size / page_size);
|
||||
uint num_pages = (uint) (vm_size / _page_size);
|
||||
|
||||
Allocation page_allocation = yield machine.allocate_pages (address_pa, num_pages, cancellable);
|
||||
|
||||
return new SimpleAllocation (page_allocation);
|
||||
return new PhysicalAllocation (page_allocation);
|
||||
}
|
||||
|
||||
private class SimpleAllocation : Object, Allocation {
|
||||
private class PhysicalAllocation : Object, Allocation {
|
||||
public uint64 virtual_address {
|
||||
get { return page_allocation.virtual_address; }
|
||||
get {
|
||||
return page_allocation.virtual_address;
|
||||
}
|
||||
}
|
||||
|
||||
public size_t size {
|
||||
get {
|
||||
return page_allocation.size;
|
||||
}
|
||||
}
|
||||
|
||||
private Allocation page_allocation;
|
||||
|
||||
public SimpleAllocation (Allocation page_allocation) {
|
||||
this.page_allocation = page_allocation;
|
||||
public PhysicalAllocation (Allocation allocation) {
|
||||
page_allocation = allocation;
|
||||
}
|
||||
|
||||
public async void deallocate (Cancellable? cancellable) throws Error, IOError {
|
||||
@@ -75,4 +95,60 @@ namespace Frida.Barebone {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TargetFunctionsAllocator : Object, Allocator {
|
||||
public size_t page_size {
|
||||
get {
|
||||
return _page_size;
|
||||
}
|
||||
}
|
||||
|
||||
private Machine machine;
|
||||
private size_t _page_size;
|
||||
private TargetFunctionsAllocatorConfig config;
|
||||
|
||||
public TargetFunctionsAllocator (Machine machine, size_t page_size, TargetFunctionsAllocatorConfig config) {
|
||||
this.machine = machine;
|
||||
this._page_size = page_size;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public async Allocation allocate (size_t size, size_t alignment, Cancellable? cancellable) throws Error, IOError {
|
||||
uint64 address = yield machine.invoke (config.alloc_function, { size }, cancellable);
|
||||
|
||||
// TODO: Handle alignment.
|
||||
|
||||
return new TargetAllocation (address, size, machine, config);
|
||||
}
|
||||
|
||||
private class TargetAllocation : Object, Allocation {
|
||||
public uint64 virtual_address {
|
||||
get {
|
||||
return _virtual_address;
|
||||
}
|
||||
}
|
||||
|
||||
public size_t size {
|
||||
get {
|
||||
return _size;
|
||||
}
|
||||
}
|
||||
|
||||
private uint64 _virtual_address;
|
||||
public size_t _size;
|
||||
private Machine machine;
|
||||
private TargetFunctionsAllocatorConfig config;
|
||||
|
||||
public TargetAllocation (uint64 address, size_t size, Machine m, TargetFunctionsAllocatorConfig c) {
|
||||
_virtual_address = address;
|
||||
_size = size;
|
||||
machine = m;
|
||||
config = c;
|
||||
}
|
||||
|
||||
public async void deallocate (Cancellable? cancellable) throws Error, IOError {
|
||||
yield machine.invoke (config.free_function, { _virtual_address, size }, cancellable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,11 @@ namespace Frida.Barebone {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async void protect_pages (uint64 virtual_address, size_t size, Gum.PageProtection prot,
|
||||
Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async Gee.List<uint64?> scan_ranges (Gee.List<Gum.MemoryRange?> ranges, MatchPattern pattern, uint max_matches,
|
||||
Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
@@ -45,8 +50,7 @@ namespace Frida.Barebone {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, uint64 landing_zone, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,13 @@ namespace Frida.Barebone {
|
||||
private const uint64 INT6_MASK = 0x3fULL;
|
||||
private const uint64 INT48_MASK = 0xffffffffffffULL;
|
||||
|
||||
private const uint64 TABLE_PXN_BIT = 1ULL << 59;
|
||||
|
||||
private const uint64 UXN_BIT = 1ULL << 54;
|
||||
private const uint64 PXN_BIT = 1ULL << 53;
|
||||
private const uint64 AP1_BIT = 1ULL << 7;
|
||||
private const uint64 AP0_BIT = 1ULL << 6;
|
||||
|
||||
public Arm64Machine (GDB.Client gdb) {
|
||||
Object (gdb: gdb);
|
||||
}
|
||||
@@ -55,7 +62,7 @@ namespace Frida.Barebone {
|
||||
|
||||
yield set_addressing_mode (gdb, PHYSICAL, cancellable);
|
||||
try {
|
||||
yield collect_ranges_in_table (p.tt1, p.first_level, p.upper_bits, p.granule, result, cancellable);
|
||||
yield collect_ranges_in_table (p.tt1, p.first_level, p.upper_bits, p, result, cancellable);
|
||||
} finally {
|
||||
set_addressing_mode.begin (gdb, VIRTUAL, null);
|
||||
}
|
||||
@@ -63,30 +70,30 @@ namespace Frida.Barebone {
|
||||
return result;
|
||||
}
|
||||
|
||||
private async void collect_ranges_in_table (uint64 table_address, uint level, uint64 upper_bits, Granule granule,
|
||||
private async void collect_ranges_in_table (uint64 table_address, uint level, uint64 upper_bits, MMUParameters p,
|
||||
Gee.List<RangeDetails> ranges, Cancellable? cancellable) throws Error, IOError {
|
||||
uint max_entries = compute_max_entries (level, granule);
|
||||
uint max_entries = compute_max_entries (level, p);
|
||||
Buffer entries = yield gdb.read_buffer (table_address, max_entries * Descriptor.SIZE, cancellable);
|
||||
uint shift = address_shift_at_level (level, granule);
|
||||
uint shift = address_shift_at_level (level, p.granule);
|
||||
for (uint i = 0; i != max_entries; i++) {
|
||||
uint64 raw_descriptor = entries.read_uint64 (i * Descriptor.SIZE);
|
||||
|
||||
Descriptor desc = Descriptor.parse (raw_descriptor, level, granule);
|
||||
Descriptor desc = Descriptor.parse (raw_descriptor, level, p.granule);
|
||||
if (desc.kind == INVALID)
|
||||
continue;
|
||||
|
||||
uint64 address = upper_bits | ((uint64) i << shift);
|
||||
|
||||
if (desc.kind == BLOCK) {
|
||||
size_t size = 1 << num_block_bits_at_level (level, granule);
|
||||
Gum.PageProtection prot = protection_from_flags (desc.flags);
|
||||
size_t size = 1 << num_block_bits_at_level (level, p.granule);
|
||||
Gum.PageProtection prot = protection_from_flags (desc.flags, p);
|
||||
|
||||
ranges.add (new RangeDetails (address, desc.target_address, size, prot, MappingType.UNKNOWN));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
yield collect_ranges_in_table (desc.target_address, level + 1, address, granule, ranges, cancellable);
|
||||
yield collect_ranges_in_table (desc.target_address, level + 1, address, p, ranges, cancellable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,9 +159,10 @@ namespace Frida.Barebone {
|
||||
yield set_addressing_mode (gdb, PHYSICAL, cancellable);
|
||||
try {
|
||||
Allocation? allocation = yield maybe_insert_descriptor_in_table (physical_address, num_pages, p.tt1,
|
||||
p.first_level, p.upper_bits, p.granule, cancellable);
|
||||
p.first_level, p.upper_bits, p, cancellable);
|
||||
if (allocation == null)
|
||||
throw new Error.NOT_SUPPORTED ("Unable to insert page table mapping; please file a bug");
|
||||
|
||||
return allocation;
|
||||
} finally {
|
||||
set_addressing_mode.begin (gdb, VIRTUAL, null);
|
||||
@@ -162,10 +170,10 @@ namespace Frida.Barebone {
|
||||
}
|
||||
|
||||
private async Allocation? maybe_insert_descriptor_in_table (uint64 physical_address, uint num_pages,
|
||||
uint64 table_address, uint level, uint64 upper_bits, Granule granule, Cancellable? cancellable)
|
||||
uint64 table_address, uint level, uint64 upper_bits, MMUParameters p, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
uint max_entries = compute_max_entries (level, granule);
|
||||
uint shift = address_shift_at_level (level, granule);
|
||||
uint max_entries = compute_max_entries (level, p);
|
||||
uint shift = address_shift_at_level (level, p.granule);
|
||||
|
||||
uint64 first_available_va = 0;
|
||||
uint64 first_available_slot = 0;
|
||||
@@ -184,13 +192,15 @@ namespace Frida.Barebone {
|
||||
uint table_index = chunk_offset + i;
|
||||
uint64 address = upper_bits | ((uint64) table_index << shift);
|
||||
|
||||
Descriptor desc = Descriptor.parse (raw_descriptor, level, granule);
|
||||
Descriptor desc = Descriptor.parse (raw_descriptor, level, p.granule);
|
||||
|
||||
if (level < 3) {
|
||||
if (desc.kind != TABLE)
|
||||
continue;
|
||||
if ((desc.flags & DescriptorFlags.PXNTABLE) != 0)
|
||||
continue;
|
||||
Allocation? allocation = yield maybe_insert_descriptor_in_table (physical_address,
|
||||
num_pages, desc.target_address, level + 1, address, granule, cancellable);
|
||||
num_pages, desc.target_address, level + 1, address, p, cancellable);
|
||||
if (allocation != null)
|
||||
return allocation;
|
||||
continue;
|
||||
@@ -215,17 +225,197 @@ namespace Frida.Barebone {
|
||||
if (num_available_slots != num_pages)
|
||||
return null;
|
||||
|
||||
Gum.PageProtection page_prot = Gum.PageProtection.READ | Gum.PageProtection.WRITE;
|
||||
if (!p.sprr_enabled)
|
||||
page_prot |= Gum.PageProtection.EXECUTE;
|
||||
|
||||
var builder = gdb.make_buffer_builder ();
|
||||
for (uint i = 0; i != num_available_slots; i++) {
|
||||
uint64 cur_physical_address = physical_address + (i * granule);
|
||||
uint64 new_descriptor = cur_physical_address | 0x40000000000403ULL;
|
||||
uint64 cur_physical_address = physical_address + (i * p.granule);
|
||||
uint64 base_descriptor = cur_physical_address | 0x403ULL;
|
||||
|
||||
uint64 new_descriptor = apply_protection_bits (base_descriptor, page_prot, p);
|
||||
|
||||
builder.append_uint64 (new_descriptor);
|
||||
}
|
||||
Bytes new_descriptors = builder.build ();
|
||||
Bytes old_descriptors = yield gdb.read_byte_array (first_available_slot, new_descriptors.get_size (), cancellable);
|
||||
yield gdb.write_byte_array (first_available_slot, new_descriptors, cancellable);
|
||||
|
||||
return new DescriptorAllocation (first_available_va, first_available_slot, old_descriptors, gdb);
|
||||
size_t size = num_pages * p.granule;
|
||||
return new DescriptorAllocation (first_available_va, size, first_available_slot, old_descriptors, gdb);
|
||||
}
|
||||
|
||||
public async void protect_pages (uint64 virtual_address, size_t size, Gum.PageProtection prot, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
MMUParameters p = yield MMUParameters.load (gdb, cancellable);
|
||||
|
||||
yield set_addressing_mode (gdb, PHYSICAL, cancellable);
|
||||
try {
|
||||
uint64 page_mask = p.granule - 1;
|
||||
uint64 aligned_va = virtual_address & ~page_mask;
|
||||
uint64 aligned_end = (virtual_address + size + page_mask) & ~page_mask;
|
||||
uint num_pages = (uint) ((aligned_end - aligned_va) / p.granule);
|
||||
|
||||
yield perform_protect_pages (aligned_va, num_pages, prot, p, cancellable);
|
||||
} finally {
|
||||
set_addressing_mode.begin (gdb, VIRTUAL, null);
|
||||
}
|
||||
}
|
||||
|
||||
private async void perform_protect_pages (uint64 start_va, uint num_pages, Gum.PageProtection prot, MMUParameters p,
|
||||
Cancellable? cancellable) throws Error, IOError {
|
||||
var table_cache = new TableWalkCache ();
|
||||
uint pages_processed = 0;
|
||||
|
||||
var processed_tables = new Gee.HashSet<uint64?> (Numeric.uint64_hash, Numeric.uint64_equal);
|
||||
bool need_exec = (prot & Gum.PageProtection.EXECUTE) != 0;
|
||||
|
||||
while (pages_processed != num_pages) {
|
||||
uint64 current_va = start_va + (uint64) pages_processed * p.granule;
|
||||
|
||||
uint64 table_pa = yield find_level3_table (current_va, p, table_cache, cancellable);
|
||||
|
||||
if (need_exec && !processed_tables.contains (table_pa)) {
|
||||
yield clear_pxn_table_bits_for_va (current_va, p, table_cache, cancellable);
|
||||
processed_tables.add (table_pa);
|
||||
}
|
||||
|
||||
uint level3_shift = address_shift_at_level (3, p.granule);
|
||||
uint64 level3_mask = (1ULL << level3_shift) - 1;
|
||||
uint64 table_base_va = current_va & ~level3_mask;
|
||||
uint64 table_end_va = table_base_va + (1ULL << level3_shift);
|
||||
uint64 remaining_va = start_va + num_pages * p.granule;
|
||||
uint64 batch_end_va = uint64.min (remaining_va, table_end_va);
|
||||
uint batch_size = (uint) ((batch_end_va - current_va) / p.granule);
|
||||
|
||||
yield protect_pages_in_table (current_va, batch_size, prot, table_pa, p, cancellable);
|
||||
|
||||
pages_processed += batch_size;
|
||||
}
|
||||
}
|
||||
|
||||
private async void protect_pages_in_table (uint64 current_va, uint batch_size, Gum.PageProtection prot,
|
||||
uint64 table_pa, MMUParameters p, Cancellable? cancellable) throws Error, IOError {
|
||||
uint index_bits = num_address_bits_at_level (3, p);
|
||||
uint index_shift = inpage_bits_for_granule (p.granule);
|
||||
uint index_mask = (1U << index_bits) - 1;
|
||||
|
||||
uint64 first_index = (current_va >> index_shift) & index_mask;
|
||||
uint64 first_slot_pa = table_pa + (first_index * Descriptor.SIZE);
|
||||
|
||||
Buffer descriptors = yield gdb.read_buffer (first_slot_pa, batch_size * Descriptor.SIZE, cancellable);
|
||||
|
||||
bool any_changed = false;
|
||||
for (uint i = 0; i != batch_size; i++) {
|
||||
uint64 raw_desc = descriptors.read_uint64 (i * Descriptor.SIZE);
|
||||
uint64 new_desc = apply_protection_bits (raw_desc, prot, p);
|
||||
|
||||
if (new_desc != raw_desc) {
|
||||
descriptors.write_uint64 (i * Descriptor.SIZE, new_desc);
|
||||
any_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (any_changed)
|
||||
yield gdb.write_byte_array (first_slot_pa, descriptors.bytes, cancellable);
|
||||
}
|
||||
|
||||
private async uint64 find_level3_table (uint64 va, MMUParameters p, TableWalkCache cache, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
TableWalkResult? cached = cache.lookup (va, p);
|
||||
if (cached != null)
|
||||
return yield walk_to_level3 (va, cached.table_pa, cached.level, p, cache, cancellable);
|
||||
|
||||
return yield walk_to_level3 (va, p.tt1, p.first_level, p, cache, cancellable);
|
||||
}
|
||||
|
||||
private async uint64 walk_to_level3 (uint64 va, uint64 start_table_pa, uint start_level, MMUParameters p,
|
||||
TableWalkCache cache, Cancellable? cancellable) throws Error, IOError {
|
||||
uint64 table_pa = start_table_pa;
|
||||
uint level = start_level;
|
||||
|
||||
while (level != 3) {
|
||||
cache.store (va, level, table_pa, p);
|
||||
|
||||
uint shift = address_shift_at_level (level, p.granule);
|
||||
uint entries = compute_max_entries (level, p);
|
||||
uint index = (uint) ((va >> shift) & (entries - 1));
|
||||
uint64 slot_pa = table_pa + ((uint64) index * Descriptor.SIZE);
|
||||
|
||||
Buffer d_buf = yield gdb.read_buffer (slot_pa, Descriptor.SIZE, cancellable);
|
||||
uint64 raw = d_buf.read_uint64 (0);
|
||||
Descriptor desc = Descriptor.parse (raw, level, p.granule);
|
||||
|
||||
if (desc.kind != TABLE)
|
||||
throw new Error.NOT_SUPPORTED ("Walk failed at level %u", level);
|
||||
|
||||
table_pa = desc.target_address;
|
||||
level++;
|
||||
}
|
||||
|
||||
return table_pa;
|
||||
}
|
||||
|
||||
private async void clear_pxn_table_bits_for_va (uint64 va, MMUParameters p, TableWalkCache cache, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
uint64 table_pa = p.tt1;
|
||||
for (uint level = p.first_level; level != 3; level++) {
|
||||
uint entries = compute_max_entries (level, p);
|
||||
uint shift = address_shift_at_level (level, p.granule);
|
||||
uint index = (uint) ((va >> shift) & (entries - 1));
|
||||
uint64 slot_pa = table_pa + (index * Descriptor.SIZE);
|
||||
|
||||
Buffer d_buf = yield gdb.read_buffer (slot_pa, Descriptor.SIZE, cancellable);
|
||||
uint64 raw_desc = d_buf.read_uint64 (0);
|
||||
Descriptor desc = Descriptor.parse (raw_desc, level, p.granule);
|
||||
if (desc.kind != TABLE)
|
||||
break;
|
||||
|
||||
if ((raw_desc & TABLE_PXN_BIT) != 0) {
|
||||
uint64 new_desc = raw_desc & ~TABLE_PXN_BIT;
|
||||
d_buf.write_uint64 (0, new_desc);
|
||||
yield gdb.write_byte_array (slot_pa, d_buf.bytes, cancellable);
|
||||
}
|
||||
|
||||
table_pa = desc.target_address;
|
||||
}
|
||||
}
|
||||
|
||||
private class TableWalkCache {
|
||||
private Gee.Map<uint64?, TableWalkResult> cache =
|
||||
new Gee.HashMap<uint64?, TableWalkResult> (Numeric.uint64_hash, Numeric.uint64_equal);
|
||||
|
||||
public TableWalkResult? lookup (uint64 va, MMUParameters p) {
|
||||
for (int level = 2; level >= (int) p.first_level; level--) {
|
||||
uint64 cache_key = compute_cache_key (va, (uint) level, p);
|
||||
TableWalkResult? result = cache[cache_key];
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void store (uint64 va, uint level, uint64 table_pa, MMUParameters p) {
|
||||
if (level >= 3)
|
||||
return;
|
||||
|
||||
uint64 cache_key = compute_cache_key (va, level, p);
|
||||
cache[cache_key] = new TableWalkResult () {
|
||||
table_pa = table_pa,
|
||||
level = level
|
||||
};
|
||||
}
|
||||
|
||||
private uint64 compute_cache_key (uint64 va, uint level, MMUParameters p) {
|
||||
uint shift = address_shift_at_level (level + 1, p.granule);
|
||||
return (va >> shift) << shift;
|
||||
}
|
||||
}
|
||||
|
||||
private class TableWalkResult {
|
||||
public uint64 table_pa;
|
||||
public uint level;
|
||||
}
|
||||
|
||||
public async Gee.List<uint64?> scan_ranges (Gee.List<Gum.MemoryRange?> ranges, MatchPattern pattern, uint max_matches,
|
||||
@@ -354,14 +544,17 @@ namespace Frida.Barebone {
|
||||
case ABS64:
|
||||
relocated.write_uint64 ((size_t) r.address, base_va + r.symbol.address + r.addend);
|
||||
break;
|
||||
case PREL32:
|
||||
var diff = (int64) (base_va + r.symbol.address + r.addend) - (int64) (base_va + r.address);
|
||||
relocated.write_int32 ((size_t) r.address, (int32) diff);
|
||||
break;
|
||||
default:
|
||||
throw new Error.NOT_SUPPORTED ("Unsupported relocation type: %s",
|
||||
Marshal.enum_to_nick<Gum.ElfArm64Relocation> (type));
|
||||
}
|
||||
}
|
||||
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, uint64 landing_zone, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, Cancellable? cancellable) throws Error, IOError {
|
||||
if (args.length > 8)
|
||||
throw new Error.NOT_SUPPORTED ("Unsupported number of arguments; please open a PR");
|
||||
|
||||
@@ -377,6 +570,7 @@ namespace Frida.Barebone {
|
||||
|
||||
regs["pc"] = impl;
|
||||
|
||||
uint64 landing_zone = saved_regs["pc"].get_uint64 ();
|
||||
regs["x30"] = landing_zone;
|
||||
|
||||
uint64 sp = saved_regs["sp"].get_uint64 ();
|
||||
@@ -406,6 +600,35 @@ namespace Frida.Barebone {
|
||||
return retval;
|
||||
}
|
||||
|
||||
public async void execute (uint64 start, uint64 end, Cancellable? cancellable) throws Error, IOError {
|
||||
bool was_running = gdb.state != STOPPED;
|
||||
if (was_running)
|
||||
yield gdb.stop (cancellable);
|
||||
|
||||
GDB.Thread thread = gdb.exception.thread;
|
||||
Gee.Map<string, Variant> saved_regs = yield thread.read_registers (cancellable);
|
||||
|
||||
var regs = new Gee.HashMap<string, Variant> ();
|
||||
regs.set_all (saved_regs);
|
||||
|
||||
regs["pc"] = start;
|
||||
|
||||
yield thread.write_registers (regs, cancellable);
|
||||
|
||||
GDB.Breakpoint bp = yield gdb.add_breakpoint (SOFT, end, 4, cancellable);
|
||||
GDB.Exception ex = null;
|
||||
do {
|
||||
ex = yield gdb.continue_until_exception (cancellable);
|
||||
} while (ex.breakpoint != bp || ex.thread.id != thread.id);
|
||||
// TODO: Improve GDB.Client to guarantee a single GDB.Thread instance per ID.
|
||||
yield bp.remove (cancellable);
|
||||
|
||||
yield thread.write_registers (saved_regs, cancellable);
|
||||
|
||||
if (was_running)
|
||||
yield gdb.continue (cancellable);
|
||||
}
|
||||
|
||||
public async CallFrame load_call_frame (GDB.Thread thread, uint arity, Cancellable? cancellable) throws Error, IOError {
|
||||
var regs = yield thread.read_registers (cancellable);
|
||||
|
||||
@@ -689,6 +912,10 @@ namespace Frida.Barebone {
|
||||
public uint first_level;
|
||||
public uint64 upper_bits;
|
||||
public uint64 tt1;
|
||||
public uint t1sz;
|
||||
|
||||
public bool sprr_enabled;
|
||||
public uint64 sprr_perm;
|
||||
|
||||
public static async MMUParameters load (GDB.Client gdb, Cancellable? cancellable) throws Error, IOError {
|
||||
GDB.Exception? exception = gdb.exception;
|
||||
@@ -716,6 +943,10 @@ namespace Frida.Barebone {
|
||||
parameters.upper_bits |= 1ULL << (63 - i);
|
||||
|
||||
parameters.tt1 = regs.ttbr1 & INT48_MASK;
|
||||
parameters.t1sz = t1sz;
|
||||
|
||||
parameters.sprr_enabled = (regs.sprr_config & 1) != 0;
|
||||
parameters.sprr_perm = regs.sprr_perm;
|
||||
|
||||
return parameters;
|
||||
}
|
||||
@@ -724,6 +955,8 @@ namespace Frida.Barebone {
|
||||
private class MMURegisters {
|
||||
public uint64 tcr;
|
||||
public uint64 ttbr1;
|
||||
public uint64 sprr_config;
|
||||
public uint64 sprr_perm;
|
||||
|
||||
public static async MMURegisters read (GDB.Thread thread, Cancellable? cancellable) throws Error, IOError {
|
||||
var regs = new MMURegisters ();
|
||||
@@ -741,10 +974,19 @@ namespace Frida.Barebone {
|
||||
regs.tcr = val;
|
||||
else if (name == "ttbr1_el1")
|
||||
regs.ttbr1 = val;
|
||||
else if (name == "sprr_config_el1")
|
||||
regs.sprr_config = val;
|
||||
else if (name == "sprr_el1br1_el1")
|
||||
regs.sprr_perm = val;
|
||||
}
|
||||
} else {
|
||||
regs.tcr = yield thread.read_register ("tcr_el1", cancellable);
|
||||
regs.ttbr1 = yield thread.read_register ("ttbr1_el1", cancellable);
|
||||
try {
|
||||
regs.sprr_config = yield thread.read_register ("sprr_config_el1", cancellable);
|
||||
regs.sprr_perm = yield thread.read_register ("sprr_el1br1_el1", cancellable);
|
||||
} catch (Error e) {
|
||||
}
|
||||
}
|
||||
|
||||
return regs;
|
||||
@@ -850,16 +1092,27 @@ namespace Frida.Barebone {
|
||||
|
||||
private class DescriptorAllocation : Object, Allocation {
|
||||
public uint64 virtual_address {
|
||||
get { return base_va; }
|
||||
get {
|
||||
return base_va;
|
||||
}
|
||||
}
|
||||
|
||||
public size_t size {
|
||||
get {
|
||||
return _size;
|
||||
}
|
||||
}
|
||||
|
||||
private uint64 base_va;
|
||||
private size_t _size;
|
||||
private uint64 first_slot;
|
||||
private Bytes? old_descriptors;
|
||||
private GDB.Client gdb;
|
||||
|
||||
public DescriptorAllocation (uint64 base_va, uint64 first_slot, Bytes old_descriptors, GDB.Client gdb) {
|
||||
public DescriptorAllocation (uint64 base_va, size_t size, uint64 first_slot, Bytes old_descriptors,
|
||||
GDB.Client gdb) {
|
||||
this.base_va = base_va;
|
||||
this._size = size;
|
||||
this.first_slot = first_slot;
|
||||
this.old_descriptors = old_descriptors;
|
||||
this.gdb = gdb;
|
||||
@@ -908,11 +1161,23 @@ namespace Frida.Barebone {
|
||||
assert_not_reached ();
|
||||
}
|
||||
|
||||
private static uint compute_max_entries (uint level, Granule granule) {
|
||||
return 1 << num_address_bits_at_level (level, granule);
|
||||
private static uint compute_max_entries (uint level, MMUParameters p) {
|
||||
return 1 << num_address_bits_at_level (level, p);
|
||||
}
|
||||
|
||||
private static uint num_address_bits_at_level (uint level, Granule granule) {
|
||||
private static uint num_address_bits_at_level (uint level, MMUParameters p) {
|
||||
if (level == p.first_level) {
|
||||
uint available_address_bits = 64 - p.t1sz - inpage_bits_for_granule (p.granule);
|
||||
uint consumed_by_lower_levels = 0;
|
||||
for (uint l = level + 1; l <= 3; l++)
|
||||
consumed_by_lower_levels += unclipped_address_bits_at_level (l, p.granule);
|
||||
return available_address_bits - consumed_by_lower_levels;
|
||||
} else {
|
||||
return unclipped_address_bits_at_level (level, p.granule);
|
||||
}
|
||||
}
|
||||
|
||||
private static uint unclipped_address_bits_at_level (uint level, Granule granule) {
|
||||
switch (granule) {
|
||||
case 4K:
|
||||
return 9;
|
||||
@@ -932,7 +1197,7 @@ namespace Frida.Barebone {
|
||||
private static uint address_shift_at_level (uint level, Granule granule) {
|
||||
uint shift = inpage_bits_for_granule (granule);
|
||||
for (int l = 2; l != (int) level - 1; l--)
|
||||
shift += num_address_bits_at_level (l, granule);
|
||||
shift += unclipped_address_bits_at_level (l, granule);
|
||||
return shift;
|
||||
}
|
||||
|
||||
@@ -949,7 +1214,45 @@ namespace Frida.Barebone {
|
||||
}
|
||||
}
|
||||
|
||||
private static Gum.PageProtection protection_from_flags (DescriptorFlags flags) {
|
||||
private static Gum.PageProtection protection_from_flags (DescriptorFlags flags, MMUParameters p) {
|
||||
if (p.sprr_enabled) {
|
||||
uint idx = 0;
|
||||
if ((flags & DescriptorFlags.AP_READ_ONLY) != 0)
|
||||
idx |= 1 << 3;
|
||||
if ((flags & DescriptorFlags.AP_ALLOW_APPLICATION) != 0)
|
||||
idx |= 1 << 2;
|
||||
if ((flags & DescriptorFlags.UXN) != 0)
|
||||
idx |= 1 << 1;
|
||||
if ((flags & DescriptorFlags.PXN) != 0)
|
||||
idx |= 1 << 0;
|
||||
|
||||
uint perm = (uint) ((p.sprr_perm >> (idx * 4)) & 0xf);
|
||||
|
||||
Gum.PageProtection prot;
|
||||
switch (perm & 3) {
|
||||
case 0:
|
||||
prot = 0;
|
||||
break;
|
||||
case 1:
|
||||
prot = READ | EXECUTE;
|
||||
if ((perm >> 2) == 2)
|
||||
prot = EXECUTE;
|
||||
break;
|
||||
case 2:
|
||||
prot = READ;
|
||||
break;
|
||||
case 3:
|
||||
prot = READ | WRITE;
|
||||
if ((perm >> 2) == 1)
|
||||
prot = 0;
|
||||
break;
|
||||
default:
|
||||
assert_not_reached ();
|
||||
}
|
||||
|
||||
return prot;
|
||||
}
|
||||
|
||||
Gum.PageProtection prot = READ;
|
||||
if ((flags & DescriptorFlags.PXN) == 0)
|
||||
prot |= EXECUTE;
|
||||
@@ -958,6 +1261,93 @@ namespace Frida.Barebone {
|
||||
return prot;
|
||||
}
|
||||
|
||||
private static uint64 apply_protection_bits (uint64 descriptor, Gum.PageProtection prot, MMUParameters p) throws Error {
|
||||
uint64 result = descriptor;
|
||||
|
||||
if (p.sprr_enabled) {
|
||||
uint target_sprr_index = find_sprr_index_for_permissions (prot, p);
|
||||
result = apply_sprr_index_to_descriptor (result, target_sprr_index);
|
||||
} else {
|
||||
result = apply_non_sprr_protection_bits (result, prot);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static uint64 apply_non_sprr_protection_bits (uint64 descriptor, Gum.PageProtection prot) {
|
||||
uint64 result = descriptor;
|
||||
|
||||
bool want_exec = (prot & Gum.PageProtection.EXECUTE) != 0;
|
||||
bool want_write = (prot & Gum.PageProtection.WRITE) != 0;
|
||||
|
||||
if (want_exec)
|
||||
result &= ~(UXN_BIT | PXN_BIT);
|
||||
else
|
||||
result |= (UXN_BIT | PXN_BIT);
|
||||
|
||||
if (want_write) {
|
||||
result &= ~(AP1_BIT | AP0_BIT);
|
||||
} else {
|
||||
result |= AP1_BIT;
|
||||
result &= ~AP0_BIT;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static uint find_sprr_index_for_permissions (Gum.PageProtection prot, MMUParameters p) throws Error {
|
||||
bool want_read = (prot & Gum.PageProtection.READ) != 0;
|
||||
bool want_write = (prot & Gum.PageProtection.WRITE) != 0;
|
||||
bool want_exec = (prot & Gum.PageProtection.EXECUTE) != 0;
|
||||
|
||||
for (uint i = 0; i != 16; i++) {
|
||||
uint perm = (uint) ((p.sprr_perm >> (i * 4)) & 0xf);
|
||||
|
||||
bool slot_allows_read = false;
|
||||
bool slot_allows_write = false;
|
||||
bool slot_allows_exec = false;
|
||||
|
||||
switch (perm & 3) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
slot_allows_exec = true;
|
||||
if ((perm >> 2) != 2)
|
||||
slot_allows_read = true;
|
||||
break;
|
||||
case 2:
|
||||
slot_allows_read = true;
|
||||
break;
|
||||
case 3:
|
||||
slot_allows_read = true;
|
||||
slot_allows_write = ((perm >> 2) != 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (slot_allows_read == want_read && slot_allows_write == want_write && slot_allows_exec == want_exec)
|
||||
return i;
|
||||
}
|
||||
|
||||
throw new Error.INVALID_ARGUMENT ("No suitable SPRR slot found for protection 0x%x", prot);
|
||||
}
|
||||
|
||||
private static uint64 apply_sprr_index_to_descriptor (uint64 descriptor, uint sprr_index) {
|
||||
uint64 result = descriptor;
|
||||
|
||||
result &= ~(AP1_BIT | AP0_BIT | UXN_BIT | PXN_BIT);
|
||||
|
||||
if ((sprr_index & 0x8) != 0)
|
||||
result |= AP1_BIT;
|
||||
if ((sprr_index & 0x4) != 0)
|
||||
result |= AP0_BIT;
|
||||
if ((sprr_index & 0x2) != 0)
|
||||
result |= UXN_BIT;
|
||||
if ((sprr_index & 0x1) != 0)
|
||||
result |= PXN_BIT;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Gum.PageProtection protection_from_corellium_pt_details (string details) {
|
||||
Gum.PageProtection prot = READ;
|
||||
if (!("pXN" in details))
|
||||
|
||||
@@ -31,6 +31,11 @@ namespace Frida.Barebone {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async void protect_pages (uint64 virtual_address, size_t size, Gum.PageProtection prot,
|
||||
Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async Gee.List<uint64?> scan_ranges (Gee.List<Gum.MemoryRange?> ranges, MatchPattern pattern,
|
||||
uint max_matches, Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
@@ -40,8 +45,7 @@ namespace Frida.Barebone {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, uint64 landing_zone, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,11 @@ namespace Frida.Barebone {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async void protect_pages (uint64 virtual_address, size_t size, Gum.PageProtection prot,
|
||||
Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async Gee.List<uint64?> scan_ranges (Gee.List<Gum.MemoryRange?> ranges, MatchPattern pattern, uint max_matches,
|
||||
Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
@@ -41,8 +46,7 @@ namespace Frida.Barebone {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, uint64 landing_zone, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@ namespace Frida.Barebone {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async void protect_pages (uint64 virtual_address, size_t size, Gum.PageProtection prot,
|
||||
Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async Gee.List<uint64?> scan_ranges (Gee.List<Gum.MemoryRange?> ranges, MatchPattern pattern, uint max_matches,
|
||||
Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
@@ -43,8 +48,7 @@ namespace Frida.Barebone {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, uint64 landing_zone, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
public async uint64 invoke (uint64 impl, uint64[] args, Cancellable? cancellable) throws Error, IOError {
|
||||
throw_not_supported ();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,26 +2,8 @@ namespace Frida {
|
||||
public sealed class BareboneHostSessionBackend : Object, HostSessionBackend {
|
||||
private BareboneHostSessionProvider? provider;
|
||||
|
||||
private const uint16 DEFAULT_PORT = 3333;
|
||||
|
||||
public async void start (Cancellable? cancellable) throws IOError {
|
||||
SocketConnectable? connectable = null;
|
||||
unowned string? address = Environment.get_variable ("FRIDA_BAREBONE_ADDRESS");
|
||||
if (address != null) {
|
||||
try {
|
||||
connectable = NetworkAddress.parse (address, DEFAULT_PORT);
|
||||
} catch (GLib.Error e) {
|
||||
}
|
||||
}
|
||||
if (connectable == null)
|
||||
connectable = new InetSocketAddress (new InetAddress.loopback (SocketFamily.IPV4), DEFAULT_PORT);
|
||||
|
||||
uint64 heap_base_pa = 0;
|
||||
unowned string? heap_base_preference = Environment.get_variable ("FRIDA_BAREBONE_HEAP_BASE");
|
||||
if (heap_base_preference != null)
|
||||
heap_base_pa = uint64.parse (heap_base_preference, 16);
|
||||
|
||||
provider = new BareboneHostSessionProvider (connectable, heap_base_pa);
|
||||
provider = new BareboneHostSessionProvider ();
|
||||
provider_available (provider);
|
||||
}
|
||||
|
||||
@@ -49,22 +31,8 @@ namespace Frida {
|
||||
}
|
||||
}
|
||||
|
||||
public SocketConnectable connectable {
|
||||
get;
|
||||
construct;
|
||||
}
|
||||
|
||||
public uint64 heap_base_pa {
|
||||
get;
|
||||
construct;
|
||||
}
|
||||
|
||||
private BareboneHostSession? host_session;
|
||||
|
||||
public BareboneHostSessionProvider (SocketConnectable connectable, uint64 heap_base_pa) {
|
||||
Object (connectable: connectable, heap_base_pa: heap_base_pa);
|
||||
}
|
||||
|
||||
public async void close (Cancellable? cancellable) throws IOError {
|
||||
if (host_session != null) {
|
||||
yield host_session.close (cancellable);
|
||||
@@ -76,6 +44,27 @@ namespace Frida {
|
||||
if (host_session != null)
|
||||
throw new Error.INVALID_OPERATION ("Already created");
|
||||
|
||||
Barebone.Config config;
|
||||
unowned string? config_path = Environment.get_variable ("FRIDA_BAREBONE_CONFIG");
|
||||
if (config_path != null) {
|
||||
try {
|
||||
var config_data = yield FS.read_all_text (File.new_for_path (config_path), cancellable);
|
||||
config = (Barebone.Config) Json.gobject_from_data (typeof (Barebone.Config), config_data);
|
||||
} catch (GLib.Error e) {
|
||||
throw new Error.INVALID_ARGUMENT ("Unable to load %s: %s", config_path, e.message);
|
||||
}
|
||||
} else {
|
||||
config = new Barebone.Config ();
|
||||
}
|
||||
|
||||
SocketConnectable connectable;
|
||||
try {
|
||||
Barebone.ConnectionConfig c = config.connection;
|
||||
connectable = NetworkAddress.parse (c.host, c.port);
|
||||
} catch (GLib.Error e) {
|
||||
throw new Error.INVALID_ARGUMENT ("Unable to load %s: %s", config_path, e.message);
|
||||
}
|
||||
|
||||
IOStream stream;
|
||||
try {
|
||||
var client = new SocketClient ();
|
||||
@@ -111,8 +100,19 @@ namespace Frida {
|
||||
|
||||
var page_size = yield machine.query_page_size (cancellable);
|
||||
|
||||
// TODO: Locate and use kernel's allocator when possible.
|
||||
Barebone.Allocator allocator = new Barebone.SimpleAllocator (machine, page_size, heap_base_pa);
|
||||
Barebone.Allocator allocator;
|
||||
Barebone.AllocatorConfig ac = config.allocator;
|
||||
if (ac is Barebone.NoAllocatorConfig) {
|
||||
allocator = new Barebone.NullAllocator (page_size);
|
||||
} else if (ac is Barebone.PhysicalAllocatorConfig) {
|
||||
allocator = new Barebone.PhysicalAllocator (machine, page_size,
|
||||
(Barebone.PhysicalAllocatorConfig) ac);
|
||||
} else if (ac is Barebone.TargetFunctionsAllocatorConfig) {
|
||||
allocator = new Barebone.TargetFunctionsAllocator (machine, page_size,
|
||||
(Barebone.TargetFunctionsAllocatorConfig) ac);
|
||||
} else {
|
||||
assert_not_reached ();
|
||||
}
|
||||
|
||||
var interceptor = new Barebone.Interceptor (machine, allocator);
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
[CCode (gir_namespace = "FridaBarebone", gir_version = "1.0")]
|
||||
namespace Frida.Barebone {
|
||||
private sealed class CModule : Object {
|
||||
public signal void console_output (string message);
|
||||
|
||||
public Gee.List<Export> exports {
|
||||
get;
|
||||
default = new Gee.ArrayList<Export> ();
|
||||
}
|
||||
|
||||
public class Export {
|
||||
public string name;
|
||||
public uint64 address;
|
||||
|
||||
internal Export (string name, uint64 address) {
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
|
||||
private Gum.ElfModule elf;
|
||||
private Allocation allocation;
|
||||
private Callback console_log_callback;
|
||||
|
||||
public async CModule.from_blob (Bytes blob, Machine machine, Allocator allocator, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
try {
|
||||
elf = new Gum.ElfModule.from_blob (blob);
|
||||
} catch (Gum.Error e) {
|
||||
throw new Error.NOT_SUPPORTED ("%s", e.message);
|
||||
}
|
||||
|
||||
allocation = yield inject_elf (elf, machine, allocator, cancellable);
|
||||
|
||||
uint64 base_va = allocation.virtual_address;
|
||||
uint64 console_log_trap = 0;
|
||||
elf.enumerate_symbols (e => {
|
||||
if (e.name == "")
|
||||
return true;
|
||||
|
||||
if (e.name[0] == '_') {
|
||||
if (e.name == "_console_log")
|
||||
console_log_trap = base_va + e.address;
|
||||
return true;
|
||||
}
|
||||
|
||||
exports.add (new Export (e.name, base_va + e.address));
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (console_log_trap != 0) {
|
||||
var handler = new ConsoleLogHandler (machine.gdb);
|
||||
handler.output.connect (on_console_output);
|
||||
console_log_callback = yield new Callback (console_log_trap, handler, machine, cancellable);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_console_output (string message) {
|
||||
console_output (message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
[CCode (gir_namespace = "FridaBarebone", gir_version = "1.0")]
|
||||
namespace Frida.Barebone {
|
||||
/**
|
||||
* Barebone backend configuration. This is specified via the FRIDA_BAREBONE_CONFIG environment
|
||||
* variable, which should point to the filesystem path of a JSON-encoded configuration file.
|
||||
*
|
||||
* Example JSON configurations:
|
||||
*
|
||||
* 1. Using all defaults:
|
||||
* {
|
||||
* "connection": {
|
||||
* "host": "127.0.0.1",
|
||||
* "port": 3333
|
||||
* },
|
||||
* "allocator": {
|
||||
* "mode": "none"
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* 2. Using a physical memory allocator:
|
||||
* {
|
||||
* "connection": {
|
||||
* "host": "127.0.0.1",
|
||||
* "port": 9000
|
||||
* },
|
||||
* "allocator": {
|
||||
* "mode": "physical",
|
||||
* "physical_base": "0x8ec9b4000"
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* 3. Using target-specific allocation functions:
|
||||
* {
|
||||
* "connection": {
|
||||
* "host": "127.0.0.1",
|
||||
* "port": 9000
|
||||
* },
|
||||
* "allocator": {
|
||||
* "mode": "target-functions",
|
||||
* "alloc_function": "0xfffffff007a3c278",
|
||||
* "free_function": "0xfffffff007a3c338"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public sealed class Config : Object, Json.Serializable {
|
||||
public ConnectionConfig connection {
|
||||
get;
|
||||
set;
|
||||
default = new ConnectionConfig ();
|
||||
}
|
||||
|
||||
public AllocatorConfig allocator {
|
||||
get;
|
||||
set;
|
||||
default = new NoAllocatorConfig ();
|
||||
}
|
||||
|
||||
public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
|
||||
if (property_name == "allocator" && property_node.get_node_type () == Json.NodeType.OBJECT) {
|
||||
var obj_node = property_node.get_object ();
|
||||
string? mode = obj_node.get_string_member ("mode");
|
||||
|
||||
Type t = 0;
|
||||
switch (mode) {
|
||||
case "none":
|
||||
t = typeof (NoAllocatorConfig);
|
||||
break;
|
||||
case "physical":
|
||||
t = typeof (PhysicalAllocatorConfig);
|
||||
break;
|
||||
case "target-functions":
|
||||
t = typeof (TargetFunctionsAllocatorConfig);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (t != 0) {
|
||||
var obj = (AllocatorConfig) Json.gobject_deserialize (t, property_node);
|
||||
if (obj != null && obj.is_valid) {
|
||||
var v = Value (t);
|
||||
v.set_object (obj);
|
||||
value = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value = Value (pspec.value_type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ConnectionConfig : Object {
|
||||
public string host {
|
||||
get;
|
||||
set;
|
||||
default = "127.0.0.1";
|
||||
}
|
||||
|
||||
public uint16 port {
|
||||
get;
|
||||
set;
|
||||
default = 3333;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AllocatorConfig : Object {
|
||||
public abstract bool is_valid {
|
||||
get;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class NoAllocatorConfig : AllocatorConfig {
|
||||
public override bool is_valid {
|
||||
get {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class PhysicalAllocatorConfig : AllocatorConfig, Json.Serializable {
|
||||
public override bool is_valid {
|
||||
get {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public uint64 physical_base {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
|
||||
if (try_deserialize_address ("physical_base", property_node, out value))
|
||||
return true;
|
||||
|
||||
value = Value (pspec.value_type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TargetFunctionsAllocatorConfig : AllocatorConfig, Json.Serializable {
|
||||
public override bool is_valid {
|
||||
get {
|
||||
return alloc_function != 0 && free_function != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public uint64 alloc_function {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public uint64 free_function {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
|
||||
if (try_deserialize_address ("alloc_function", property_node, out value))
|
||||
return true;
|
||||
|
||||
if (try_deserialize_address ("free_function", property_node, out value))
|
||||
return true;
|
||||
|
||||
value = Value (pspec.value_type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool try_deserialize_address (string name, Json.Node node, out Value val) {
|
||||
val = Value (typeof (uint64));
|
||||
|
||||
if (node.get_value_type () != typeof (string))
|
||||
return false;
|
||||
|
||||
uint64 v;
|
||||
if (!uint64.try_parse (node.get_string (), out v, null, 16))
|
||||
return false;
|
||||
|
||||
val = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
[CCode (gir_namespace = "FridaBarebone", gir_version = "1.0")]
|
||||
namespace Frida.Barebone {
|
||||
private class ConsoleLogHandler : Object, CallbackHandler {
|
||||
public signal void output (string message);
|
||||
|
||||
public uint arity {
|
||||
get { return 2; }
|
||||
}
|
||||
|
||||
private GDB.Client gdb;
|
||||
|
||||
public ConsoleLogHandler (GDB.Client gdb) {
|
||||
this.gdb = gdb;
|
||||
}
|
||||
|
||||
public async uint64 handle_invocation (uint64[] args, CallFrame frame, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
var message = args[0];
|
||||
var len = (long) args[1];
|
||||
|
||||
Bytes str_bytes = yield gdb.read_byte_array (message, len, cancellable);
|
||||
unowned uint8[] str_data = str_bytes.get_data ();
|
||||
unowned string str_raw = (string) str_data;
|
||||
string str = str_raw.substring (0, len);
|
||||
|
||||
output (str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
[CCode (gir_namespace = "FridaBarebone", gir_version = "1.0")]
|
||||
namespace Frida.Barebone {
|
||||
public async Allocation inject_elf (Gum.ElfModule elf, Machine machine, Allocator allocator, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
size_t vm_size = (size_t) elf.mapped_size;
|
||||
|
||||
size_t page_size = yield machine.query_page_size (cancellable);
|
||||
uint num_pages = (uint) (vm_size / page_size);
|
||||
if (vm_size % page_size != 0)
|
||||
num_pages++;
|
||||
|
||||
var allocation = yield allocator.allocate (num_pages * page_size, page_size, cancellable);
|
||||
try {
|
||||
uint64 base_va = allocation.virtual_address;
|
||||
|
||||
Bytes relocated_image = machine.relocate (elf, base_va);
|
||||
yield machine.gdb.write_byte_array (base_va, relocated_image, cancellable);
|
||||
|
||||
yield machine.protect_pages (base_va, vm_size, READ | EXECUTE, cancellable);
|
||||
} catch (GLib.Error e) {
|
||||
yield allocation.deallocate (cancellable);
|
||||
throw_api_error (e);
|
||||
}
|
||||
|
||||
return allocation;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,9 @@ namespace Frida.Barebone {
|
||||
public abstract async Allocation allocate_pages (uint64 physical_address, uint num_pages, Cancellable? cancellable)
|
||||
throws Error, IOError;
|
||||
|
||||
public abstract async void protect_pages (uint64 virtual_address, size_t size, Gum.PageProtection prot,
|
||||
Cancellable? cancellable) throws Error, IOError;
|
||||
|
||||
public abstract async Gee.List<uint64?> scan_ranges (Gee.List<Gum.MemoryRange?> ranges, MatchPattern pattern,
|
||||
uint max_matches, Cancellable? cancellable) throws Error, IOError;
|
||||
|
||||
@@ -65,8 +68,7 @@ namespace Frida.Barebone {
|
||||
|
||||
public abstract void apply_relocation (Gum.ElfRelocationDetails r, uint64 base_va, Buffer relocated) throws Error;
|
||||
|
||||
public abstract async uint64 invoke (uint64 impl, uint64[] args, uint64 landing_zone, Cancellable? cancellable)
|
||||
throws Error, IOError;
|
||||
public abstract async uint64 invoke (uint64 impl, uint64[] args, Cancellable? cancellable) throws Error, IOError;
|
||||
|
||||
public abstract async CallFrame load_call_frame (GDB.Thread thread, uint arity, Cancellable? cancellable)
|
||||
throws Error, IOError;
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
backend_sources += files(
|
||||
'barebone-host-session.vala',
|
||||
'config.vala',
|
||||
'script.vala',
|
||||
'machine.vala',
|
||||
'allocator.vala',
|
||||
'callback.vala',
|
||||
'memory-scanner.vala',
|
||||
'interceptor.vala',
|
||||
'c-module.vala',
|
||||
'rust-module.vala',
|
||||
'console.vala',
|
||||
'elf.vala',
|
||||
'arch-x86' / 'machine.vala',
|
||||
'arch-x86_64' / 'machine.vala',
|
||||
'arch-arm' / 'machine.vala',
|
||||
|
||||
Generated
+4
-4
@@ -8,7 +8,7 @@
|
||||
"name": "frida-barebone-script-runtime",
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"@types/frida-gum": "^19.0.0",
|
||||
"@types/frida-gum": "^19.0.1",
|
||||
"esbuild": "^0.25.5",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
@@ -439,9 +439,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/frida-gum": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.0.0.tgz",
|
||||
"integrity": "sha512-qViK1KwvPEAkajwSUv0wpZvZLiX8xO4JFFCh8dfYZfzSyOEfoE0KliCP/nJSKIKG6N3hXnPowrvPufjs5fLKAA==",
|
||||
"version": "19.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.0.1.tgz",
|
||||
"integrity": "sha512-mp8BpWWkQFJH86ZN5uXZuDiA7KY/+jDknrw0a06x0/+F5ucPwctHrCuV6iT+LLCp/GyICc36ssedF33B1WoLsw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"watch": "tsc -w"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/frida-gum": "^19.0.0",
|
||||
"@types/frida-gum": "^19.0.1",
|
||||
"esbuild": "^0.25.5",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
|
||||
@@ -84,23 +84,11 @@ namespace Frida.Barebone {
|
||||
throw new Error.NOT_SUPPORTED ("%s", e.message);
|
||||
}
|
||||
|
||||
size_t vm_size = (size_t) elf.mapped_size;
|
||||
allocation = yield inject_elf (elf, machine, allocator, cancellable);
|
||||
|
||||
size_t page_size = yield machine.query_page_size (cancellable);
|
||||
uint num_pages = (uint) (vm_size / page_size);
|
||||
if (vm_size % page_size != 0)
|
||||
num_pages++;
|
||||
|
||||
var gdb = machine.gdb;
|
||||
|
||||
allocation = yield allocator.allocate (num_pages * page_size, page_size, cancellable);
|
||||
uint64 base_va = allocation.virtual_address;
|
||||
|
||||
Bytes relocated_image = machine.relocate (elf, base_va);
|
||||
yield gdb.write_byte_array (base_va, relocated_image, cancellable);
|
||||
|
||||
uint64 console_log_trap = 0;
|
||||
elf.enumerate_dynamic_symbols (e => {
|
||||
elf.enumerate_symbols (e => {
|
||||
if (e.name == "")
|
||||
return true;
|
||||
|
||||
@@ -116,38 +104,14 @@ namespace Frida.Barebone {
|
||||
});
|
||||
|
||||
if (console_log_trap != 0) {
|
||||
console_log_callback = yield new Callback (console_log_trap, new ConsoleLogHandler (this, gdb),
|
||||
machine, cancellable);
|
||||
var handler = new ConsoleLogHandler (machine.gdb);
|
||||
handler.output.connect (on_console_output);
|
||||
console_log_callback = yield new Callback (console_log_trap, handler, machine, cancellable);
|
||||
}
|
||||
}
|
||||
|
||||
private class ConsoleLogHandler : Object, CallbackHandler {
|
||||
public uint arity {
|
||||
get { return 2; }
|
||||
}
|
||||
|
||||
private weak RustModule parent;
|
||||
private GDB.Client gdb;
|
||||
|
||||
public ConsoleLogHandler (RustModule parent, GDB.Client gdb) {
|
||||
this.parent = parent;
|
||||
this.gdb = gdb;
|
||||
}
|
||||
|
||||
public async uint64 handle_invocation (uint64[] args, CallFrame frame, Cancellable? cancellable)
|
||||
throws Error, IOError {
|
||||
var message = args[0];
|
||||
var len = (long) args[1];
|
||||
|
||||
Bytes str_bytes = yield gdb.read_byte_array (message, len, cancellable);
|
||||
unowned uint8[] str_data = str_bytes.get_data ();
|
||||
unowned string str_raw = (string) str_data;
|
||||
string str = str_raw.substring (0, len);
|
||||
|
||||
parent.console_output (str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
private void on_console_output (string message) {
|
||||
console_output (message);
|
||||
}
|
||||
|
||||
private const string CRATE_NAME = "rustmodule";
|
||||
@@ -201,7 +165,7 @@ namespace Frida.Barebone {
|
||||
.resolve_relative_path (CRATE_NAME);
|
||||
}
|
||||
|
||||
yield write_text_file (workdir, "module.lds", make_linker_script (symbols), cancellable);
|
||||
yield write_text_file (workdir, "module.lds", make_linker_script (code, symbols), cancellable);
|
||||
} catch (GLib.Error e) {
|
||||
throw new Error.PERMISSION_DENIED ("%s", e.message);
|
||||
}
|
||||
@@ -270,8 +234,8 @@ namespace Frida.Barebone {
|
||||
return rs.str;
|
||||
}
|
||||
|
||||
private static string make_linker_script (Gee.Map<string, uint64?> symbols) {
|
||||
var script = new StringBuilder.sized (256);
|
||||
private static string make_linker_script (string code, Gee.Map<string, uint64?> symbols) {
|
||||
var script = new StringBuilder.sized (512);
|
||||
|
||||
foreach (var e in symbols.entries) {
|
||||
unowned string name = e.key;
|
||||
@@ -282,15 +246,16 @@ namespace Frida.Barebone {
|
||||
.append_printf ("0x%" + uint64.FORMAT_MODIFIER + "x;\n", address);
|
||||
}
|
||||
|
||||
script.append (prettify_text_asset (BASE_LINKER_SCRIPT));
|
||||
|
||||
return script.str;
|
||||
}
|
||||
|
||||
private const string BASE_LINKER_SCRIPT = """
|
||||
script.append ("""
|
||||
SECTIONS {
|
||||
.text : {
|
||||
*(.text*);
|
||||
""");
|
||||
|
||||
foreach (string name in extract_extern_c_symbols (code))
|
||||
script.append_printf (" KEEP(*(.text.%s))\n", name);
|
||||
|
||||
script.append ("""
|
||||
_console_log = .;
|
||||
. += 8;
|
||||
}
|
||||
@@ -307,7 +272,25 @@ namespace Frida.Barebone {
|
||||
*(.bss*)
|
||||
}
|
||||
}
|
||||
""";
|
||||
""");
|
||||
|
||||
return prettify_text_asset (script.str);
|
||||
}
|
||||
|
||||
private static Gee.List<string> extract_extern_c_symbols (string code) {
|
||||
var names = new Gee.ArrayList<string> ();
|
||||
|
||||
var export_pattern = /\#\[\s*no_mangle\s*\]\s*pub\s+(?:unsafe\s+)?extern\s*"C"\s+fn\s+([A-Za-z_]\w*)\s*\(/;
|
||||
|
||||
try {
|
||||
MatchInfo info;
|
||||
for (export_pattern.match (code, 0, out info); info.matches (); info.next ())
|
||||
names.add (info.fetch (1));
|
||||
} catch (RegexError e) {
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
private const string BUILTINS = """
|
||||
#![no_main]
|
||||
|
||||
@@ -304,6 +304,13 @@ Object.defineProperties(Process, {
|
||||
});
|
||||
|
||||
const marshalers: { [type: string]: Marshaler } = {
|
||||
void: {
|
||||
fromNative(v) {
|
||||
},
|
||||
toNative(v) {
|
||||
throw new Error("invalid operation");
|
||||
}
|
||||
},
|
||||
pointer: {
|
||||
fromNative(v) {
|
||||
return new BNativePointer(v);
|
||||
@@ -338,6 +345,17 @@ const marshalers: { [type: string]: Marshaler } = {
|
||||
return BigInt(v);
|
||||
}
|
||||
},
|
||||
size_t: {
|
||||
fromNative(v) {
|
||||
return new BUInt64(v);
|
||||
},
|
||||
toNative(v) {
|
||||
if (typeof v === "number") {
|
||||
return BigInt(v);
|
||||
}
|
||||
return v.$v;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function getMarshalerFor(t: NativeFunctionReturnType | NativeFunctionArgumentType): Marshaler {
|
||||
|
||||
+114
-9
@@ -42,8 +42,6 @@ namespace Frida {
|
||||
|
||||
private Gee.Queue<QuickJS.Value?> tick_callbacks = new Gee.ArrayQueue<QuickJS.Value?> ();
|
||||
|
||||
private Barebone.Allocation? cached_landing_zone; // TODO: Deallocate on teardown.
|
||||
|
||||
private Gee.Set<Barebone.Callback> native_callbacks = new Gee.HashSet<Barebone.Callback> ();
|
||||
|
||||
private static QuickJS.ClassID cpu_context_class;
|
||||
@@ -56,6 +54,9 @@ namespace Frida {
|
||||
private static QuickJS.ClassExoticMethods invocation_args_exotic_methods;
|
||||
private static QuickJS.ClassID invocation_retval_class;
|
||||
|
||||
private static QuickJS.ClassID c_module_class;
|
||||
private Gee.Set<Barebone.CModule> c_modules = new Gee.HashSet<Barebone.CModule> ();
|
||||
|
||||
private static QuickJS.ClassID rust_module_class;
|
||||
private Gee.Set<Barebone.RustModule> rust_modules = new Gee.HashSet<Barebone.RustModule> ();
|
||||
|
||||
@@ -155,6 +156,7 @@ namespace Frida {
|
||||
|
||||
var memory_obj = ctx.make_object ();
|
||||
add_cfunc (memory_obj, "alloc", on_memory_alloc, 1);
|
||||
add_cfunc (memory_obj, "protect", on_memory_protect, 3);
|
||||
add_cfunc (memory_obj, "scan", on_memory_scan, 4);
|
||||
add_cfunc (memory_obj, "scanSync", on_memory_scan_sync, 3);
|
||||
global.set_property_str (ctx, "Memory", memory_obj);
|
||||
@@ -206,6 +208,17 @@ namespace Frida {
|
||||
ir.class_name = "InvocationReturnValue";
|
||||
rt.make_class (QuickJS.make_class_id (ref invocation_retval_class), ir);
|
||||
|
||||
QuickJS.ClassDef cm;
|
||||
cm.class_name = "CModule";
|
||||
cm.finalizer = on_c_module_finalize;
|
||||
rt.make_class (QuickJS.make_class_id (ref c_module_class), cm);
|
||||
var cm_proto = ctx.make_object ();
|
||||
add_cfunc (cm_proto, "dispose", on_c_module_dispose, 0);
|
||||
ctx.set_class_proto (c_module_class, cm_proto);
|
||||
var cm_ctor = ctx.make_cfunction2 (on_c_module_construct, cm.class_name, 1, constructor, 0);
|
||||
cm_ctor.set_constructor (ctx, cm_proto);
|
||||
global.set_property_str (ctx, "CModule", cm_ctor);
|
||||
|
||||
QuickJS.ClassDef rm;
|
||||
rm.class_name = "RustModule";
|
||||
rm.finalizer = on_rust_module_finalize;
|
||||
@@ -672,11 +685,7 @@ namespace Frida {
|
||||
|
||||
private async void do_invoke (uint64 impl, uint64[] args, Promise<uint64?> promise) {
|
||||
try {
|
||||
if (cached_landing_zone == null)
|
||||
cached_landing_zone = yield services.allocator.allocate (4, 1, io_cancellable);
|
||||
|
||||
uint64 retval = yield services.machine.invoke (impl, args, cached_landing_zone.virtual_address,
|
||||
io_cancellable);
|
||||
uint64 retval = yield services.machine.invoke (impl, args, io_cancellable);
|
||||
|
||||
promise.resolve (retval);
|
||||
} catch (GLib.Error e) {
|
||||
@@ -1124,6 +1133,41 @@ namespace Frida {
|
||||
}
|
||||
}
|
||||
|
||||
private static QuickJS.Value on_memory_protect (QuickJS.Context ctx, QuickJS.Value this_val, QuickJS.Value[] argv) {
|
||||
BareboneScript * script = ctx.get_opaque ();
|
||||
|
||||
uint64 address;
|
||||
if (!script->unparse_native_pointer (argv[0], out address))
|
||||
return QuickJS.Exception;
|
||||
|
||||
uint size;
|
||||
if (!script->unparse_uint (argv[1], out size))
|
||||
return QuickJS.Exception;
|
||||
|
||||
Gum.PageProtection prot;
|
||||
if (!script->unparse_page_protection (argv[2], out prot))
|
||||
return QuickJS.Exception;
|
||||
|
||||
var promise = new Promise<bool?> ();
|
||||
script->do_memory_protect.begin (address, size, prot, promise);
|
||||
|
||||
bool? result = script->process_events_until_ready (promise);
|
||||
if (result == null)
|
||||
return QuickJS.Exception;
|
||||
|
||||
return ctx.make_bool (result);
|
||||
}
|
||||
|
||||
private async void do_memory_protect (uint64 address, size_t size, Gum.PageProtection prot, Promise<bool?> promise) {
|
||||
try {
|
||||
yield services.machine.protect_pages (address, size, prot, io_cancellable);
|
||||
|
||||
promise.resolve (true);
|
||||
} catch (GLib.Error e) {
|
||||
promise.resolve (false);
|
||||
}
|
||||
}
|
||||
|
||||
private static QuickJS.Value on_memory_scan (QuickJS.Context ctx, QuickJS.Value this_val, QuickJS.Value[] argv) {
|
||||
BareboneScript * script = ctx.get_opaque ();
|
||||
|
||||
@@ -1791,6 +1835,67 @@ namespace Frida {
|
||||
return QuickJS.Undefined;
|
||||
}
|
||||
|
||||
private static QuickJS.Value on_c_module_construct (QuickJS.Context ctx, QuickJS.Value new_target,
|
||||
QuickJS.Value[] argv) {
|
||||
BareboneScript * script = ctx.get_opaque ();
|
||||
|
||||
Bytes blob;
|
||||
if (!script->unparse_bytes (argv[0], out blob))
|
||||
return QuickJS.Exception;
|
||||
|
||||
var promise = new Promise<Barebone.CModule> ();
|
||||
script->load_c_module.begin (blob, promise);
|
||||
|
||||
Barebone.CModule? mod = script->process_events_until_ready (promise);
|
||||
if (mod == null)
|
||||
return QuickJS.Exception;
|
||||
|
||||
var proto = new_target.get_property (ctx, script->prototype_key);
|
||||
var wrapper = ctx.make_object_with_proto_and_class (proto, c_module_class);
|
||||
ctx.free_value (proto);
|
||||
|
||||
wrapper.set_opaque (mod);
|
||||
script->c_modules.add (mod);
|
||||
|
||||
foreach (var e in mod.exports)
|
||||
wrapper.set_property_str (ctx, e.name, script->make_native_pointer (e.address));
|
||||
|
||||
mod.console_output.connect (script->on_console_output);
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private async void load_c_module (Bytes blob, Promise<Barebone.CModule> promise) {
|
||||
try {
|
||||
var mod = yield new Barebone.CModule.from_blob (blob, services.machine, services.allocator, io_cancellable);
|
||||
|
||||
promise.resolve (mod);
|
||||
} catch (GLib.Error e) {
|
||||
promise.reject (e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void on_c_module_finalize (QuickJS.Runtime rt, QuickJS.Value val) {
|
||||
Barebone.CModule * mod = val.get_opaque (c_module_class);
|
||||
if (mod == null)
|
||||
return;
|
||||
|
||||
BareboneScript * script = rt.get_opaque ();
|
||||
script->c_modules.remove (mod);
|
||||
}
|
||||
|
||||
private static QuickJS.Value on_c_module_dispose (QuickJS.Context ctx, QuickJS.Value this_val, QuickJS.Value[] argv) {
|
||||
Barebone.CModule * mod = this_val.get_opaque (c_module_class);
|
||||
|
||||
if (mod != null) {
|
||||
this_val.set_opaque (null);
|
||||
BareboneScript * script = ctx.get_opaque ();
|
||||
script->c_modules.remove (mod);
|
||||
}
|
||||
|
||||
return QuickJS.Undefined;
|
||||
}
|
||||
|
||||
private static QuickJS.Value on_rust_module_construct (QuickJS.Context ctx, QuickJS.Value new_target,
|
||||
QuickJS.Value[] argv) {
|
||||
BareboneScript * script = ctx.get_opaque ();
|
||||
@@ -1860,7 +1965,7 @@ namespace Frida {
|
||||
foreach (var e in mod.exports)
|
||||
wrapper.set_property_str (ctx, e.name, script->make_native_pointer (e.address));
|
||||
|
||||
mod.console_output.connect (script->on_rust_module_console_output);
|
||||
mod.console_output.connect (script->on_console_output);
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
@@ -1898,7 +2003,7 @@ namespace Frida {
|
||||
return QuickJS.Undefined;
|
||||
}
|
||||
|
||||
private void on_rust_module_console_output (string message) {
|
||||
private void on_console_output (string message) {
|
||||
var builder = new Json.Builder ();
|
||||
builder
|
||||
.begin_object ()
|
||||
|
||||
Generated
+4
-4
@@ -33,7 +33,7 @@
|
||||
"@frida/url": "^1.0.2",
|
||||
"@frida/util": "^1.0.3",
|
||||
"@frida/vm": "^2.0.0",
|
||||
"@types/frida-gum": "19.0.0",
|
||||
"@types/frida-gum": "19.0.1",
|
||||
"@types/node": "18.19.103",
|
||||
"frida-fs": "7.0.0"
|
||||
}
|
||||
@@ -248,9 +248,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/frida-gum": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.0.0.tgz",
|
||||
"integrity": "sha512-qViK1KwvPEAkajwSUv0wpZvZLiX8xO4JFFCh8dfYZfzSyOEfoE0KliCP/nJSKIKG6N3hXnPowrvPufjs5fLKAA==",
|
||||
"version": "19.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.0.1.tgz",
|
||||
"integrity": "sha512-mp8BpWWkQFJH86ZN5uXZuDiA7KY/+jDknrw0a06x0/+F5ucPwctHrCuV6iT+LLCp/GyICc36ssedF33B1WoLsw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"@frida/url": "^1.0.2",
|
||||
"@frida/util": "^1.0.3",
|
||||
"@frida/vm": "^2.0.0",
|
||||
"@types/frida-gum": "19.0.0",
|
||||
"@types/frida-gum": "19.0.1",
|
||||
"@types/node": "18.19.103",
|
||||
"frida-fs": "7.0.0"
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace Frida {
|
||||
}
|
||||
|
||||
private void on_server_connection (IOStream connection, SocketAddress remote_address, DynamicInterface? dynamic_iface) {
|
||||
#if IOS || TVOS
|
||||
#if HAVE_LOCAL_BACKEND && (IOS || TVOS)
|
||||
/*
|
||||
* We defer the launchd injection until the first connection is established in order
|
||||
* to avoid bootloops on unsupported jailbreaks.
|
||||
|
||||
@@ -808,7 +808,10 @@ namespace Frida {
|
||||
var lldb = yield start_lldb_service (cancellable);
|
||||
var process = yield lldb.launch (argv, launch_options, cancellable);
|
||||
if (process.observed_state == ALREADY_RUNNING) {
|
||||
yield lldb.kill (cancellable);
|
||||
try {
|
||||
yield lldb.kill (cancellable);
|
||||
} catch (Error e) {
|
||||
}
|
||||
yield lldb.close (cancellable);
|
||||
|
||||
lldb = yield start_lldb_service (cancellable);
|
||||
|
||||
@@ -24,17 +24,21 @@ struct _FridaUploadApi
|
||||
int (* listen) (int socket, int backlog);
|
||||
int (* getsockname) (int socket, struct sockaddr * restrict address, socklen_t * restrict address_len);
|
||||
int (* accept) (int socket, struct sockaddr * restrict address, socklen_t * restrict address_len);
|
||||
int (* close) (int fd);
|
||||
ssize_t (* read) (int fd, void * buf, size_t n);
|
||||
ssize_t (* write) (int fd, const void *buf, size_t n);
|
||||
int (* getpagesize) (void);
|
||||
int (* mprotect) (void * addr, size_t len, int prot);
|
||||
void (* sys_icache_invalidate) (void * start, size_t len);
|
||||
void (* sys_dcache_flush) (void * start, size_t len);
|
||||
mach_port_t (* _mach_task_self) (void);
|
||||
kern_return_t (* mach_vm_allocate) (vm_map_t target, mach_vm_address_t * address, mach_vm_size_t size, int flags);
|
||||
kern_return_t (* mach_vm_deallocate) (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size);
|
||||
kern_return_t (* vm_remap) (vm_map_t target_task, vm_address_t * target_address, vm_size_t size, vm_address_t mask, int flags,
|
||||
vm_map_t src_task, vm_address_t src_address, boolean_t copy, vm_prot_t * cur_protection, vm_prot_t * max_protection,
|
||||
vm_inherit_t inheritance);
|
||||
void * (* dlopen) (const char * path, int mode);
|
||||
void * (* dlsym) (void * handle, const char * symbol);
|
||||
int (* mprotect) (void * addr, size_t len, int prot);
|
||||
int (* close) (int fd);
|
||||
|
||||
int * (* get_errno_storage) (void);
|
||||
};
|
||||
@@ -46,18 +50,20 @@ struct _FridaUploadApi
|
||||
listen, \
|
||||
getsockname, \
|
||||
accept, \
|
||||
close, \
|
||||
read, \
|
||||
write, \
|
||||
getpagesize, \
|
||||
mprotect, \
|
||||
sys_icache_invalidate, \
|
||||
sys_dcache_flush, \
|
||||
dlsym (RTLD_DEFAULT, "mach_task_self"), \
|
||||
mach_vm_allocate, \
|
||||
mach_vm_deallocate, \
|
||||
vm_remap, \
|
||||
dlopen, \
|
||||
dlsym, \
|
||||
mprotect, \
|
||||
close, \
|
||||
__error \
|
||||
__error, \
|
||||
}
|
||||
|
||||
#define FRIDA_RX_BUFFER_SIZE (1024 * 1024)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "upload-api.h"
|
||||
|
||||
static uint64_t frida_query_debugger_mapping_enforced (const FridaUploadApi * api);
|
||||
|
||||
uint64_t
|
||||
frida_listen (int rx_buffer_size, const FridaUploadApi * api)
|
||||
{
|
||||
@@ -35,7 +37,7 @@ frida_listen (int rx_buffer_size, const FridaUploadApi * api)
|
||||
if (res == -1)
|
||||
goto listen_failed;
|
||||
|
||||
return ((uint64_t) fd << 16) | ntohs (addr.sin6_port);
|
||||
return (frida_query_debugger_mapping_enforced (api) << 56) | ((uint64_t) fd << 16) | ntohs (addr.sin6_port);
|
||||
|
||||
socket_failed:
|
||||
{
|
||||
@@ -67,10 +69,38 @@ failure:
|
||||
if (fd != -1)
|
||||
api->close (fd);
|
||||
|
||||
return ((uint64_t) error_code << 56);
|
||||
return ((uint64_t) error_code << 57);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
frida_query_debugger_mapping_enforced (const FridaUploadApi * api)
|
||||
{
|
||||
uint64_t is_enforced;
|
||||
mach_port_t task;
|
||||
int page_size;
|
||||
mach_vm_address_t start;
|
||||
vm_address_t addr;
|
||||
vm_prot_t cur_prot, max_prot;
|
||||
|
||||
task = api->_mach_task_self ();
|
||||
page_size = api->getpagesize ();
|
||||
|
||||
api->mach_vm_allocate (task, &start, page_size, VM_FLAGS_ANYWHERE);
|
||||
*(uint32_t *) start = 1337;
|
||||
api->mprotect ((void *) start, page_size, PROT_READ | PROT_EXEC);
|
||||
|
||||
addr = 0;
|
||||
api->vm_remap (task, &addr, page_size, 0, VM_FLAGS_ANYWHERE, task, start, FALSE, &cur_prot, &max_prot, VM_INHERIT_NONE);
|
||||
|
||||
is_enforced = (cur_prot & (VM_PROT_READ | VM_PROT_EXECUTE)) != (VM_PROT_READ | VM_PROT_EXECUTE);
|
||||
|
||||
api->mach_vm_deallocate (task, addr, page_size);
|
||||
api->mach_vm_deallocate (task, start, page_size);
|
||||
|
||||
return is_enforced;
|
||||
}
|
||||
|
||||
#ifdef BUILDING_TEST_PROGRAM
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -258,6 +258,7 @@ int64_t
|
||||
frida_receive (int listener_fd, uint64_t session_id_top, uint64_t session_id_bottom, const char * apple[], const FridaUploadApi * api)
|
||||
{
|
||||
int result = 0;
|
||||
mach_port_t task;
|
||||
bool expecting_client;
|
||||
int res;
|
||||
struct sockaddr_in addr;
|
||||
@@ -265,6 +266,8 @@ frida_receive (int listener_fd, uint64_t session_id_top, uint64_t session_id_bot
|
||||
int client_fd;
|
||||
uint32_t ACK_MAGIC = 0xac4ac4ac;
|
||||
|
||||
task = api->_mach_task_self ();
|
||||
|
||||
expecting_client = true;
|
||||
|
||||
do
|
||||
@@ -307,16 +310,33 @@ frida_receive (int listener_fd, uint64_t session_id_top, uint64_t session_id_bot
|
||||
{
|
||||
uint64_t address;
|
||||
uint32_t size;
|
||||
vm_address_t writable_address;
|
||||
vm_prot_t cur_prot, max_prot;
|
||||
size_t n;
|
||||
|
||||
FRIDA_READ_VALUE (address);
|
||||
FRIDA_READ_VALUE (size);
|
||||
|
||||
success = frida_read_chunk (client_fd, (void *) address, size, &n, api);
|
||||
writable_address = 0;
|
||||
success = api->vm_remap (task, &writable_address, size, 0, VM_FLAGS_ANYWHERE, task, address, FALSE, &cur_prot, &max_prot,
|
||||
VM_INHERIT_NONE) == 0;
|
||||
if (!success)
|
||||
break;
|
||||
|
||||
success = api->mprotect ((void *) writable_address, size, VM_PROT_READ | VM_PROT_WRITE) == 0;
|
||||
if (!success)
|
||||
goto unmap_writable;
|
||||
|
||||
success = frida_read_chunk (client_fd, (void *) writable_address, size, &n, api);
|
||||
if (!success)
|
||||
goto unmap_writable;
|
||||
|
||||
api->sys_icache_invalidate ((void *) address, n);
|
||||
api->sys_dcache_flush ((void *) address, n);
|
||||
|
||||
unmap_writable:
|
||||
api->mach_vm_deallocate (task, writable_address, size);
|
||||
|
||||
break;
|
||||
}
|
||||
case FRIDA_UPLOAD_COMMAND_APPLY_THREADED:
|
||||
|
||||
+308
-269
@@ -185,7 +185,9 @@ namespace Frida.Fruity.Injector {
|
||||
|
||||
private async GadgetDetails inject_module (Cancellable? cancellable) throws GLib.Error {
|
||||
module_size = compute_virtual_size (module);
|
||||
module.base_address = yield lldb.allocate (module_size, "rw", cancellable);
|
||||
module.base_address = yield lldb.allocate (module_size, "rx", cancellable);
|
||||
|
||||
yield lldb.spray_pages (module.base_address, (size_t) module.segments.index (0).vm_size, page_size, cancellable);
|
||||
|
||||
unowned Gum.DarwinModuleImage image = module.image;
|
||||
unowned uint8[] image_data = ((uint8[]) image.data)[0:image.size];
|
||||
@@ -355,6 +357,8 @@ namespace Frida.Fruity.Injector {
|
||||
.end_object ()
|
||||
.set_member_name ("teardown")
|
||||
.add_string_value ("full")
|
||||
.set_member_name ("code_signing")
|
||||
.add_string_value ("optional")
|
||||
.end_object ();
|
||||
string raw_config = Json.to_string (config.get_root (), false);
|
||||
string config_param = "frida_gadget_config=" + Base64.encode (raw_config.data);
|
||||
@@ -362,7 +366,10 @@ namespace Frida.Fruity.Injector {
|
||||
var apple_strv_builder = new StringVectorBuilder (args_builder);
|
||||
|
||||
apple_strv_builder
|
||||
.append_string (range_param)
|
||||
.append_string (range_param);
|
||||
|
||||
var config_offset = args_builder.offset;
|
||||
apple_strv_builder
|
||||
.append_string (config_param)
|
||||
.append_terminator ();
|
||||
var apple_strv_offset = apple_strv_builder.append_placeholder ();
|
||||
@@ -375,17 +382,19 @@ namespace Frida.Fruity.Injector {
|
||||
.append_pointer (symbols.listen)
|
||||
.append_pointer (symbols.getsockname)
|
||||
.append_pointer (symbols.accept)
|
||||
.append_pointer (symbols.close)
|
||||
.append_pointer (symbols.read)
|
||||
.append_pointer (symbols.write)
|
||||
.append_pointer (symbols.getpagesize)
|
||||
.append_pointer (symbols.mprotect)
|
||||
.append_pointer (symbols.sys_icache_invalidate)
|
||||
.append_pointer (symbols.sys_dcache_flush)
|
||||
.append_pointer (symbols._mach_task_self)
|
||||
.append_pointer (symbols.mach_vm_allocate)
|
||||
.append_pointer (symbols.mach_vm_deallocate)
|
||||
.append_pointer (symbols.vm_remap)
|
||||
.append_pointer (symbols.dlopen)
|
||||
.append_pointer (symbols.dlsym)
|
||||
.append_pointer (symbols.mprotect)
|
||||
.append_pointer (symbols.close)
|
||||
.append_pointer (symbols.get_errno_storage);
|
||||
|
||||
apple_strv_builder.build (args);
|
||||
@@ -400,13 +409,19 @@ namespace Frida.Fruity.Injector {
|
||||
upload_api
|
||||
}, null, cancellable);
|
||||
|
||||
uint8 error_code = (uint8) ((listen_result >> 56) & 0xff);
|
||||
uint32 listener_fd = (uint32) ((listen_result >> 16) & 0xffffffffU);
|
||||
uint16 listener_port = (uint16) (listen_result & 0xffff);
|
||||
uint8 error_code = (uint8) ((listen_result >> 57) & 0x7f);
|
||||
bool debugger_mapping_enforced = ((listen_result >> 56) & 0x1) != 0;
|
||||
uint32 listener_fd = (uint32) ((listen_result >> 16) & 0xffffffffU);
|
||||
uint16 listener_port = (uint16) (listen_result & 0xffff);
|
||||
|
||||
if (error_code != 0)
|
||||
throw new Error.UNSUPPORTED ("Unable to listen on TCP (error_code=%u)", error_code);
|
||||
|
||||
if (debugger_mapping_enforced) {
|
||||
string overwrite_config_param = "frida_gadget_config=" + Base64.encode (raw_config.replace ("optional", "required", 1).data);
|
||||
yield lldb.write_byte_array (args + config_offset, new Bytes.static (overwrite_config_param.data), cancellable);
|
||||
}
|
||||
|
||||
yield lldb.write_byte_array (code, new Bytes.static (UPLOAD_RECEIVER_CODE), cancellable);
|
||||
|
||||
// The generated session ID only acts as a sanitycheck for now
|
||||
@@ -565,17 +580,19 @@ namespace Frida.Fruity.Injector {
|
||||
public uint64 listen;
|
||||
public uint64 getsockname;
|
||||
public uint64 accept;
|
||||
public uint64 close;
|
||||
public uint64 read;
|
||||
public uint64 write;
|
||||
public uint64 getpagesize;
|
||||
public uint64 mprotect;
|
||||
public uint64 sys_icache_invalidate;
|
||||
public uint64 sys_dcache_flush;
|
||||
public uint64 _mach_task_self;
|
||||
public uint64 mach_vm_allocate;
|
||||
public uint64 mach_vm_deallocate;
|
||||
public uint64 vm_remap;
|
||||
public uint64 dlopen;
|
||||
public uint64 dlsym;
|
||||
public uint64 mprotect;
|
||||
public uint64 close;
|
||||
public uint64 get_errno_storage;
|
||||
|
||||
private const string LIBSYSTEM = "/usr/lib/libSystem.B.dylib";
|
||||
@@ -588,17 +605,19 @@ namespace Frida.Fruity.Injector {
|
||||
.add (LIBSYSTEM, "_listen")
|
||||
.add (LIBSYSTEM, "_getsockname")
|
||||
.add (LIBSYSTEM, "_accept")
|
||||
.add (LIBSYSTEM, "_close")
|
||||
.add (LIBSYSTEM, "_read")
|
||||
.add (LIBSYSTEM, "_write")
|
||||
.add (LIBSYSTEM, "_getpagesize")
|
||||
.add (LIBSYSTEM, "_mprotect")
|
||||
.add (LIBSYSTEM, "_sys_icache_invalidate")
|
||||
.add (LIBSYSTEM, "_sys_dcache_flush")
|
||||
.add (LIBSYSTEM, "_mach_task_self")
|
||||
.add (LIBSYSTEM, "_mach_vm_allocate")
|
||||
.add (LIBSYSTEM, "_mach_vm_deallocate")
|
||||
.add (LIBSYSTEM, "_vm_remap")
|
||||
.add (LIBSYSTEM, "_dlopen")
|
||||
.add (LIBSYSTEM, "_dlsym")
|
||||
.add (LIBSYSTEM, "_mprotect")
|
||||
.add (LIBSYSTEM, "_close")
|
||||
.add (LIBSYSTEM, "___error")
|
||||
;
|
||||
}
|
||||
@@ -610,184 +629,205 @@ namespace Frida.Fruity.Injector {
|
||||
listen = symbols.get (LIBSYSTEM, "_listen");
|
||||
getsockname = symbols.get (LIBSYSTEM, "_getsockname");
|
||||
accept = symbols.get (LIBSYSTEM, "_accept");
|
||||
close = symbols.get (LIBSYSTEM, "_close");
|
||||
read = symbols.get (LIBSYSTEM, "_read");
|
||||
write = symbols.get (LIBSYSTEM, "_write");
|
||||
getpagesize = symbols.get (LIBSYSTEM, "_getpagesize");
|
||||
mprotect = symbols.get (LIBSYSTEM, "_mprotect");
|
||||
sys_icache_invalidate = symbols.get (LIBSYSTEM, "_sys_icache_invalidate");
|
||||
sys_dcache_flush = symbols.get (LIBSYSTEM, "_sys_dcache_flush");
|
||||
_mach_task_self = symbols.get (LIBSYSTEM, "_mach_task_self");
|
||||
mach_vm_allocate = symbols.get (LIBSYSTEM, "_mach_vm_allocate");
|
||||
mach_vm_deallocate = symbols.get (LIBSYSTEM, "_mach_vm_deallocate");
|
||||
vm_remap = symbols.get (LIBSYSTEM, "_vm_remap");
|
||||
dlopen = symbols.get (LIBSYSTEM, "_dlopen");
|
||||
dlsym = symbols.get (LIBSYSTEM, "_dlsym");
|
||||
mprotect = symbols.get (LIBSYSTEM, "_mprotect");
|
||||
close = symbols.get (LIBSYSTEM, "_close");
|
||||
get_errno_storage = symbols.get (LIBSYSTEM, "___error");
|
||||
}
|
||||
}
|
||||
|
||||
/* Compiled from helpers/upload-listener.c */
|
||||
private const uint8[] UPLOAD_LISTENER_CODE = {
|
||||
0xff, 0x83, 0x01, 0xd1, 0xf6, 0x57, 0x03, 0xa9, 0xf4, 0x4f, 0x04, 0xa9, 0xfd, 0x7b, 0x05, 0xa9, 0xfd, 0x43, 0x01,
|
||||
0x91, 0xf3, 0x03, 0x01, 0xaa, 0x08, 0x00, 0x00, 0x90, 0x08, 0xb1, 0x04, 0x91, 0xa0, 0xc3, 0x1d, 0xb8, 0x00, 0x01,
|
||||
0xc0, 0x3d, 0xe0, 0x07, 0x80, 0x3d, 0x00, 0xc1, 0xc0, 0x3c, 0xe0, 0xc3, 0x81, 0x3c, 0x28, 0x00, 0x40, 0xf9, 0xc0,
|
||||
0x03, 0x80, 0x52, 0x21, 0x00, 0x80, 0x52, 0x02, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0x31,
|
||||
0xc0, 0x04, 0x00, 0x54, 0xf4, 0x03, 0x00, 0xaa, 0x68, 0x06, 0x40, 0xf9, 0xa3, 0x93, 0x00, 0xd1, 0xe1, 0xff, 0x9f,
|
||||
0x52, 0x42, 0x00, 0x82, 0x52, 0x84, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0x31, 0xe0, 0x03,
|
||||
0x00, 0x54, 0x88, 0x03, 0x80, 0x52, 0xe8, 0x0f, 0x00, 0xb9, 0x68, 0x0a, 0x40, 0xf9, 0xe1, 0x43, 0x00, 0x91, 0xe0,
|
||||
0x03, 0x14, 0xaa, 0x82, 0x03, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0x31, 0x00, 0x03, 0x00, 0x54,
|
||||
0x68, 0x12, 0x40, 0xf9, 0xe1, 0x43, 0x00, 0x91, 0xe2, 0x33, 0x00, 0x91, 0xe0, 0x03, 0x14, 0xaa, 0x00, 0x01, 0x3f,
|
||||
0xd6, 0x1f, 0x04, 0x00, 0x31, 0x60, 0x02, 0x00, 0x54, 0x68, 0x0e, 0x40, 0xf9, 0xe0, 0x03, 0x14, 0xaa, 0x21, 0x00,
|
||||
0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0x31, 0xe0, 0x01, 0x00, 0x54, 0x88, 0x7e, 0x40, 0x93, 0xe9,
|
||||
0x27, 0x40, 0x79, 0x29, 0x09, 0xc0, 0x5a, 0x35, 0x7d, 0x10, 0x53, 0x15, 0xbd, 0x70, 0xb3, 0x0d, 0x00, 0x00, 0x14,
|
||||
0x15, 0x20, 0xe0, 0xd2, 0x0b, 0x00, 0x00, 0x14, 0x15, 0x40, 0xe0, 0xd2, 0x06, 0x00, 0x00, 0x14, 0x15, 0x60, 0xe0,
|
||||
0xd2, 0x04, 0x00, 0x00, 0x14, 0x15, 0x80, 0xe0, 0xd2, 0x02, 0x00, 0x00, 0x14, 0x15, 0xa0, 0xe0, 0xd2, 0x68, 0x42,
|
||||
0x40, 0xf9, 0xe0, 0x03, 0x14, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0xe0, 0x03, 0x15, 0xaa, 0xfd, 0x7b, 0x45, 0xa9, 0xf4,
|
||||
0x4f, 0x44, 0xa9, 0xf6, 0x57, 0x43, 0xa9, 0xff, 0x83, 0x01, 0x91, 0xc0, 0x03, 0x5f, 0xd6, 0x00, 0x1e, 0x00, 0x00,
|
||||
0xff, 0x83, 0x02, 0xd1, 0xf8, 0x5f, 0x06, 0xa9, 0xf6, 0x57, 0x07, 0xa9, 0xf4, 0x4f, 0x08, 0xa9, 0xfd, 0x7b, 0x09,
|
||||
0xa9, 0xfd, 0x43, 0x02, 0x91, 0xf3, 0x03, 0x01, 0xaa, 0x08, 0x00, 0x00, 0x90, 0x08, 0xf1, 0x07, 0x91, 0xe0, 0x47,
|
||||
0x00, 0xb9, 0x00, 0x01, 0xc0, 0x3d, 0xe0, 0x0b, 0x80, 0x3d, 0x00, 0xc1, 0xc0, 0x3c, 0xe0, 0xc3, 0x82, 0x3c, 0x28,
|
||||
0x00, 0x40, 0xf9, 0xc0, 0x03, 0x80, 0x52, 0x21, 0x00, 0x80, 0x52, 0x02, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6,
|
||||
0x1f, 0x04, 0x00, 0x31, 0xa0, 0x0a, 0x00, 0x54, 0xf4, 0x03, 0x00, 0xaa, 0x68, 0x06, 0x40, 0xf9, 0xe3, 0x13, 0x01,
|
||||
0x91, 0xe1, 0xff, 0x9f, 0x52, 0x42, 0x00, 0x82, 0x52, 0x84, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04,
|
||||
0x00, 0x31, 0xc0, 0x09, 0x00, 0x54, 0x88, 0x03, 0x80, 0x52, 0xe8, 0x1f, 0x00, 0xb9, 0x68, 0x0a, 0x40, 0xf9, 0xe1,
|
||||
0x83, 0x00, 0x91, 0xe0, 0x03, 0x14, 0xaa, 0x82, 0x03, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0x31,
|
||||
0xe0, 0x08, 0x00, 0x54, 0x68, 0x12, 0x40, 0xf9, 0xe1, 0x83, 0x00, 0x91, 0xe2, 0x73, 0x00, 0x91, 0xe0, 0x03, 0x14,
|
||||
0xaa, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0x31, 0x40, 0x08, 0x00, 0x54, 0x68, 0x0e, 0x40, 0xf9, 0xe0, 0x03,
|
||||
0x14, 0xaa, 0x21, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0x31, 0xc0, 0x07, 0x00, 0x54, 0x68,
|
||||
0x36, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0xf5, 0x03, 0x00, 0xaa, 0x68, 0x26, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6,
|
||||
0x68, 0x3a, 0x40, 0xf9, 0x16, 0x7c, 0x40, 0x93, 0xa1, 0xe3, 0x00, 0xd1, 0xe0, 0x03, 0x15, 0xaa, 0xe2, 0x03, 0x16,
|
||||
0xaa, 0x23, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0xa0, 0x83, 0x5c, 0xf8, 0x28, 0xa7, 0x80, 0x52, 0x08, 0x00,
|
||||
0x00, 0xb9, 0x68, 0x2a, 0x40, 0xf9, 0xb7, 0x00, 0x80, 0x52, 0xe1, 0x03, 0x16, 0xaa, 0xa2, 0x00, 0x80, 0x52, 0x00,
|
||||
0x01, 0x3f, 0xd6, 0xbf, 0x03, 0x1c, 0xf8, 0x68, 0x42, 0x40, 0xf9, 0xa6, 0x83, 0x5c, 0xf8, 0x49, 0x00, 0x80, 0x52,
|
||||
0xe9, 0x13, 0x00, 0xb9, 0xe9, 0x23, 0x01, 0x91, 0xaa, 0x13, 0x01, 0xd1, 0xea, 0x27, 0x00, 0xa9, 0xa1, 0x03, 0x01,
|
||||
0xd1, 0xe0, 0x03, 0x15, 0xaa, 0xe2, 0x03, 0x16, 0xaa, 0x03, 0x00, 0x80, 0xd2, 0x24, 0x00, 0x80, 0x52, 0xe5, 0x03,
|
||||
0x15, 0xaa, 0x07, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0xa8, 0xc3, 0x5b, 0xb8, 0xff, 0x02, 0x28, 0x6a, 0xf7,
|
||||
0x07, 0x9f, 0x1a, 0x68, 0x3e, 0x40, 0xf9, 0xa1, 0x03, 0x5c, 0xf8, 0x1f, 0x00, 0x00, 0x94, 0x68, 0x3e, 0x40, 0xf9,
|
||||
0xa1, 0x83, 0x5c, 0xf8, 0x1c, 0x00, 0x00, 0x94, 0xe8, 0x1e, 0x48, 0xd3, 0x89, 0x7e, 0x40, 0x93, 0x08, 0x41, 0x09,
|
||||
0xaa, 0xe9, 0x47, 0x40, 0x79, 0x29, 0x09, 0xc0, 0x5a, 0x29, 0x7d, 0x10, 0x53, 0x15, 0x01, 0x09, 0xaa, 0x0d, 0x00,
|
||||
0x00, 0x14, 0x15, 0x40, 0xe0, 0xd2, 0x0b, 0x00, 0x00, 0x14, 0x15, 0x80, 0xe0, 0xd2, 0x06, 0x00, 0x00, 0x14, 0x15,
|
||||
0xc0, 0xe0, 0xd2, 0x04, 0x00, 0x00, 0x14, 0x15, 0x00, 0xe1, 0xd2, 0x02, 0x00, 0x00, 0x14, 0x15, 0x40, 0xe1, 0xd2,
|
||||
0x68, 0x1a, 0x40, 0xf9, 0xe0, 0x03, 0x14, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0xe0, 0x03, 0x15, 0xaa, 0xfd, 0x7b, 0x49,
|
||||
0xa9, 0xf4, 0x4f, 0x48, 0xa9, 0xf6, 0x57, 0x47, 0xa9, 0xf8, 0x5f, 0x46, 0xa9, 0xff, 0x83, 0x02, 0x91, 0xc0, 0x03,
|
||||
0x5f, 0xd6, 0xe0, 0x03, 0x15, 0xaa, 0xe2, 0x03, 0x16, 0xaa, 0x00, 0x01, 0x1f, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Compiled from helpers/upload-receiver.c */
|
||||
private const uint8[] UPLOAD_RECEIVER_CODE = {
|
||||
0xfc, 0x6f, 0xba, 0xa9, 0xfa, 0x67, 0x01, 0xa9, 0xf8, 0x5f, 0x02, 0xa9, 0xf6, 0x57, 0x03, 0xa9, 0xf4, 0x4f, 0x04,
|
||||
0xa9, 0xfd, 0x7b, 0x05, 0xa9, 0xfd, 0x43, 0x01, 0x91, 0xff, 0x03, 0x03, 0xd1, 0xfa, 0x03, 0x04, 0xaa, 0xfb, 0x03,
|
||||
0x03, 0xaa, 0xf7, 0x03, 0x02, 0xaa, 0xf8, 0x03, 0x01, 0xaa, 0xf9, 0x03, 0x00, 0xaa, 0xbf, 0xc3, 0x19, 0xb8, 0x88,
|
||||
0x95, 0x98, 0x52, 0x48, 0x89, 0xb5, 0x72, 0xa8, 0x03, 0x18, 0xb8, 0x13, 0x02, 0x80, 0x52, 0xb3, 0x43, 0x18, 0xb8,
|
||||
0x48, 0x17, 0x40, 0xf9, 0xa1, 0xe3, 0x01, 0xd1, 0xa2, 0xf3, 0x01, 0xd1, 0xe0, 0x03, 0x19, 0xaa, 0x00, 0x01, 0x3f,
|
||||
0xd6, 0x1f, 0x04, 0x00, 0x31, 0xe1, 0x00, 0x00, 0x54, 0x48, 0x47, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0x08, 0x00,
|
||||
0x40, 0xb9, 0x1f, 0x11, 0x00, 0x71, 0xa0, 0xfe, 0xff, 0x54, 0xd7, 0x01, 0x00, 0x14, 0xf6, 0x03, 0x00, 0xaa, 0xa1,
|
||||
0x43, 0x02, 0xd1, 0x02, 0x02, 0x80, 0x52, 0x53, 0x02, 0x00, 0x94, 0xa8, 0x27, 0x77, 0xa9, 0x1f, 0x00, 0x00, 0x71,
|
||||
0x00, 0x11, 0x58, 0xfa, 0x20, 0x01, 0x57, 0xfa, 0x60, 0x00, 0x00, 0x54, 0x65, 0x02, 0x00, 0x94, 0xe8, 0xff, 0xff,
|
||||
0x17, 0x58, 0x02, 0x00, 0x94, 0x20, 0x39, 0x00, 0x34, 0xa8, 0x23, 0x00, 0xd1, 0x1a, 0x01, 0x10, 0xf8, 0xa8, 0x33,
|
||||
0x00, 0xd1, 0x19, 0x01, 0x10, 0xb8, 0xbb, 0x83, 0x11, 0xf8, 0xa1, 0x47, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x22,
|
||||
0x00, 0x80, 0x52, 0x41, 0x02, 0x00, 0x94, 0xe0, 0x37, 0x00, 0x34, 0xa8, 0xf3, 0x56, 0x38, 0x10, 0x05, 0x00, 0x51,
|
||||
0x1f, 0x1a, 0x00, 0x71, 0x68, 0x37, 0x00, 0x54, 0x1f, 0x1a, 0x00, 0xf1, 0x10, 0x92, 0x9f, 0x9a, 0xb1, 0x38, 0x00,
|
||||
0x10, 0x1f, 0x20, 0x03, 0xd5, 0x30, 0x7a, 0xb0, 0xb8, 0x11, 0x00, 0x00, 0x10, 0x30, 0x02, 0x10, 0x8b, 0x00, 0x02,
|
||||
0x1f, 0xd6, 0xa1, 0x83, 0x01, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x02, 0x01, 0x80, 0x52, 0x30, 0x02, 0x00, 0x94, 0xc0,
|
||||
0x35, 0x00, 0x34, 0xa1, 0xa3, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x82, 0x00, 0x80, 0x52, 0x2b, 0x02, 0x00, 0x94,
|
||||
0x20, 0x35, 0x00, 0x36, 0xa1, 0x03, 0x5a, 0xf8, 0xa2, 0x83, 0x55, 0xb8, 0xa3, 0x83, 0x02, 0xd1, 0xe0, 0x03, 0x16,
|
||||
0xaa, 0xe4, 0x03, 0x1a, 0xaa, 0xbb, 0x01, 0x00, 0x94, 0xf7, 0x03, 0x00, 0xaa, 0x48, 0x23, 0x40, 0xf9, 0x36, 0x02,
|
||||
0x00, 0x94, 0x48, 0x27, 0x40, 0xf9, 0x34, 0x02, 0x00, 0x94, 0x57, 0xfb, 0x07, 0x37, 0x9c, 0x01, 0x00, 0x14, 0xa1,
|
||||
0x83, 0x01, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x02, 0x01, 0x80, 0x52, 0x19, 0x02, 0x00, 0x94, 0xe0, 0x32, 0x00, 0x34,
|
||||
0xa1, 0x83, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x02, 0x01, 0x80, 0x52, 0x14, 0x02, 0x00, 0x94, 0x40, 0x32, 0x00,
|
||||
0x34, 0xa1, 0xa3, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x42, 0x00, 0x80, 0x52, 0x0f, 0x02, 0x00, 0x94, 0xa0, 0x31,
|
||||
0x00, 0x34, 0xf5, 0x03, 0x00, 0x91, 0xa8, 0x83, 0x55, 0x78, 0x08, 0x71, 0x1d, 0x53, 0x08, 0x3d, 0x00, 0x11, 0x08,
|
||||
0x3d, 0x7c, 0x92, 0xe9, 0x03, 0x00, 0x91, 0x37, 0x01, 0x08, 0xcb, 0xff, 0x02, 0x00, 0x91, 0xa8, 0x83, 0x55, 0x78,
|
||||
0x02, 0xf1, 0x7d, 0xd3, 0xe0, 0x03, 0x16, 0xaa, 0xe1, 0x03, 0x17, 0xaa, 0x01, 0x02, 0x00, 0x94, 0xc0, 0x2f, 0x00,
|
||||
0x34, 0xa1, 0xc3, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x42, 0x00, 0x80, 0x52, 0xfc, 0x01, 0x00, 0x94, 0x20, 0x2f,
|
||||
0x00, 0x34, 0xa8, 0x03, 0x55, 0x78, 0x09, 0x71, 0x1d, 0x53, 0x29, 0x3d, 0x00, 0x11, 0x29, 0x3d, 0x7c, 0x92, 0xea,
|
||||
0x03, 0x00, 0x91, 0x58, 0x01, 0x09, 0xcb, 0x1f, 0x03, 0x00, 0x91, 0x02, 0xf1, 0x7d, 0xd3, 0xe0, 0x03, 0x16, 0xaa,
|
||||
0xe1, 0x03, 0x18, 0xaa, 0xf0, 0x01, 0x00, 0x94, 0xa0, 0x2d, 0x00, 0x34, 0x14, 0x00, 0x80, 0xd2, 0xba, 0x03, 0x5a,
|
||||
0xf8, 0xbb, 0x03, 0x56, 0xf8, 0xbc, 0x03, 0x55, 0x78, 0x9f, 0x02, 0x1c, 0xeb, 0x40, 0x27, 0x00, 0x54, 0x19, 0x7b,
|
||||
0x74, 0xf8, 0x33, 0x03, 0x40, 0xf9, 0xf3, 0x01, 0xf0, 0xb7, 0x68, 0xfe, 0x6b, 0xd3, 0x69, 0xaa, 0x40, 0x92, 0x6a,
|
||||
0xaa, 0x6a, 0x93, 0x4a, 0x31, 0x55, 0x92, 0x09, 0x1d, 0x48, 0xb3, 0x28, 0x01, 0x0a, 0xaa, 0x69, 0x7e, 0x40, 0x92,
|
||||
0x7f, 0x02, 0x41, 0xf2, 0xea, 0x03, 0x9a, 0x9a, 0x08, 0x01, 0x89, 0x9a, 0x49, 0x01, 0x1b, 0x8b, 0x20, 0x01, 0x08,
|
||||
0x8b, 0x53, 0x01, 0xf8, 0xb6, 0x04, 0x00, 0x00, 0x14, 0x68, 0x3e, 0x40, 0x92, 0xe0, 0x7a, 0x68, 0xf8, 0xd3, 0x00,
|
||||
0xf8, 0xb6, 0x61, 0xca, 0x71, 0xd3, 0x63, 0xc2, 0x70, 0xd3, 0x62, 0xbe, 0x60, 0xd3, 0xe4, 0x03, 0x19, 0xaa, 0xb6,
|
||||
0x01, 0x00, 0x94, 0x68, 0xf6, 0x73, 0xd3, 0x20, 0x03, 0x00, 0xf9, 0x39, 0x4f, 0x28, 0x8b, 0xa8, 0xfc, 0xff, 0x35,
|
||||
0x94, 0x06, 0x00, 0x91, 0xe0, 0xff, 0xff, 0x17, 0xa1, 0x83, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x02, 0x01, 0x80,
|
||||
0x52, 0xc6, 0x01, 0x00, 0x94, 0x80, 0x28, 0x00, 0x34, 0xa1, 0xa3, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x02, 0x01,
|
||||
0x80, 0x52, 0xc1, 0x01, 0x00, 0x94, 0xe0, 0x27, 0x00, 0x34, 0xa1, 0xc3, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x02,
|
||||
0x01, 0x80, 0x52, 0xbc, 0x01, 0x00, 0x94, 0x40, 0x27, 0x00, 0x34, 0xb9, 0xf3, 0x75, 0xa9, 0xa8, 0x03, 0x55, 0xf8,
|
||||
0xa8, 0x83, 0x10, 0xf8, 0x48, 0x2b, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0xbf, 0x03, 0x1a, 0xf8, 0x48, 0x2f, 0x40,
|
||||
0xf9, 0xa1, 0x83, 0x01, 0xd1, 0xa9, 0x43, 0x00, 0xd1, 0x20, 0x01, 0x10, 0xb8, 0x22, 0x00, 0xa0, 0x52, 0x23, 0x00,
|
||||
0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x14, 0x00, 0x80, 0x52, 0x13, 0x00, 0x80, 0xd2, 0xb8, 0x03, 0x5a, 0xf8, 0x35,
|
||||
0x83, 0x00, 0x91, 0x37, 0x00, 0x80, 0x52, 0x28, 0x13, 0x40, 0xb9, 0x9f, 0x02, 0x08, 0x6b, 0x60, 0x0c, 0x00, 0x54,
|
||||
0xa8, 0x02, 0x40, 0xb9, 0x09, 0xfd, 0x9f, 0x52, 0xe9, 0xff, 0xaf, 0x72, 0x09, 0x01, 0x09, 0x0b, 0x3f, 0x2d, 0x00,
|
||||
0x71, 0xe9, 0x22, 0xc9, 0x1a, 0x2a, 0x10, 0x81, 0x52, 0x29, 0x01, 0x0a, 0x0a, 0x24, 0x99, 0x40, 0x7a, 0x04, 0x09,
|
||||
0x4c, 0x7a, 0x01, 0x01, 0x00, 0x54, 0xa8, 0x0a, 0x40, 0xb9, 0xa0, 0x02, 0x08, 0x8b, 0x48, 0x37, 0x40, 0xf9, 0x21,
|
||||
0x01, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x00, 0x7b, 0x33, 0xf8, 0x73, 0x06, 0x00, 0x91, 0xa8, 0x06, 0x40, 0xb9,
|
||||
0xb5, 0x02, 0x08, 0x8b, 0x94, 0x06, 0x00, 0x11, 0xe8, 0xff, 0xff, 0x17, 0xa1, 0x83, 0x01, 0xd1, 0xe0, 0x03, 0x16,
|
||||
0xaa, 0x02, 0x01, 0x80, 0x52, 0x8c, 0x01, 0x00, 0x94, 0x40, 0x21, 0x00, 0x34, 0xa1, 0x83, 0x02, 0xd1, 0xe0, 0x03,
|
||||
0x16, 0xaa, 0x82, 0x00, 0x80, 0x52, 0x87, 0x01, 0x00, 0x94, 0xa0, 0x20, 0x00, 0x34, 0xa1, 0xa3, 0x02, 0xd1, 0xe0,
|
||||
0x03, 0x16, 0xaa, 0x82, 0x00, 0x80, 0x52, 0x82, 0x01, 0x00, 0x94, 0x00, 0x20, 0x00, 0x36, 0x48, 0x3f, 0x40, 0xf9,
|
||||
0xa0, 0x03, 0x5a, 0xf8, 0xa1, 0x03, 0x56, 0xb8, 0xa2, 0x83, 0x55, 0xb8, 0x00, 0x01, 0x3f, 0xd6, 0xe0, 0xe6, 0xff,
|
||||
0x34, 0xf9, 0x00, 0x00, 0x14, 0xa1, 0x83, 0x01, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x02, 0x01, 0x80, 0x52, 0x76, 0x01,
|
||||
0x00, 0x94, 0x80, 0x1e, 0x00, 0x34, 0xa1, 0xc3, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x82, 0x00, 0x80, 0x52, 0x71,
|
||||
0x01, 0x00, 0x94, 0xe0, 0x1d, 0x00, 0x34, 0x13, 0x00, 0x80, 0x52, 0xb4, 0x03, 0x5a, 0xf8, 0xa8, 0x03, 0x55, 0xb8,
|
||||
0x7f, 0x02, 0x08, 0x6b, 0xe0, 0xe4, 0xff, 0x54, 0xbf, 0xff, 0x35, 0xa9, 0x88, 0x5a, 0x73, 0xf8, 0xa1, 0x83, 0x02,
|
||||
0xd1, 0xa2, 0xa3, 0x02, 0xd1, 0x77, 0x01, 0x00, 0x94, 0x73, 0x06, 0x00, 0x11, 0xf7, 0xff, 0xff, 0x17, 0xa1, 0x83,
|
||||
0x01, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x02, 0x01, 0x80, 0x52, 0x60, 0x01, 0x00, 0x94, 0xc0, 0x1b, 0x00, 0x34, 0xa1,
|
||||
0xd3, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x82, 0x00, 0x80, 0x52, 0x5b, 0x01, 0x00, 0x94, 0x20, 0x1b, 0x00, 0x34,
|
||||
0xa1, 0x83, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0x02, 0x01, 0x80, 0x52, 0x56, 0x01, 0x00, 0x94, 0x80, 0x1a, 0x00,
|
||||
0x34, 0x13, 0x00, 0x80, 0x52, 0xb4, 0x03, 0x5a, 0xf8, 0xa8, 0xc3, 0x54, 0xb8, 0x7f, 0x02, 0x08, 0x6b, 0x80, 0xe1,
|
||||
0xff, 0x54, 0xbf, 0x7f, 0x35, 0xa9, 0xa8, 0x03, 0x56, 0xf8, 0x89, 0x5a, 0x73, 0xb8, 0x08, 0x01, 0x09, 0x8b, 0xa1,
|
||||
0xa3, 0x02, 0xd1, 0xa2, 0xc3, 0x02, 0xd1, 0x5a, 0x01, 0x00, 0x94, 0x73, 0x06, 0x00, 0x11, 0xf5, 0xff, 0xff, 0x17,
|
||||
0x53, 0x01, 0x00, 0x94, 0x20, 0xe0, 0x07, 0x37, 0xc3, 0x00, 0x00, 0x14, 0x1a, 0x0f, 0x13, 0x8b, 0x88, 0xdf, 0x41,
|
||||
0x29, 0x95, 0x03, 0x08, 0x8b, 0x88, 0x17, 0x40, 0xb9, 0x1f, 0x0d, 0x00, 0x71, 0xc0, 0x12, 0x00, 0x54, 0x1f, 0x09,
|
||||
0x00, 0x71, 0xe0, 0x14, 0x00, 0x54, 0x1f, 0x05, 0x00, 0x71, 0x21, 0x02, 0x00, 0x54, 0x88, 0x0b, 0x40, 0xb9, 0x93,
|
||||
0x03, 0x08, 0x8b, 0xf4, 0x03, 0x1a, 0xaa, 0xb7, 0x01, 0x00, 0xb4, 0x69, 0x02, 0x40, 0xb9, 0x28, 0x1d, 0x00, 0x72,
|
||||
0xa0, 0x00, 0x00, 0x54, 0xa9, 0x26, 0x49, 0x8b, 0x34, 0x01, 0x00, 0x94, 0xe0, 0x43, 0xc1, 0xda, 0x02, 0x00, 0x00,
|
||||
0x14, 0x00, 0x00, 0x80, 0xd2, 0x80, 0x86, 0x00, 0xf8, 0x73, 0x12, 0x00, 0x91, 0xf7, 0x06, 0x00, 0xd1, 0xb7, 0xfe,
|
||||
0xff, 0xb5, 0x09, 0x00, 0x80, 0xd2, 0x88, 0x07, 0x40, 0xb9, 0x88, 0x03, 0x08, 0x8b, 0xa8, 0x03, 0x10, 0xf8, 0x0a,
|
||||
0x45, 0x40, 0xb8, 0xaa, 0x03, 0x12, 0xf8, 0xa8, 0x03, 0x11, 0xf8, 0xa8, 0x03, 0x52, 0xf8, 0x3f, 0x01, 0x08, 0xeb,
|
||||
0xc0, 0x0c, 0x00, 0x54, 0xa9, 0x83, 0x12, 0xf8, 0xa8, 0x03, 0x51, 0xf8, 0x08, 0x79, 0x69, 0xb8, 0xc8, 0x0b, 0x00,
|
||||
0x34, 0x15, 0x00, 0x80, 0xd2, 0xa9, 0x03, 0x50, 0xf8, 0x3b, 0x01, 0x08, 0x8b, 0x68, 0x0f, 0x40, 0x79, 0x6a, 0x2b,
|
||||
0x40, 0x79, 0x69, 0x5b, 0x00, 0x91, 0xa9, 0xab, 0x33, 0xa9, 0x09, 0x79, 0x1d, 0x12, 0xa9, 0x43, 0x13, 0xb8, 0x1f,
|
||||
0x31, 0x00, 0x71, 0xe9, 0xff, 0x9f, 0x52, 0x0a, 0xe0, 0xbf, 0x12, 0x54, 0x01, 0x89, 0x9a, 0x1f, 0x05, 0x00, 0x71,
|
||||
0xaa, 0x83, 0x50, 0xf8, 0x49, 0x01, 0x9f, 0x9a, 0x3c, 0x03, 0x09, 0xcb, 0x1f, 0x19, 0x00, 0x71, 0xe8, 0x03, 0x8a,
|
||||
0x9a, 0x37, 0x03, 0x08, 0xcb, 0xa8, 0x03, 0x54, 0xf8, 0xbf, 0x02, 0x08, 0xeb, 0xe0, 0x08, 0x00, 0x54, 0xa8, 0x83,
|
||||
0x53, 0xf8, 0x08, 0x79, 0x75, 0x78, 0xe9, 0xff, 0x9f, 0x52, 0x1f, 0x01, 0x09, 0xeb, 0x00, 0x08, 0x00, 0x54, 0x69,
|
||||
0x07, 0x40, 0xf9, 0x29, 0x03, 0x09, 0x8b, 0x6a, 0x0b, 0x40, 0x79, 0xa9, 0x26, 0x0a, 0x9b, 0x38, 0x01, 0x08, 0x8b,
|
||||
0xa8, 0x43, 0x53, 0xb8, 0x1f, 0x09, 0x00, 0x71, 0x41, 0x02, 0x00, 0x54, 0x08, 0x03, 0x40, 0xf9, 0xe8, 0x00, 0xf8,
|
||||
0xb7, 0x09, 0xad, 0x6c, 0xd3, 0x29, 0x1d, 0x48, 0x92, 0x0a, 0x8d, 0x40, 0x92, 0xea, 0x02, 0x0a, 0x8b, 0x49, 0x01,
|
||||
0x09, 0x8b, 0x05, 0x00, 0x00, 0x14, 0x09, 0x5d, 0x40, 0x92, 0x49, 0x7b, 0x69, 0xf8, 0x0a, 0xfd, 0x58, 0xd3, 0x29,
|
||||
0x01, 0x2a, 0x8b, 0x09, 0x03, 0x00, 0xf9, 0x08, 0xf9, 0x73, 0xd3, 0x18, 0x0b, 0x08, 0x8b, 0x28, 0xfe, 0xff, 0xb5,
|
||||
0x27, 0x00, 0x00, 0x14, 0x13, 0x03, 0x40, 0xf9, 0x70, 0xfe, 0x7e, 0xd3, 0x62, 0xbe, 0x60, 0xd3, 0x63, 0xc2, 0x70,
|
||||
0xd3, 0x61, 0xca, 0x71, 0xd3, 0x1f, 0x0e, 0x00, 0xf1, 0x10, 0x92, 0x9f, 0x9a, 0x51, 0x0e, 0x00, 0x10, 0x1f, 0x20,
|
||||
0x03, 0xd5, 0x30, 0x7a, 0xb0, 0xb8, 0x11, 0x00, 0x00, 0x10, 0x30, 0x02, 0x10, 0x8b, 0x00, 0x02, 0x1f, 0xd6, 0x68,
|
||||
0xca, 0x73, 0xd3, 0x08, 0x1d, 0x48, 0x92, 0x69, 0xaa, 0x40, 0x92, 0x89, 0x03, 0x09, 0x8b, 0x20, 0x01, 0x08, 0x8b,
|
||||
0x10, 0x00, 0x00, 0x14, 0x68, 0x02, 0x14, 0x8a, 0x48, 0x7b, 0x68, 0xf8, 0x69, 0xca, 0x60, 0xd3, 0x3f, 0x01, 0x41,
|
||||
0xf1, 0xe9, 0xb3, 0x6d, 0xb2, 0xe9, 0x33, 0x89, 0x9a, 0x69, 0xca, 0x60, 0xb3, 0x00, 0x01, 0x09, 0x8b, 0x07, 0x00,
|
||||
0x00, 0x14, 0x20, 0x43, 0x33, 0x8b, 0x03, 0x00, 0x00, 0x14, 0x68, 0x02, 0x14, 0x8a, 0x40, 0x7b, 0x68, 0xf8, 0xe4,
|
||||
0x03, 0x18, 0xaa, 0xab, 0x00, 0x00, 0x94, 0x00, 0x03, 0x00, 0xf9, 0x68, 0xf6, 0x73, 0xd3, 0x18, 0x0f, 0x08, 0x8b,
|
||||
0x68, 0xfb, 0xff, 0xb5, 0xb5, 0x06, 0x00, 0x91, 0xb8, 0xff, 0xff, 0x17, 0xa9, 0x83, 0x52, 0xf8, 0x29, 0x05, 0x00,
|
||||
0x91, 0xbb, 0x83, 0x51, 0xf8, 0x99, 0xff, 0xff, 0x17, 0xa8, 0x23, 0x00, 0xd1, 0x1a, 0x01, 0x50, 0xf8, 0x48, 0x33,
|
||||
0x40, 0xf9, 0xa1, 0x03, 0x5a, 0xf8, 0xa9, 0x43, 0x00, 0xd1, 0x20, 0x01, 0x50, 0xb8, 0x22, 0x00, 0xa0, 0x52, 0x00,
|
||||
0x01, 0x3f, 0xd6, 0xa8, 0x33, 0x00, 0xd1, 0x19, 0x01, 0x50, 0xb8, 0x6c, 0xfe, 0xff, 0x17, 0xbf, 0x02, 0x00, 0x91,
|
||||
0xa8, 0x23, 0x00, 0xd1, 0x1a, 0x01, 0x50, 0xf8, 0xa8, 0x33, 0x00, 0xd1, 0x19, 0x01, 0x50, 0xb8, 0xbb, 0x83, 0x51,
|
||||
0xf8, 0x65, 0xfe, 0xff, 0x17, 0xe8, 0x03, 0x1c, 0xaa, 0x09, 0x8d, 0x40, 0xb8, 0x13, 0x01, 0x09, 0x8b, 0xf4, 0x03,
|
||||
0x1a, 0xaa, 0x77, 0xef, 0xff, 0xb4, 0x69, 0x82, 0x5f, 0xf8, 0x28, 0x3d, 0x00, 0x72, 0xa0, 0x00, 0x00, 0x54, 0xa9,
|
||||
0x82, 0x49, 0x8b, 0xa2, 0x00, 0x00, 0x94, 0xe0, 0x43, 0xc1, 0xda, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0xd2,
|
||||
0x68, 0x06, 0x41, 0xf8, 0x08, 0x00, 0x08, 0x8b, 0x88, 0x86, 0x00, 0xf8, 0xf7, 0x06, 0x00, 0xd1, 0x97, 0xfe, 0xff,
|
||||
0xb5, 0x6d, 0xff, 0xff, 0x17, 0x88, 0x0b, 0x40, 0xb9, 0x88, 0x03, 0x08, 0x8b, 0x13, 0x11, 0x00, 0x91, 0xf4, 0x03,
|
||||
0x1a, 0xaa, 0x17, 0xed, 0xff, 0xb4, 0x69, 0xc2, 0x5f, 0xb8, 0x28, 0x1d, 0x00, 0x72, 0xa0, 0x00, 0x00, 0x54, 0xa9,
|
||||
0x26, 0x49, 0x8b, 0x8f, 0x00, 0x00, 0x94, 0xe0, 0x43, 0xc1, 0xda, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0xd2,
|
||||
0x68, 0x86, 0x80, 0xb8, 0x08, 0x00, 0x08, 0x8b, 0x88, 0x86, 0x00, 0xf8, 0xf7, 0x06, 0x00, 0xd1, 0x97, 0xfe, 0xff,
|
||||
0xb5, 0x5a, 0xff, 0xff, 0x17, 0xbf, 0x02, 0x00, 0x91, 0x99, 0x00, 0x00, 0x94, 0x48, 0x43, 0x40, 0xf9, 0xe0, 0x03,
|
||||
0x19, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0xa0, 0xc3, 0x99, 0xb8, 0xbf, 0x43, 0x01, 0xd1, 0xfd, 0x7b, 0x45, 0xa9, 0xf4,
|
||||
0x4f, 0x44, 0xa9, 0xf6, 0x57, 0x43, 0xa9, 0xf8, 0x5f, 0x42, 0xa9, 0xfa, 0x67, 0x41, 0xa9, 0xfc, 0x6f, 0xc6, 0xa8,
|
||||
0xc0, 0x03, 0x5f, 0xd6, 0x0c, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0xb4, 0x01, 0x00, 0x00, 0x9c, 0x02, 0x00,
|
||||
0x00, 0xf4, 0x02, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x24, 0x00,
|
||||
0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xf8, 0x5f, 0xbc, 0xa9, 0xf6, 0x57, 0x01, 0xa9, 0xf4,
|
||||
0x4f, 0x02, 0xa9, 0xfd, 0x7b, 0x03, 0xa9, 0xfd, 0xc3, 0x00, 0x91, 0xf3, 0x03, 0x04, 0xaa, 0xf4, 0x03, 0x03, 0xaa,
|
||||
0xf5, 0x03, 0x02, 0xaa, 0xf6, 0x03, 0x01, 0xaa, 0xf7, 0x03, 0x00, 0xaa, 0x43, 0x00, 0x00, 0xb4, 0x9f, 0x02, 0x00,
|
||||
0xf9, 0xbf, 0x02, 0x00, 0xf1, 0xf8, 0x17, 0x9f, 0x1a, 0xd5, 0x03, 0x00, 0xb4, 0x68, 0x1a, 0x40, 0xf9, 0xe0, 0x03,
|
||||
0x17, 0xaa, 0xe1, 0x03, 0x16, 0xaa, 0xe2, 0x03, 0x15, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0xb1, 0xe1,
|
||||
0x00, 0x00, 0x54, 0x68, 0x46, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0x08, 0x00, 0x40, 0xb9, 0x1f, 0x11, 0x00, 0x71,
|
||||
0xa0, 0xfe, 0xff, 0x54, 0x0a, 0x00, 0x00, 0x14, 0x1f, 0x04, 0x00, 0xf1, 0x2b, 0x01, 0x00, 0x54, 0x94, 0x00, 0x00,
|
||||
0xb4, 0x88, 0x02, 0x40, 0xf9, 0x08, 0x01, 0x00, 0x8b, 0x88, 0x02, 0x00, 0xf9, 0xd6, 0x02, 0x00, 0x8b, 0xb5, 0x02,
|
||||
0x00, 0xcb, 0xe8, 0xff, 0xff, 0x17, 0x18, 0x00, 0x80, 0x52, 0xe0, 0x03, 0x18, 0xaa, 0xfd, 0x7b, 0x43, 0xa9, 0xf4,
|
||||
0x4f, 0x42, 0xa9, 0xf6, 0x57, 0x41, 0xa9, 0xf8, 0x5f, 0xc4, 0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0x38, 0x00, 0x80, 0x52,
|
||||
0xf9, 0xff, 0xff, 0x17, 0xf6, 0x57, 0xbd, 0xa9, 0xf4, 0x4f, 0x01, 0xa9, 0xfd, 0x7b, 0x02, 0xa9, 0xfd, 0x83, 0x00,
|
||||
0x91, 0xf3, 0x03, 0x02, 0xaa, 0xf4, 0x03, 0x01, 0xaa, 0xf5, 0x03, 0x00, 0xaa, 0x88, 0x00, 0x80, 0x52, 0xf6, 0x03,
|
||||
0x08, 0xaa, 0x48, 0x02, 0x00, 0xb4, 0x68, 0x1e, 0x40, 0xf9, 0xe0, 0x03, 0x15, 0xaa, 0xe1, 0x03, 0x14, 0xaa, 0xe2,
|
||||
0x03, 0x16, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0xb1, 0xe1, 0x00, 0x00, 0x54, 0x68, 0x46, 0x40, 0xf9,
|
||||
0x00, 0x01, 0x3f, 0xd6, 0x08, 0x00, 0x40, 0xb9, 0x1f, 0x11, 0x00, 0x71, 0xa0, 0xfe, 0xff, 0x54, 0x05, 0x00, 0x00,
|
||||
0x14, 0x94, 0x02, 0x00, 0x8b, 0xc8, 0x02, 0x00, 0xcb, 0x1f, 0x00, 0x00, 0xf1, 0xcc, 0xfd, 0xff, 0x54, 0xdf, 0x02,
|
||||
0x00, 0xf1, 0xe0, 0x17, 0x9f, 0x1a, 0xfd, 0x7b, 0x42, 0xa9, 0xf4, 0x4f, 0x41, 0xa9, 0xf6, 0x57, 0xc3, 0xa8, 0xc0,
|
||||
0x03, 0x5f, 0xd6, 0x44, 0x3c, 0x50, 0xb3, 0x7f, 0x00, 0x00, 0x71, 0x48, 0x00, 0x84, 0x9a, 0x3f, 0x0c, 0x00, 0x71,
|
||||
0x28, 0x02, 0x00, 0x54, 0xf0, 0x03, 0x01, 0x2a, 0x1f, 0x0e, 0x00, 0xf1, 0x10, 0x92, 0x9f, 0x9a, 0xd1, 0x01, 0x00,
|
||||
0x10, 0x1f, 0x20, 0x03, 0xd5, 0x30, 0x7a, 0xb0, 0xb8, 0x11, 0x00, 0x00, 0x10, 0x30, 0x02, 0x10, 0x8b, 0x00, 0x02,
|
||||
0x1f, 0xd6, 0x00, 0x01, 0xc1, 0xda, 0xc0, 0x03, 0x5f, 0xd6, 0x00, 0x05, 0xc1, 0xda, 0xc0, 0x03, 0x5f, 0xd6, 0x00,
|
||||
0x09, 0xc1, 0xda, 0xc0, 0x03, 0x5f, 0xd6, 0x00, 0x0d, 0xc1, 0xda, 0xc0, 0x03, 0x5f, 0xd6, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x14, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0xd2, 0xe4, 0x03, 0x1a,
|
||||
0xaa, 0x95, 0xff, 0xff, 0x17, 0xea, 0x03, 0x09, 0xaa, 0x4b, 0x15, 0x40, 0x38, 0x7f, 0x7d, 0x01, 0x71, 0x21, 0x11,
|
||||
0x8a, 0x9a, 0xa9, 0x23, 0x00, 0xd1, 0x29, 0x01, 0x50, 0xf8, 0x29, 0x39, 0x40, 0xf9, 0x08, 0x05, 0x00, 0x51, 0x00,
|
||||
0x5b, 0x68, 0xf8, 0x20, 0x01, 0x1f, 0xd6, 0xa1, 0x03, 0x02, 0xd1, 0xe0, 0x03, 0x16, 0xaa, 0xe2, 0x03, 0x1a, 0xaa,
|
||||
0xb5, 0xff, 0xff, 0x17, 0xa4, 0x93, 0x01, 0xd1, 0x00, 0x00, 0x80, 0x52, 0xe3, 0x03, 0x1b, 0xaa, 0x00, 0x01, 0x1f,
|
||||
0xd6, 0xa0, 0x03, 0x5a, 0xf8, 0xa1, 0x03, 0x56, 0xf8, 0x00, 0x01, 0x1f, 0xd6, 0x48, 0x43, 0x40, 0xf9, 0xe0, 0x03,
|
||||
0x16, 0xaa, 0x00, 0x01, 0x1f, 0xd6
|
||||
0xa9, 0xfd, 0x7b, 0x05, 0xa9, 0xfd, 0x43, 0x01, 0x91, 0xff, 0x43, 0x03, 0xd1, 0xfb, 0x03, 0x04, 0xaa, 0xf6, 0x03,
|
||||
0x03, 0xaa, 0xf8, 0x03, 0x02, 0xaa, 0xf9, 0x03, 0x01, 0xaa, 0xf5, 0x03, 0x00, 0xaa, 0xbf, 0xc3, 0x19, 0xb8, 0x88,
|
||||
0x95, 0x98, 0x52, 0x48, 0x89, 0xb5, 0x72, 0xa8, 0x43, 0x18, 0xb8, 0x88, 0x34, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6,
|
||||
0xfa, 0x03, 0x00, 0xaa, 0x13, 0x02, 0x80, 0x52, 0xb3, 0x83, 0x18, 0xb8, 0x68, 0x17, 0x40, 0xf9, 0xa1, 0xd3, 0x01,
|
||||
0xd1, 0xa2, 0xe3, 0x01, 0xd1, 0xe0, 0x03, 0x15, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0x31, 0xe1, 0x00,
|
||||
0x00, 0x54, 0x68, 0x4f, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0x08, 0x00, 0x40, 0xb9, 0x1f, 0x11, 0x00, 0x71, 0xa0,
|
||||
0xfe, 0xff, 0x54, 0xf1, 0x01, 0x00, 0x14, 0xf7, 0x03, 0x00, 0xaa, 0xa1, 0x43, 0x02, 0xd1, 0x02, 0x02, 0x80, 0x52,
|
||||
0x79, 0x02, 0x00, 0x94, 0xa8, 0x27, 0x77, 0xa9, 0x1f, 0x00, 0x00, 0x71, 0x00, 0x11, 0x59, 0xfa, 0x20, 0x01, 0x58,
|
||||
0xfa, 0x60, 0x00, 0x00, 0x54, 0x84, 0x02, 0x00, 0x94, 0xe8, 0xff, 0xff, 0x17, 0x7a, 0x02, 0x00, 0x94, 0x60, 0x3c,
|
||||
0x00, 0x34, 0x38, 0x00, 0x80, 0x52, 0xbb, 0x83, 0x11, 0xf8, 0xa8, 0x13, 0x00, 0xd1, 0x15, 0x01, 0x10, 0xb8, 0xa8,
|
||||
0x43, 0x00, 0xd1, 0x16, 0x01, 0x10, 0xf8, 0xa8, 0x53, 0x00, 0xd1, 0x1a, 0x01, 0x10, 0xb8, 0xa1, 0x47, 0x02, 0xd1,
|
||||
0xe0, 0x03, 0x17, 0xaa, 0x22, 0x00, 0x80, 0x52, 0x64, 0x02, 0x00, 0x94, 0xc0, 0x3a, 0x00, 0x34, 0xa8, 0xf3, 0x56,
|
||||
0x38, 0x10, 0x05, 0x00, 0x51, 0x1f, 0x1a, 0x00, 0x71, 0x48, 0x3a, 0x00, 0x54, 0x1f, 0x1a, 0x00, 0xf1, 0x10, 0x92,
|
||||
0x9f, 0x9a, 0x11, 0x00, 0x00, 0x90, 0x31, 0xf2, 0x21, 0x91, 0x30, 0x7a, 0xb0, 0xb8, 0x11, 0x00, 0x00, 0x10, 0x30,
|
||||
0x02, 0x10, 0x8b, 0x00, 0x02, 0x1f, 0xd6, 0xa1, 0x83, 0x01, 0xd1, 0x50, 0x02, 0x00, 0x94, 0xe0, 0x38, 0x00, 0x34,
|
||||
0xa1, 0xe3, 0x02, 0xd1, 0xe0, 0x03, 0x17, 0xaa, 0x82, 0x00, 0x80, 0x52, 0x50, 0x02, 0x00, 0x94, 0x40, 0x38, 0x00,
|
||||
0x34, 0xbf, 0x03, 0x16, 0xf8, 0x68, 0x43, 0x40, 0xf9, 0xa2, 0x83, 0x54, 0xb8, 0xa6, 0x03, 0x5a, 0xf8, 0xff, 0x83,
|
||||
0x00, 0xd1, 0x49, 0x00, 0x80, 0x52, 0xe9, 0x13, 0x00, 0xb9, 0xa1, 0x83, 0x02, 0xd1, 0xa9, 0xa3, 0x02, 0xd1, 0xe9,
|
||||
0x07, 0x00, 0xf9, 0xa9, 0x93, 0x02, 0xd1, 0xe9, 0x03, 0x00, 0xf9, 0xe0, 0x03, 0x1a, 0xaa, 0x03, 0x00, 0x80, 0xd2,
|
||||
0x24, 0x00, 0x80, 0x52, 0xe5, 0x03, 0x1a, 0xaa, 0x07, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0xff, 0x83, 0x00,
|
||||
0x91, 0xc0, 0x35, 0x00, 0x35, 0x68, 0x2b, 0x40, 0xf9, 0xa0, 0x03, 0x56, 0xf8, 0xa1, 0x83, 0x54, 0xb8, 0x62, 0x00,
|
||||
0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x60, 0x2e, 0x00, 0x35, 0xa1, 0x03, 0x56, 0xf8, 0xa2, 0x83, 0x54, 0xb8, 0xa3,
|
||||
0xc3, 0x02, 0xd1, 0xe0, 0x03, 0x17, 0xaa, 0xe4, 0x03, 0x1b, 0xaa, 0xba, 0x01, 0x00, 0x94, 0x80, 0x2d, 0x00, 0x34,
|
||||
0x68, 0x2f, 0x40, 0xf9, 0x40, 0x02, 0x00, 0x94, 0x68, 0x33, 0x40, 0xf9, 0x3e, 0x02, 0x00, 0x94, 0x33, 0x00, 0x80,
|
||||
0x52, 0x67, 0x01, 0x00, 0x14, 0xa1, 0x83, 0x01, 0xd1, 0x21, 0x02, 0x00, 0x94, 0x00, 0x33, 0x00, 0x34, 0xa1, 0xe3,
|
||||
0x02, 0xd1, 0xe0, 0x03, 0x17, 0xaa, 0x82, 0x00, 0x80, 0x52, 0x21, 0x02, 0x00, 0x94, 0x60, 0x32, 0x00, 0x34, 0x13,
|
||||
0x00, 0x80, 0x52, 0xb4, 0x03, 0x5a, 0xf8, 0xa8, 0x83, 0x54, 0xb8, 0x7f, 0x02, 0x08, 0x6b, 0x80, 0xf6, 0xff, 0x54,
|
||||
0xbf, 0x03, 0x16, 0xf8, 0xbf, 0x03, 0x15, 0xf8, 0x88, 0x5a, 0x73, 0xf8, 0xa1, 0x83, 0x02, 0xd1, 0xa2, 0xc3, 0x02,
|
||||
0xd1, 0x22, 0x02, 0x00, 0x94, 0x73, 0x06, 0x00, 0x11, 0xf6, 0xff, 0xff, 0x17, 0xa1, 0x83, 0x02, 0xd1, 0x0c, 0x02,
|
||||
0x00, 0x94, 0x60, 0x30, 0x00, 0x34, 0xa1, 0xc3, 0x02, 0xd1, 0x09, 0x02, 0x00, 0x94, 0x00, 0x30, 0x00, 0x34, 0xa1,
|
||||
0xe3, 0x02, 0xd1, 0x06, 0x02, 0x00, 0x94, 0xa0, 0x2f, 0x00, 0x34, 0xbc, 0x03, 0x56, 0xf8, 0xa8, 0xeb, 0x74, 0xa9,
|
||||
0xa8, 0x83, 0x10, 0xf8, 0x68, 0x37, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0xbf, 0x03, 0x1a, 0xf8, 0x68, 0x3b, 0x40,
|
||||
0xf9, 0xa1, 0x83, 0x01, 0xd1, 0xa9, 0x63, 0x00, 0xd1, 0x20, 0x01, 0x10, 0xb8, 0x22, 0x00, 0xa0, 0x52, 0x23, 0x00,
|
||||
0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x13, 0x00, 0x80, 0x52, 0x15, 0x00, 0x80, 0xd2, 0xb4, 0x03, 0x5a, 0xf8, 0x56,
|
||||
0x83, 0x00, 0x91, 0x48, 0x13, 0x40, 0xb9, 0x7f, 0x02, 0x08, 0x6b, 0xe0, 0x12, 0x00, 0x54, 0xc8, 0x02, 0x40, 0xb9,
|
||||
0x09, 0xfd, 0x9f, 0x52, 0xe9, 0xff, 0xaf, 0x72, 0x09, 0x01, 0x09, 0x0b, 0x3f, 0x2d, 0x00, 0x71, 0x09, 0x23, 0xc9,
|
||||
0x1a, 0x2a, 0x10, 0x81, 0x52, 0x29, 0x01, 0x0a, 0x0a, 0x24, 0x99, 0x40, 0x7a, 0x04, 0x09, 0x4c, 0x7a, 0x01, 0x01,
|
||||
0x00, 0x54, 0xc8, 0x0a, 0x40, 0xb9, 0x69, 0x47, 0x40, 0xf9, 0xc0, 0x02, 0x08, 0x8b, 0x21, 0x01, 0x80, 0x52, 0x20,
|
||||
0x01, 0x3f, 0xd6, 0x80, 0x7a, 0x35, 0xf8, 0xb5, 0x06, 0x00, 0x91, 0xc8, 0x06, 0x40, 0xb9, 0xd6, 0x02, 0x08, 0x8b,
|
||||
0x73, 0x06, 0x00, 0x11, 0xe8, 0xff, 0xff, 0x17, 0xa1, 0x83, 0x01, 0xd1, 0xd9, 0x01, 0x00, 0x94, 0x00, 0x2a, 0x00,
|
||||
0x34, 0xa1, 0x83, 0x02, 0xd1, 0xe0, 0x03, 0x17, 0xaa, 0x82, 0x00, 0x80, 0x52, 0xd9, 0x01, 0x00, 0x94, 0x60, 0x29,
|
||||
0x00, 0x34, 0xa1, 0xc3, 0x02, 0xd1, 0xe0, 0x03, 0x17, 0xaa, 0x82, 0x00, 0x80, 0x52, 0xd4, 0x01, 0x00, 0x94, 0xc0,
|
||||
0x28, 0x00, 0x36, 0x68, 0x2b, 0x40, 0xf9, 0xa0, 0x03, 0x5a, 0xf8, 0xa1, 0x03, 0x56, 0xb8, 0xa2, 0x03, 0x55, 0xb8,
|
||||
0x00, 0x01, 0x3f, 0xd6, 0xc0, 0xec, 0xff, 0x34, 0x3f, 0x01, 0x00, 0x14, 0xa1, 0x83, 0x01, 0xd1, 0xc5, 0x01, 0x00,
|
||||
0x94, 0x80, 0x27, 0x00, 0x34, 0xa1, 0x83, 0x02, 0xd1, 0xc2, 0x01, 0x00, 0x94, 0x20, 0x27, 0x00, 0x34, 0xa1, 0xc3,
|
||||
0x02, 0xd1, 0xe0, 0x03, 0x17, 0xaa, 0x42, 0x00, 0x80, 0x52, 0xc2, 0x01, 0x00, 0x94, 0x80, 0x26, 0x00, 0x34, 0xf4,
|
||||
0x03, 0x00, 0x91, 0xa8, 0x03, 0x55, 0x78, 0x08, 0x71, 0x1d, 0x53, 0x08, 0x3d, 0x00, 0x11, 0x08, 0x3d, 0x7c, 0x92,
|
||||
0xe9, 0x03, 0x00, 0x91, 0x38, 0x01, 0x08, 0xcb, 0x1f, 0x03, 0x00, 0x91, 0xa8, 0x03, 0x55, 0x78, 0x02, 0xf1, 0x7d,
|
||||
0xd3, 0xe0, 0x03, 0x17, 0xaa, 0xe1, 0x03, 0x18, 0xaa, 0xb4, 0x01, 0x00, 0x94, 0xa0, 0x24, 0x00, 0x34, 0xa1, 0xe3,
|
||||
0x02, 0xd1, 0xe0, 0x03, 0x17, 0xaa, 0x42, 0x00, 0x80, 0x52, 0xaf, 0x01, 0x00, 0x94, 0x00, 0x24, 0x00, 0x34, 0xa8,
|
||||
0x83, 0x54, 0x78, 0x09, 0x71, 0x1d, 0x53, 0x29, 0x3d, 0x00, 0x11, 0x29, 0x3d, 0x7c, 0x92, 0xea, 0x03, 0x00, 0x91,
|
||||
0x59, 0x01, 0x09, 0xcb, 0x3f, 0x03, 0x00, 0x91, 0x02, 0x7d, 0x7d, 0xd3, 0xe0, 0x03, 0x17, 0xaa, 0xe1, 0x03, 0x19,
|
||||
0xaa, 0xa3, 0x01, 0x00, 0x94, 0x80, 0x22, 0x00, 0x34, 0x15, 0x00, 0x80, 0xd2, 0xb6, 0x03, 0x5a, 0xf8, 0xbb, 0x03,
|
||||
0x56, 0xf8, 0xbc, 0x83, 0x54, 0x78, 0xbf, 0x02, 0x1c, 0xeb, 0x00, 0x1a, 0x00, 0x54, 0x3a, 0x7b, 0x75, 0xf8, 0x53,
|
||||
0x03, 0x40, 0xf9, 0xf3, 0x01, 0xf0, 0xb7, 0x68, 0xfe, 0x6b, 0xd3, 0x69, 0xaa, 0x40, 0x92, 0x6a, 0xaa, 0x6a, 0x93,
|
||||
0x4a, 0x31, 0x55, 0x92, 0x09, 0x1d, 0x48, 0xb3, 0x28, 0x01, 0x0a, 0xaa, 0xe9, 0x03, 0x13, 0x2a, 0x7f, 0x02, 0x41,
|
||||
0xf2, 0xea, 0x03, 0x96, 0x9a, 0x08, 0x01, 0x89, 0x9a, 0x49, 0x01, 0x1b, 0x8b, 0x20, 0x01, 0x08, 0x8b, 0x53, 0x01,
|
||||
0xf8, 0xb6, 0x04, 0x00, 0x00, 0x14, 0x68, 0x3e, 0x40, 0x92, 0x00, 0x7b, 0x68, 0xf8, 0xd3, 0x00, 0xf8, 0xb6, 0x61,
|
||||
0xca, 0x71, 0xd3, 0x63, 0xc2, 0x70, 0xd3, 0x62, 0xbe, 0x60, 0xd3, 0xe4, 0x03, 0x1a, 0xaa, 0x5d, 0x01, 0x00, 0x94,
|
||||
0x40, 0x03, 0x00, 0xf9, 0x68, 0xf6, 0x73, 0xd3, 0x5a, 0x0f, 0x08, 0x8b, 0x7f, 0x2a, 0x4d, 0xf2, 0x81, 0xfc, 0xff,
|
||||
0x54, 0xb5, 0x06, 0x00, 0x91, 0xdf, 0xff, 0xff, 0x17, 0xa1, 0x83, 0x01, 0xd1, 0x75, 0x01, 0x00, 0x94, 0x80, 0x1d,
|
||||
0x00, 0x34, 0xa1, 0x93, 0x02, 0xd1, 0xe0, 0x03, 0x17, 0xaa, 0x82, 0x00, 0x80, 0x52, 0x75, 0x01, 0x00, 0x94, 0xe0,
|
||||
0x1c, 0x00, 0x34, 0xa1, 0x83, 0x02, 0xd1, 0x6d, 0x01, 0x00, 0x94, 0x80, 0x1c, 0x00, 0x34, 0x13, 0x00, 0x80, 0x52,
|
||||
0xb4, 0x03, 0x5a, 0xf8, 0xa8, 0xc3, 0x55, 0xb8, 0x7f, 0x02, 0x08, 0x6b, 0xa0, 0xe0, 0xff, 0x54, 0xbf, 0xff, 0x34,
|
||||
0xa9, 0xa8, 0x03, 0x56, 0xf8, 0x89, 0x5a, 0x73, 0xb8, 0x08, 0x01, 0x09, 0x8b, 0xa1, 0xc3, 0x02, 0xd1, 0xa2, 0xe3,
|
||||
0x02, 0xd1, 0x72, 0x01, 0x00, 0x94, 0x73, 0x06, 0x00, 0x11, 0xf5, 0xff, 0xff, 0x17, 0x6b, 0x01, 0x00, 0x94, 0x40,
|
||||
0xdf, 0x07, 0x37, 0xd3, 0x00, 0x00, 0x14, 0x98, 0x0e, 0x15, 0x8b, 0x88, 0xe7, 0x41, 0x29, 0x96, 0x03, 0x08, 0x8b,
|
||||
0x88, 0x17, 0x40, 0xb9, 0x1f, 0x0d, 0x00, 0x71, 0xc0, 0x16, 0x00, 0x54, 0x1f, 0x09, 0x00, 0x71, 0xc0, 0x13, 0x00,
|
||||
0x54, 0x1f, 0x05, 0x00, 0x71, 0x81, 0x02, 0x00, 0x54, 0x88, 0x0b, 0x40, 0xb9, 0x93, 0x03, 0x08, 0x8b, 0x94, 0x22,
|
||||
0x00, 0xd1, 0xf5, 0x03, 0x18, 0xaa, 0xf9, 0x01, 0x00, 0xb4, 0x69, 0x02, 0x40, 0xb9, 0x28, 0x1d, 0x40, 0x92, 0xe8,
|
||||
0x00, 0x00, 0x34, 0xc9, 0x26, 0x49, 0x8b, 0x4f, 0x01, 0x00, 0x94, 0x80, 0x7a, 0x68, 0xf8, 0x20, 0x01, 0x3f, 0xd6,
|
||||
0xe0, 0x43, 0xc1, 0xda, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0xd2, 0xa0, 0x86, 0x00, 0xf8, 0x73, 0x12, 0x00,
|
||||
0x91, 0x39, 0x07, 0x00, 0xd1, 0x79, 0xfe, 0xff, 0xb5, 0x09, 0x00, 0x80, 0xd2, 0x88, 0x07, 0x40, 0xb9, 0x88, 0x03,
|
||||
0x08, 0x8b, 0xa8, 0x03, 0x10, 0xf8, 0x0a, 0x45, 0x40, 0xb8, 0xaa, 0x03, 0x12, 0xf8, 0xa8, 0x03, 0x11, 0xf8, 0xa8,
|
||||
0x03, 0x52, 0xf8, 0x3f, 0x01, 0x08, 0xeb, 0xc0, 0x0c, 0x00, 0x54, 0xa9, 0x83, 0x12, 0xf8, 0xa8, 0x03, 0x51, 0xf8,
|
||||
0x08, 0x79, 0x69, 0xb8, 0xc8, 0x0b, 0x00, 0x34, 0x1c, 0x00, 0x80, 0xd2, 0xa9, 0x03, 0x50, 0xf8, 0x35, 0x01, 0x08,
|
||||
0x8b, 0xa8, 0x0e, 0x40, 0x79, 0xa9, 0x2a, 0x40, 0x79, 0xa9, 0x03, 0x14, 0xf8, 0xa9, 0x5a, 0x00, 0x91, 0xa9, 0x83,
|
||||
0x13, 0xf8, 0x09, 0x79, 0x1d, 0x12, 0xa9, 0x43, 0x13, 0xb8, 0x1f, 0x31, 0x00, 0x71, 0xe9, 0xff, 0x9f, 0x52, 0x0a,
|
||||
0xe0, 0xbf, 0x12, 0x54, 0x01, 0x89, 0x9a, 0x1f, 0x05, 0x00, 0x71, 0xaa, 0x83, 0x50, 0xf8, 0x49, 0x01, 0x9f, 0x9a,
|
||||
0x56, 0x03, 0x09, 0xcb, 0x1f, 0x19, 0x00, 0x71, 0xe8, 0x03, 0x8a, 0x9a, 0x5b, 0x03, 0x08, 0xcb, 0xa8, 0x03, 0x54,
|
||||
0xf8, 0x9f, 0x03, 0x08, 0xeb, 0xc0, 0x08, 0x00, 0x54, 0xa8, 0x83, 0x53, 0xf8, 0x08, 0x79, 0x7c, 0x78, 0xe9, 0xff,
|
||||
0x9f, 0x52, 0x1f, 0x01, 0x09, 0xeb, 0xe0, 0x07, 0x00, 0x54, 0xa9, 0x06, 0x40, 0xf9, 0x49, 0x03, 0x09, 0x8b, 0xaa,
|
||||
0x0a, 0x40, 0x79, 0x89, 0x27, 0x0a, 0x9b, 0x39, 0x01, 0x08, 0x8b, 0xa8, 0x43, 0x53, 0xb8, 0x1f, 0x09, 0x00, 0x71,
|
||||
0x41, 0x02, 0x00, 0x54, 0x29, 0x03, 0x40, 0xf9, 0xe9, 0x00, 0xf8, 0xb7, 0x28, 0xfd, 0x73, 0xd3, 0x2a, 0xfd, 0x64,
|
||||
0xd3, 0x29, 0x8d, 0x40, 0x92, 0x69, 0x03, 0x09, 0x8b, 0x29, 0xe1, 0x0a, 0x8b, 0x06, 0x00, 0x00, 0x14, 0x28, 0xf9,
|
||||
0x73, 0xd3, 0x2a, 0x5d, 0x40, 0x92, 0x0a, 0x7b, 0x6a, 0xf8, 0x29, 0xfd, 0x58, 0xd3, 0x49, 0x01, 0x29, 0x8b, 0x29,
|
||||
0x03, 0x00, 0xf9, 0x39, 0x0b, 0x08, 0x8b, 0x28, 0xfe, 0xff, 0xb5, 0x26, 0x00, 0x00, 0x14, 0x33, 0x03, 0x40, 0xf9,
|
||||
0x70, 0xfe, 0x7e, 0xd3, 0x62, 0xbe, 0x60, 0xd3, 0x63, 0xc2, 0x70, 0xd3, 0x61, 0xca, 0x71, 0xd3, 0x1f, 0x0e, 0x00,
|
||||
0xf1, 0x10, 0x92, 0x9f, 0x9a, 0x11, 0x00, 0x00, 0x90, 0x31, 0x62, 0x22, 0x91, 0x30, 0x7a, 0xb0, 0xb8, 0x11, 0x00,
|
||||
0x00, 0x10, 0x30, 0x02, 0x10, 0x8b, 0x00, 0x02, 0x1f, 0xd6, 0x68, 0xfe, 0x6b, 0xd3, 0x69, 0xaa, 0x40, 0x92, 0xc9,
|
||||
0x02, 0x09, 0x8b, 0x20, 0xe1, 0x08, 0x8b, 0x10, 0x00, 0x00, 0x14, 0x40, 0x43, 0x33, 0x8b, 0x03, 0x00, 0x00, 0x14,
|
||||
0x68, 0x02, 0x14, 0x8a, 0x00, 0x7b, 0x68, 0xf8, 0xe4, 0x03, 0x19, 0xaa, 0xc1, 0x00, 0x00, 0x94, 0x09, 0x00, 0x00,
|
||||
0x14, 0x68, 0x02, 0x14, 0x8a, 0x08, 0x7b, 0x68, 0xf8, 0x89, 0x00, 0xa0, 0x52, 0x3f, 0x81, 0x53, 0xea, 0xe9, 0xb3,
|
||||
0x6d, 0xb2, 0xe9, 0x03, 0x89, 0x9a, 0x69, 0xca, 0x60, 0xb3, 0x00, 0x01, 0x09, 0x8b, 0x20, 0x03, 0x00, 0xf9, 0x68,
|
||||
0xf6, 0x73, 0xd3, 0x39, 0x0f, 0x08, 0x8b, 0x88, 0xfb, 0xff, 0xb5, 0x9c, 0x07, 0x00, 0x91, 0xb9, 0xff, 0xff, 0x17,
|
||||
0xa9, 0x83, 0x52, 0xf8, 0x29, 0x05, 0x00, 0x91, 0xbb, 0x83, 0x51, 0xf8, 0x99, 0xff, 0xff, 0x17, 0x68, 0x3f, 0x40,
|
||||
0xf9, 0xa1, 0x03, 0x5a, 0xf8, 0xa9, 0x63, 0x00, 0xd1, 0x20, 0x01, 0x50, 0xb8, 0x22, 0x00, 0xa0, 0x52, 0x00, 0x01,
|
||||
0x3f, 0xd6, 0x03, 0x00, 0x00, 0x14, 0x9f, 0x02, 0x00, 0x91, 0xbb, 0x83, 0x51, 0xf8, 0xa8, 0x13, 0x00, 0xd1, 0x15,
|
||||
0x01, 0x50, 0xb8, 0xa8, 0x43, 0x00, 0xd1, 0x16, 0x01, 0x50, 0xf8, 0xa8, 0x53, 0x00, 0xd1, 0x1a, 0x01, 0x50, 0xb8,
|
||||
0x38, 0x00, 0x80, 0x52, 0x5c, 0xfe, 0xff, 0x17, 0x13, 0x00, 0x80, 0x52, 0x68, 0x3f, 0x40, 0xf9, 0xa1, 0x03, 0x56,
|
||||
0xf8, 0xa2, 0x83, 0x54, 0xb8, 0xe0, 0x03, 0x1a, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0xb3, 0xca, 0x07, 0x37, 0x2e, 0x00,
|
||||
0x00, 0x14, 0x88, 0x0b, 0x40, 0xb9, 0x93, 0x22, 0x00, 0xd1, 0x88, 0x03, 0x08, 0x8b, 0x14, 0x11, 0x00, 0x91, 0xf5,
|
||||
0x03, 0x18, 0xaa, 0x79, 0xee, 0xff, 0xb4, 0x89, 0xc2, 0x5f, 0xb8, 0x28, 0x1d, 0x40, 0x92, 0xe8, 0x00, 0x00, 0x34,
|
||||
0xc9, 0x26, 0x49, 0x8b, 0xb3, 0x00, 0x00, 0x94, 0x60, 0x7a, 0x68, 0xf8, 0x20, 0x01, 0x3f, 0xd6, 0xe0, 0x43, 0xc1,
|
||||
0xda, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0xd2, 0x88, 0x86, 0x80, 0xb8, 0x08, 0x00, 0x08, 0x8b, 0xa8, 0x86,
|
||||
0x00, 0xf8, 0x39, 0x07, 0x00, 0xd1, 0x59, 0xfe, 0xff, 0xb5, 0x63, 0xff, 0xff, 0x17, 0xe8, 0x03, 0x1c, 0xaa, 0x09,
|
||||
0x8d, 0x40, 0xb8, 0x93, 0x22, 0x00, 0xd1, 0x14, 0x01, 0x09, 0x8b, 0xf5, 0x03, 0x18, 0xaa, 0xb9, 0xeb, 0xff, 0xb4,
|
||||
0x89, 0x82, 0x5f, 0xf8, 0x28, 0x3d, 0x40, 0xf2, 0xe0, 0x00, 0x00, 0x54, 0xc9, 0x82, 0x49, 0x8b, 0x9d, 0x00, 0x00,
|
||||
0x94, 0x60, 0x7a, 0x68, 0xf8, 0x20, 0x01, 0x3f, 0xd6, 0xe0, 0x43, 0xc1, 0xda, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00,
|
||||
0x80, 0xd2, 0x88, 0x06, 0x41, 0xf8, 0x08, 0x00, 0x08, 0x8b, 0xa8, 0x86, 0x00, 0xf8, 0x39, 0x07, 0x00, 0xd1, 0x59,
|
||||
0xfe, 0xff, 0xb5, 0x4d, 0xff, 0xff, 0x17, 0x9f, 0x02, 0x00, 0x91, 0x9e, 0x00, 0x00, 0x94, 0x68, 0x1b, 0x40, 0xf9,
|
||||
0xe0, 0x03, 0x15, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0xa0, 0xc3, 0x99, 0xb8, 0xbf, 0x43, 0x01, 0xd1, 0xfd, 0x7b, 0x45,
|
||||
0xa9, 0xf4, 0x4f, 0x44, 0xa9, 0xf6, 0x57, 0x43, 0xa9, 0xf8, 0x5f, 0x42, 0xa9, 0xfa, 0x67, 0x41, 0xa9, 0xfc, 0x6f,
|
||||
0xc6, 0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0x0c, 0x00, 0x00, 0x00, 0x38, 0x02, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0xe8,
|
||||
0x01, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x78, 0x03, 0x00, 0x00, 0xdc, 0x03, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf8, 0x5f, 0xbc, 0xa9, 0xf6, 0x57, 0x01,
|
||||
0xa9, 0xf4, 0x4f, 0x02, 0xa9, 0xfd, 0x7b, 0x03, 0xa9, 0xfd, 0xc3, 0x00, 0x91, 0xf3, 0x03, 0x04, 0xaa, 0xf4, 0x03,
|
||||
0x03, 0xaa, 0xf5, 0x03, 0x02, 0xaa, 0xf6, 0x03, 0x01, 0xaa, 0xf7, 0x03, 0x00, 0xaa, 0x43, 0x00, 0x00, 0xb4, 0x9f,
|
||||
0x02, 0x00, 0xf9, 0xbf, 0x02, 0x00, 0xf1, 0xf8, 0x17, 0x9f, 0x1a, 0xd5, 0x03, 0x00, 0xb4, 0x68, 0x1e, 0x40, 0xf9,
|
||||
0xe0, 0x03, 0x17, 0xaa, 0xe1, 0x03, 0x16, 0xaa, 0xe2, 0x03, 0x15, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00,
|
||||
0xb1, 0xe1, 0x00, 0x00, 0x54, 0x68, 0x4e, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0x08, 0x00, 0x40, 0xb9, 0x1f, 0x11,
|
||||
0x00, 0x71, 0xa0, 0xfe, 0xff, 0x54, 0x0a, 0x00, 0x00, 0x14, 0x1f, 0x04, 0x00, 0xf1, 0x2b, 0x01, 0x00, 0x54, 0x94,
|
||||
0x00, 0x00, 0xb4, 0x88, 0x02, 0x40, 0xf9, 0x08, 0x01, 0x00, 0x8b, 0x88, 0x02, 0x00, 0xf9, 0xd6, 0x02, 0x00, 0x8b,
|
||||
0xb5, 0x02, 0x00, 0xcb, 0xe8, 0xff, 0xff, 0x17, 0x18, 0x00, 0x80, 0x52, 0xe0, 0x03, 0x18, 0xaa, 0xfd, 0x7b, 0x43,
|
||||
0xa9, 0xf4, 0x4f, 0x42, 0xa9, 0xf6, 0x57, 0x41, 0xa9, 0xf8, 0x5f, 0xc4, 0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0x38, 0x00,
|
||||
0x80, 0x52, 0xf9, 0xff, 0xff, 0x17, 0xf6, 0x57, 0xbd, 0xa9, 0xf4, 0x4f, 0x01, 0xa9, 0xfd, 0x7b, 0x02, 0xa9, 0xfd,
|
||||
0x83, 0x00, 0x91, 0xf3, 0x03, 0x02, 0xaa, 0xf4, 0x03, 0x01, 0xaa, 0xf5, 0x03, 0x00, 0xaa, 0x88, 0x00, 0x80, 0x52,
|
||||
0xf6, 0x03, 0x08, 0xaa, 0x48, 0x02, 0x00, 0xb4, 0x68, 0x22, 0x40, 0xf9, 0xe0, 0x03, 0x15, 0xaa, 0xe1, 0x03, 0x14,
|
||||
0xaa, 0xe2, 0x03, 0x16, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0x1f, 0x04, 0x00, 0xb1, 0xe1, 0x00, 0x00, 0x54, 0x68, 0x4e,
|
||||
0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0x08, 0x00, 0x40, 0xb9, 0x1f, 0x11, 0x00, 0x71, 0xa0, 0xfe, 0xff, 0x54, 0x05,
|
||||
0x00, 0x00, 0x14, 0x94, 0x02, 0x00, 0x8b, 0xc8, 0x02, 0x00, 0xcb, 0x1f, 0x00, 0x00, 0xf1, 0xcc, 0xfd, 0xff, 0x54,
|
||||
0xdf, 0x02, 0x00, 0xf1, 0xe0, 0x17, 0x9f, 0x1a, 0xfd, 0x7b, 0x42, 0xa9, 0xf4, 0x4f, 0x41, 0xa9, 0xf6, 0x57, 0xc3,
|
||||
0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0x44, 0x3c, 0x50, 0xb3, 0x7f, 0x00, 0x00, 0x71, 0x48, 0x00, 0x84, 0x9a, 0xf0, 0x03,
|
||||
0x01, 0x2a, 0x1f, 0x0e, 0x00, 0xf1, 0x10, 0x92, 0x9f, 0x9a, 0x11, 0x00, 0x00, 0x90, 0x31, 0x62, 0x29, 0x91, 0x30,
|
||||
0x7a, 0xb0, 0xb8, 0x11, 0x00, 0x00, 0x10, 0x30, 0x02, 0x10, 0x8b, 0x00, 0x02, 0x1f, 0xd6, 0xf1, 0x03, 0x00, 0xaa,
|
||||
0xf0, 0x03, 0x08, 0xaa, 0x1f, 0x21, 0x03, 0xd5, 0x0c, 0x00, 0x00, 0x14, 0xf1, 0x03, 0x00, 0xaa, 0xf0, 0x03, 0x08,
|
||||
0xaa, 0x11, 0x0a, 0xc1, 0xda, 0x08, 0x00, 0x00, 0x14, 0xf1, 0x03, 0x00, 0xaa, 0xf0, 0x03, 0x08, 0xaa, 0x11, 0x0e,
|
||||
0xc1, 0xda, 0x04, 0x00, 0x00, 0x14, 0xf1, 0x03, 0x00, 0xaa, 0xf0, 0x03, 0x08, 0xaa, 0x5f, 0x21, 0x03, 0xd5, 0xe0,
|
||||
0x03, 0x11, 0xaa, 0xc0, 0x03, 0x5f, 0xd6, 0x0c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
|
||||
0x2c, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x17, 0xaa, 0x02, 0x01, 0x80, 0x52, 0x03, 0x00, 0x80, 0xd2, 0xe4, 0x03, 0x1b,
|
||||
0xaa, 0x8c, 0xff, 0xff, 0x17, 0x03, 0x00, 0x80, 0xd2, 0xe4, 0x03, 0x1b, 0xaa, 0x89, 0xff, 0xff, 0x17, 0xea, 0x03,
|
||||
0x09, 0xaa, 0x4b, 0x15, 0x40, 0x38, 0x7f, 0x7d, 0x01, 0x71, 0x21, 0x11, 0x8a, 0x9a, 0x69, 0x4b, 0x40, 0xf9, 0xc0,
|
||||
0x03, 0x5f, 0xd6, 0xa1, 0xf3, 0x01, 0xd1, 0xe0, 0x03, 0x17, 0xaa, 0xe2, 0x03, 0x1b, 0xaa, 0xad, 0xff, 0xff, 0x17,
|
||||
0xa4, 0x93, 0x01, 0xd1, 0x00, 0x00, 0x80, 0x52, 0xe3, 0x03, 0x16, 0xaa, 0x00, 0x01, 0x1f, 0xd6, 0x68, 0x1b, 0x40,
|
||||
0xf9, 0xe0, 0x03, 0x17, 0xaa, 0x00, 0x01, 0x1f, 0xd6, 0xa0, 0x03, 0x5a, 0xf8, 0xa1, 0x03, 0x55, 0xf8, 0x00, 0x01,
|
||||
0x1f, 0xd6
|
||||
};
|
||||
|
||||
private static bool is_dyld_stub_binder (string module_name, string symbol_name) {
|
||||
@@ -1202,73 +1242,72 @@ namespace Frida.Fruity.Injector {
|
||||
/* Compiled from helpers/symbol-fetcher.c */
|
||||
private const uint8[] SYMBOL_FETCHER_CODE = {
|
||||
0xff, 0x03, 0x02, 0xd1, 0xfc, 0x6f, 0x02, 0xa9, 0xfa, 0x67, 0x03, 0xa9, 0xf8, 0x5f, 0x04, 0xa9, 0xf6, 0x57, 0x05,
|
||||
0xa9, 0xf4, 0x4f, 0x06, 0xa9, 0xfd, 0x7b, 0x07, 0xa9, 0xfd, 0xc3, 0x01, 0x91, 0xf4, 0x03, 0x01, 0xaa, 0xe0, 0x07,
|
||||
0x00, 0xf9, 0x13, 0x00, 0x80, 0xd2, 0x19, 0x00, 0x80, 0xd2, 0x35, 0x80, 0x00, 0x91, 0x3a, 0x10, 0x40, 0xb9, 0x16,
|
||||
0x00, 0x00, 0x90, 0xd6, 0x3e, 0x13, 0x91, 0x17, 0x00, 0x00, 0x90, 0xf7, 0x5a, 0x13, 0x91, 0x1a, 0x04, 0x00, 0x34,
|
||||
0xa8, 0x02, 0x40, 0xb9, 0x1f, 0x09, 0x00, 0x71, 0xa0, 0x01, 0x00, 0x54, 0x1f, 0x2d, 0x00, 0x71, 0xa0, 0x01, 0x00,
|
||||
0x54, 0x1f, 0x65, 0x00, 0x71, 0x81, 0x01, 0x00, 0x54, 0xb8, 0x22, 0x00, 0x91, 0xe0, 0x03, 0x18, 0xaa, 0xe1, 0x03,
|
||||
0x16, 0xaa, 0xaa, 0x00, 0x00, 0x94, 0x80, 0x01, 0x00, 0x34, 0xb3, 0xa2, 0x41, 0xa9, 0xe8, 0x0b, 0x00, 0xf9, 0x04,
|
||||
0x00, 0x00, 0x14, 0xfc, 0x03, 0x15, 0xaa, 0x02, 0x00, 0x00, 0x14, 0xfb, 0x03, 0x15, 0xaa, 0xa8, 0x06, 0x40, 0xb9,
|
||||
0xb5, 0x02, 0x08, 0x8b, 0x5a, 0x07, 0x00, 0x51, 0x7a, 0xfd, 0xff, 0x35, 0x09, 0x00, 0x00, 0x14, 0xe0, 0x03, 0x18,
|
||||
0xaa, 0xe1, 0x03, 0x17, 0xaa, 0x9b, 0x00, 0x00, 0x94, 0x00, 0xff, 0xff, 0x34, 0xa8, 0x0e, 0x40, 0xf9, 0xa9, 0x16,
|
||||
0x40, 0xf9, 0x19, 0x01, 0x09, 0xcb, 0xf4, 0xff, 0xff, 0x17, 0x88, 0x02, 0x13, 0xcb, 0x28, 0x03, 0x08, 0x8b, 0x89,
|
||||
0x0b, 0x40, 0xb9, 0x13, 0x01, 0x09, 0x8b, 0x89, 0x13, 0x40, 0xb9, 0x19, 0x01, 0x09, 0x8b, 0xe8, 0x07, 0x40, 0xf9,
|
||||
0xe8, 0x0f, 0x00, 0xf9, 0x16, 0x00, 0x00, 0x90, 0xd6, 0x72, 0x0f, 0x91, 0x35, 0x01, 0x80, 0x52, 0x78, 0x0b, 0x40,
|
||||
0xb9, 0x68, 0x0f, 0x40, 0xb9, 0x1f, 0x03, 0x08, 0x6b, 0xc0, 0x0a, 0x00, 0x54, 0x77, 0x52, 0x38, 0x8b, 0xe8, 0x02,
|
||||
0x40, 0xb9, 0x3c, 0x03, 0x08, 0x8b, 0xe0, 0x03, 0x1c, 0xaa, 0xe1, 0x03, 0x16, 0xaa, 0x6a, 0x00, 0x00, 0x94, 0xa0,
|
||||
0x07, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00, 0x90, 0x21, 0xbc, 0x0f, 0x91, 0x65, 0x00, 0x00, 0x94,
|
||||
0x00, 0x07, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00, 0x90, 0x21, 0xf8, 0x0f, 0x91, 0x60, 0x00, 0x00,
|
||||
0x94, 0x60, 0x06, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00, 0x90, 0x21, 0x54, 0x10, 0x91, 0x72, 0x00,
|
||||
0x00, 0x94, 0xc0, 0x05, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00, 0x90, 0x21, 0x8c, 0x10, 0x91, 0x6d,
|
||||
0x00, 0x00, 0x94, 0x20, 0x05, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00, 0x90, 0x21, 0xf4, 0x10, 0x91,
|
||||
0x68, 0x00, 0x00, 0x94, 0x80, 0x04, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00, 0x90, 0x21, 0x40, 0x11,
|
||||
0x91, 0x4c, 0x00, 0x00, 0x94, 0xe0, 0x03, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00, 0x90, 0x21, 0x88,
|
||||
0x11, 0x91, 0x47, 0x00, 0x00, 0x94, 0x40, 0x03, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00, 0x90, 0x21,
|
||||
0xec, 0x11, 0x91, 0x42, 0x00, 0x00, 0x94, 0xa0, 0x02, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00, 0x90,
|
||||
0x21, 0x44, 0x12, 0x91, 0x5c, 0x00, 0x00, 0x94, 0x00, 0x02, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00, 0x00,
|
||||
0x90, 0x21, 0x64, 0x12, 0x91, 0x57, 0x00, 0x00, 0x94, 0x60, 0x01, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01, 0x00,
|
||||
0x00, 0x90, 0x21, 0x84, 0x12, 0x91, 0x33, 0x00, 0x00, 0x94, 0xc0, 0x00, 0x00, 0x37, 0xe0, 0x03, 0x1c, 0xaa, 0x01,
|
||||
0x00, 0x00, 0x90, 0x21, 0xd0, 0x12, 0x91, 0x2e, 0x00, 0x00, 0x94, 0x20, 0x02, 0x00, 0x34, 0xba, 0x00, 0x00, 0x34,
|
||||
0xe8, 0x0f, 0x40, 0xf9, 0x49, 0x01, 0x80, 0x52, 0x09, 0x15, 0x00, 0x38, 0xe8, 0x0f, 0x00, 0xf9, 0xe8, 0x06, 0x40,
|
||||
0xf9, 0x81, 0x02, 0x08, 0x8b, 0xe0, 0x63, 0x00, 0x91, 0x4c, 0x00, 0x00, 0x94, 0xe8, 0x0f, 0x40, 0xf9, 0x15, 0x15,
|
||||
0x00, 0x38, 0xe8, 0x0f, 0x00, 0xf9, 0xe0, 0x63, 0x00, 0x91, 0xe1, 0x03, 0x1c, 0xaa, 0x5d, 0x00, 0x00, 0x94, 0x5a,
|
||||
0x07, 0x00, 0x11, 0x18, 0x07, 0x00, 0x11, 0xa9, 0xff, 0xff, 0x17, 0xe1, 0x23, 0x41, 0xa9, 0x49, 0x01, 0x80, 0x52,
|
||||
0x09, 0x15, 0x00, 0x38, 0xe8, 0x0f, 0x00, 0xf9, 0xe0, 0x63, 0x00, 0x91, 0x3d, 0x00, 0x00, 0x94, 0xe8, 0x0f, 0x40,
|
||||
0xf9, 0x29, 0x01, 0x80, 0x52, 0x09, 0x15, 0x00, 0x38, 0xe8, 0x0f, 0x00, 0xf9, 0x01, 0x00, 0x00, 0x90, 0x21, 0x14,
|
||||
0x13, 0x91, 0xe0, 0x63, 0x00, 0x91, 0x4c, 0x00, 0x00, 0x94, 0xe8, 0x0f, 0x40, 0xf9, 0xe9, 0x07, 0x40, 0xf9, 0x00,
|
||||
0x01, 0x09, 0xcb, 0x1f, 0x01, 0x00, 0x39, 0xfd, 0x7b, 0x47, 0xa9, 0xf4, 0x4f, 0x46, 0xa9, 0xf6, 0x57, 0x45, 0xa9,
|
||||
0xf8, 0x5f, 0x44, 0xa9, 0xfa, 0x67, 0x43, 0xa9, 0xfc, 0x6f, 0x42, 0xa9, 0xff, 0x03, 0x02, 0x91, 0xc0, 0x03, 0x5f,
|
||||
0xd6, 0xf6, 0x57, 0xbd, 0xa9, 0xf4, 0x4f, 0x01, 0xa9, 0xfd, 0x7b, 0x02, 0xa9, 0xfd, 0x83, 0x00, 0x91, 0xf3, 0x03,
|
||||
0x01, 0xaa, 0xf4, 0x03, 0x00, 0xaa, 0x35, 0x00, 0x40, 0x39, 0x96, 0x02, 0x40, 0x39, 0x36, 0x01, 0x00, 0x34, 0xdf,
|
||||
0x02, 0x15, 0x6b, 0xa1, 0x00, 0x00, 0x54, 0xe0, 0x03, 0x14, 0xaa, 0xe1, 0x03, 0x13, 0xaa, 0x12, 0x00, 0x00, 0x94,
|
||||
0x60, 0x00, 0x00, 0x37, 0x94, 0x06, 0x00, 0x91, 0xf7, 0xff, 0xff, 0x17, 0xdf, 0x02, 0x00, 0x71, 0xe0, 0x07, 0x9f,
|
||||
0x1a, 0xfd, 0x7b, 0x42, 0xa9, 0xf4, 0x4f, 0x41, 0xa9, 0xf6, 0x57, 0xc3, 0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0x08, 0x14,
|
||||
0x40, 0x38, 0x29, 0x14, 0x40, 0x38, 0x1f, 0x01, 0x00, 0x71, 0x00, 0x11, 0x49, 0x7a, 0x80, 0xff, 0xff, 0x54, 0x1f,
|
||||
0x01, 0x09, 0x6b, 0xe0, 0x17, 0x9f, 0x1a, 0xc0, 0x03, 0x5f, 0xd6, 0x28, 0x00, 0x40, 0x39, 0xa8, 0x00, 0x00, 0x34,
|
||||
0x21, 0x04, 0x00, 0x91, 0x09, 0x14, 0x40, 0x38, 0x3f, 0x01, 0x08, 0x6b, 0x60, 0xff, 0xff, 0x54, 0x1f, 0x01, 0x00,
|
||||
0x71, 0xe0, 0x17, 0x9f, 0x1a, 0xc0, 0x03, 0x5f, 0xd6, 0x09, 0x00, 0x80, 0x52, 0x08, 0x00, 0x40, 0xf9, 0x8a, 0x07,
|
||||
0x80, 0x52, 0x0b, 0x00, 0x00, 0x90, 0x6b, 0xc1, 0x13, 0x91, 0x5f, 0x11, 0x00, 0x31, 0x80, 0x01, 0x00, 0x54, 0x2c,
|
||||
0x24, 0xca, 0x9a, 0x8c, 0x0d, 0x40, 0x92, 0x2d, 0x01, 0x00, 0x12, 0x9f, 0x01, 0x00, 0x71, 0xa0, 0x19, 0x40, 0x7a,
|
||||
0x29, 0x15, 0x9f, 0x1a, 0x69, 0x00, 0x00, 0x36, 0x6c, 0x69, 0x6c, 0x38, 0x0c, 0x15, 0x00, 0x38, 0x4a, 0x11, 0x00,
|
||||
0x51, 0xf4, 0xff, 0xff, 0x17, 0x69, 0x00, 0x00, 0x37, 0x09, 0x06, 0x80, 0x52, 0x09, 0x15, 0x00, 0x38, 0x08, 0x00,
|
||||
0x00, 0xf9, 0xc0, 0x03, 0x5f, 0xd6, 0x08, 0x00, 0x40, 0xf9, 0x29, 0x00, 0x40, 0x39, 0x89, 0x00, 0x00, 0x34, 0x21,
|
||||
0x04, 0x00, 0x91, 0x09, 0x15, 0x00, 0x38, 0xfc, 0xff, 0xff, 0x17, 0x08, 0x00, 0x00, 0xf9, 0xc0, 0x03, 0x5f, 0xd6,
|
||||
0x6c, 0x69, 0x62, 0x64, 0x79, 0x6c, 0x64, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x00,
|
||||
0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x62, 0x6a, 0x43, 0x49, 0x6e, 0x69, 0x74, 0x00, 0x72, 0x65, 0x73, 0x74,
|
||||
0x61, 0x72, 0x74, 0x57, 0x69, 0x74, 0x68, 0x44, 0x79, 0x6c, 0x64, 0x49, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x00,
|
||||
0x5f, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x00, 0x5f, 0x5f, 0x5a, 0x4e, 0x35,
|
||||
0x64, 0x79, 0x6c, 0x64, 0x34, 0x31, 0x32, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f,
|
||||
0x45, 0x00, 0x5f, 0x5f, 0x5a, 0x4c, 0x31, 0x32, 0x73, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x00, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65,
|
||||
0x00, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63,
|
||||
0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x68, 0x72, 0x65,
|
||||
0x61, 0x64, 0x48, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x00, 0x5f, 0x64, 0x6c, 0x6f, 0x70, 0x65, 0x6e, 0x00, 0x5f,
|
||||
0x73, 0x74, 0x72, 0x63, 0x6d, 0x70, 0x00, 0x64, 0x6f, 0x4d, 0x6f, 0x64, 0x49, 0x6e, 0x69, 0x74, 0x46, 0x75, 0x6e,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x64, 0x6f, 0x47, 0x65, 0x74, 0x44, 0x4f, 0x46, 0x53, 0x65, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x00, 0x64, 0x79, 0x6c, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x5f, 0x5f, 0x54, 0x45,
|
||||
0x58, 0x54, 0x00, 0x5f, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x45, 0x44, 0x49, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
||||
0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
|
||||
0xa9, 0xf4, 0x4f, 0x06, 0xa9, 0xfd, 0x7b, 0x07, 0xa9, 0xfd, 0xc3, 0x01, 0x91, 0xf4, 0x03, 0x01, 0xaa, 0xe0, 0x0b,
|
||||
0x00, 0xf9, 0x13, 0x00, 0x80, 0xd2, 0x15, 0x00, 0x80, 0xd2, 0x38, 0x80, 0x00, 0x91, 0x39, 0x10, 0x40, 0xb9, 0x16,
|
||||
0x00, 0x00, 0x90, 0xd6, 0x1e, 0x13, 0x91, 0x1a, 0x00, 0x00, 0x90, 0x5a, 0x3b, 0x13, 0x91, 0xd9, 0x03, 0x00, 0x34,
|
||||
0x08, 0x03, 0x40, 0xb9, 0x1f, 0x09, 0x00, 0x71, 0xa0, 0x01, 0x00, 0x54, 0x1f, 0x2d, 0x00, 0x71, 0x20, 0x01, 0x00,
|
||||
0x54, 0x1f, 0x65, 0x00, 0x71, 0x41, 0x01, 0x00, 0x54, 0x00, 0x23, 0x00, 0x91, 0xe1, 0x03, 0x16, 0xaa, 0xa4, 0x00,
|
||||
0x00, 0x94, 0x60, 0x01, 0x00, 0x34, 0x13, 0xef, 0x41, 0xa9, 0x04, 0x00, 0x00, 0x14, 0xfc, 0x03, 0x18, 0xaa, 0x02,
|
||||
0x00, 0x00, 0x14, 0xf7, 0x03, 0x18, 0xaa, 0x08, 0x07, 0x40, 0xb9, 0x18, 0x03, 0x08, 0x8b, 0x39, 0x07, 0x00, 0x51,
|
||||
0xb9, 0xfd, 0xff, 0x35, 0x09, 0x00, 0x00, 0x14, 0x00, 0x23, 0x00, 0x91, 0xe1, 0x03, 0x1a, 0xaa, 0x96, 0x00, 0x00,
|
||||
0x94, 0x00, 0xff, 0xff, 0x34, 0x08, 0x0f, 0x40, 0xf9, 0x09, 0x17, 0x40, 0xf9, 0x15, 0x01, 0x09, 0xcb, 0xf4, 0xff,
|
||||
0xff, 0x17, 0xfb, 0x07, 0x00, 0xf9, 0x1b, 0x00, 0x80, 0x52, 0x88, 0x02, 0x13, 0xcb, 0xa8, 0x02, 0x08, 0x8b, 0xe9,
|
||||
0x0a, 0x40, 0xb9, 0x1a, 0x01, 0x09, 0x8b, 0xe9, 0x12, 0x40, 0xb9, 0x13, 0x01, 0x09, 0x8b, 0xe8, 0x0b, 0x40, 0xf9,
|
||||
0xe8, 0x0f, 0x00, 0xf9, 0x16, 0x00, 0x00, 0x90, 0xd6, 0x52, 0x0f, 0x91, 0x39, 0x01, 0x80, 0x52, 0x95, 0x0b, 0x40,
|
||||
0xb9, 0x88, 0x0f, 0x40, 0xb9, 0xbf, 0x02, 0x08, 0x6b, 0x40, 0x0a, 0x00, 0x54, 0x58, 0x53, 0x35, 0x8b, 0x17, 0x03,
|
||||
0x40, 0xb9, 0x60, 0x02, 0x17, 0x8b, 0xe1, 0x03, 0x16, 0xaa, 0x64, 0x00, 0x00, 0x94, 0xa0, 0x07, 0x00, 0x37, 0x60,
|
||||
0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x9c, 0x0f, 0x91, 0x5f, 0x00, 0x00, 0x94, 0x00, 0x07, 0x00, 0x37,
|
||||
0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0xd8, 0x0f, 0x91, 0x5a, 0x00, 0x00, 0x94, 0x60, 0x06, 0x00,
|
||||
0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x34, 0x10, 0x91, 0x6c, 0x00, 0x00, 0x94, 0xc0, 0x05,
|
||||
0x00, 0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x6c, 0x10, 0x91, 0x67, 0x00, 0x00, 0x94, 0x20,
|
||||
0x05, 0x00, 0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0xd4, 0x10, 0x91, 0x62, 0x00, 0x00, 0x94,
|
||||
0x80, 0x04, 0x00, 0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x20, 0x11, 0x91, 0x46, 0x00, 0x00,
|
||||
0x94, 0xe0, 0x03, 0x00, 0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x68, 0x11, 0x91, 0x41, 0x00,
|
||||
0x00, 0x94, 0x40, 0x03, 0x00, 0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0xcc, 0x11, 0x91, 0x3c,
|
||||
0x00, 0x00, 0x94, 0xa0, 0x02, 0x00, 0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x24, 0x12, 0x91,
|
||||
0x56, 0x00, 0x00, 0x94, 0x00, 0x02, 0x00, 0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x44, 0x12,
|
||||
0x91, 0x51, 0x00, 0x00, 0x94, 0x60, 0x01, 0x00, 0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x64,
|
||||
0x12, 0x91, 0x2d, 0x00, 0x00, 0x94, 0xc0, 0x00, 0x00, 0x37, 0x60, 0x02, 0x17, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21,
|
||||
0xb0, 0x12, 0x91, 0x28, 0x00, 0x00, 0x94, 0xc0, 0x01, 0x00, 0x34, 0x5b, 0x00, 0x00, 0x34, 0x6c, 0x00, 0x00, 0x94,
|
||||
0x08, 0x07, 0x40, 0xf9, 0xe0, 0x63, 0x00, 0x91, 0x81, 0x02, 0x08, 0x8b, 0x49, 0x00, 0x00, 0x94, 0xe8, 0x0f, 0x40,
|
||||
0xf9, 0x19, 0x15, 0x00, 0x38, 0xe8, 0x0f, 0x00, 0xf9, 0xe0, 0x63, 0x00, 0x91, 0x61, 0x02, 0x17, 0x8b, 0x5a, 0x00,
|
||||
0x00, 0x94, 0x7b, 0x07, 0x00, 0x11, 0xb5, 0x06, 0x00, 0x11, 0xad, 0xff, 0xff, 0x17, 0x5e, 0x00, 0x00, 0x94, 0xe0,
|
||||
0x63, 0x00, 0x91, 0xe1, 0x07, 0x40, 0xf9, 0x3c, 0x00, 0x00, 0x94, 0xe8, 0x0f, 0x40, 0xf9, 0x29, 0x01, 0x80, 0x52,
|
||||
0x09, 0x15, 0x00, 0x38, 0xe8, 0x0f, 0x00, 0xf9, 0x01, 0x00, 0x00, 0x90, 0x21, 0xf4, 0x12, 0x91, 0xe0, 0x63, 0x00,
|
||||
0x91, 0x4b, 0x00, 0x00, 0x94, 0xe9, 0x23, 0x41, 0xa9, 0x00, 0x01, 0x09, 0xcb, 0x1f, 0x01, 0x00, 0x39, 0xfd, 0x7b,
|
||||
0x47, 0xa9, 0xf4, 0x4f, 0x46, 0xa9, 0xf6, 0x57, 0x45, 0xa9, 0xf8, 0x5f, 0x44, 0xa9, 0xfa, 0x67, 0x43, 0xa9, 0xfc,
|
||||
0x6f, 0x42, 0xa9, 0xff, 0x03, 0x02, 0x91, 0xc0, 0x03, 0x5f, 0xd6, 0xf6, 0x57, 0xbd, 0xa9, 0xf4, 0x4f, 0x01, 0xa9,
|
||||
0xfd, 0x7b, 0x02, 0xa9, 0xfd, 0x83, 0x00, 0x91, 0xf3, 0x03, 0x01, 0xaa, 0xf4, 0x03, 0x00, 0xaa, 0x35, 0x00, 0x40,
|
||||
0x39, 0x96, 0x02, 0x40, 0x39, 0x36, 0x01, 0x00, 0x34, 0xdf, 0x02, 0x15, 0x6b, 0xa1, 0x00, 0x00, 0x54, 0xe0, 0x03,
|
||||
0x14, 0xaa, 0xe1, 0x03, 0x13, 0xaa, 0x12, 0x00, 0x00, 0x94, 0x60, 0x00, 0x00, 0x37, 0x94, 0x06, 0x00, 0x91, 0xf7,
|
||||
0xff, 0xff, 0x17, 0xdf, 0x02, 0x00, 0x71, 0xe0, 0x07, 0x9f, 0x1a, 0xfd, 0x7b, 0x42, 0xa9, 0xf4, 0x4f, 0x41, 0xa9,
|
||||
0xf6, 0x57, 0xc3, 0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0x08, 0x14, 0x40, 0x38, 0x29, 0x14, 0x40, 0x38, 0x1f, 0x01, 0x00,
|
||||
0x71, 0x00, 0x11, 0x49, 0x7a, 0x80, 0xff, 0xff, 0x54, 0x1f, 0x01, 0x09, 0x6b, 0xe0, 0x17, 0x9f, 0x1a, 0xc0, 0x03,
|
||||
0x5f, 0xd6, 0x28, 0x00, 0x40, 0x39, 0xa8, 0x00, 0x00, 0x34, 0x21, 0x04, 0x00, 0x91, 0x09, 0x14, 0x40, 0x38, 0x3f,
|
||||
0x01, 0x08, 0x6b, 0x60, 0xff, 0xff, 0x54, 0x1f, 0x01, 0x00, 0x71, 0xe0, 0x17, 0x9f, 0x1a, 0xc0, 0x03, 0x5f, 0xd6,
|
||||
0x09, 0x00, 0x80, 0x52, 0x08, 0x00, 0x40, 0xf9, 0x8a, 0x07, 0x80, 0x52, 0x0b, 0x00, 0x00, 0x90, 0x6b, 0x81, 0x13,
|
||||
0x91, 0x5f, 0x11, 0x00, 0x31, 0x80, 0x01, 0x00, 0x54, 0x2c, 0x24, 0xca, 0x9a, 0x8c, 0x0d, 0x40, 0xf2, 0xed, 0x17,
|
||||
0x9f, 0x1a, 0x2d, 0x01, 0x0d, 0x2a, 0xbf, 0x01, 0x00, 0x72, 0x29, 0x15, 0x9f, 0x1a, 0x69, 0x00, 0x00, 0x36, 0x6c,
|
||||
0x69, 0x6c, 0x38, 0x0c, 0x15, 0x00, 0x38, 0x4a, 0x11, 0x00, 0x51, 0xf4, 0xff, 0xff, 0x17, 0x69, 0x00, 0x00, 0x37,
|
||||
0x09, 0x06, 0x80, 0x52, 0x09, 0x15, 0x00, 0x38, 0x08, 0x00, 0x00, 0xf9, 0xc0, 0x03, 0x5f, 0xd6, 0x08, 0x00, 0x40,
|
||||
0xf9, 0x29, 0x00, 0x40, 0x39, 0x89, 0x00, 0x00, 0x34, 0x21, 0x04, 0x00, 0x91, 0x09, 0x15, 0x00, 0x38, 0xfc, 0xff,
|
||||
0xff, 0x17, 0x08, 0x00, 0x00, 0xf9, 0xc0, 0x03, 0x5f, 0xd6, 0xe8, 0x0f, 0x40, 0xf9, 0x49, 0x01, 0x80, 0x52, 0x09,
|
||||
0x15, 0x00, 0x38, 0xe8, 0x0f, 0x00, 0xf9, 0xc0, 0x03, 0x5f, 0xd6, 0x6c, 0x69, 0x62, 0x64, 0x79, 0x6c, 0x64, 0x5f,
|
||||
0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x00, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x62,
|
||||
0x6a, 0x43, 0x49, 0x6e, 0x69, 0x74, 0x00, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x57, 0x69, 0x74, 0x68, 0x44,
|
||||
0x79, 0x6c, 0x64, 0x49, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x00, 0x5f, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
|
||||
0x73, 0x49, 0x6e, 0x66, 0x6f, 0x00, 0x5f, 0x5f, 0x5a, 0x4e, 0x35, 0x64, 0x79, 0x6c, 0x64, 0x34, 0x31, 0x32, 0x67,
|
||||
0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x00, 0x5f, 0x5f, 0x5a, 0x4c, 0x31, 0x32,
|
||||
0x73, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x00, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68,
|
||||
0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x00, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c,
|
||||
0x69, 0x7a, 0x65, 0x4d, 0x61, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x72,
|
||||
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x48, 0x65, 0x6c, 0x70, 0x65, 0x72,
|
||||
0x73, 0x00, 0x5f, 0x64, 0x6c, 0x6f, 0x70, 0x65, 0x6e, 0x00, 0x5f, 0x73, 0x74, 0x72, 0x63, 0x6d, 0x70, 0x00, 0x64,
|
||||
0x6f, 0x4d, 0x6f, 0x64, 0x49, 0x6e, 0x69, 0x74, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x64,
|
||||
0x6f, 0x47, 0x65, 0x74, 0x44, 0x4f, 0x46, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x64, 0x79, 0x6c,
|
||||
0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x5f, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x00, 0x5f, 0x5f, 0x4c, 0x49, 0x4e,
|
||||
0x4b, 0x45, 0x44, 0x49, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
|
||||
0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
|
||||
};
|
||||
|
||||
private async SymbolSet resolve_symbols (SymbolQuery query, Cancellable? cancellable) throws GLib.Error {
|
||||
@@ -1343,52 +1382,52 @@ namespace Frida.Fruity.Injector {
|
||||
private const uint8[] SYMBOL_RESOLVER_CODE = {
|
||||
0xff, 0xc3, 0x01, 0xd1, 0xfc, 0x6f, 0x01, 0xa9, 0xfa, 0x67, 0x02, 0xa9, 0xf8, 0x5f, 0x03, 0xa9, 0xf6, 0x57, 0x04,
|
||||
0xa9, 0xf4, 0x4f, 0x05, 0xa9, 0xfd, 0x7b, 0x06, 0xa9, 0xfd, 0x83, 0x01, 0x91, 0xf5, 0x03, 0x02, 0xaa, 0xf3, 0x03,
|
||||
0x01, 0xaa, 0xf4, 0x03, 0x00, 0xaa, 0x08, 0x00, 0x80, 0xd2, 0x49, 0x04, 0x40, 0xb9, 0x0a, 0x03, 0x80, 0x52, 0xeb,
|
||||
0x07, 0x7d, 0xb2, 0x37, 0x2d, 0x0a, 0x9b, 0x76, 0x19, 0x00, 0x30, 0x1f, 0x20, 0x03, 0xd5, 0x18, 0x61, 0x00, 0x91,
|
||||
0x01, 0xaa, 0xf4, 0x03, 0x00, 0xaa, 0x08, 0x00, 0x80, 0xd2, 0x49, 0x04, 0x40, 0xb9, 0x0a, 0x03, 0x80, 0x52, 0x29,
|
||||
0x7d, 0xaa, 0x9b, 0x37, 0x61, 0x00, 0x91, 0x16, 0x00, 0x00, 0x90, 0xd6, 0xa6, 0x0d, 0x91, 0x18, 0x61, 0x00, 0x91,
|
||||
0xff, 0x02, 0x18, 0xeb, 0x60, 0x01, 0x00, 0x54, 0xb9, 0x06, 0x40, 0xf9, 0x28, 0x03, 0x08, 0x8b, 0x00, 0x05, 0x40,
|
||||
0xf9, 0xe1, 0x03, 0x16, 0xaa, 0xad, 0x00, 0x00, 0x94, 0xe8, 0x03, 0x18, 0xaa, 0xe0, 0xfe, 0xff, 0x34, 0x28, 0x03,
|
||||
0x18, 0x8b, 0x08, 0x81, 0x5e, 0xf8, 0x02, 0x00, 0x00, 0x14, 0x08, 0x00, 0x80, 0xd2, 0x19, 0x00, 0x80, 0xd2, 0xe8,
|
||||
0x7f, 0x00, 0xa9, 0x16, 0x00, 0x80, 0xd2, 0x1b, 0x00, 0x80, 0xd2, 0x1c, 0x81, 0x00, 0x91, 0x1a, 0x11, 0x40, 0xb9,
|
||||
0x58, 0x04, 0x80, 0x52, 0x18, 0x00, 0xb0, 0x72, 0x75, 0x06, 0x80, 0x52, 0x15, 0x00, 0xb0, 0x72, 0x5a, 0x04, 0x00,
|
||||
0x34, 0x88, 0x03, 0x40, 0xb9, 0x1f, 0x01, 0x18, 0x6b, 0xa0, 0x01, 0x00, 0x54, 0x1f, 0x01, 0x15, 0x6b, 0xa0, 0x01,
|
||||
0x00, 0x54, 0x1f, 0x65, 0x00, 0x71, 0x81, 0x01, 0x00, 0x54, 0x97, 0x23, 0x00, 0x91, 0xe0, 0x03, 0x17, 0xaa, 0x41,
|
||||
0x14, 0x00, 0x70, 0x1f, 0x20, 0x03, 0xd5, 0x90, 0x00, 0x00, 0x94, 0x60, 0x01, 0x00, 0x34, 0x99, 0x0f, 0x40, 0xf9,
|
||||
0x04, 0x00, 0x00, 0x14, 0xf6, 0x03, 0x1c, 0xaa, 0x02, 0x00, 0x00, 0x14, 0xfb, 0x03, 0x1c, 0xaa, 0x88, 0x07, 0x40,
|
||||
0xb9, 0x9c, 0x03, 0x08, 0x8b, 0x5a, 0x07, 0x00, 0x51, 0x7a, 0xfd, 0xff, 0x35, 0x0b, 0x00, 0x00, 0x14, 0xe0, 0x03,
|
||||
0x17, 0xaa, 0xa1, 0x12, 0x00, 0x50, 0x1f, 0x20, 0x03, 0xd5, 0x81, 0x00, 0x00, 0x94, 0xe0, 0xfe, 0xff, 0x34, 0x88,
|
||||
0xf9, 0xe1, 0x03, 0x16, 0xaa, 0xaf, 0x00, 0x00, 0x94, 0xe8, 0x03, 0x18, 0xaa, 0xe0, 0xfe, 0xff, 0x34, 0x28, 0x03,
|
||||
0x18, 0x8b, 0x08, 0x81, 0x5e, 0xf8, 0x02, 0x00, 0x00, 0x14, 0x08, 0x00, 0x80, 0xd2, 0x18, 0x00, 0x80, 0xd2, 0xe8,
|
||||
0x7f, 0x00, 0xa9, 0x1a, 0x00, 0x80, 0xd2, 0x1b, 0x00, 0x80, 0xd2, 0x1c, 0x81, 0x00, 0x91, 0x16, 0x11, 0x40, 0xb9,
|
||||
0x59, 0x04, 0x80, 0x52, 0x19, 0x00, 0xb0, 0x72, 0x77, 0x06, 0x80, 0x52, 0x17, 0x00, 0xb0, 0x72, 0x15, 0x00, 0x00,
|
||||
0x90, 0xb5, 0x5e, 0x0d, 0x91, 0x16, 0x04, 0x00, 0x34, 0x88, 0x03, 0x40, 0xb9, 0x1f, 0x01, 0x19, 0x6b, 0xa0, 0x01,
|
||||
0x00, 0x54, 0x1f, 0x01, 0x17, 0x6b, 0x20, 0x01, 0x00, 0x54, 0x1f, 0x65, 0x00, 0x71, 0x41, 0x01, 0x00, 0x54, 0x80,
|
||||
0x23, 0x00, 0x91, 0xe1, 0x03, 0x15, 0xaa, 0x92, 0x00, 0x00, 0x94, 0x60, 0x01, 0x00, 0x34, 0x98, 0x0f, 0x40, 0xf9,
|
||||
0x04, 0x00, 0x00, 0x14, 0xfb, 0x03, 0x1c, 0xaa, 0x02, 0x00, 0x00, 0x14, 0xfa, 0x03, 0x1c, 0xaa, 0x88, 0x07, 0x40,
|
||||
0xb9, 0x9c, 0x03, 0x08, 0x8b, 0xd6, 0x06, 0x00, 0x51, 0xb6, 0xfd, 0xff, 0x35, 0x0b, 0x00, 0x00, 0x14, 0x80, 0x23,
|
||||
0x00, 0x91, 0x01, 0x00, 0x00, 0x90, 0x21, 0x78, 0x0d, 0x91, 0x83, 0x00, 0x00, 0x94, 0xe0, 0xfe, 0xff, 0x34, 0x88,
|
||||
0x0f, 0x40, 0xf9, 0x89, 0x17, 0x40, 0xf9, 0x08, 0x01, 0x09, 0xcb, 0xe8, 0x07, 0x00, 0xf9, 0xf2, 0xff, 0xff, 0x17,
|
||||
0x96, 0x00, 0x00, 0xb4, 0xc8, 0xa2, 0x00, 0x91, 0xf7, 0x03, 0x40, 0xf9, 0x04, 0x00, 0x00, 0x14, 0xf7, 0x03, 0x40,
|
||||
0xf9, 0xbb, 0x05, 0x00, 0xb4, 0x68, 0x23, 0x00, 0x91, 0xe9, 0x02, 0x19, 0xcb, 0xea, 0x07, 0x40, 0xf9, 0x49, 0x01,
|
||||
0x09, 0x8b, 0x08, 0x01, 0x40, 0xb9, 0x35, 0x01, 0x08, 0x8b, 0x61, 0x0f, 0x00, 0x10, 0x1f, 0x20, 0x03, 0xd5, 0xe0,
|
||||
0x03, 0x15, 0xaa, 0x31, 0x00, 0x00, 0x94, 0xf6, 0x02, 0x00, 0x8b, 0x01, 0x0f, 0x00, 0x10, 0x1f, 0x20, 0x03, 0xd5,
|
||||
0x9a, 0x00, 0x00, 0xb4, 0x48, 0xa3, 0x00, 0x91, 0xf7, 0x03, 0x40, 0xf9, 0x04, 0x00, 0x00, 0x14, 0xf7, 0x03, 0x40,
|
||||
0xf9, 0xbb, 0x05, 0x00, 0xb4, 0x68, 0x23, 0x00, 0x91, 0xe9, 0x02, 0x18, 0xcb, 0xea, 0x07, 0x40, 0xf9, 0x49, 0x01,
|
||||
0x09, 0x8b, 0x08, 0x01, 0x40, 0xb9, 0x35, 0x01, 0x08, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x20, 0x0d, 0x91, 0xe0,
|
||||
0x03, 0x15, 0xaa, 0x31, 0x00, 0x00, 0x94, 0xf6, 0x02, 0x00, 0x8b, 0x01, 0x00, 0x00, 0x90, 0x21, 0x40, 0x0d, 0x91,
|
||||
0xe0, 0x03, 0x15, 0xaa, 0x2c, 0x00, 0x00, 0x94, 0xf7, 0x02, 0x00, 0x8b, 0x80, 0x02, 0x40, 0xf9, 0x60, 0x02, 0x00,
|
||||
0xb4, 0x21, 0x01, 0x80, 0x52, 0xc0, 0x02, 0x3f, 0xd6, 0x40, 0x01, 0x00, 0xb4, 0xf5, 0x03, 0x00, 0xaa, 0x94, 0x42,
|
||||
0x00, 0x91, 0x81, 0x82, 0x5f, 0xf8, 0x01, 0xff, 0xff, 0xb4, 0xe0, 0x03, 0x15, 0xaa, 0xe0, 0x02, 0x3f, 0xd6, 0x60,
|
||||
0x86, 0x00, 0xf8, 0x94, 0x22, 0x00, 0x91, 0xfa, 0xff, 0xff, 0x17, 0x94, 0x42, 0x00, 0x91, 0x88, 0x82, 0x5f, 0xf8,
|
||||
0x08, 0xfe, 0xff, 0xb4, 0x7f, 0x86, 0x00, 0xf8, 0x94, 0x22, 0x00, 0x91, 0xfc, 0xff, 0xff, 0x17, 0xfd, 0x7b, 0x46,
|
||||
0xa9, 0xf4, 0x4f, 0x45, 0xa9, 0xf6, 0x57, 0x44, 0xa9, 0xf8, 0x5f, 0x43, 0xa9, 0xfa, 0x67, 0x42, 0xa9, 0xfc, 0x6f,
|
||||
0x41, 0xa9, 0xff, 0xc3, 0x01, 0x91, 0xc0, 0x03, 0x5f, 0xd6, 0x15, 0x00, 0x80, 0xd2, 0xd9, 0xff, 0xff, 0x17, 0xe8,
|
||||
0x03, 0x00, 0xaa, 0x0a, 0x00, 0x80, 0xd2, 0x00, 0x00, 0x80, 0xd2, 0x09, 0x01, 0x40, 0xf9, 0x2b, 0x15, 0x40, 0x38,
|
||||
0x6c, 0x19, 0x40, 0x92, 0x8c, 0x21, 0xca, 0x9a, 0x80, 0x01, 0x00, 0xaa, 0x4a, 0x1d, 0x00, 0x91, 0x6b, 0xff, 0x3f,
|
||||
0x37, 0x09, 0x01, 0x00, 0xf9, 0xc0, 0x03, 0x5f, 0xd6, 0xff, 0x43, 0x01, 0xd1, 0xf8, 0x5f, 0x01, 0xa9, 0xf6, 0x57,
|
||||
0x41, 0xa9, 0xff, 0xc3, 0x01, 0x91, 0xc0, 0x03, 0x5f, 0xd6, 0x15, 0x00, 0x80, 0xd2, 0xd9, 0xff, 0xff, 0x17, 0x09,
|
||||
0x00, 0x80, 0xd2, 0x08, 0x00, 0x80, 0xd2, 0x0a, 0x00, 0x40, 0xf9, 0x4b, 0x15, 0x40, 0x38, 0x6c, 0x19, 0x40, 0x92,
|
||||
0x8c, 0x21, 0xc9, 0x9a, 0x88, 0x01, 0x08, 0xaa, 0x29, 0x1d, 0x00, 0x91, 0x6b, 0xff, 0x3f, 0x37, 0x0a, 0x00, 0x00,
|
||||
0xf9, 0xe0, 0x03, 0x08, 0xaa, 0xc0, 0x03, 0x5f, 0xd6, 0xff, 0x43, 0x01, 0xd1, 0xf8, 0x5f, 0x01, 0xa9, 0xf6, 0x57,
|
||||
0x02, 0xa9, 0xf4, 0x4f, 0x03, 0xa9, 0xfd, 0x7b, 0x04, 0xa9, 0xfd, 0x03, 0x01, 0x91, 0xf4, 0x03, 0x01, 0xaa, 0xf3,
|
||||
0x03, 0x00, 0xaa, 0xe8, 0x03, 0x00, 0xaa, 0xe8, 0x07, 0x00, 0xf9, 0xc8, 0x04, 0x00, 0xb4, 0x3a, 0x00, 0x00, 0x94,
|
||||
0x60, 0x00, 0x00, 0xb4, 0x88, 0x02, 0x40, 0x39, 0x88, 0x04, 0x00, 0x34, 0x15, 0x00, 0x80, 0x52, 0xe8, 0x07, 0x40,
|
||||
0xf9, 0x08, 0x01, 0x00, 0x8b, 0x16, 0x15, 0x40, 0x38, 0xe8, 0x07, 0x00, 0xf9, 0xdf, 0x02, 0x35, 0x6b, 0xc0, 0x02,
|
||||
0x03, 0x00, 0xaa, 0xe8, 0x03, 0x00, 0xaa, 0xe8, 0x07, 0x00, 0xf9, 0x08, 0x05, 0x00, 0xb4, 0x39, 0x00, 0x00, 0x94,
|
||||
0x88, 0x02, 0x40, 0x39, 0x48, 0x00, 0x00, 0x35, 0xc0, 0x04, 0x00, 0xb5, 0x15, 0x00, 0x80, 0x52, 0xe8, 0x07, 0x40,
|
||||
0xf9, 0x08, 0x01, 0x00, 0x8b, 0x16, 0x15, 0x40, 0x38, 0xe8, 0x07, 0x00, 0xf9, 0xdf, 0x02, 0x35, 0x6b, 0xa0, 0x02,
|
||||
0x00, 0x54, 0xe8, 0x07, 0x40, 0xf9, 0x08, 0x05, 0x00, 0x91, 0x38, 0x00, 0x80, 0x52, 0xf7, 0x03, 0x14, 0xaa, 0x09,
|
||||
0xf1, 0x5f, 0x38, 0x49, 0x01, 0x00, 0x34, 0xb8, 0x00, 0x00, 0x36, 0xea, 0x16, 0xc0, 0x38, 0x3f, 0x01, 0x0a, 0x6b,
|
||||
0xf8, 0x17, 0x9f, 0x1a, 0x02, 0x00, 0x00, 0x14, 0x18, 0x00, 0x80, 0x52, 0xe8, 0x07, 0x00, 0xf9, 0x08, 0x05, 0x00,
|
||||
0x91, 0xf6, 0xff, 0xff, 0x17, 0xe8, 0x07, 0x00, 0xf9, 0x1f, 0x00, 0x00, 0x94, 0xb5, 0x06, 0x00, 0x11, 0x98, 0xfd,
|
||||
0x07, 0x36, 0xf4, 0x03, 0x17, 0xaa, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0xd2, 0x68, 0x02, 0x00, 0x8b, 0x1f,
|
||||
0x00, 0x00, 0xf1, 0xe8, 0x03, 0x88, 0x9a, 0xda, 0xff, 0xff, 0x17, 0x00, 0x00, 0x80, 0xd2, 0x03, 0x00, 0x00, 0x14,
|
||||
0x13, 0x00, 0x00, 0x94, 0x12, 0x00, 0x00, 0x94, 0xfd, 0x7b, 0x44, 0xa9, 0xf4, 0x4f, 0x43, 0xa9, 0xf6, 0x57, 0x42,
|
||||
0xa9, 0xf8, 0x5f, 0x41, 0xa9, 0xff, 0x43, 0x01, 0x91, 0xc0, 0x03, 0x5f, 0xd6, 0x08, 0x00, 0x40, 0x39, 0x29, 0x00,
|
||||
0x40, 0x39, 0x1f, 0x01, 0x09, 0x6b, 0xc1, 0x00, 0x00, 0x54, 0x00, 0x04, 0x00, 0x91, 0x21, 0x04, 0x00, 0x91, 0x48,
|
||||
0xff, 0xff, 0x35, 0x20, 0x00, 0x80, 0x52, 0xc0, 0x03, 0x5f, 0xd6, 0x00, 0x00, 0x80, 0x52, 0xc0, 0x03, 0x5f, 0xd6,
|
||||
0xe0, 0x23, 0x00, 0x91, 0xae, 0xff, 0xff, 0x17, 0x5f, 0x64, 0x6c, 0x6f, 0x70, 0x65, 0x6e, 0x00, 0x5f, 0x64, 0x6c,
|
||||
0x73, 0x79, 0x6d, 0x00, 0x5f, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x00, 0x5f, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x45, 0x44,
|
||||
0x49, 0x54, 0x00, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f,
|
||||
0x6c, 0x69, 0x62, 0x64, 0x79, 0x6c, 0x64, 0x2e, 0x64, 0x79, 0x6c, 0x69, 0x62, 0x00
|
||||
0x91, 0xf6, 0xff, 0xff, 0x17, 0xe8, 0x07, 0x00, 0xf9, 0x1e, 0x00, 0x00, 0x94, 0xb8, 0x00, 0x00, 0x37, 0xb5, 0x06,
|
||||
0x00, 0x11, 0xeb, 0xff, 0xff, 0x17, 0xf7, 0x03, 0x14, 0xaa, 0x04, 0x00, 0x00, 0x14, 0x68, 0x02, 0x00, 0x8b, 0xf4,
|
||||
0x03, 0x17, 0xaa, 0x60, 0xfb, 0xff, 0xb5, 0x08, 0x00, 0x80, 0xd2, 0xf4, 0x03, 0x17, 0xaa, 0xd8, 0xff, 0xff, 0x17,
|
||||
0x00, 0x00, 0x80, 0xd2, 0x03, 0x00, 0x00, 0x14, 0x10, 0x00, 0x00, 0x94, 0x0f, 0x00, 0x00, 0x94, 0xfd, 0x7b, 0x44,
|
||||
0xa9, 0xf4, 0x4f, 0x43, 0xa9, 0xf6, 0x57, 0x42, 0xa9, 0xf8, 0x5f, 0x41, 0xa9, 0xff, 0x43, 0x01, 0x91, 0xc0, 0x03,
|
||||
0x5f, 0xd6, 0x08, 0x14, 0x40, 0x38, 0x29, 0x14, 0x40, 0x38, 0x1f, 0x01, 0x00, 0x71, 0x00, 0x11, 0x49, 0x7a, 0x80,
|
||||
0xff, 0xff, 0x54, 0x1f, 0x01, 0x09, 0x6b, 0xe0, 0x17, 0x9f, 0x1a, 0xc0, 0x03, 0x5f, 0xd6, 0xe0, 0x23, 0x00, 0x91,
|
||||
0xaf, 0xff, 0xff, 0x17, 0x5f, 0x64, 0x6c, 0x6f, 0x70, 0x65, 0x6e, 0x00, 0x5f, 0x64, 0x6c, 0x73, 0x79, 0x6d, 0x00,
|
||||
0x5f, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x00, 0x5f, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x45, 0x44, 0x49, 0x54, 0x00, 0x2f,
|
||||
0x75, 0x73, 0x72, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x64,
|
||||
0x79, 0x6c, 0x64, 0x2e, 0x64, 0x79, 0x6c, 0x69, 0x62, 0x00
|
||||
};
|
||||
|
||||
private string demangle (string symbol_name) {
|
||||
|
||||
+46
-1
@@ -508,6 +508,41 @@ namespace Frida.GDB {
|
||||
yield write_byte_array (address, new Bytes ({ val ? 1 : 0 }), cancellable);
|
||||
}
|
||||
|
||||
public async void spray_pages (uint64 address, size_t size, size_t page_size, Cancellable? cancellable = null)
|
||||
throws Error, IOError {
|
||||
int n_pages = (int) (size / page_size);
|
||||
if (n_pages == 0)
|
||||
throw new Error.INVALID_ARGUMENT ("Expected one or more pages");
|
||||
|
||||
var builder = make_packet_builder_sized (64);
|
||||
Future<bool>? last_write = null;
|
||||
|
||||
for (int i = 0; i < n_pages; i += 2) {
|
||||
bool is_last = (i + 2 >= n_pages);
|
||||
|
||||
uint64 last_byte_addr = address + ((uint64) i * page_size) + page_size - 1;
|
||||
size_t write_count = is_last ? 1 : 2;
|
||||
|
||||
builder
|
||||
.append_c ('M')
|
||||
.append_address (last_byte_addr)
|
||||
.append_c (',')
|
||||
.append_size (write_count)
|
||||
.append_c (':')
|
||||
.append_escaped ((write_count == 2) ? "0000" : "00");
|
||||
|
||||
var request = new Promise<bool> ();
|
||||
perform_execute.begin (builder.build (), cancellable, request);
|
||||
|
||||
builder.reset ();
|
||||
|
||||
if (is_last)
|
||||
last_write = request.future;
|
||||
}
|
||||
|
||||
yield last_write.wait_async (cancellable);
|
||||
}
|
||||
|
||||
public BufferBuilder make_buffer_builder () {
|
||||
return new BufferBuilder (byte_order, pointer_size);
|
||||
}
|
||||
@@ -729,6 +764,16 @@ namespace Frida.GDB {
|
||||
check_execute_response (response);
|
||||
}
|
||||
|
||||
private async void perform_execute (Bytes command, Cancellable? cancellable, Promise<bool> request)
|
||||
throws Error, IOError {
|
||||
try {
|
||||
yield execute (command, cancellable);
|
||||
request.resolve (true);
|
||||
} catch (GLib.Error e) {
|
||||
request.reject (e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void check_execute_response (Packet packet) throws Error {
|
||||
unowned string response = packet.payload;
|
||||
if (response[0] == 'E') {
|
||||
@@ -1678,7 +1723,7 @@ namespace Frida.GDB {
|
||||
|
||||
var response = yield client.query (request, cancellable);
|
||||
|
||||
return Protocol.parse_pointer_value (response.payload, client.pointer_size, client.byte_order);
|
||||
return Protocol.parse_integer_value (response.payload, client.byte_order);
|
||||
}
|
||||
|
||||
public async void write_register (string name, uint64 val, Cancellable? cancellable = null) throws Error, IOError {
|
||||
|
||||
+4
-4
@@ -9,7 +9,7 @@
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@frida/buffer": "^7.0.4",
|
||||
"frida-java-bridge": "^7.0.4"
|
||||
"frida-java-bridge": "^7.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.25.5",
|
||||
@@ -534,9 +534,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/frida-java-bridge": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/frida-java-bridge/-/frida-java-bridge-7.0.4.tgz",
|
||||
"integrity": "sha512-dE5XCvasUwA/wiVb5gSwBPf6dortI8VtD0qLlw2T0ryqX/0lg4BEtEkg1oRr9IlHDVBTjPOqe9KRzdPar8U3EQ==",
|
||||
"version": "7.0.7",
|
||||
"resolved": "https://registry.npmjs.org/frida-java-bridge/-/frida-java-bridge-7.0.7.tgz",
|
||||
"integrity": "sha512-Au+dsBEjr4x5E5VxptPwY6xMPpr0zYdOcf1/zFZSeq/F1VXS0ScH+1FUA6n5Xp4JsE1CigTnn0T3z13xBKsu6w==",
|
||||
"license": "LGPL-2.0 WITH WxWindows-exception-3.1"
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@frida/buffer": "^7.0.4",
|
||||
"frida-java-bridge": "^7.0.4"
|
||||
"frida-java-bridge": "^7.0.7"
|
||||
}
|
||||
}
|
||||
+2015
-737
File diff suppressed because it is too large.
Load diff
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida/frida-gum.git
|
||||
revision = 17.2.2
|
||||
revision = 17.2.14
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida/lwip.git
|
||||
revision = 267d9f082e9e38083b643421a93c03d4a7046fd0
|
||||
revision = 13fb5e0f519cc46dc4cd938808430f60a73f03d4
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
@@ -118,6 +118,9 @@ namespace QuickJS {
|
||||
[CCode (cname = "JS_NewAtom")]
|
||||
public Atom make_atom (string str);
|
||||
|
||||
[CCode (cname = "JS_NewBool")]
|
||||
public Value make_bool (bool v);
|
||||
|
||||
[CCode (cname = "JS_NewInt32")]
|
||||
public Value make_int32 (int32 v);
|
||||
|
||||
|
||||
Reference in new issue
Block a user