Skip to content

Challenges and Solutions

Sam Duy edited this page May 31, 2018 · 1 revision

While doing the project, we tackled 4 main challenges.

  • Generate input files to make a uClinux profile (related to Step 1).
  • Implement new Address Space for uClinux in Volatility (Step 2).
  • Fixed issues with Linux signatures (Step 3,4).
  • Fixed issues with how plugin works (Step 7)

Challenge 1: Creating a new profile

Challenge

Creating a new profile Some source code compilation is needed (to generate modules.o), then using another tool: dwarfdump to generate the file.

Require physical access to the machine.

Many embedded systems removed this file (and all the debug symbols information).

Solution

For the first phase, we decided to utilize QEMU with the original source code of uClinux. (Machine: ARM Versatile PB. uClinux version: 20160919 release, v4.4.0).

Challenge 2: Implement new Address Space for uClinux in Volatility

Challenge

Creating a new profile

Solution

Currently, all current Address Spaces are failed: Due to wrong signatures or Address translation failed.

uClinux memory dump (in our test) matches with the ARM Address Space. However, the vtop() of ARM AS mis-translates the addresses. (It doesn’t take into account virtual_is_physical case).

class UClinuxAddressSpace(arm.ArmAddressSpace):
 
    def vtop(self, vaddr):
          return vaddr

Challenge 3: Fixed issues with Linux signatures

Challenge

Creating a new profile

Volatility hard-coded some signatures (struct names, symbols names) in its source code. Many are correct with newer Linux version only. (e.g. “init_task” was “init_mm” in order Linux version 2.4.x)

Some are invoked without exception handling, caused the program failed unnecessarily (e.g. “swapper_pg_dir”).

init_task_addr = self.addr_space.profile.get_symbol("init_task")

Solution

Debug the program and update all the signatures when necessary.

Update some program logics. (e.g. some value such as DTB can be Zero.)

init_task_addr = self.addr_space.profile.get_symbol("init_task")
if init_task_addr is None:
      init_task_addr = self.addr_space.profile.get_symbol("init_mm")

Challenge 4: Fixed issues with how plugin works

Challenge

Creating a new profile

Even plugins also hard-coded some signatures (and not inherit from common or base classes): e.g. “init_task”. And “tasks” member of init_task struct was also named differently in older versions of Linux.

Solution

Update signatures based on Linux source code analysis.

+	if init_mm_flag:
+	    for task in init_task.run_list:
+		yield task
+	else:
+	    for task in init_task.tasks:
+		yield task