8000 Frida ARM64E inspection problem summary · Issue #1025 · frida/frida-gum · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Frida ARM64E inspection problem summary #1025
Open
@ying911008

Description

@ying911008

Problem description

On the macOS ARM64 platform, when a dynamic library is injected into a binary using the insert_dylib tool, Frida mistakenly identifies a normal ARM64 program as an ARM64E architecture, causing the hook function to not work properly.

Reason analysis

Source code analysis reveals that the problem is in the ARM64 Darwin implementation of the gum_do_query_cpu_features function:

static GumCpuFeatures
gum_do_query_cpu_features (void)
{
  GumCpuFeatures features = 0;
  GumDarwinAllImageInfos infos;
  GumDarwinCpuSubtype subtype;

  gum_darwin_query_all_image_infos (mach_task_self (), &infos);

  subtype = *((GumDarwinCpuSubtype *) (infos.dyld_image_load_address + 8));
  if ((subtype & GUM_DARWIN_CPU_SUBTYPE_MASK) == GUM_DARWIN_CPU_SUBTYPE_ARM64E)
    features |= GUM_CPU_PTRAUTH;

  return features;
}

Instead of reading the CPU subtype of the Mach-O header directly, Frida detects it by:

  1. Call gum_darwin_query_all_image_infos to obtain dyld information
  2. Read the CPU subtype from the dyld load address offset by 8 bytes
  3. Check whether the subtype is ARM64E
    When the insert_dylib tool is used to inject the dynamic library, it may modify parts of the binary, causing the layout of the dyld in memory to change after it loads, causing Frida to read the CPU subtype information from the wrong place.

Repeat step

  1. Create a normal ARM64 binary file
  2. Use the insert_dylib tool to inject dynamic libraries
  3. Use Frida to try the binary after hook injection
  4. Observed that Frida incorrectly identified the program as the ARM64E architecture (confirmed by the CPU attribute value of 0x40)

Solution suggestion

It is recommended to modify the gum_do_query_cpu_features function to use a more reliable method to detect CPU subtypes:

static GumCpuFeatures
gum_do_query_cpu_features (void)
{
  GumCpuFeatures features = 0;
  
  // 使用 Mach-O 头部直接检测 CPU 子类型
  const struct mach_header_64 *header = NULL;
  header = (const struct mach_header_64 *)_dyld_get_image_header(0);
  
  if (header != NULL) {
    // 直接从 Mach-O 头部读取 CPU 类型和子类型
    if (header->magic == MH_MAGIC_64 && 
        header->cputype == CPU_TYPE_ARM64 &&
        (header->cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64E) {
      features |= GUM_CPU_PTRAUTH;
    }
  } else {
    // 如果无法获取头部,回退到原来的方法
    GumDarwinAllImageInfos infos;
    GumDarwinCpuSubtype subtype;
    
    gum_darwin_query_all_image_infos (mach_task_self (), &infos);
    subtype = *((GumDarwinCpuSubtype *) (infos.dyld_image_load_address + 8));
    if ((subtype & GUM_DARWIN_CPU_SUBTYPE_MASK) == GUM_DARWIN_CPU_SUBTYPE_ARM64E)
      features |= GUM_CPU_PTRAUTH;
  }
  
  return features;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0