Hot answers tagged

30

General Prerequisites When analyzing binaries, it is important to be able to put what is observed into context. For example, how can CPU instructions be differentiated from data in a binary with a non-standard format? This requires some background knowledge of computer systems in general. I would argue that before any attempt at reverse engineering firmware ...


12

Values around FFFFFFFF are used in Cortex-M for exception returns (ECX_RETURN). Currently defined values: 0xFFFFFFF1 - return to Handler mode, restore state from main stack 0xFFFFFFF9 - return to Thread mode, restore state from main stack 0xFFFFFFFD - return to Thread mode, restore state from process stack So the actual branch address is taken from the ...


11

The extra s character added to the ARM instruction mean that the APSR (Application Processor Status Register) will be updated depending on the outcome of the instruction. The status register (APSR) contain four flags N, Z, C and V which means the following: N == 0: The result is greater or equal to 0, which is considered positive, and so the N (negative) ...


11

There is SmartDec, a native-code to C/C++ decompiler. It has two versions. Standalone and plugin to IDA. The latter supports all IDA's architectures, provides full GUI integration - is easy to work with -, makes use of IDA Flirt signatures and will make use of runtime information if you use it together with funcap. There is also Retargetable Decompiler, an ...


11

An ARM object file should contain symbols identifying the regions that are arm code ($a), thumb code ($t) and literal data ($d). You can see these as symbols #4 and #5 in your read-elf output. i.e. offset 0 is arm, offset 8 is thumb obj-dump will output these symbols too if you use the--special-symsoption. Reading the ARM ELF ABI will help you understand ...


11

Currently you can't decrypt iOS apps without a device. The encryption keys are ultimately protected by an unknown key which is burned into the processor and cannot be extracted using software, that's why no "offline" decryption app has been made.


11

So, I have figured it out myself in the end. I'll try to describe the process. First, a bit of background on NAND: it is organized in pages which are grouped into blocks. You can read or write a single page at a time but erasing (which turns all bits to 1s (so bytes to FFs)) can be only done one block at a time (writing can only change bits from 1 to 0 but ...


11

arm64 syscall numbers are defined at: https://github.com/torvalds/linux/blob/v4.17/include/uapi/asm-generic/unistd.h This is a bit confusing since it is quite different from x86 and x86_64 and arm 32-bit which define syscall numbers under arch/, e.g. arch/arm/tools/syscall.tbl for arm 32-bit, but the arm64 file has a comment saying: New architectures should ...


10

While the "GCC compiler" may be the same software (generally speaking), the specific instances used for compiling code here and there can produce quite different output. when compiling GCC itself, you can set hundreds of options, many of them influencing the generated code. even after building the compiler, every specific compile may use additional options, ...


9

Yes, it's because of pipelining. From http://winarm.scienceprog.com/arm-mcu-types/how-does-arm7-pipelining-works.html -- PC (Program Counter) is calculated 8 bytes ahead of current instruction.


9

Update: See this answer for up-to-date information on where ARM64 syscall definitions are found. Note that the information below may just be for backwards-compatibility. See arch/arm64/include/asm/unistd32.h: ... #define __NR_restart_syscall 0 __SYSCALL(__NR_restart_syscall, sys_restart_syscall) #define __NR_exit 1 __SYSCALL(__NR_exit, sys_exit) #...


9

There're two broad ways in which you can declare JNI functions. The first is the more obvious way in which the JNI function has to follow a specific naming convention like JNIEXPORT void JNICALL Java_com_app_foo_bar. You can easily identify such functions using readelf. The other not so obvious way is to use RegisterNatives. Here your functions can have ...


9

This doc may be interesting for you: https://github.com/CAS-Atlantic/AArch64-Encoding


8

Usual ADD doesn't update flags. ADDS does. See better documentation at arm infocenter. As it wrote there: If S is specified, these instructions update the N, Z, C and V flags according to the result.


8

If it is ARM architecture that may use THUMB encoding it can be result of the following issue: If I remember correctly, calls to the virtual functions can be executed with assembly command similar to BLX as indirect jump, which allows switching between ARM and THUMB encoding. In this case this + 1 means that the target of the jump is encoded in THUMB. See ...


7

Here's what IDA considers a return in ARM: RET (=MOV PC, LR) POP {reglist} if reglist includes LR or PC LDMFD SP, {reglist}, LDMED SP, {reglist} or LDMDB R11, {reglist} if reglist includes LR or PC LDR PC, [SP], #4 BX LR BX reg if preceded by POP {reglist} and reglist includes reg.


7

According to documentation the first one is base object destructor and the second one is deleting destructor. Constructors and destructors are simply special cases of <unqualified-name>, where the final <unqualified-name> of a nested name is replaced by one of the following: <ctor-dtor-name> ::= C1 # complete object constructor ...


7

Libraries like STL or Boost are tricky. Because they're heavily template-based and most of their code is generated at compile time, it's pretty difficult to make FLIRT-style signatures for them. Too much depends on the specific compiler, build options, optimization settings and so on, so unless you match them pretty closely when generating signatures, you're ...


7

The ! denotes writeback of the base register. Base register is the register used to address the memory to be read or written - in your case it's R4. Writeback means that the base register will be updated with the delta equal to the size of transferred data. So, the instruction ldm r4!, {r0, r1, r2, r3} can be represented by the following pseudocode: r0 =...


7

As you need just 2 more bytes, you don't need a large code cave. Out of the box, there are four things you can try: It's very likely you have a function or 2 in your text segment that are present in some source code, but never called. Look for loc_XXXX labels that have the standard function prefix (push ....,LR) and the suffix (pop ....,PC) a few dozen ...


7

I generally try to avoid booting the whole embedded OS when analyzing a target system. Instead, try to run a single target binary with qemu-system-arm -E PATH="/bin:/usr/bin" -E OTHERENVVARS=foo -g 10000 ./myTargetBinary. See slides 27+ in my presentation https://files.sans.org/summit/hackfest2015/PDFs/IoT-Devices-Fall-Like-Backward-Capacitors-Or-the-Month-...


7

So to make an order from the comments - you can do it by using two approaches. Use the original opcodes and write them using wx which stands for "write hex": wx e10b00f9 If you still want to use wa you can do this like this: wa str x1,sp,0x10 In general, handling function's local variables can be done using the afv command and subcommands. Execute afv? ...


7

In fact, the behavior you are describing is coming from the usual behavior of the GOT/PLT sections. They are used to dynamically link the program calls to shared libraries functions at runtime. In fact, a shared library can be loaded at any place in the process memory, there is no way to predict statically where it will pop up. So, the GOT/PLT load the ...


6

There are several different calling conventions around on ARM platforms. They vary both according to the processor features (for example, on processors with floating point registers (VFP), it's more efficient to pass floats around in them, but you lose compatibility with processors without VFP) and according to the operating system. A given installation of ...


6

By default, as, uses the old 'divided' syntax for arm and thumb instructions. Hence it is not recognising your pop.w instruction. To make it work, add .syntax unified at the start of your program. This tells it to use the new unified syntax and you should find it assembles pop.w successfully. See https://sourceware.org/binutils/docs-2.24/as/...


6

From http://bear.ces.cwru.edu/eecs_382/ARM7-TDMI-manual-pt2.pdf: E1F322D1 equals 11100001111100110010001011010001 in binary. Your question is specific to the offset, so we can examine the last dozen bits of that binary string with regard to the decomposition rules in the screenshot above: ... Offset 1 SH 1 Offset ... 0010 1 10 1 0001 Thus, the high ...


6

I am a developer of the Rockbox open-source project. We figured out the encryption of the firmware upgrade a look time ago by essentially doing the same thing (dumping the chip). upgtool can extract the firmware from UPG tools, those can be extracted from the firmware upgrade installer using cabextract and looking at the file Data/Device/NW_WM_FW.UPG It ...


6

Obstacles One of the difficulties associated with analyzing firmware is that firmware binaries do not usually have a standard format and do not segregate code and data in a standard manner like ELF or PE binaries do. The absence of clearly identifiable partitions within firmware binaries that allow for fast and accurate identification and differentiation ...


6

For the first instruction (0x90000008) it matches the opcode below for PC relative addressing instruction. 0x90000008 = 0b10010000000000000000000000001000 so we have op=1 (ADRP), immlo=0, immhi=0 and Rd=8 (X8). The instruction decodes to ADRP X8, #0. This is going take the current page the instruction pointer is at, add 0<<12, and store in register ...


Only top voted, non community-wiki answers of a minimum length are eligible