免责声明:这项研究始于2013年,因此,如果您认为某些方法既愚蠢又危险,那就对了。 但是,我在此过程中学到了很多东西。参赛作品这一切都在我第一个孩子出生前的几个月开始。 我和我的妻子一直想买一台很酷的Leica相机,突然意识到如果我们现在不买相机,那么我们很长一段时间都做不到。 因此,我们订购了M240相机和...动臂,我们被安排了六个月的时间。 很快我就厌倦了等待,于是我开始研究他们的网站。 我的注意力立即吸引到文件部分。 好吧,您可以猜测为什么...固件!
我看到了一个以
PWAD magic开头的未加密和未压缩的文件(
m8-2_005.upd
)。 你认识吗 是的,没错,这就是Doom Patch WAD格式。 男人似乎喜欢经典。 该格式已被
很好地记录下来 ,因此解析它并不困难。
徕卡固件文件
固件Leica M8
这实际上非常有趣,因为当我后来研究压缩的Leica T固件文件时,我首先决定测试id Software过去使用的压缩方法。
维基百科说,他们使用
LHA格式 ,本质上是LZW。 但是普通的LZW解压缩器不适合使用,因此我开始寻找id软件的特定实现-瞧,我在
源代码中找到了
地下墓穴世界末日 。 我必须承认,幸运。
无论如何,请回到M8。 这是固件结构:
规则:0x0000008C(3036:0x00000BDC)-XML说明
LUTS:0x00000C68(183274:0x0002CBEA)
GAMMA:0x0000007C(31760:0x00007C10)
增益:0x00007C8C(50344:0x0000C4A8)
徕卡:0x00014134(7000:0x00001B58)
BLEMISH:0x00015C8C(250:0x000000FA)
WREF:0x00015D88(82480:0x00014230)
OBJ:0x00029FB8(11268:0x00002C04)
版本:0x0002CBBC(46:0x0000002E)
PXA:0x0002D854(858384:0x000D1910)
BF:0x000FF164(134522:0x00020D7A)-Analog Devices Blackfin处理器系列
GUI:0x0011FEE0(3574180:0x003689A4)
TRANS:0x0000005C(59988:0x0000EA54)-本地化
图像:0x0000EAB0(267433:0x000414A9)
21_1PRT:0x000000CC(18411:0x000047EB)-JFIF的图片
21_2GRP:0x000048B8(23172:0x00005A84)-JFIF的图片
21_3PAN:0x0000A33C(23034:0x000059FA)-JFIF的图片
24_1PRT:0x0000FD38(18489:0x00004839)-JFIF的图片
24_2GRP:0x00014574(23230:0x00005ABE)-JFIF的图片
24_3PAN:0x0001A034(22998:0x000059D6)-JFIF的图片
28_1PRT:0x0001FA0C(22605:0x0000584D)-JFIF的图片
28_2GRP:0x0002525C(23081:0x00005A29)-JFIF的图片
28_3PAN:0x0002AC88(23282:0x00005AF2)-JFIF的图片
35_1PRT:0x0003077C(22496:0x000057E0)-JFIF的图片
35_2GRP:0x00035F5C(23532:0x00005BEC)-JFIF的图片
35_3PAN:0x0003BB48(22881:0x00005961)-JFIF的图片
FONT1:0x0004FF5C(1522988:0x00173D2C)
FONT2:0x001C3C88(1723676:0x001A4D1C)
版本:0x003689A4(0:0x00000000)
M16C:0x00488884(130406:0x0001FD66)-瑞萨M16C系列(Motorola S记录)
FPGA:0x004A85EC(131604:0x00020214)-Xilinx Spartan 3
FSL:0x004C8800(814:0x0000032E)-第一阶段引导程序
开箱即用的IDA不支持Blackfin处理器,但是有一个
第三方插件 。
固件Leica M9
Leica M9固件文件(
m9-1_196.upd
)看起来已加密:直方图显示约0.45%的分布。

故事的结局? 也许不是。 事实是Leica在相机中使用了性能较弱的处理器,并且当时在消费类电子产品中经常使用XOR加密,因此我决定为XOR操作编写一个简单的工具,以将固件与本人进行比较并计算一些统计数据。
密钥长度是通过搜索最长的重复模式来确定的。 这很有意义,因为任何固件通常都包含大量重复数据块,例如0x00 / 0xFF填充或带有LUT像素的图形。 密钥本身是通过密钥长度内字节的频率来计算的,最常见的字节进入密钥缓冲区。 程序的结果清楚地表明了XOR加密。 然后,我不得不对
工具进行一些
修改,以获取潜在的密钥并解密代码。 再次证明这是一个PWAD文件。
PWAD的内容揭示了以下结构:
规则:0x0000007C(2788:0x00000AE4)-XML说明
LUTS:0x00000B60(4060616:0x003DF5C8)
过程:0x0000004C(3900572:0x003B849C)
创建:0x0000004C(20:0x00000014)-时间戳
LUTS:0x00000060(427744:0x000686E0)
增益图:0x00068740(20008:0x00004E28)
镜头:0x0006D568(3452724:0x0034AF34)
CCD:0x003B84E8(148662:0x000244B6)
创建:0x0000004C(20:0x00000014)-时间戳
BLEMISH:0x00000060(1092:0x00000444)
WREF:0x000004A4(147452:0x00023FFC)
LIN:0x000244A0(22:0x00000016)
ICCPROF:0x003DC9A0(4304:0x000010D0)
ECI-RGB:0x0000003C(540:0x0000021C)
sRGB:0x00000258(3144:0x00000C48)
A-RGB:0x00000EA0(560:0x00000230)
WBPARAM:0x003DDA70(7000:0x00001B58)
BF561:0x003E0128(289128:0x00046968)-Analog Devices Blackfin处理器系列
bf0:0x0000004C(117846:0x0001CC56)-主处理器
bf1:0x0001CCA4(117826:0x0001CC42)-子处理器的固件
bf0.map:0x000398E8(27072:0x000069C0)-主处理器固件卡,字符:D
bf1.map:0x000402A8(26304:0x000066C0)-带有字符D的子处理器固件卡
身体:0x00426A90(143280:0x00022FB0)-瑞萨M16C系列(摩托罗拉S记录)
GUI:0x00449A40(3647624:0x0037A888)
TRANS:0x0000005C(131656:0x00020248)-本地化
图像:0x000202A4(267433:0x000414A9)
21_1PRT:0x000000CC(18411:0x000047EB)-JFIF的图片
21_2GRP:0x000048B8(23172:0x00005A84)-JFIF的图片
21_3PAN:0x0000A33C(23034:0x000059FA)-JFIF的图片
24_1PRT:0x0000FD38(18489:0x00004839)-JFIF的图片
24_2GRP:0x00014574(23230:0x00005ABE)-JFIF的图片
24_3PAN:0x0001A034(22998:0x000059D6)-JFIF的图片
28_1PRT:0x0001FA0C(22605:0x0000584D)-JFIF的图片
28_2GRP:0x0002525C(23081:0x00005A29)-JFIF的图片
28_3PAN:0x0002AC88(23282:0x00005AF2)-JFIF的图片
35_1PRT:0x0003077C(22496:0x000057E0)-JFIF的图片
35_2GRP:0x00035F5C(23532:0x00005BEC)-JFIF的图片
35_3PAN:0x0003BB48(22881:0x00005961)-JFIF的图片
字体1:0x00061750(1522988:0x00173D2C)
USBLOGO:0x001D547C(1775:0x000006EF)-JFIF的图片
FONT2:0x001D5B6C(1723676:0x001A4D1C)
FPGA:0x007C42C8(150176:0x00024AA0)-Xilinx Spartan 3A
BF547:0x007E8D68(937576:0x000E4E68)-Analog Devices Blackfin处理器系列(FSL?)
固件Leica M240
我习惯于每天早晨检查Leica固件的下载页面。 很快出现了一个新文件:
FW_M240_1_1_0_2.FW 。
它看起来没有加密,但已被压缩...
压缩方式
直方图显示了0x9D处的巨大爆发。

也许这是某种压缩魔术。 在Internet上进行的搜索[9D +压缩]没有任何结果,只是将0x1F9D
用作LZW压缩的签名 。 如果有的话,我了解LZ压缩类型,并决定查看0x9D之后的字节。 我看到了四个选择:
9D 70 C4
9D 00
9D XX YY
9D XX 8Y YY
您还注意到了什么:
- 第一个选项仅在地址0x30处弹出一次:它可能用作压缩数据的指示器;
- XX不得超过0x7F;
- 在第三和第四种情况下,YY的最后一个字节不得超过0x7F
根据我对LZ的了解,这与LZ77或LZSS非常相似,其中YY是缩进步骤,而XX是要复制的字节数。 第二种选择是发出0x9D的特殊情况。 我编写了一个简单的C函数来实现此逻辑。 她确认我们正在朝正确的方向前进,但是第四个选择仍然不适合该计划。
我尝试了各种方式来解释它,但是没有任何结果。 因此,我向同志请教。 一个人注意到,根据我自己的观察,YY的第四个字节仅在设置最高位0x8Y时出现:这只是缩进步骤的额外距离。 我感到ham愧,一切都变得如此明显...
最终,解压缩器开始发出有效流……直到它卡在文件中间。 这是由于滑动窗口的长度未知而发生的。 其他调试和测试解决了这种情况。
因此,有一个
用于解析固件M240的
工具 。
固件结构
为了使用未知格式,我没有比测量代码段的某些偏移量和大小更好的方法了-尝试在文件头中查找最接近的值。 例如,以下代码块:
0x00: 1E 1C AF 2E 01 01 00 02 07 E1 EA 5E 00 5C 1A B1
0x10: 01 29 1A 7E AE 38 73 65 9C 3D 75 B4 34 2F 44 6E
0x20: 13 17 8E 6B 00 00 00 01 00 00 00 30 E1 E3 50 D1
最终变成:
1E1CAF2E — "LEICA FILE"
01010002 - 1.1.0.2
005C1AB1 — (big endian)
01291A7E — (big endian)
AE3873659C3D75B4342F446E13178E6B — MD5
00000001 —
00000030 —
当我了解固件的结构时,我改进了工具,最后产生了以下结果:
Running with options:
+ firmware folder: M240_FIRMWARE
+ verbose enabled
Open firmware file: FW_M240_1_1_0_2.FW
File size: 6036193 | 0x005C1AE1
Parse container header:
version: 1.1.0.2
packed size: 6036145 | 0x005C1AB1
unpacked size: 19470974 | 0x01291A7E
body blocks: 1 | 0x00000001
body offset: 48 | 0x00000030
MD5: AE387365 9C3D75B4 342F446E 13178E6B
MD5 check: PASSED
Uncompress container body:
6036145 -> 19470974
Uncompression: DONE
Split container:
Number of sections: 9 | 0x00000009
Section table size: 612 | 0x00000264
Section table offset: 36 | 0x00000024
Section 1
Section Name: "[A]IMG_LOKI-212"
Section offset: 0 | 0x00000000
Section size: 7340032 | 0x00700000
Section base: 1048576 | 0x00100000
MD5: A8D55AA2 B0ACDB14 0673AD79 707674F3
MD5 check: PASSED
Create file: M240_FIRMWARE/IMG_LOKI-212.bin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Section 9
Section Name: "[A]IMG-LENSDATA-213"
Section offset: 19214844 | 0x012531FC
Section size: 255478 | 0x0003E5F6
Section base: 16252928 | 0x00F80000
MD5: 39C2BEC0 27ED23F6 2C1C8513 EEE697B9
MD5 check: PASSED
Create file: M240_FIRMWARE/IMG-LENSDATA-213.bin
Splitting container: DONE
Extraction COMPLETE!
M240固件包含一个包含九个元素的容器:
IMG_LOKI-212.bin -
IMG_LOKI-213.bin -
CTRL_SYS-11.bin - -
IMG-FPGA-212.bin - ()
IMG-FPGA-213.bin - ()
IMG-DSP-212.bin - DSP
IMG-DSP-213.bin - DSP
IMG-LENSDATA-212.bin -
IMG-LENSDATA-213.bin -
如您所见,在一个固件中有两组文件。 后来我得知212是图像处理微电路的一个版本,并且有两个版本的Leica M240投入生产。 这项研究基于版本212。
系统管理:CTRL_SYS-11.bin
唯一常见的部分是系统控制芯片的固件。 这是一个非常大的二进制文件,代码可以轻松猜出它的用途。
$ strings CTRL_SYS-11.bin | rg SH
-> Test SH7216 data flash driver
-> Test SH7216 SCI driver
-> Test SH7216 I2C driver
-> Test SH7216 MTU2 driver
-> Test SH7216 ADC functions
-> Test SH7216 CMT driver
因此,我们拥有瑞萨的SH7216处理器(SH-2A),它负责加载的早期阶段,I / O测试和固件更新。 开箱即用的IDA支持这种类型的处理器。 只剩下找到正确的基本加载地址,这可以从固件部分的描述中得知:这是
0x0
。
Section Name: "[A]CTRL_SYS-11"
Section offset: 14680064 | 0x00E00000
Section size: 917277 | 0x000DFF1D
Section base: 0 | 0x00000000
我将其加载到IDA中并识别了所有功能,但我并没有特别对其进行研究,因为主处理器的固件更加有趣。
在此还应注意,该芯片的UART通向服务端口,并在其中显示下载日志。 我们待会儿会再谈这个。
主芯片:IMG_LOKI-212.bin
要开始对该固件进行反向工程,您必须首先回答以下几个问题:
- 什么类型的处理器
- 什么是基本加载地址
- 它基于什么操作系统(如果有)
借助我们的工具,我们已经知道基本负载的地址:这是
0x100000
。
Section Name: "[A]IMG_LOKI-212"
Section offset: 0 | 0x00000000
Section size: 7340032 | 0x00700000
Section base: 1048576 | 0x00100000
固件以可读形式存储其余答案。 例如,这一行:
$ strings ./IMG_LOKI-212.bin | rg Softune
6Softune REALOS/FR is Realtime OS for FR Family, based on micro-ITRON COPYRIGHT(C) FUJITSU LIMITED 1994-1999
...
因此,我们正在处理定制处理器
Fujitsu FR (徕卡称之为
Maestro )和操作系统
Softune REALOS 。 实际上,这比Blackfin好得多,因为开箱即用的IDA支持FR。
FR处理器模块
现实情况并非如此,因为下载固件文件后,IDA程序未显示任何指令,外部链接等。
我决定修复它,但最后我不得不
完全重写固件的某些部分 。 结果如下:


除了对
ana
,
ins
和
out
进行更正
out
,全新的
emu
代码还可以:
- 识别各种类型的代码和数据的外部链接;
- 识别开关语句
- 执行堆栈跟踪;
- 单独的堆栈参数和局部变量
- 正确识别功能。
但是,正如您所注意到的,最大的变化是说明的大写字母:)
想查看全套说明吗? 这是:
LSR MOV BN LDRES EXTSH
ADD2 ORH MUL LSR2 JMP BP STRES EXTUH
ADDC ORB MULU ASR CALL BV COPOP SRCH0
ADDN EOR MULH ASR2 RET BNV COPLD SRCH1
ADDN2 EORH MULUH LDI INT BLT COPST SRCHC
SUB EORB DIV0S LDI集成BGE COPSV LDM0
SUBC BANDL DIV0U LDI便携式NOP LDM1
SUBN BANDH DIV1 LD BRA BGT ANDCCR STM0
CMP BORL DIV2 LDUH BNO BLS ORCCR STM1
CMP2 BORH DIV3 LDUB BEQ BHI STILM ENTER
AND BEORL DIV4S ST BNE DMOV ADDSP离开
ANDH BEORH LSL STH BC DMOVH EXTSB XCHB
ANDB BTSTL LSL2 STB BNC DMOVB EXTUB
因此,简单而美丽。
顺便说一句,您可能已经注意到某些说明不统一:
胸罩:D loc_xxx
LDI:8#0x64,R5
这不是处理器模块中的错误,但实际上是Fujitsu FR系列的功能。 它被称为
延迟时隙 ,对于RISC处理器而言非常典型。
从
FR80处理器手册 (请注意:该链接不再起作用):
紧接在分支指令之后的指令(其位置称为“延迟槽”)在分支之前执行,而目标地址处的指令在分支之后执行。 由于延迟时隙中的指令是在分支操作之前执行的,因此表观执行速度为1个周期。
因此,从本质上讲,这是对流水线的优化,最好记住它,因为Leica固件中到处都使用它。
软件REALOS
从维基 :
Softune是富士通针对富士通FR,FR-V和F2MC处理器系列的集成开发环境。 由REALOS µITRON实时内核提供支持。 例如,它可用于尼康DSLR相机(请参阅尼康EXPEED)和某些带有K的宾得相机。
所以这是一个非常流行的体面的RTOS,带有任务,信号量和其他功能。 我想知道是否可以识别Leica固件中的某些标准库功能。
我必须把研究的第一部分称为浪费大量时间,这就是原因。
事实证明,很难找到Softune IDE,但最终我设法得到了一些东西。 正如预期的那样,IDE包含了库。 有四个二进制文件:
- lib911.lib
- lib911e.lib
- lib911if.lib
- lib911p.lib
我不知道为什么,也许是出于惯性,当我破解与徕卡有关的所有内容时,我又开始了对该格式的逆向工程。 是的,有充分记录的
对象模块格式 。 是的,当然,我
为此编写了一个特殊的工具 :
Fujitsu RISC Library Tool v1.0
Usage: FRLibTool [-s start] [-i imagebase] [-o output] [-f index] [-dv] FIRMWARE.BIN LIBRARY.LIB
This tool will help you to find Softune REALOS library functions in FR (Fujitsu RISC) firmware.
Use following arguments:
-f Specify firmware image file
-s Specify firmware image scan offset
-b Specify firmware imagebase
-o Specify output type (exclusively)
list - list of functions
idc - IDC script
py - IDA python script
pat - FLAIR pattern file
-i xxx Specify index of particular function
-d Dump library
-v Be verbose
使用它,您可以创建
*.pat
文件,并将其用作
IDA FLAIR中的输入以生成
签名文件 。
$ FRLibTool -o pat lib911.lib
$ FRLibTool -o pat lib911e.lib
$ FRLibTool -o pat lib911if.lib
$ FRLibTool -o pat lib911p.lib
...
$ sigmake -n "SOFTUNE C/C++ Library" lib911.pat lib911e.pat lib911if.pat lib911p.pat softune.sig
应用此签名后,我终于在
IMG_LOKI-212.idb中愉快地看到了对应
关系 。

布局图
固件中的行数立即引起关注。 许多功能因其功能而被命名。 这在逆向工程过程中了解常规模式非常有用。
同样重要的是要注意,固件文件的某些部分已在重置处理程序中复制到其他地址。 例如,运行时内置的加载器在RAM中的位置更高。
我不得不手动创建其他部分,因此,我得到了以下布局:

打断
中断向量表可以通过访问TBR(表基址寄存器)找到:
LDI:32 #int_table, R0
MOV R0, TBR
通常,它发生在固件最开始的向量复位处理程序中。
表中处理程序的地址根据公式
TBR + (0x3FC - 4 × inum)
以相反的顺序存储,因此表末尾的复位向量偏移量为
0x3FC
。
我从FR手册中发现了大部分干扰,并建议Leica Maestro具有类似的布局。 然后,他带走了每个处理程序,并试图找到一个字符串或任何其他揭示中断目的的提示。
结果,我列出了以下列表:

预计会有许多中断,例如AUDIO / SDIO / VIDEO / JPEG / RAW,但尝试找出其中最神秘的中断吗? 我说的是打断
int_uart_in
。 相机似乎支持某种控制台模式UART CLI。
系统调用
与几乎所有操作系统一样,Softline REALOS也使用系统调用。 在汇编器中,它们如下所示:

系统调用处理程序的实际地址计算如下。 让我们开始寻找
INT #0x40
中断处理程序。 如上所述,这
(0x3FC - 4 × inum) = (0x3FC - 4 × 0x40) = 0x2FC = int_realos_syscall
在处理程序中,很容易找到带有16位字的系统调用表底部的链接。 此表中的特定记录由公式
syscall_table_bottom + (num * 2)
:
[syscall_table_bottom + (-23 * 2)] = [syscall_table_bottom - 0x2E] = [0x1012EA] = 0xE68
这看起来不像一个地址,因为系统调用处理程序的实际地址计算为
syscall_table_bottom + offset
。 整个过程如图所示。
Softline REALOS / FR内核手册中指出了所有系统调用及其功能,因此我设法恢复了表中所有已实现的处理程序,并进一步改进了IDB。

当然,您可以通过在IDA中定义系统调用的类型来使代码更加美观。

我写
了一个Python脚本来自动搜索这些系统调用以及更多内容。
任务
在
sta_tsk
系统调用中
sta_tsk
我注意到不是将main函数作为参数传递,而是将pid作为参数传递。 这意味着是时候寻找大量的任务描述符了。 从
sta_tsk
本身开始
sta_tsk
。
ROM:102180 sys_sta_tsk:
ROM:102180 ST RP,@ -R15
ROM:102182 LDUB @(R14,0x4F),R3
ROM:102184 LDI:32#word_100B80,R14
在开始时,我们会看到一些链接。 我不得不对数据类型进行一些修改,但最终这些部分融合在一起:
ROM:100B80 word_100B80:.word 0xF; 任务数
ROM:100B82。字0x1C; 任务描述符大小
ROM:100B84。长0x82A09F5C; 任务1描述符
ROM:100B88。长0x1000D
ROM:100B8C。长0
ROM:100B90。长0x40000000
ROM:100B94 .long sub_1A7DB2; 任务主体
ROM:100B98。长0x8286EEC0
ROM:100B9C。长0
ROM:100BA0 .long 0x82A09F88; 任务2描述符
ROM:100BA4。长0x20010
ROM:100BA8。长0
ROM:100BAC。长0x40000000
ROM:100BB0 .long sub_1A6BD2; 任务主体
ROM:100BB4。长0x8287EEC0
ROM:100BB8。长0
...
等等。 只有15个任务。 查看每个主要功能,确定任务的名称和目的(最后一个任务除外)只是时间问题。 以下是完整列表:
- 子CPU
显然,此任务负责捕获操作,例如曝光,屏幕上的瞄准等。
- 关键经理
最有可能的是,此任务与硬件按钮相关联。
- Guimanager
非常重要的任务是在其中实现UI状态机和界面呈现。
- 调试管理器
是的,有一些要调试的东西。 百胜
- 档案管理员
此任务全部关于文件操作。
- 法玛纳格
我要说的是,该任务负责文件和内存,因为它取决于文件管理器和内存管理器的任务。
- 内存管理器
毫不奇怪:内存操作,池管理等。
- 影像管理员
此任务管理编码/解码过程和其他图像处理过程。
- Usbmanager
当前的挑战是USB通信处理,其中包括MassStorage,PTP和Leica自己的协议。
- IO管理器
这个任务似乎是在管理诸如SD和CF卡之类的存储设备(什么?还有哪些其他CF?也许来自213型)。
- 系统管理员
各种任务,例如常规系统操作,电源管理等。
- 设置管理器
处理相机状态和设置。
- 监控经理
跟踪摄像机状态变化并通知其他任务。
- 外围设备管理器
此任务控制GPS,亮度和其他一些传感器。
- 不明
不幸的是,我没有发现对她有意义的东西。
有趣的是,在主数组之后还有另一个出色的描述符。
ROM:100D28 dword_100D28: .long 0x82A0A1F0
ROM:100D2C .long 0x21
ROM:100D30 .long 0
ROM:100D34 .long 0x80000000
ROM:100D38 .long tid16_task
ROM:100D3C .long 0x8285EEC0
ROM:100D40 .long 0
任务的功能仅仅是分支本身。
ROM:101494 sub_101494:
ROM:101494 BRA sub_101494 ; CODE XREF: sub_101494
在
start
函数的末尾引用该描述符,该函数负责创建其他任务并设置固件。 因此,这很可能是系统不活动的任务。
模块和消息
除了任务,您还可以定义一些逻辑对象,例如IO和外围模块。 模块作为一组消息处理程序呈现,作为任务之一的一部分。
IO组似乎包括:
- IO经理
- 副处理器
- USB管理器
- USB PTP
- USB Leica协议
- USB大容量存储
- 按钮管理器
- 调试管理器
- 镜头经理
在外围组中:
- 周边经理
- 光线感应器
- 发光二极管
- 讲者
- 倾斜传感器
- 封盖识别
- GPS模块
- 3DAxis模块
消息传递系统本身使用标准的SOFTUNE结构:
struct RealOS_MsgPayload { uint32_t msgID; // +0x0 uint32_t data[]; // +0x4 } struct RealOS_Message { uint32_t os_reserved1; // +0x0 uint32_t os_reserved2; // +0x4 uint32_t to; // +0x8 uint32_t from; // +0xC RealOS_MsgPayload* payload; // +0x10 }
不出所料,IPC也有几个消息组。 由于许多消息是在任务和模块中处理的,因此我只能恢复其中一些组:
0x1101xxxx-全局系统消息:
0x11010002 = SYS_UPDATE_BOOTLOADER或
0x11010005 = SYS_ERASE_SETTINGS
0x1102xxxx-与图像捕获有关的消息:
0x11020001 = CMD_CAP_CAPTURE或
0x11020008 = IMAGE_STATUS_CHANGED
0x1104xxxx - , :
0x11040002 = PLY_DISABLE_PLAY_MODE
0x11040004 = PLY_IMAGE_READY
0x1108xxxx - PTP .:
0x11080002 = DBG_CHANGE_LEVEL
0x11080012 = DBG_WRITE_ROM_DUMP_SD
0x2201xxxx - USB PTP
0x22010108 =
0x22010118 = DebugObject
0x2202xxxx - SUBCPU:
0x22020002 = E_SUBCPU_REQUEST_M_EXPOSURE_REQUEST
0x22020015 = E_IO_SUBCPU_COMMAND_CLEANING_SENSOR
0x2203xxxx - :
0x22030001 =
0x2204xxxx - IO:
0x2204000C = / Mass Storage
0x22040012 =
0x330000xx - UI:
0x33000001 =
0x33000007 =
0x440000xx - ,
0x44000013 = E_IMG_CMD_CHANGE_PINFO
0x55xxxxxx — FAM:
0x558800xx = - FAM
0x558888xx = FAM
0x6602xxxx — LED, :
0x66020001 - LED X
0x66020002 = LED
0x6604xxxx - :
0x66040001 =
0x66040007 =
0x6611xxxx - ,
0x6622xxxx - ,
0x6660xxxx-其他与内存有关的消息:
0x66600006 =直方图
0x66600011 = RAWCOMP
0x771100xx和0x77AA00xx-与切换摄像头模式有关的消息
不幸的是,许多其他职位仍然未知。图形用户界面
在固件文件中,我们还将查看以下部分:CTRL_SYS-11,IMG-LOKI-212,IMG-DSP-212,IMG-FPGA-212和IMG-LENSDATA-212。令我惊讶的是完全缺乏GUI资源。但是它们应该在某个地方,并且很可能内置在IMG-LOKI-212中。我进行反向固件开发的常用方法之一是恢复所有可能的交叉引用。不仅在代码中,而且在数据部分中。然后,我仔细阅读它们,尝试找到一些模式或指向代码已知部分的链接。徕卡固件也不例外。有许多相似的数据序列,还有指向其他数据序列的地址,等等。当我爬上链接层次结构时,我终于看到了一个熟悉的功能。例如,我发现一个没有任何链接的数据结构: g_data = { ... }
另一个结构解决了这个问题: g_data_struct1 = { ... , &g_data }
依次由另一种结构引用: g_data_struct2 = { &g_data, ... }
该数据结构具有来自代码的链接,并将其作为参数传递给另一个函数: func1() ╰ func2(..., &g_data_struct2, ...)
但是,func1()
它不是直接从另一个函数调用的,而是存储在某个数组中: g_func_list1[] = { ..., func1(), ... }
从上方看,我在代码中找到了一个调用g_func_list1
: func3() { g_func_list1[x] }
同样,此函数存储在数组中: g_func_list2[] = { ..., func3(), ... }
其他一些代码访问数组本身: func4() { g_func_list2[x] }
幸运的是,这次是从另一个函数调用该函数,依此类推gui_MADE_ApplicationRun
。 gui_Statemachine_DoStateChange() ╰ gui_MADE_ApplicationRun() ╰ func5() ╰ func4()
有些行表示GUI子系统称为“ MADE”,并且使用MADE_GetSysTri
任何手段来处理页面转换。GUI状态机基本上是通过功能实现的gui_Statemachine_DoStateChange
。收集有关GUI的信息后,出现了大致情况:
如您所见,GUI资源的主要功能是gui_CopyImageDesc
(尽管这不是真实名称)。她有以下论点: gui_CopyImageDesc( uint32_t dstAddress; // R4 - destination address UIDescType type; // R5 - description type UITarget target; // R6 - rendering target uint32_t descAddress; // R7 - description address uint8_t always0; // (SP + 0x0) - always 0 uint8_t index1; // (SP + 0x4) - index 1 uint8_t index2; // (SP + 0x8) - index 2 uint16_t x_offset; // (SP + 0xC) - x offset uint16_t y_offset; // (SP + 0x10) - y offset uint16_t unknown2; // (SP + 0x14) - uint32_t language1; // (SP + 0x18) - language id 1 uint32_t language2; // (SP + 0x1C) - language id 2 uint32_t funcAddress; // (SP + 0x20) - function address )
资源描述有四种类型: struct UIDescType0Header struct UIDescType1Header struct UIDescType2 struct UIDescType3 { { { { uint32_t address; uint32_t address; uint32_t reg; uint16_t x_offset; uint16_t entries; uint16_t entries; uint32_t address; uint16_t y_offset; uint16_t unknown; uint16_t unknown; uint16_t unknown1; uint32_t address; } } uint16_t unknown2; } uint16_t unknown3; struct UIDescType0Entry struct UIDescType1Entry uint16_t tableoff; { { } uint16_t x_offset; uint16_t x_offset; uint16_t y_offset; uint16_t y_offset; uint32_t address; uint32_t address; } uint16_t objects; uint16_t total_w; uint16_t total_h; uint16_t unknown; }
第一种类型具有标头,该标头引用记录数组。每个记录都有像素数据的坐标和地址。当前类型似乎描述了状态相关的元素,例如图标,这些元素可能会变灰或从UI中消失。第二种类型也以标题开头,用于定位,描述行或文本块。第三种类型描述了不同语言的字符映射。后一种类型负责所有其他静态资源,例如图像,背景等。现在,让我们看一下图像本身的数据。前六个字节看起来像一个小标头,其后是某种重复模式,其中每个第二个字节为或。这是合乎逻辑的假设,并+0x00: 00 08 00 14 00 01 A2 FF 0A 04 05 FF 0C 04 03 FF
+0x10: 0D 04 03 FF 0E 04 02 FF 0E 04 02 FF 04 04 06 FF
+0x20: 04 04 02 FF 04 04 06 FF 04 04 02 FF 04 04 06 FF
+0x30: 04 04 02 FF 04 04 06 FF 04 04 02 FF 04 04 06 FF
+0x40: 04 04 02 FF 04 04 06 FF 04 04 02 FF 04 04 06 FF
+0x50: 04 04 02 FF 04 04 06 FF 04 04 02 FF 0E 04 02 FF
+0x60: 0E 04 02 FF 0D 04 03 FF 0D 04 03 FF 0C 04 04 FF
+0x70: 04 04 0C FF 04 04 0C FF 04 04 0C FF 04 04 0C FF
+0x80: 04 04 0C FF 04 04 0C FF 04 04 0C FF 04 04 0C FF
+0x90: 04 04 0D FF 02 04 2D FF 00 06 00 14 00 01 79 FF
0xFF
0x04
0x0008
0x0014
-具有直接字节顺序(大字节序)的视图中的宽度和高度。在此转储的结尾,我们看到了另一个序列的开始00 06 00 14 00 01
。这很可能是下一个资源(已通过链接确认)。因此,实际图像数据的大小是146字节。但是图像大小应为0x8 * 0x14 = 0xA0 =160。很明显,数据不是纯像素,甚至也不是8位LUT,因为它要小14个字节。那呢
可能是某种压缩。查看此十六进制转储,很难相信使用了某种复杂的方案。 Leica的GUI并不是很丰富,因此以我的经验,最好在这里使用LUT表。在这种情况下,UI资源将完全重复LUT索引,例如03 03 03
或1 1 1
。通常,压缩程序会尝试消除数据重复,将其替换为链接。即使使用RLE这样的简单方法,这些索引数组也非常适合压缩[data][number]
。一个简单的命令来写data
(计算)number
时间。考虑到所有这些,我建议我们最有可能查看具有两种LUT颜色(0xFF
和0x04
)的简单图像,并且该颜色前面的字节是要绘制的像素数。你想:“然后你写了另一种乐器。”但是不,我拿着笔和纸开始装满牢房。我仍然有那张照片真是可笑。
一路上的某个地方,我意识到160像素不足以显示这张图片,因此0x8和0x14需要乘以2。第三个单词0x0001表示图像是否为ASCII字符,因此最终的ImageAsset结构如下: struct ImageAsset { uint16_t width; // /2 (big endian) uint16_t height; // /2 (big endian) uint16_t ascii; // 1, ASCII struct image_data { uint8_t number; // uint8_t color; // LUT } data[]; }
但是仍然缺少一部分:LUT。找到它并不难,因为已经手动恢复了许多链接和结构,所以我慢慢浏览了数据部分,从16位或32位值中查找256个元素的数组,直到遇到此问题为止:再一次,谢谢在Blackmagic Design工作中,我立即识别出YUV像素(例如,所有值为8080的值)。我不是一个傻瓜再次在纸上手动绘制整个用户界面,所以是的,我编写了另一个工具-M240UITool。除了将所有图像资源从固件文件重置为BMP / PNG之外,该工具还可以在IDA中创建IDC脚本来确定所有UI资源。.long 0x7008080, 0x72D8080, 0x73C8080, 0x75A8080, 0x79B8080, 0x71DFF6B, 0x7BE8080, 0x7FF8080
.long 0x77BBD27, 0x75B60E7, 0x7835F4A, 0x7D3089F, 0x7018080, 0x7028080, 0x7038080, 0x7048080
.long 0x7058080, 0x7068080, 0x7078080, 0x7088080, 0x7098080, 0x70A8080, 0x70B8080, 0x70C8080
.long 0x70D8080, 0x70E8080, 0x70F8080, 0x7108080, 0x7118080, 0x7128080, 0x7952B15, 0x7138080
.long 0x7148080, 0x7158080, 0x7168080, 0x7178080, 0x7188080, 0x7198080, 0x71A8080, 0x71C8080
.long 0x71D8080, 0x71E8080, 0x71F8080, 0x7338080, 0x7208080, 0x7218080, 0x7228080, 0x7238080
.long 0x7248080, 0x7248080, 0x7268080, 0x7278080, 0x7288080, 0x7298080, 0x72A8080, 0x72B8080
.long 0x72C8080, 0x75E8080, 0x7608080, 0x7628080, 0x7648080, 0x7678080, 0x7688080, 0x7698080
.long 0x76B8080, 0x76E8080, 0x7708080, 0x7728080, 0x7758080, 0x7778080, 0x7798080, 0x77C8080
.long 0x77E8080, 0x7818080, 0x7838080, 0x7868080, 0x7888080, 0x78B8080, 0x78D8080, 0x7908080
.long 0x7928080, 0x7958080, 0x7978080, 0x7998080, 0x79C8080, 0x79D8080, 0x7668080, 0x79E8080
.long 0x7A18080, 0x7A28080, 0x7A38080, 0x7A68080, 0x7A78080, 0x7A88080, 0x7AB8080, 0x7AC8080
.long 0x7AD8080, 0x7B08080, 0x7B28080, 0x7B58080, 0x7B88080, 0x7B98080, 0x7BC8080, 0x7CC8080
.long 0x7AB3BBB, 0x7E10094, 0x7E4556E, 0x4008080, 0x2922D17, 0x7B2AB00, 0x7C2A262, 0x71DFF6B
.long 0x768D4A2, 0x769D4EA, 0x7BD88AE, 0x705997B, 0x70BB377, 0x711CC73, 0x717E66F, 0x7238866
.long 0x729A262, 0x72FBB5E, 0x735D55A, 0x7417751, 0x747914D, 0x74DAA48, 0x753C444, 0x75F663B
.long 0x76B9933, 0x7998080, 0x771B32F, 0x77D5526, 0x7836F22, 0x789881E, 0x78FA21A, 0x7159095
.long 0x71AAA91, 0x720C38D, 0x726DD88, 0x7506F6A, 0x7568866, 0x75CA262, 0x762BB5E, 0x76E5E55
.long 0x7747751, 0x77A914D, 0x780AA48, 0x78C4D3F, 0x792663B, 0x7988037, 0x79E9933, 0x7AA3C2A
.long 0x7B05526, 0x7B66F22, 0x7BC881E, 0x72488AE, 0x72AA1AA, 0x72FBBA6, 0x735D4A2, 0x7427799
.long 0x7489095, 0x74DAA91, 0x753C38D, 0x77E556E, 0x7836F6A, 0x7898866, 0x78FA262, 0x79C4459
.long 0x7A15E55, 0x7A77751, 0x7AD914D, 0x7BF4D3F, 0x7CC8080, 0x7C5663B, 0x7CB8037, 0x7337FC8
.long 0x73999C4, 0x73FB2C0, 0x745CCBB, 0x7757799, 0x74C54FF, 0x77B9095, 0x780AA91, 0x7AB3C72
.long 0x7B1556E, 0x7B66F6A, 0x7BC8866, 0x74277E1, 0x74890DD, 0x74EAAD9, 0x754C3D5, 0x76066CC
.long 0x7667FC8, 0x76C99C4, 0x772B2C0, 0x77E55B7, 0x7846EB3, 0x78A88AE, 0x790A1AA, 0x7526EFB
.long 0x75787F7, 0x75DA1F3, 0x763BAEE, 0x76F5DE6, 0x77577E1, 0x77B90DD, 0x781AAD9, 0x78D4CD0
.long 0x79366CC, 0x79F99C4, 0x7E10094, 0x7CF44A1, 0x7DB7799, 0x7E71A90, 0x7ED338C, 0x7FF8080
.long 0x7328080, 0x7DC8080, 0x7C88080, 0x7508080, 0x775CD2C, 0x76944EA, 0x7808080, 0x71A61FF
.long 0x7244D40, 0x7242C15, 0xFFF8080, 0xF338080, 0xF668080, 0xF998080, 0xFCC8080, 0xF008080
.long 0xF4C54FF, 0xFAB3BBB, 0xFE10094, 0xFE4556E, 0xF952B15, 0xFDA7751, 0xFB2AB00, 0xFC2A262
.long 0xF1DFF6B, 0xF68D4A2, 0xF69D4EA, 0xFBD88AE, 0xA922D17, 0xC6E4130, 0xE286963, 0x74C55FF
.long 0x768D536, 0x7FF8080, 0x7FF8080, 0x7FF8080, 0x2922D17, 0x46E4130, 0x6286963, 0x8080
Leica M (typ 240) UI Tool v1.0
Usage: ./M240UITool [-a address] [-i imagebase] [-s script] [-d dump] [-f folder] [-l LUT] [-rbv] FIRMWARE.BIN
This tool will help you to find UI resources in firmware.
Use following arguments:
-a Specify address of the gui_CopyImageDesc function (ex. 0x2F95E0)
-i Specify firmware imagebase
-s Specify IDC file name
-c Specify container file name
-d Specify dump image format
png - PNG format
bmp - BMP (ARGB) format
-f Specify folder for dumped images
-l Specify LUT for images (filename of address)
-b Specify number of bytes to display in verbose mode
-r Try to recover string characters
-v Be verbose
我们已经知道,从一个UI页面创建的功能来看,它被多次调用gui_CopyImageDesc
。我认为制作一个UI资源浏览器并定义所有页面呈现功能会很棒。该选项专用于此-c
-它创建了一个用于查看资源的特殊容器。谁说UI资源浏览器可能看起来并不异常?
该工具具有交互性(屏幕截图上的半透明按钮),不仅使您可以滚动浏览EVF / LCD菜单的页面,还可以查看一页内的渲染步骤。不幸的是,该杰作的源代码在某个地方丢失了,但是头文件仍在M240UITool代码中,因此从技术上讲,您可以从头开始重新创建它。调试菜单
在进行逆向工程时,我们主要寻找哪条线?我认为,这个词debug
及其派生词。固件中有很多有趣的行,但是这些行很特别:似乎可以使用某些组合键进入调试模式。所有这些行都从一个巨型函数调用,该函数实现了按钮扫描状态机。这是IDA中的样子:$ strings ./IMG_LOKI-212_1.1.0.2.bin | grep "Debug Mode"
GUI: State: %d! Scanning for Debug Mode successful
GUI: Scanning for Debug Mode: State: %d, Ignore long DEL
GUI: Scanning for Debug Mode: State: %d
GUI: Scanning for Debug Mode: State: %d, Ignore long DEL
GUI: Scanning for Debug Mode: State: %d
GUI: Scanning for Debug Mode: State: %d, Ignore long DEL
GUI: Scanning for Debug Mode: State: %d
GUI: Scanning for Debug Mode: State: %d, Ignore long DEL
GUI: Scanning for Debug Mode: State: %d
GUI: Scanning for Debug Mode: State: %d, Ignore long DEL
GUI: Scanning for Debug Mode: State: %d
...
GUI: ScanningForDebugWithKeyAndJoyStick(): g_GUI_CheckForDebugWithKeyAndJoyStick = %d
ScanningForDebugWithKeyAndJoyStick
我不会说谎,花了一些时间来了解固件中如何处理硬件按钮,然后恢复按钮和操纵杆的枚举类型。但是当我得到合并的时候,我很生气地发现她什么也没做。它可能只能在特定的GUI页面上使用。 GUI状态机的手动跟踪又过了两个晚上-问题得以解决,我们还设法找到了Reset菜单页面。最后,欢迎使用调试模式。
我考虑过是否要宣布这一组合,但决定弃权。我尊重徕卡所做的辛勤工作,发布了其独特的设备,并且我不为这样的事实负责,因为他们的服务中心将由于一些深思熟虑的好奇心而填补相机破碎的尸体。但是,我仍然会提供一些枚举类型,以便为准备采用这种方法的人员简化逆向工程。 enum ControlActionType { kControlAction_Idle, // 0 kControlAction_Push, // 1 kControlAction_Release, // 2 kControlAction_LongPush // 3 }; enum ControlBtnType { kControlBtn_LV, // 0 kControlBtn_PLAY, // 1 kControlBtn_DEL, // 2 kControlBtn_ISO, // 3 kControlBtn_MENU, // 4 kControlBtn_SET // 5 }; enum ControlJoystickType { kControlJoy_INFO, // 0 kControlJoy_Up, // 1 kControlJoy_Down, // 2 kControlJoy_Left, // 3 kControlJoy_Right // 4 };
点对点
考虑到USB任务,我定义了三种模式(在调试菜单中也已确认):PTP最为有趣,因为PTP有据可查,可让您控制摄像机。在固件中找到PTP处理程序非常容易,因为此代码中有很多调用。所有PTP呼叫均分为三类:传统,徕卡扩展(LE)和生产。调试消息有助于为几乎所有代码建立名称。 旧版:徕卡扩展:生产:
0x1001-GetDeviceInfo 0x9001-设置相机设置0x9100-公开生产会议
0x1002 - OpenSession 0x9002 - Get Camera Settings 0x9101 - Close Production Session
0x1003 - CloseSession 0x9003 - Get Lens Parameter 0x9102 - UpdateFirmware
0x1004 - Get Storage ID 0x9004 - Release Stage 0x9103 - Open OSD Session
0x1005 - Get Storage Info 0x9005 - Open LE Session 0x9104 - Close OSD Session
0x1006 - GetNumObjects 0x9006 - Close LE Session 0x9105 - Get OSD Data
0x1007 - GetObjectHandles 0x9007 - RequestObjectTransferReady 0x9106 - GetFirmwareStruct
0x1008 - GetObjectInfo 0x9008 - GetGeoTackingData 0x910B - GetDebugMenu
0x1009 - GetObject 0x900A - Open Debug Session 0x910C - SetDebugMenu
0x100A - Get Thumb 0x900B - Close Debug Session 0x910D - ODIN Message
0x100B - Delete Object 0x900C - Get Debug Buffer 0x910E - GetDebugObjectHandles
0x100E - Initiate Capture 0x900D - Debug Command String 0x910F - GetDebugObject
0x1014 - GetDevicePropDesc 0x900E - Get Debug Route 0x9110 - DeleteDebugObject
0x1015 - GetDevicePropV 0x900F - SetIPTCData 0x9111 - GetDebugObjectInfo
0x101C - Initiate Open Capture 0x9010 - GetIPTCData 0x9112 - WriteDebugObject
0x9020 - Get3DAxisData 0x9113 - CreateDebugObject
0x9030 - OpenLiveViewSession 0x9114 - Calibrate 3Daxis
0x9031 - CloseLiveViewSession 0x9115 - Magnetic calibration
0x9033 - Unknown 0x9116 - Get Viewfinder Data
PTP接口本身的实现似乎是标准的,但是某些命令具有一些限制,在此我特意忽略了这些限制。无论如何,以上所有都是令人兴奋的。您可能会想:“让我们通过USB插入相机,然后开始使用libptp进行探测。”没错
该死的...Leica M240没有USB端口。手柄口
徕卡为此相机提供的配件很少,但是其中一个特别有趣。我们正在谈论多功能手柄Leica M(14495)。它取代了外壳的底部金属部分,提供了内置GPS和几个连接器,例如USB,SCA闪光端子,DIN / ISO-X和电源插座。
然后您再说一遍:“太好了,现在就购买它,将其连接到相机,通过USB连接相机,并开始使用libptp进行探测。”没错
只是该死的...它的成本近900美元。这几乎是创建您自己的适配器的九百个原因。但是,以防万一,我为此配件设置了eBay通知。连接器
相机上的连接器如下:
我试图在Internet上找到它,但是说真的,您如何在Google上描述它?绝望了一下,我开始考虑一些疯狂的事情,例如将箔或针刺到橡皮上。但是一旦在Blackmagic Design工作时,看着摄像机电路板,我注意到其中一个连接器的形状非常熟悉。第二天,我将我的Leica M240投入使用-是的,它看起来很相似,只是用了很多垫子才更长。仍然需要询问我们的组件管理器的零件号,然后在Samtec目录中找到它:ERM8-013-05.0-L-DV-TR。
我们还询问了Samtec是否可以获取样本,他们表示同意。
可以用烙铁,硬纸板和电工胶带做一些工作-我自己的插头已经准备好(2013年样品)。
五年后的2018年,我决定亲自要求Samtec发送另一个样本。我想做得更好。ERCD-013-05.00-TTR-TTR-1-D
再次使用烙铁进行大量工作,打磨,切割线,使用脏话,再使用烙铁进行工作,以做出一个新的,更具吸引力的选择:
引脚排列
连接器中有26个触点:每侧13个。甚至在焊接我的零件之前,我就用万用表和逻辑分析仪探查了相机的连接器。顺便说一句,您需要在底盖传感器上放一块磁铁,以便相机认为盖已就位。接地(相机关闭,没有电池)我总是从地面开始,因为它安全且非常容易找到。
因此,我们有8条接地线(深灰色)。电位(摄像头打开)摄像头打开时,您可以测量每个引脚上的电位,并了解逻辑和功率级别。alexhude.imtqy.com/assets/2019/2019-01-24-hacking-leica-m240/probe2_potential.png引脚8–9和11–13的性能对于逻辑引脚而言过高,因此我将其定义为电源(红色)。电阻(相机关闭,没有电池)测量电阻非常有用。在某些情况下,这有助于识别输入并将某些行分组。
连接输出(相机关闭,没有电池)然后,我决定检查相机机身上的所有外部打击垫,以检查它们是否已连接至维修端口。
闪光同步触点直接连接到10号线。逻辑分析仪(相机已打开)按照以下顺序记录每条线的数据:打开,相机应处于LV模式,拍照,开始录像。
- : 01 21.
01 — 115200, 8 , 1 -, , LSB .

500 , -
C3 3C 02 81 00 01 00 82, C3 3C 02 81 01 01 00 83, C3 3C 02 81 02 01 00 80
…
21 — 115200, 8 , 1 -, , LSB .

SH7216 (“Leica Camera AG” ).
-. , Maestro Debug.

310kOhm.
我不知道为什么,但是我建议其他数据线可能具有相似的阻力或将被关闭。因此,我将〜300kOhm,〜200kOhm和〜100kOhm的线定义为数据线(图片中的蓝色阴影)。通常,绘制了以下图片。
数据线上有12位候选人。但是如何检查它们呢?在与钢铁专家就集成电路的电气保护进行了简短的交谈之后,我开始通过4kOhm的电阻戳接触点,该电阻将电流降低到输入不应燃烧的水平。串口
我还假设RX线应该在TX附近。02、03和20行看起来像是不错的选择,因为它们的电压都像TX一样,为3.3V。最初,我尝试使用Bus Pirate探索这些线路。不幸的是,结果很脏。然后,我认为基于SiLabs的电缆在macOS上更加可靠且无冲突。首先,我将TX电缆连接到引脚20,并help
在引导加载程序之后开始键入。不出所料,在短暂的延迟之后,相机重复了角色。
触点02和03是UART的下一个候选对象。不幸的是,没有迹象表明这些线正在被挖掘。在该图中,众所周知的UART用深绿色阴影表示。
USB接口
一切始于将USB电缆切成两半,中间有一个接头,并带有4kOhm的电阻用于感测。差分对的信号完整性?不,那我真的不在乎。 :)
然后,我在家中探查了几个USB家庭设备,以了解该端口上的通信情况。佳能
相机Blackmagic便携式
摄像机佳能
摄像机JVC摄像机
钥匙扣
KidiZoom相机
有点不同,但是初始D-D +状态很低。好吧,我们将知道,现在我们将检查是否具有:- 22-不太可能,因为D-D +是差分对,应该非常接近;
- 04/05-不太可能,因为它们具有不同的抵抗力;
- 14/15 — , ;
- 15/16 — , .
因此,我将USB D-D +连接到15/16引脚,然后将其连接到iMac ...
在USB PTP屏幕上,但是相机未出现在主机上。我试图在电子电路的布局上配置不同的选项,但是没有任何效果。小猎犬显示出很多包装损坏和其他错误。最后,我放弃并返回对固件进行反向工程。这是最后的引脚分配,USB标记为深绿色。
谁曾想到,几年后,同样的eBay通知会传给我,我会以低廉的价格购买所需的配件。最后,我可以检验对PTP的假设。但是起初,很好奇USB PHY在小工具内部的外观。
内部是SMSC 2512b集线器从手柄插孔到Mini USB接口的路上。该芯片在默认模式下工作,因为没有EEPROM或SCL / SDA引脚。第一个下游端口连接到相机机身上的插槽,但第二个未连接任何东西。我可能错过了一些东西,但是对我来说,这样的解决方案没有多大意义。技术护照说,该芯片具有“完全集成的USB引脚以及用于升高和降低电压的电阻器”。也许徕卡的工程师决定不实施自己的USB PHY,而是在集线器中使用了一个经过良好测试并且可以立即使用的集线器。实际上,我不能怪他们,因为在我尝试这样做之前,事实证明这是一项艰巨的任务。谁知道,也许这是防止伪造的功能。无论如何,如果您了解USB PHY并准备为您提供帮助,请随时给我写信:没有这个品牌附件的情况下,应该可以通过USB端口工作:)再次PTP
就像我说的,是时候玩Leica PTP扩展程序了。幸运的是,我找到了一个非常酷的C ++库,而不是libptp,它是libEasyPTP。基于此库编写工具也不需要花费很多时间:我已经知道Leica PTP界面的一些局限性。而且,尽管M240PTPTool有很多缺陷,但它非常适合概念验证(程序代码)的作用。仅两个请求通过PTP:GetDebugBuffer(0x900C)和DebugCommandString(0x900D)。顺便说一句,为了让模块填写调试日志,您需要在菜单中将“调试级别”设置为“调试”或“调试RAW”。M240PTPTool界面中有几个选项:- 退出 -关闭工具;
- 刷新 -合并摄像机的调试缓冲区:
M240> flush
I:[00:11:468]|01| DATE/TIME CORRECTED by 5921 sec
D:[00:12:079]|00| Send message from TID 0 to TID 1 over MBX 3 - length: 4 - MesgID: 0x22020103
D:[00:12:179]|00| Send message from TID 0 to TID 1 over MBX 3 - length: 4 - MesgID: 0x22020103
D:[00:12:282]|11| Message received from TID 0 for TID 1 over MBX 3
D:[00:12:283]|11| Message received from TID 0 for TID 1 over MBX 3
D:[00:12:301]|00| Send message from TID 0 to TID 1 over MBX 3 - length: 4 - MesgID: 0x22020103
D:[00:12:402]|00| Send message from TID 0 to TID 1 over MBX 3 - length: 4 - MesgID: 0x22020103
D:[00:12:502]|00| Send message from TID 0 to TID 1 over MBX 3 - length: 4 - MesgID: 0x22020103
...
其他任何文本作为调试命令发送到相机。例如,它help
显示带有参数的所有可能的命令:完整列表很大,但是看起来,您可以将直接消息发送给Softune执行任何任务!将其发送到那里会很有趣。经常在固件中搜索的另一条流行线是。让我们看看是否有一个。显然,您可以将固件转储到SD卡上。使用“将文件转储到卡”行的链接,很容易找到造成此问题的代码。它位于巨大的系统任务块(众所周知,pid 11)中,并由不带参数的消息调用。表盘在M240PTPTool,按Enter键和看屏幕。M240> help
********* debug command description ********
exposure request
Description: requests a release from Sub CPU
Parameter 1: Exposure Time TV
still request
Description: simulates the -still request- command flow of Sub CPU
Parameter: no
...
send Message;[Parameter1];[Parameter2];[Parameter2];...;...
Description: Sending Message to Task
Parameter 1: Receiver Task ID
Parameter 2: Command ID
Parameter 3: Command Data[0] (32 Bit)
Parameter 4: Command Data[1] (32 Bit)
Parameter 5: .
Parameter 6: .
use maximum 10 Parameter
...
dump
$ strings IMG_LOKI-212_1.1.0.2.bin | rg -i dump
GUI: HEX DUMP: Address: %x, Length: %d
HSK: DBG_WRITE_ROM_DUMP_SD: File was properly opened, but it seems to be empty.
ROM_DUMP
HSK: DBG_WRITE_ROM_DUMP_SD: Flushing Dump to ROM. Size %d
SD:\ROM_DUMP.bin
HSK: DBG_WRITE_ROM_DUMP_SD Command received!
ROM_DUMP.bin
HSK: DUMP failed, no cards inserted!
HSK: DUMP FlashROM to SD card.
HSK: DUMP FlashROM to CF card.
Dumping files to card
0x11080006
send Message;11;0x11080006
然后取出SD卡并检查其中的内容。
这是一个完整的转储,包括固件。这开辟了无限的可能性。例如,您可以制造一个带有MCU的小型设备,支持USB主机和用于启动复杂消息序列的按钮...然后我们有了第二个孩子。 :)
结语
如果您不想损坏设备,通常可以通过一种方法来检查它,而无需打开外壳或将导线焊接到电路板上。如果您感兴趣,以下是我的提示:- 查找有关该设备的所有公共信息:技术规格,组件数据,内部照片,工厂视频;)
- 如果您有固件,请深入研究并寻找外部输出的提示;
- , ;
- GND// , ;
- ;
- , ;
- , (, );
- , Google (USB/UART/SPI/I2C/1Wire);
- , ;
, ;
- , .
github.com/alexhude!