Hot answers tagged

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 ...


6

This is most likely code that was compiled without optimizations (-O0 ). In such code redundant operations are very common as the compiler faithfully translates individual statements to machine code but does not try to perform optimizations to remove or simplify redundant ones.


6

From Ghidra.re: Sometimes you will see warnings in the decompiler view stating that there are too many branches to recover a jumptable. One reason for this is that there actually is a jump table, but the decompiler can’t determine bounds on the switch variable For your example, this is saying there may a jump table (which is really just an array of ...


5

This general pattern of exclusive-access instructions is usually seen when atomic variables are modified. C++ Example (C++11 or later) #include <atomic> void release( std::atomic<int>& refcount ) { refcount--; } You can see here on godbolt that GCC's ARM64 compilation of the above produces your assembly code. C Example (C11) #...


5

you can right click the file you import at Active Project tab in ghidra main window, and select Set Language


4

This is function dflt (or __aeabi_i2d) from the ARM compiler libraries. It performs a conversion of a 32-bit signed integer in R0 into a a soft-float double (64-bit floating point value) in R0:R1. An IEEE 754 double consists of a sign bit, 11-bit exponent and 52-bit fraction: 63 62 52 51 0 +------------...


4

LDRD R8, R9, [R3, #0x20] - I'm guessing they meant to write 8 words (where a word is 4 bytes long). The same goes for 9 words (instead of bytes) LDRNE R2, [R5, #960]! - 960 is added to the address contained in R5, the value (4 bytes) contained at resulting address is then loaded into R2. Following the load the address which was accessed previously is stored ...


4

There are plenty of non-Linux solutions for embedded systems, ranging from an RTOS such as eCos, FreeRTOS, ThreadX, Nucleus and many others to a completely monolithic, custom made firmware without any specific OS environment. About the only way to find out for sure is to start disassembling and figure out how it works. My old presentation may be of some use ...


3

For the ARM946E-S Technical Reference Manual, the exception vectors (including the reset vector) should be located at either 0x00000000 or 0xFFFF0000 in memory, depending on whether the Alternate vectors select bit is set. The layout of these vectors looks like: Exception | Address ----------------------------|-------------...


3

This sounds analogous to given a document, infer the language. I'd compare the frequency (count for each value in the file) of instructions with the frequency of instructions derived from files for known processor types. Effectively a unigram model. If you source the files in a common format I can give you a hand.


3

This is probably because *ledTimer is volatile. Here's a short bit of code that produces a similar result: int main() { volatile unsigned short *ledTimer{(unsigned short *)0x14f36}; for (--(*ledTimer); *ledTimer; --(*ledTimer)); } Now compile with gcc 8.3.1 with -march=armv7 -O1 and we get something that starts to resemble what you've listed: main: ...


2

Usually all the grounds on the PCB are connected together, so look for something like a metal shield, USB connector housing, or any other element that should be connected to ground (e.g. a capacitor). There may also be big copper areas used for the ground plane.


2

as my previous answer was deleted (I'm guessing because it was not an answer per se) I've got more of an answer for you. the firmware does nothing to stop you from using UART to interact with it except require a login. root login is enabled for such an endeavor and you already have the password in the buildroot.config file. from there you'll need to dig into ...


2

There's a few other options can help you narrow down the specific architecture / core / SoC. Identify which combinations of ARM/THUMB16/THUMB32 instructions it contains. Look at disassembly to identify the offsets of key memory regions (code, data, flash etc) Similarly, SoCs tend to have memory mapped peripherals. Identifying what's being accessed here ...


2

While ARMv7-A does include the Thumb-2 subset used in ARMv7-M, the actually used instructions in ARMv7-A binaries will likely be pretty different from those used in ARMv7-M microcontrollers. For one example, microcontrollers rarely use NEON floating-point or vector instructions from ARMv7-A (Cortex-M4F has FPU but IIRC it’s single precision only). Conversely,...


2

You can't - the Intel hex format doesn't hold this kind of data. You need to manually look for the correct architecture. You can use IDA or Ghidra for that and open in the following for each architecture it might be. Then you need to disassemble the whole file and look if it makes sense. (Control flow, number of functions, xrefs,...) Or of course, use some ...


2

Seems like you've already figured this out, but this is a Ghidra markup. It can be enabled/disabled via Edit -> Tool Options -> Listing Fields -> Operands Field -> Always Show Primary Reference Here's what the help says about the option: Always Show Primary Reference - Option to force the display of the primary reference on all operands.  If a ...


2

ARM implements subtraction using addition with the complement of the second argument. Unusually, this implementational detail is exposed in the carry flag behaviour. The description of the condition flags on page 66 (3-19) of the user guide you link to explains this anomaly - A carry occurs: • ... • if the result of a subtraction is positive or zero • ... ...


2

This is not really related to reverse engineering and might be a better fit for another StackExchange site. That said, I would look into using the x86/x86_64 QEMU with USB passthrough in full-system mode. Basically it will be running a small x86 virtual machine with that driver loaded and passing the USB device directly through to the VM. Then you can set ...


1

routine sub_8081ECE4 seems to subtract 7 bytes from this address 0x8082e7c4 (R1=R7+0x54=0x8082e770+0x54) to data on the stack (I presume that is the entered password). Can you provide bytes @0x8082e7c4? EDIT: The block with a yellow background is some sort of decryption routine, substracting entered char with a byte table @0x8082e770. You need to look closer ...


1

Well, I managed to do it with the add_dref() function: add_dref(frm, to, type) Create a data cross-reference. Parameters: to - linear address of referenced data (C++: ea_t) type - cross-reference type (C++: dref_t) Returns: bool success (may fail if user-defined xref exists from->to) So I can just call this for every resolved symbols: ...


1

It's possible that the kernel is not actually gzip compressed but uses another algorithm. I would recommend using vmlinux-to-elf which can not only automatically detect the compressed stream, uncompress, and convert to an ELF but also parse the kallsyms tables and symbolize the image.


1

Is your binary relocated on load (ASLR)? In that case 14608 points to some random memory (probably unallocated). You need to use a position-independent instruction to load the address of the dlopen stub (e.g. ADRL).


1

Your translation is wrong. The two BIC instructions clear the 13 low bits of the stack pointer (1FC0|3F = 1FFF). In kernel mode, this produces a pointer to the thread_info structure for the current thread. The ldr then reads the field at offset 8 in it which seems to be addr_limit and r3+1 apparently should not exceed it. Combined, the code matches this ...


1

See this answer for details on how branch instructions are encoded on ARM. Here's what you should do: Set Options->General->Number of opcode bytes to 4 (if it was 0 initially) Find any B instruction. Just to make sure you understand it, work out the displacement from pc+8 at the B instruction to the destination, and verify that the displacement in the ...


1

when I set a breakpoint at say 0x010451 It's critical to first understand that there is actually no such valid address for an instruction. On an ARM processor, instructions are always aligned to their width - 16 bit thumb instructions are aligned to 16 bits, 32 bit ARM instructions are aligned to 32 bits, etc. Rather, such values that are not actually ...


1

You are on the right lines with integer division. The first 3 instructions are reasonably clear - R2 after UMULL is the result of an integer division by 1.875 (= 0x100000000 / 0x88888889) the following MOV is then a further integer divide by 8 resulting in R2 now containing the original R3 divided by 15 (= 1.875 * 8) the first RSB is then a multiplication ...


1

No, TCK doesn’t have to match the CPU clock. In fact its usual speed is in kilohertz, not megahertz. However, you likely won’t see it in the oscilloscope or logic analyzer because it is driven by the JTAG probe and not the CPU. Discovering the JTAG pins requires active probing using something like JTAGulator, you are unlikely to find it via passive ...


1

The segment register value applies from one change point until the next or end of segment, so you don't have to set it for each function, just once per segment or a contiguous ARM or Thumb chunk is enough. If you have many wrong intermediate changepoints from previous analysis, you can delete them en masse from the "Jump to segment register..." dialog (Ctrl-...


1

If you touched vector table, first entry is initial value for stack pointer. In the most cases it is set to highest possible RAM address. If it's for example 0x2000A000, then you know you have MCU with 40KB RAM. It make it easier later if your MCU is not custom chip but duplicate of some known MCU from ST, NXP or other vendor. Maybe try some official tools ...


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