I'm Using ARM ADS tool chain to build elf and bin files. map file shows a function 0x20253025. In the elf file I see a branch instruction to the same function as BB,6D,E B,FF (4 bytes). BB is interpreted ad so BB is fine.But the 24 bit address 6DEBFF does not correlate with #0x20253025. ANy idea where to look or how I can get the pattern?
Branch instructions do not usually have the absolute target address: they are encoded with relative offsets. See the branch instruction encoding.
Related
I am trying to read the MCU_ID (device electronic signature) from STM32L476 chip using a JTAG ST-Link/V2 on Windows 7. No code has to be uploaded inside the chip, the program shall just be launched on my cumputer and read this information from the flash memory.
I have managed to find and extract the following screenshot from the Reference Manuel given on ST website :
So I have to read the value stored in the flash memory at the adess 0x1FFF7590 by using a C program. I am using the Atollic TrueStudio IDE which is recommended by ST itself, but it seems to me that it includes the "stm32l476xx.h"library which does not even contain any function which could help me.
What I have done so far
After spending days and days looking for some functions or examples to do something as simple as read flash memory, I have asked on this very site How to interact with a STM32 chip memory, which helped me understand a couple of things about what I had to do; nevertheless, I haven't been able to find what I was looking for even after days reading all the links and docs advised in the comments.
I have asked a couple of professionals who told me that I should search for a JTAG driver to interact with the flash memory, but it seems a bit complicated and I haven't been able to found any.
Someone on this site told me that simply using pointer should be enough; the lack of C example and internet tutorials couldn't help me figure out how to do so.
Finally, I started recently digging around STM32Cube and HAL, even since I wanted to avoid using those because I thought that a simple read could be done without having to include those layers. Asking this question is my final hope before trying to use them.
In Conclusion :
I can't show any code since the only thing I have so far is a #include "stm32l476xx.h"and an empty main.
A hint or solution on How to read a STM32L476's flash memory in C would be just perfect. Every example of C (or any programming language which would be as low or higher level) program or instructions interacting with a STM32 chip's memory could help me a lot since it is very hard to find on internet.
Reading MCU ID using ST-Link (graphical interface)
You can use ST-Link Utility (can be downloaded from ST.com here: http://www.st.com/en/embedded-software/stsw-link004.html). After you do Target->Connect you can specify the address and number of bytes you want to read on top of the Window. This also works for the memory area where MCU ID is defined.
For STM32L476 MCU that you use it's going to be memory address 0x1FFF7590, size 0xC (96 bits). Pressing enter should allow you to see the unique ID read from the MCU you're connected to, in form of 3x32 bit values.
Reading MCU ID using ST-Link (command line interface)
ST-Link Utility provides CLI (command line interface) to do the most common operations. This is done using ST-LINK_CLI.exe located in your ST-Link Utility installation directory.
Reading Unique ID as 32-bit values (STM32L476 MCU from the example):
ST-LINK_CLI.exe -r32 0x1FFF7590 0xC
Reading as 8-bit values:
ST-LINK_CLI.exe -r8 0x1FFF7590 0xC
You can also read it to file using -Dump parameter:
ST-LINK_CLI.exe -Dump 0x1FFF7590 0xC D:\temp\out.bin
Keep in mind that you must have the priviledges to write to the destination directory. If you don't run the command prompt with administrative priviledges, in most common cases this means that you won't be able to create the file in locations such as root drive directory (C:\out.bin) or inside "Program Files", where most likely your program is installed (for example by specifying a relative path, such as giving an output file name only out.bin). The program sadly doesn't inform about failed attempts to write the file, however it does say when it succeeds to create the file. The program execution should end with a green line saying Dumping memory to D:\temp\out.bin succeded. In addition, keep in mind that only the following file extensions are supported: *.bin *.hex *.srec *.s19. It cannot be anything because the extension determines the format in which the data will be written to the file.
You can find more information about CLI parameters in User Manual UM0892.
Reading MCU ID using C code
The same can be done using a program loaded into the MCU. You read it by simply accessing the memory directly. Sample code:
#define STM32_UNIQUEID_ADDR 0x1FFF7590
uint32_t id[3];
id[0] = *(STM32_UNIQUEID_ADDR + 0);
id[1] = *(STM32_UNIQUEID_ADDR + 1);
id[2] = *(STM32_UNIQUEID_ADDR + 2);
After this operation id array should contain the same 3x32bit values you've previously read using ST-Link Utility. You may of course choose to read it as uint8_t byte array of size 12, you may even choose to read it into a struct, in case you're interested in the details (lot number, wafer number etc.). This example should however give you a general idea of how to access this value.
There is Texane stlink, that does what you want. It's written in C, interacts with STM32 chips through an ST-Link adapter, and it can read from chip memory.
What you are looking for is not a feature of ST but a feature of ARM.
Remember, ST simply uses an ARM core. I know most programmers load some code in RAM and use that to access flash. You can find these simple programs in the install directory or Keil for example.
I think this is the manual you will need. But I don't know if there is more information behind the login-wall.
I want to extract machine code from XBee DigiMesh firmware (Cortex-M3, EM357), so I have SREC file with 3 sections inside. I suppose that one of these sections is a code section, but arm-none-eabi-objdump reports "unknown instruction" very often. Does anyone know why this happens?
This is how I try to do this:
arm-none-eabi-objcopy --input-target=srec --output-target=binary -j .sec2 xbp24-dm_8073.ehx2.dec sec2.bin
arm-none-eabi-objdump -D -bbinary -marm -Mforce-thumb sec2.bin
Firmware: http://tmp.nazaryev.ru/xbp24-dm_8073.ehx2.dec
EM357 datasheet: https://www.silabs.com/documents/public/data-sheets/EM35x.pdf
Update: there is answer at https://reverseengineering.stackexchange.com/questions/15049/cant-extract-machine-code-from-cortex-m3-firmware
The cortex-m3 supports thumb2, which is variable instruction length, you cannot simply start at the beginning and disassemble a variable length instruction set you can/will easily get out of sync and the output turns to garbage and remain that way forever. Likely not in this case, but you will have errors, this is expected. it is quite possible they added items to confuse a disassembler as well.
Also you could have a lot of data here, or it could be compressed code, or who knows what else...
Being a cortex-m the first chunk of words are not a vector table, so what is this code. If you examine the output in the way you have used the gnu tools, this does not look like real code, so perhaps encrypted or compressed or other. Do you see stack frames being built and functions ending with a pop (ldmia) that contains the link register with some static words after that then what looks like the beginning of the next function? Granted it might not all be compiled code, but some of it should look like compiled code.
if you are trying to hack some firmware you should perhaps figure out how/where this is loaded and create/use an instruction set simulator. without a vector table to start with though, have fun.
the way you did your disassembly you lost the address content
S123110001BE8110204D5401BE96102452...
0x1100 : 0x01BE
0x1102 : 0x8110
0x1104 : 0x204D
0x1108 : 0x5401
0x110C : 0xBE96
0x110E : 0x1024
and so on, that or probably byteswapped
0x1100 : 0xBE01
0x1102 : 0x1081
You could take that srec and create a program:
.hword 0xbe01
.hword 0x1081
one for each contiguous address range of items, when the address jumps start a new file, create a linker script to cover the start addresses of each section, assemble, make a _start label in one of them, link with the script then you have an elf you can disassemble, I still expect it to be problematic, but some of the relative addressing would make sense and or absolute addressing.
Also note your entry point
S903189351
assuming that is real, no reason to assume that it is.
I'm collecting program counter samples from a ARM Cortex M3. A long list like this:
0x8005b2a
0x8001324
0x8005b34
0x8001318
The pc is sampled periodically. I now want to have a static flat profile from the running program. Like (g)prof is doing with support of the linux kernel.
Is there a way to convert these PC samples in a (g)prof readable format or are there other tools that give me a profile based on these pc samples and an *.elf / *.lst file ?
Hans Müller, as I understand, gprof format is not so easy to generate (https://sourceware.org/binutils/docs/gprof/File-Format.html - "new file format is defined in header file gmon_out.h. It consists of a header containing the magic cookie and a version number, ... Histogram records consist of a header that is followed by an array of bins...")
I can recommend generation of
gpreftools (pprof tool - https://gperftools.googlecode.com/git/doc/cpuprofile-fileformat.html) or
callgrind.out formats (callgrind_annotate and kcachegrind GUI tool - http://valgrind.org/docs/manual/cl-format.html but you should resolve symbol names and kcachegrind requires name compression to be turned on)
Easier way (for flat) is to use some awk/perl/python scripting and addr2line tool from binutils (you need addr2line with support of target architecture). This tool will give you function names from address (if you correctly map PC samples to virtual addresses of elf binary), and your script should sum samples for every function, then sort. It is harder to handle callgraph in small scripts.
gpreftools's pprof is just script which can run addr2line for you (you still need right variant of addr2line). It is capable of summing samples for functions and sorting, and even may call objdump to get annotated disassembly.
Both formats may be used for flat profiles, but they support callgraphs to some level. pprof allows you to save full backtrace in every event; while callgrind.out format stores only pairs caller-callee (cfn), and kcachegrind may incorrectly guess pathes to hot code.
I need to differentiate a 32 bit PE from a 16 bit DOS MZ.
What is the correct way to do it?
I can use heuristics like looking for the PE header, but I feel like it's not necessarily deterministic
All DOS style executables have an 'MZ' as the first two bytes.
To identify an MSDOS executable vs. the multitude of other variants the best bet seems to be to read the position of the relocation table at offset 0x0018 in the file, if this is greater than 0x0040 (into the file) it is not just plain DOS.
To specifically identify the executable as a 'PE' executable there is a pointer at offset 0x003C in the file. This is an offset within the file the will have the bytes 'PE' and two nuls. Other MSDOS 'MZ' variants will use the same location to put other codes eg: 'NE', 'W3', 'LE' etc.
'PE' style executables also come in many forms, I expect you'll be interested in 32bit vs. 64bit at the very least.
Probably the ultimate authority on this sort of thing is the Unix 'file' command, it's designed to reliably identify ANY file type by investigating it's contents. The MSDOS part is listed here. Microsoft is NOT a reliable authority on this because they ignore non-Microsoft information.
A plain DOS EXE header is only 28 (0x1C) bytes long and is usually followed by the DOS relocation table if present. The IMAGE_DOS_HEADER struct of the NT PE header is much larger at 64 (0x40) bytes as it has been extended for the various other Windows executable formats. This header size difference is why the answer from #user3710044 is not only the fastest but its reliable: an EXE is plain DOS if the relocation table [e_lfarlc] < 0x40).
As long as you realize that the e_lfanew member (an offset to a number of possible "extended" headers) does not exist in a plain DOS executable, you can also use the following logic to distinguish between the various MZ-style formats:
If the beginning of the file does not begin with "MZ" or "ZM", it is not an DOS or Windows executable image. Otherwise you may have one of the following types of executable formats: plain DOS, NE (Windows 16-bit), LE (16-bit VXD), PE32, or PE32+ (PE64).
Determine if you have a plain DOS executable by looking at the e_lfanew value. A plain DOS executable will have an out-of-range e_lfanew pointing outside of the limits of the file, a zero, or if the offset happens to be in range, the signature at its offset won't match any signatures below.
Try to match the signature of the "in-range" offset pointed to by e_lfanew with the following WORD or DWORD values:
"PE" followed by two zero bytes if the image is a PE32 or PE32+ (PE64) and is further determined by the "magic" in the NT Optional Header
"NE" indicates the image is a 16-bit Windows executable
"LE" indicates the image is a 16-bit Virtual Device Driver (VXD)
More obscure signatures (referenced from Ralph Brown's INT 21/AH=4Bh):
LX variant of LE used in OS/2 2.x
W3 Windows WIN386.EXE file; a collection of LE files
W4 Windows95 VMM32.VXD file
DL HP 100LX/200LX system manager compliant executable (.EXM)
MP old PharLap .EXP
P2 PharLap 286 .EXP
P3 PharLap 386 .EXP
We are trying to write a pseudo-OS for an ev3 Lego brick. We already know, that there is an u-boot loader in the ROM of the brick, and that it loads an uImage file from the first partition of the SD-Card. We have tried to understand how the Linux ev3 kernel works and where is the entry point (assuming the main function). We have a potential entry point, but we don't know, how this location is marked as entry points or how to code a simplified version.
We want to create our own binary, which can be converted to an uImage file (with mkimage).
How do we have to do this?
How to mark a certain C-function as entry point?