Talking about the debugging of the shelled ELF (that is, the android so file), elfandroid

Source: Internet
Author: User

Talking about the debugging of the shelled ELF (that is, the android so file), elfandroid

This article only discusses how to debug the shelled ELF file, including the use of Debugging techniques and solutions to possible problems during debugging, DEX does not contain how to restore the reinforcement. This article will take a shell program and a reinforcement as the target.

1. Introduction to ELF format

ELF stands for Executable and Linkable Format, which is an Executable file Format in Linux.

This file format is the same as that in WINDOWS. It can be divided into two types:

1. Executable File, which corresponds to the PE subtype: EXE

2. Shared Object File (Shared Object File), suffixed with. so, corresponding to PE subtype: DLL

Ii. ELF File Loading Process

1. Load the required image data through Section Header or Program Header

Unlike windows pe, some ELF file data is not loaded into the memory image.

2. load so need lib and SYM

Import_table similar to PE

3. Execute relocation (if any)

Reloc_table similar to PE

4. Run the INIT_ARRAY or INIT segments (if any, the address in the array is not equal to 0 xffffffff, and 0 indicates the end)

Similar to the TLS of PE, the known ELF shelled ELF and shell code appear in these two sections.

TLS in PE is often found in shells, such as Vmprotect and Execryptor.

5. Execute the entry point code (if any)

All the above loading process code is included in linker. so. For details, see Android source code or reverse linker. so.

Iii. Introduction to ARM CPU
1. Instruction Set Overview

ARMCPU adopts the Reduced Instruction Set architecture (X86 is a CISC, Complex Instruction Set) and has a long instruction set. Compared with the CISC architecture, ARMCPU saves power and improves execution efficiency.

2. Three ARM Instruction Sets

ARM (4-byte), THUMB (2-byte), and THUMB2 (4-byte ). The three instruction sets can be switched in the same execution program. The switching principle is as follows:

ARM <-> THUMB, THUMB <-> ARM (the highest bit of the PC determines the instruction set type: 1 is THUMB; 0 is ARM)

THUMB <-> THUMB2 (determined by the 27-31 bits)

Thumb2 is actually an extension of thumb. It aims to complete multiple 2-byte commands for a 4-byte command.

3. Registers

General registers: r0-r15

Special Registers: r13 = SP (stack address), r14 = LR (function return address), r15 = PC (current instruction stream address)

It also includes CPSR, APSR, floating point and other registers. For details, refer to the ARM Instruction Set manual.

4. shell SO debugging

1. ELF code execution sequence

As described above, the SO shell code of shelling is in the INIT_ARRAY and INIT segments.

Let's first look at the SO after being shelled. in linux, run the readelf-a command to view ELF information:

 

 

In ELF-HEADER, we can see an Entry with the address 0x22a8.

The INIT_ARRAY array is displayed in the dynamic section. The array address is 0 × 21000, And the size is 12 BYTES.

Use IDA to check the array content:

 

As mentioned above,-1 is invalid, and 0 indicates the end. The INIT valid address is only 0 × 2418.

That is to say, after the SO is loaded, it will start from the address 0 × 2418 and then execute the Entry after the execution is complete.

Let's take a look at the reinforced ELF information:

 

 

In ELF-HEADER, we can see that there is an Entry with the address 0 × 3860:

 

When IDA opens a reinforced file, it will prompt an error and cannot open it. The following explains why in Anti-Anti Debugger.

The INIT_ARRAY array is displayed in the dynamic section. The array address is 0x28CA4 and the size is 8 BYTES.

We also see the INIT segment with the address 0 × 11401.

Here, we will summarize the execution sequence:

According to the linker code, when both the INIT and INIT_ARRAY segments exist, run the INIT segment first and then the INIT_ARRAY segment. Otherwise, run the corresponding function separately and finally execute the ENTRY:

 

2. Prepare SO_LOADER yourself

Debugging SO and PE_DLL is actually the same. Both require a host process. here we need to write a SO_LOADER. Refer to the code below and compile it through NDK. (The code was provided by Wang Chen at an early stage ):

 

3. Prepare the environment

Here I use IDA6.6 as the debugger.

Step 1: copy the debugger to your Android phone:

 

Command: adb push android_server/data/local/tmp/and

Why do we change the name of android_server to "and ~~~, In fact, this is to prevent the Debugger from being detected. I will detail this part in Anti-Anti Debugger later.

Step 2: Start the debugger

Enter the/data/local/tmp/directory and start the debugger.

 

Step 3: redirect the debugging port

Adb forward tcp: 23946 tcp: 23946

So far, the mobile phone end has been set up. Let's see how to set it in IDA.

IDA loads our own so_loader. At 854C, press the F2 breakpoint:

 

Select Debuger-Select Debugger in the menu bar and Select Remote Arm linux/Andoid debugger

 

Click OK and run F9:

 

In configuration, enter 127.0.0.1 in Hostname and click OK.

If this file does not exist on your mobile phone, you will be prompted to COPY it. Click OK. If this file exists, the following options will appear. You can select USE FOUND, if the program you want to debug has been modified, select copy new to overwrite a NEW one.

 

Then all the way to OK, the debugging status will appear ~~, The current PC is the breakpoint we set in F2 just now:

 

4. How to break the SO INIT_ARRAY and INIT segments

As mentioned above, SO is loaded in linker. so. What we need to do is to set the breakpoint in linker. so.

Find the code first. IDA opens linker. so and finds it in the string window.

Call_constructors_recursive, double-click and view the reference:

 

 

Double-click the second reference, and then find blx r3 (call the init segment), B. w xxxxxxxx (call the init_array segment ):

 

 

Now we have found the address 0x54d0 and 0x3af0, and return to the IDA we just debugged.

Choose debugger-Debugger windows-module list on the menu bar to open the process module list:

 

The base of linker. so is 40002000, which corresponds to the following two addresses:

0 × 40002000 + 0x54d0 = 0x400074d0

0x40002000 + 0x3af0 = 0x40005af0

GO in the IDA View-PC window:

 

At 0x74d0, press the C key to turn it into code. Strange, why didn't it respond !! The following prompt is displayed in the bottom output window:

 

Here is a very important question. As I mentioned above, the program to be debugged can be switched between the three instruction sets, at this time, IDA does not know whether the current Code address is ARM or THUMB. In this case, we need to compare it with static, or you are absolutely familiar with the instruction set, you can see the byte code to know which instruction set is used:

 

In static mode, IDA obviously gives a 2-byte command, which must be THUMB. We need to change the current address to THUMB.

Method: press ALT + G on the keyboard to call out the window:

 

T, DS don't worry about it. We just need to change the VALUE to 1, which is the THUMB instruction set, to 1 and click OK.

CODE16 appeared on the original address, and then we went to C again:

 

After C, the code will appear !!! This is how ARM and THUMB switch. Remember:

 

Let's look at another address, 0x400a5af0, and try again in the same way:

 

The problem comes again. It's strange. Why isn't the command below ?! This is IDA's BUG. In analyticdb 6.6, the parsing of the THUMB2 command in the debugging status is problematic... but it doesn't matter. Let's look at it:

 

This code is the most important. Execute the address function in every init_array in blx r2.

So far, we have finished talking about how to break the INIT and INIT_ARRAY segments. Let's debug the rest!

5. Anti Debugger

1. Anti IDA

In fact, this problem is caused by the inconsistency between ida elf and linker ELF, and IDA is more rigorous.

Use ida to open a reinforced so, and the prompt is:

 

This prompt indicates that a data description is invalid. Let's see which one is.

SHT is about Section Table. Let's take a look at the ELF header data as follows:

 

Shoff is the value. Let's use the hexadecimal editor to see it:

 

All are 0. Obviously there is a problem here. First, we need to clear the value 0 and save the file.

Re-load, there are still problems, the prompt is as follows:

 

After debugging IDA's ELF plug-in, this error occurs when the physical offset in the program header is greater than the file size.

 

Apparently, p_offset of the first group of data in the Program Header exceeds the file size. According to the ELF structure, the data offset is located and changed to 0. IDA is loaded successfully.

2. Anti Debugger

Debug the shelling program and summarize the methods used.

Method 1: Check the file name of the parent process

Call getppid to obtain the id of the parent process. open ("/proc/ppid/cmdline") to obtain the name of the parent process and check the name of the common debugger. This is the name of the above COPY file, why do we need to change android_server to a random file name.

Countermeasure: Modify the return value of getppid. Just give it a usable one.

In fact, there are other ways to get the ppid, such as open ("/proc/pid/status"), read the handle content, and find the ppid in it.

Method 2: exception traps

Similar to WINDOWS, you can set a trap to detect the debugger.

Countermeasure: by default, all traps of IDA are handled by the debugger, so we need to modify the corresponding settings. Select debugger-debugger options from the menu, and click edit exceptions.

 

On trap, right-click and edit it as follows:

 

Of course, there are still many ways to check the debugger. You can refer to the recruitment and splitting methods. I will not detail them here.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.