silentmj原创文章,转载请保留署名,谢谢:)
一、事情的开始,本部分解释
1)bin文件时如何进入我们程序的
2)bin文件进入程序以后在哪里
一切都开始于ZY_CODE\M2378-CFNS20\Startup.s Line 87
----------------------------------------------------------------------------
CODE32
IF :DEF: LOW
AREA boots,CODE,READONLY ;定义boots节
ENTRY ;标识程序执行的第一条指令
IF :DEF: CRP
incbin ZY_CODE\M2378-CFNS20\BOOT\boot_CRP.bin
ELSE
incbin ZY_CODE\M2378-CFNS20\BOOT\boot.bin
ENDIF
ENDIF
AREA vectors,CODE,READONLY ;定义vectors节
begin ;标号begin
IF :DEF: HIGH
ENTRY ;标识程序执行的第一条指令
incbin ZY_CODE\M2378-CFNS20\High\lpc2300.bin
ELSE
incbin ZY_CODE\M2378-CFNS20\Low\lpc2300.bin
ENDIF
------------------------------------------------------------------------------
从以上可以看出Startup.s的编译结果取决于不同的汇编器设置
DebugInLowAddr模式下ARM Assembler的设置
DebugInHighAddr模式下ARM Assembler的设置
Release模式下ARM Assembler的设置
从上面3副图,我们可以看出在Equivalent Command Line定义的伪指令决定了开头的汇编代码如何编译,
下面我们均已DebugInLowAddr模式为例进行分析,由
-keep -PD "LOW SETL {TRUE}" -g -apcs /interwork
可知开头的汇编代码短等于
----------------------------------------------------------------------------
CODE32
AREA boots,CODE,READONLY ;定义boots节
ENTRY ;标识程序执行的第一条指令
incbin ZY_CODE\M2378-CFNS20\BOOT\boot.bin ;包含boot.bin
AREA vectors,CODE,READONLY ;定义vectors节
begin ;标号begin
incbin ZY_CODE\M2378-CFNS20\Low\lpc2300.bin ;包含lpc2300.bin文件
------------------------------------------------------------------------------
于是我们得到如下关系
在startup.o中
boot.bin---------->boots节
lpc2300.bin------->vector节
这可以从IDA中和scf文件中得到印证:
startup.o的节分布情况
最终的axf文件中的节分布情况
scf文件内容:
-------------------------------------------------------------------------------
;** File Name: inchipL.scf
;** Last modified Date: 2004-09-17
;** Last Version: 1.0
;** Descriptions: Scatter File
;**
;**------------------------------------------------------------------------------------------------------
;** Created By: Chenmingji
;** Created date: 2004-09-17
;** Version: 1.0
;** Descriptions: First version
;**
;**------------------------------------------------------------------------------------------------------
;**------------------------------------------------------------------------------------------------------
;** Modified by: LinEnqiang
;** Modified date: 2007-11-22
;** Version: 1.1
;** Descriptions: For MiniARM2378
;**
BOOT_LOAD 0x00000000
{
BOOT_EXEC 0x00000000
{
Startup.o (boots,+First)
}
}
ROM_LOAD 0x00002000
{
LowAddr 0x00002000
{
Startup.o (vectors,+First)
* (+RO)
}
IRAM 0x80000000
{
Startup.o (MyStacks)
* (+RW,+ZI)
}
HEAP +0 UNINIT
{
Startup.o (Heap)
}
STACKS_BOTTOM +0
{
Startup.o (StackBottom)
}
STACKS 0x80010000 UNINIT
{
Startup.o (HeapTop)
Startup.o (Stacks)
}
}
-------------------------------------------------------------------------------
二、bin文件中导出函数的定位
图1,IDA中startup.o中ResetInit之前的代码反汇编结果
图2,ADS中startup.s中ResetInit之前的代码部分
从以上2幅图片我们可以知道lpc2300.bin中的内容确实以代码和数据的方式进入了我们的程序中。那么下面我们要做的就是已知某个函数的名称,得到反汇编后的代码了
我们可以从DebugInLowAddr\a.sym文件得到某函数的入口地址, a.sym文件中的内容看起来类似这个样子
-------------------------------------------------------------
#<SYMDEFS># ARM Linker, ADS1.2 [Build 805]: Last Updated: Wed May 05 12:52:30 2010
0x00000024 D UndefinedAddr
0x0000002c D PrefetchAddr
0x00000030 D DataAbortAddr
0x0000003c D FIQ_Addr
0x00002000 A RunFirst
0x00002040 A OSIntCtxSw
0x00002048 T functionEnter
0x00002058 T GetVersion
0x00002068 T SysInit
0x00002078 T upgradeBegin
0x00002088 T upgradeDataWrite
0x00002098 T upgradeBreak
0x000020a8 T upgradeEnd
0x000020b8 T upgradeBegin2
0x000020c8 T upgradeDataWrite2
0x000020d8 T upgradeBreak2
0x000020e8 T upgradeEnd2
0x000020f8 T crc8Cal
0x00002108 T crc16Cal
0x00002118 T eccCal
0x00002128 T eccDataCorrect
0x00002138 T MD5Init
0x00002148 T MD5Update
0x00002158 T MD5Final
0x00002168 T SHA1Init
0x00002178 T SHA1Update
0x00002188 T SHA1Final
……………………………………
-------------------------------------------------------------
下面,我们以其中的htonl这个函数为例来进行分析,首先从
0x000029e8 T htonl
这一行我们可以得知,htonl函数的入口地址应该自29e8处
从以上代码片段我们可以知道,真正的函数入口在B872处,前往B872处,由于htonl函数所完成的功能是为我们所熟知的,我们马上可以确定这确实是htonl的一个实现。
有兴趣的朋友可以结合IDA,多验证几个函数,呵呵。
三、一点感想:
进一步的分析还表明,这些固件程序中还结合了安全芯片来验证硬件确实为ZLG所生产。结合了软件(通过库文件隐藏源码),硬件(安全芯片)的方法,应该说此种保护方式确实能较好的起到防止抄板者盗用ZLG工程模板的目的。
但由于bin文件中的ARM指令本身并未加密,给定充足的时间,“意志鉴定”的破解者还是能够逆向出bin文件中真正有价值的信息,如网络、文件系统部分的关键算法的。
最后希望这篇文章能对搞ARM开发的朋友们开发自己的源码保护方案起到一定的借鉴作用,谢谢。