我目前正在为旧的TMS320C5 16位微处理器还原固件文件。我正在使用IDA pro这样做,我需要为文件中包含的每个对象手动创建细分。我要求一个逐步的步骤来做到这一点。以下是有关原因/原因的更多信息。它从外部,更大,更慢的内存中加载该内存。

固件文件包含一个内存映像,该映像直接写入设备的慢速内存。它使用多任务RTOS进行操作。每个任务/过程都存储在二进制文件中的不同位置,并且看起来没有任何特定的顺序。据我了解,文件中的每个任务都以4个单词开头,其中之一表示将当前任务加载到快速存储器中的基址。在某些情况下,可以将2个或3个任务加载到快速存储器中的相同基址上。 3)。因此它们与PC(程序计数器)或某些其他寄存器的内容无关。

当然,我现在希望分支指令和调用指令与其段中的适当功能和部分保持一致。尽管我对IDA中的分段没有很强的了解,但我阅读了其他一些主题,例如如何处理在不同执行之间更改其地址的代码,IDA分段问题和IDA中的分段。如何克服NONAME问题,但没有一个能提供我所需的完整解决方案,因为我不认为CS / DS和其他英特尔产品适用于此。我在IDA PRO书中也找不到真正有用的东西。

到目前为止,通过执行以下操作,看来我已经完成了50%的工作: br />使用“选择器”子视图创建新的选择器:“视图”>“打开子视图”>“选择器”。
在子视图中单击鼠标右键,选择“添加选择器”。
按照下面的图1创建了一些示例。
命令行和SetSegmentAttr函数,我更改了段之一的选择器:SetSegmentAttr(ScreenEA(),SEGATTR_SEL,1)


例如,在其中有一个任务从线性地址0xCAEFD开始的固件。此任务已加载到快速存储器中的0x2C00。因此,我想创建一个包含此任务的段,其基地址为0x2C00。在按照上述步骤更改块的段时,偏移量从0x9EF02开始(参见图2)。我希望它从0x0开始。我有些需要以某种方式更改偏移量。我知道“移动段”选项,但是似乎“物理地”将段更改为该地址,我不希望这样做,因为某些任务在快速内存中共享相同的基地址(或者彼此接近并且将被覆盖另一个任务)。为了将每个任务隔离到自己的段中以便分支和调用对齐,我需要完成哪些步骤?例如,在图3中,我希望IDA将BCND 2C1Dh, geq链接到段中相应的0x2C1D位置,而不是对应的线性地址。

图3:


感谢您的帮助

评论

这可能会有所帮助,尤其是示例。

#1 楼

确实不是答案,但是评论太久了。另外,我非常了解x86体系结构,但对TMS320C5却一无所知,所以请您放心使用。

我担心您要尝试的操作不会与IDA细分的工作原理非常吻合,而IDA细分的工作原理基本上源于80x86的处理方式。这意味着段寄存器包含20位地址的高16位,偏移量包含低16位;并要计算物理地址,请执行segment<<4 | offset。这意味着,例如1234:0020之类的地址等效于1236:0000-两者都映射到12360的物理地址。现在,如果您的二进制文件在段1234-物理地址12340-处加载,则没有“固有的”方式可以告诉12360的偏移量是多少;它可能是0020段中的1234,或者是0000段中的1236。 IDA分段只会告诉反汇编程序一个新的分段从12360物理地址开始,因此,如果将ds寄存器设置为该分段,则ds:0将访问s defined at that 12360`地址的变量。

这是与您的处理器的不同之处在于,将永远不会切入或切出代码,物理内存中的代码区域也不会重叠,并且段内的偏移量始终始于0000。即使在病理情况下,metainfo .EXE文件指出要加载一个要偏移0200的段,加载程序也会生成一个新段,用00填充前0x200字节,然后从.EXE文件中的内容加载到此零之后。 d out块。

IDA不能做的-据我所知-类似于“使0000-CAEFD成为一个分段;然后从C82FD开始另一个分段,其中地址CAEFD的偏移量为2C00 ,因为这会使C82FDCAEFD之间的文件部分的含义含糊不清,因此您不知道它属于哪个段。

在您的情况下,当您说基址应该是2C00时,您告诉IDA文件中的地址2C00应该等​​于段中的地址0000。这就是为什么它显示偏移量9EF02的原因;如果2C00(文件位置)对应于0000(段开始),则CAEFD-2C00=9EF02(文件位置)对应于9EF02(段内的位置)。尝试将9EF02用作段开头; CAEFD处的字节是该段中的2C00字节,因此它具有2C00的偏移量。
如果我的原始固件的大小不是64K的倍数,请附加0字节,直到它为止。
当我识别任务并执行偏移量时,请附加尽可能多的10000字节需要到达该任务的起始地址,复制任务本身并附加更多10000字节以再次达到64K的倍数。包含原始固件的块以及多个仅包含一个任务和一堆零的64 KB块。

现在,当您加载该文件时,为第一个大块定义一个段,以及每个附加的64 KB块的一个分段。这样,每个任务可以有一个段。分段很容易定义,因为它们每个都以file byte的倍数开头,除第一个以外的所有大小正好是memory byte字节,并且q4312079q和q4312079q之间具有1:1的关系,这会使IDA满意。

评论


你好。所以我终于做到了。我注意到固件似乎是内存的实时快照,因此,我注意到堆管理块在每1K左右重复出现。每个块包含一个值,该值指示下一条指令在页面中的确切位置。结合您的主张和IDAPython,我能够使用这些块来剪切文件。我写了一个空的64K页面,然后使用此“书签”和file.seek()将块写入了64k文件中。现在一切都完美地对齐了。谢谢!

–感染包
15年12月18日在21:21