I am currently working on reversing a firmware file for the older TMS320C5 16-bit microprocessor. I'm using IDA pro to do so and I need to manually create segments for each object contained in the file. I'm asking for a step-by-step procedure to do so. Below is more information on why/what.
The TMS320C5, like many other processors, access an internal cache, called the "Fast Memory" which is a single 64K page. It loads this memory from the contents of an outside, bigger and slower memory.
The firmware file contains a memory image, which is written directly to the slow memory of the device. It operates using a multi-tasking RTOS. Each tasks/process is stored at different locations in the binary file and do not appear to be in any particular order. From my understanding, each task within the file is preceded by 4 words, one of them indicating the base address where the current task will be loaded in fast memory. In some cases, 2 or 3 tasks can be loaded at the same base address in fast memory.
It seems that each branch/call instruction within a task uses a direct address within the current page (see figure 3). So they are not relative to the PC (Program Counter) or the contents of some other register.
Of course, I'd now like that branching and calling instructions be aligned with the proper functions and sections within their segment. While I do not have a strong grasp on segmentation in IDA, I read some other thread such as How to deal with code that change its address among different execution, IDA segmentation problem and Segments in IDA. How to overcome NONAME problem, but none offer a complete solution to what I need, as I do not believe CS/DS and other Intel segments apply here. I could not find any really useful in the IDA PRO book either.
So far, it seems I have accomplish 50% of what I need by doing the following:
- Creating a new selector using the Selector subview: View > Open Subviews > Selectors.
- Right-click in the subview, select Add Selector.
- Created some examples as per figure 1 below.
- Using the command-line and SetSegmentAttr function, I've change the selector of one of the segment: SetSegmentAttr(ScreenEA(), SEGATTR_SEL, 1)
As an example, there is a task within the firmware which starts at linear address 0xCAEFD. This tasks is loaded at 0x2C00 in fast memory. As such, I'd like to create a segment containing this task and for which the base address is 0x2C00. While I changed the segment of the block using the procedure above, the offset starts at 0x9EF02 (see figure 2). I expected it to starts at 0x0.
I suspect I somewhat need to change the offset somehow. I'm aware of the Move Segment option, but it seems it "physically" change the segment to the address, which I do not want since some tasks share the same base address in fast memory (or are close to each other and will overwrite another task). What are the steps I need to complete in order to isolate each task into its own segment so that branches and calls align? For example, in figure 3, I would like IDA to link the
BCND 2C1Dh, geq to the corresponding 0x2C1D location within the segment, rather than the corresponding linear address.
Thanks for any help