Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2024] AArch64 support #1088

Open
wants to merge 42 commits into
base: develop
Choose a base branch
from

Conversation

Abyss-W4tcher
Copy link
Contributor

@Abyss-W4tcher Abyss-W4tcher commented Jan 20, 2024

Hi 👋,

This PR provides AArch64 integration to the Volatility3 framework, as well as a design rework in the current linux stacker.

Implementation follows ARM official documentation, and includes essential APIs for higher level code (plugins etc.).

You can follow the roadmap here :


My ressources :


Testing :

  • RaspberryPi (virtual) : Linux version 6.1.21
  • Android AVD (virtual) : Linux version 3.18.94
  • RaspberryPi (physical) : Linux version 6.1.0-rpi8-rpi-v8
  • Google Pixel 6A (physical) : Linux version 5.10.157-android13-4-00003-g830b023b88f3-dirty
  • Jetson lime (physical) : Linux version 4.9.201-tegra
  • NXP LX2160 (physical) : Linux version 6.1.36

Thanks to everyone who took the time to test this PR on their devices !


Unstable plugins :

  • linux.bash :
    • sections have no size on Android related samples.
    • 12/04/24 update : Android does not ship with bash by default, as it's not GNU/Linux running on the system . Either we need a dedicated plugin (.ash_history ?), or a check to tell users why the plugin isn't working.
  • linux.lsof :
    • dentry members can be NULL, and this behaviour isn't handled (more informations in the dedicated Slack thread)

Please note that this is still experimental, testing is still going on. If you want to try this PR out, here are the steps :

  • Merge/checkout the PR into your local Volatility3 copy (git checkout aarch64-support)
  • Make a memory capture of your AArch64 device (see attached ressources)
  • Create the ISF against the vmlinux file with dwarf2json
  • Set the following on top of the plugins you plan to use :
requirements.ModuleRequirement(
      name="kernel",
      description="Linux kernel",
      architectures=["Intel32", "Intel64", "AArch64"],
)

If you have any real-life samples to provide, or if you encounter any error, feel free to comment below !

Copy link
Member

@ikelos ikelos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for this, it looks awesome! I haven't been through it all, I've most concentrated on the arm layer at the moment (and I haven't made my way through all of that). The comments pointing to the location of useful documentation is massively useful and very much appreciated! 5:D There's a few little bits that can be cleaned up but on the whole it looks perfectly in line with the rest of volatility, so good work! It'll take me a while to find time to go through more of it, and check the various references to fully get what's going on.

I'm trying to figure out the split between mapping and _mapping, it looks like _mapping returns every chunk, and mapping coalesces them together is that about right? I think that's probably for the best, but it feels like it makes for bulky code somehow. Really excited to see where this codes (and find some Windows-on-arm samples to try it against too!). 5:D

kaslr_shift = init_task_address - cls.virtual_to_physical_address(
init_task_json_address
)
if layer_class == arm.AArch64:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than changing the API, it should be possible to derive this by getting the layer using layer_name and then doing an if on the class of the layer. The if statement feels a little ugly though, since it'll need support for every layer that comes about. It might be worth separating this out into a class that can be attached to each class, so that a new layer class can be introduced without tinkering with this code in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the whole find_aslr function worked out of the box, without the need to use the virtual_to_physical_address function, I did this quick fix to avoid repeating the whole function (separating in find_aslr_aarch64 and find_aslr_intel).

But if in the future we have to add some other specific AArch64 code to find_aslr (e.g. handle some retrocompatibility), we will eventually do a clear separation. So I guess we could do it directly even if the code will be 99% the same ?

)
self._base_layer = self.config["memory_layer"]
# self._swap_layers = [] # TODO
self._page_map_offset = self.config["page_map_offset"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two pages maps as part of AArch64, aren't there? Which one should people provide here? Might be better to use the terminology used by the architecture here, rather than reusing values used elsewhere...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the Linux Stacker, we are instantiating the kernel Layer. We pass the kernel DTB (Translation Table Base 1 Base Address) to the AArch64 layer. There is in fact a unique page map for the whole kernel, stored in ARM register TTBR1, and a page map for the user land stored in TTBR0. TTBR0 is not constant, and changes on every process context switch. What this means, is that TTBR0 is changed to the value of the current process DTB (which happens continuously).

For me, there are only two possible callers to this layer :

  • LinuxStacker (kernel, only once)
  • "Processes"

People should not have to instantiate the kernel layer twice, but only user space layers (programs) ? In another comment I detailed how I implemented a check to facilitate this.

# self._swap_layers = [] # TODO
self._page_map_offset = self.config["page_map_offset"]
self._tcr_el1_tnsz = self.config["tcr_el1_tnsz"]
self._page_size = self.config["page_size"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this part of the architecture, or is it dynamic, or is it something pre-defined?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • _page_map_offset is the DTB (either kernel or specific to a process). For the kernel, it can be calculated thanks to the existing Intel implementation. For the process, I don't know exactly where, but it is stored in the task_struct directly if I'm not mistaken.
  • _tcr_el1_tnsz : The size offset of the memory region addressed by TTBR1_EL1. The region size is 2(64-T1SZ) bytes -> See page 7081 of the doc. It is defined in the kernel config, but we cannot predict it (it is calculated in LinuxStacker).
  • _page_size : Page size (4, 16 or 64 KB), also defined in the kernel config, but we cannot predict it (it is calculated in LinuxStacker).

self._tcr_el1_tnsz = self.config["tcr_el1_tnsz"]
self._page_size = self.config["page_size"]

# Context : TTB0 (user) or TTB1 (kernel)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this layer will only cope with one of user or kernel? That might be complex to handle in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This layer needs to be instantiated one time for the kernel, and as many times as there are processes. End users should not have to instantiate the kernel layer twice, and instantiating a process layer is basically the same as the Intel logic (I think mostly of malfind, which I used to validate the processes layers translations).

49
if self._ttbs_granules[ttb] in [4, 16] and self._is_52bits[ttb]
else 47,
self._ttb_lookups_descriptors[ttb][-1][1],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be handy to have some descriptions of what the array looks like somewhere (maybe in the docstring for _determine_tbbs_lookup_descriptors), otherwise it's difficult to tell what the last element would contain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted, I will take a look !

)
level += 1

if AARCH64_TRANSLATION_DEBUGGING:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, probably better to have a togglable instance variable, rather than a global module variable.

name="memory_layer", optional=False
),
requirements.IntRequirement(name="page_map_offset", optional=False),
requirements.IntRequirement(name="page_map_offset_kernel", optional=False),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This... doesn't look like it's used anywhere, and anything related to the kernel shouldn't be a requirement of the layer to operate, it should be optional, because the architecture should be able to map with or without a kernel?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"page_map_offset_kernel" is instantied once by the LinuxStacker, when creating the kernel layer. This implies that any other caller will try to stack in user space, without passing "page_map_offset_kernel" but only "page_map_offset" (it is the same naming as Intel, to avoid rewriting everything). Thanks to how the framework is designed, the class will still be able to access "page_map_offset_kernel", which indicates what is the current context (am I being instantiated for user space or for kernel space ?). See :

self._virtual_addr_space = (
            self._page_map_offset == self.config["page_map_offset_kernel"]
        )

self._virtual_addr_space = 0 -> we are in user space/context (TTB0)
self._virtual_addr_space = 1 -> we are in kernel space/context (TTB1)

Additionally, we need to keep track of the context, because of this part :

        # Check if requested address belongs to the context virtual memory space
        if ttb_selector != self._virtual_addr_space:
            raise exceptions.InvalidAddressException(
                layer_name=self.name,
                invalid_address=virtual_offset,
            )

Making the page_size or tcr_el1_tnsz options optional isn't viable, because they are constant for their whole spaces. In my sense, calculating everything once and for all in the LinuxStacker, allows compatibility with existing LinuxIntel APIs and facilitates higher layers stacking. As pointed out, Volatility will keep track of the previous config options for layers stacking on top of the AArch64 one.

),
requirements.IntRequirement(name="page_map_offset", optional=False),
requirements.IntRequirement(name="page_map_offset_kernel", optional=False),
requirements.IntRequirement(name="tcr_el1_tnsz", optional=False),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can actually provide a description field with requirements, which might be quite handy here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted, I will take a look !

requirements.TranslationLayerRequirement(
name="memory_layer", optional=False
),
requirements.IntRequirement(name="page_map_offset", optional=False),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might also be good to provide a description here (as noted later, Requirement classes can take a description attribute. Just some clarification on exactly what this would be for arm, since it's not quite as obvious as with intel....

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted, I will take a look !

def maximum_address(cls) -> int:
return (1 << cls._maxvirtaddr) - 1

def __canonicalize(self, addr: int) -> int:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two don't appear to get called from anywhere and are strictly private? Are they necessary? If they can't be depended on in children of this class, then they don't seem all that useful?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inspired from : https://github.com/volatilityfoundation/volatility3/blob/develop/volatility3/framework/layers/intel.py#L93 and https://github.com/volatilityfoundation/volatility3/blob/develop/volatility3/framework/layers/intel.py#L119.

I realize now that I messed up the visibility of canonicalize, and will fix it. I did not investigated which higher level code was likely to use these functions, but it definetely crashed when they were missing.

@Abyss-W4tcher
Copy link
Contributor Author

Hi @ikelos, thanks for your quick replies !

I will check every of your comment right now, as I have some spare time. Regarding your general concern regarding mapping, it is more or less the exact Intel implementation from https://github.com/volatilityfoundation/volatility3/blob/develop/volatility3/framework/layers/intel.py#L271. It worked well out of the box for this layer :).

@ikelos
Copy link
Member

ikelos commented Jan 21, 2024

Hehehe, yeah, I figured it might be. That's not too sweet the intel layer isn't overly complicated but it's fine for now. If you find any ways of simplifying it we can back port then to intel too... 5;D

@Abyss-W4tcher
Copy link
Contributor Author

Abyss-W4tcher commented Jan 22, 2024

Here is what a typical layer instantiation debug looks like :

Kernel layer instantiated by LinuxStacker and a higher stacker :

DEBUG    volatility3.framework.automagic.linux: Linux ASLR shift values determined: physical -ffffffbfc7e00000 virtual 172a600000
DEBUG    volatility3.framework.layers.arm: Base layer : Elf64Layer
DEBUG    volatility3.framework.layers.arm: Virtual address space : kernel
DEBUG    volatility3.framework.layers.arm: Virtual addresses space range : ('0xffffffc000000000', '0xffffffffffffffff')
DEBUG    volatility3.framework.layers.arm: Page size : 4
DEBUG    volatility3.framework.layers.arm: T1SZ : 25
DEBUG    volatility3.framework.layers.arm: Page map offset : 0x41963000
DEBUG    volatility3.framework.layers.arm: Translation mappings : [(38, 30), (29, 21), (20, 12)]
DEBUG    volatility3.framework.automagic.linux: Kernel DTB was found at: 0x41963000
DEBUG    volatility3.framework.automagic.linux: AArch64 image found
DEBUG    volatility3.framework.layers.arm: Base layer : memory_layer
DEBUG    volatility3.framework.layers.arm: Virtual address space : kernel
DEBUG    volatility3.framework.layers.arm: Virtual addresses space range : ('0xffffffc000000000', '0xffffffffffffffff')
DEBUG    volatility3.framework.layers.arm: Page size : 4
DEBUG    volatility3.framework.layers.arm: T1SZ : 25
DEBUG    volatility3.framework.layers.arm: Page map offset : 0x41963000
DEBUG    volatility3.framework.layers.arm: Translation mappings : [(38, 30), (29, 21), (20, 12)]

Processes layers instantiated by malfind :

DEBUG    volatility3.framework.layers.arm: Base layer : memory_layer
DEBUG    volatility3.framework.layers.arm: Virtual address space : user
DEBUG    volatility3.framework.layers.arm: Virtual addresses space range : ('0x0', '0x3fffffffff')
DEBUG    volatility3.framework.layers.arm: Page size : 4
DEBUG    volatility3.framework.layers.arm: T0SZ : 25
DEBUG    volatility3.framework.layers.arm: Page map offset : 0x47266000
DEBUG    volatility3.framework.layers.arm: Translation mappings : [(38, 30), (29, 21), (20, 12)]

DEBUG    volatility3.framework.layers.arm: Base layer : memory_layer
DEBUG    volatility3.framework.layers.arm: Virtual address space : user
DEBUG    volatility3.framework.layers.arm: Virtual addresses space range : ('0x0', '0x3fffffffff')
DEBUG    volatility3.framework.layers.arm: Page size : 4
DEBUG    volatility3.framework.layers.arm: T0SZ : 25
DEBUG    volatility3.framework.layers.arm: Page map offset : 0x47928000
DEBUG    volatility3.framework.layers.arm: Translation mappings : [(38, 30), (29, 21), (20, 12)]

Check out memory samples here [7 days] :

return self._page_is_dirty(self._translate_entry(offset)[2])

@staticmethod
def _page_is_dirty(entry: int) -> bool:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dirty state is hardware managed only > Armv8.1-A. It is software managed by Linux (bit 55), so we can use it reliably and for all Arm versions.

However, we need to know how Windows manages it (add a class WindowsMixIn(AArch64) which overwrites _page_is_dirty), or directly use the hardware managed version for any OS, but it won't work for memory dumps < Armv8.1-A.

[1], see D8.4.6, page 5877 and [1], see D8.4.6, page 5877 and https://developer.arm.com/documentation/102376/0200/Access-Flag/Dirty-state


# Never stack on top of an intel layer
# Never stack on top of a linux layer
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To improve this, why not add an explicit layer property, like _is_top_layer inside volatility3/framework/layers/intel.py#Intel and volatility3/framework/layers/arm.py#AArch64 and check with following :

        if getattr(layer, "_is_top_layer") and layer._is_top_layer:
            return None

If we keep the current implementation, we have to change the Linux, Windows and Mac stacker for each new architecture layer.

Copy link
Member

@ikelos ikelos Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of the reason is virtualization, it's possible to have an arm layer inside an intel layer (and it's certainly possible to have an intel layer on top an intel layer). You're right, it's not really a scalable solution (hence the FIXME right beneath this line), but it's also not a trivial attribute...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which stacker is supposed to do this (LinuxStacker, WindowsIntelStacker and MacIntelStacker blocks it), for example if a VM managed by qemu-system-aarch64 on an Intel host was running when the memory was dumped ?

Will a "VM (qemu) layer" be available from the globals context.layers variable too :

  • FileLayer
    • LimeLayer
      • IntelLayer
        • Memory Layer
        • QemuLayer (not sure about this one)
          • IntelLayer
            • Memory Layer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is anything automatic in core that would do that, but it would be nice to have.

There has been this issue from a while ago that talks about that kind of thing.
#464

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing it out :) So in the current state, as it is not implemented, we will continue to strictly refuse stacking on top of Linux and AArch64. Adding an explicit flag on those two might be a temporary and more scalable solution ?

I leave this as a side note, for a potentiel reader in the future interested in AArch64 hypervisor execution mode (and what it might imply, if treating a layer from the hypervisor point of view) : https://developer.arm.com/documentation/102412/0103/Privilege-and-Exception-levels/Exception-levels

@garanews
Copy link
Contributor

@Abyss-W4tcher I am trying your branch 👀
Target:

uname -a
Linux instance-20221125-1059 5.15.0-1040-oracle #46-Ubuntu SMP Fri Jul 14 21:47:21 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.3 LTS
Release:        22.04
Codename:       jammy

Dump:

sudo insmod /var/lib/dkms/lime-forensics/1.9.1-3/5.15.0-1040-oracle/aarch64/module/lime.ko "path=/tmp/arm_ram.lime format=lime"

Symbol creation:

sudo apt install linux-image-5.15.0-1040-oracle-dbgsym
dwarf2json linux --elf  /usr/lib/debug/boot/vmlinux-5.15.0-1040-oracle >  ubuntu_arm_5.15.0-1040.json 

Updated the pslist plugin adding AArch64 and run it:

python vol.py -vvvvvvvvvvvvvvv  -f arm_ram.lime linux.pslist

OUTPUT:

Level 6  volatility3.framework: Importing from the following paths: C:\ioc\volarm\volatility3\volatility3\framework\layers
Level 6  volatility3.framework: Importing from the following paths: C:\ioc\volarm\volatility3\volatility3\framework\layers
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.kernel.symbol_table_name
Level 6  volatility3.framework: Importing from the following paths: C:\ioc\volarm\volatility3\volatility3\framework\layers
Level 9  volatility3.framework.automagic.construct_layers: Failed on requirement: plugins.PsList.kernel.symbol_table_name
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.kernel.symbol_table_name
Level 9  volatility3.framework.automagic.construct_layers: Failed on requirement: plugins.PsList.kernel
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.kernel.symbol_table_name
Level 9  volatility3.framework.automagic.construct_layers: Failed on requirement: plugins.PsList
Level 6  volatility3.framework: Importing from the following paths: C:\ioc\volarm\volatility3\volatility3\framework\layers
Level 6  volatility3.framework: Importing from the following paths: C:\ioc\volarm\volatility3\volatility3\framework\layers
Level 6  volatility3.framework: Importing from the following paths: C:\ioc\volarm\volatility3\volatility3\framework\layers
Level 6  volatility3.framework: Importing from the following paths: C:\ioc\volarm\volatility3\volatility3\framework\layers
Level 6  volatility3.framework: Importing from the following paths: C:\ioc\volarm\volatility3\volatility3\framework\layers
DEBUG    volatility3.framework.automagic.stacker: physical_layer maximum_address: 25763184799
DEBUG    volatility3.framework.automagic.stacker: Stacked layers: ['IntelLayer', 'LimeLayer', 'FileLayer']
INFO     volatility3.framework.automagic: Running automagic: SymbolFinder
INFO     volatility3.framework.automagic: Running automagic: LinuxSymbolFinder
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.kernel.symbol_table_name
DEBUG    volatility3.framework.automagic.symbol_finder: Identified banner: b'Linux version 5.15.0-1040-oracle (buildd@bos01-arm64-037) (gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #46-Ubuntu SMP Fri Jul 14 21:47:21 UTC 2023 (Ubuntu 5.15.0-1040.46-oracle 5.15.111)\n\x00'
DEBUG    volatility3.framework.automagic.symbol_finder: Using symbol library: file:///C:/ioc/volarm/volatility3/volatility3/symbols/ubuntu_arm_5.15.0-1040.json
INFO     volatility3.schemas: Dependency for validation unavailable: jsonschema
DEBUG    volatility3.schemas: All validations will report success, even with malformed input
INFO     volatility3.framework.automagic: Running automagic: KernelModule

OFFSET (V)      PID     TID     PPID    COMM    File output
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!assoc_array_ptr
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!netns_ipvs
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!mtd_info
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!can_pkg_stats
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!can_rcv_lists_stats
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!can_dev_rcv_lists
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!mpls_route
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!sctp_mib
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!smc_stats_rsn
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!smc_stats
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!dn_dev
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!garp_port
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!macsec_ops
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!mctp_dev
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!mpls_dev
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!mrp_port
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!tipc_bearer
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!udp_tunnel_nic
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!pcpu_dstats
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!phylink
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!cfg80211_conn
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!cfg80211_cached_keys
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!cfg80211_cqm_config
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!cfg80211_internal_bss
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!sfp
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!libipw_device
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!smc_hashinfo
DEBUG    volatility3.framework.symbols: Unresolved reference: symbol_table_name1!dsa_8021q_context


Any suggestion? 👅

@Abyss-W4tcher
Copy link
Contributor Author

Abyss-W4tcher commented Feb 16, 2024

Hi @garanews, could we discuss about it in Slack DMs, to avoid filling the PR with comments ?

I'll post a summary here if we get this fixed :)

edit : The branch wasn't correctly merged. Be sure to do git checkout aarch64-support in your local copy. 😄Analysis was successful after the merge.

garanews added a commit to LDO-CERT/orochi that referenced this pull request Apr 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants