风之栖息地

快速寻找串行接口

字数统计: 4.3k阅读时长: 17 min
2019/03/02 Share

这是一篇来自devttys0的一篇文章,在寻找串口的方法上给出了很多有用的方法,是一篇不错的总结文,在国内没有看到翻译,所以就想翻译成中文供大家学习,第一次做翻译,如有错误之处,请大家体谅,可以给我留言,我会快速修改。

原文链接

鉴于这个博客的名声和我拥有的点击量,我认为现在是大家一起讨论串口的时候了,尤其是嵌入式系统的串口。

我的目标是通过使用确定的测试和有根据的猜测来讲解我发现的有效识别和逆向嵌入式串口的技术,而不需要特别昂贵的设备。

简介

串口对于嵌入式开发人员特别有用,通常会使用串口来:

  • 进入boot loader
  • 得到启动和调试信息
  • 通过shell和系统交互

不用说这个功能同样对黑客有用,所以在嵌入式设备上找到一个串口会非常有用。作为一个学习案例,我们将测试Westell 9100EM FiOS 路由器的PCB,用于寻找可能的串口。

现在,不是你们父亲那一代寻找的RS-232串口,现在有通用异步收发器,Universal Asynchronous Receiver Transmitters (UARTs),常见于嵌入式设备中。虽然协议兼容,RS-232和UART不是电压兼容(从这里开始我会把UART和串口互换)。UARTs常用在3.3V,但是也有可能用在其他其他标准电压上。(5V、1.8V等)

不幸的是,这里没有任何工业标准的UART引脚输出,并且制造商通常不会宣传或记录他们的调试接口。所以为了连接这些串口,我们需要做一些工作。尤其,我们需要逆向工程硬件接口和软件协议设置。

让我们先从硬件接口开始,为此,你需要一个万用表和一对眼球(甚至一个也可以做的很好,23333)。是的,示波器和逻辑分析仪很有用,有时也是必要的,但是在99%的时间里,一个可靠的万用表和一点点知识就是你需要的全部。

识别串口头

第一步是尝试识别串口标头的潜在对象。大部分的串口头至少有四个引脚:

  • Vcc
  • Ground
  • Transmit
  • Receive

通常情况下,你将要寻找单排4-6个引脚的地方,虽然这不是一个严格的规定,它们可以采用制造商决定的任何引脚配置。

在我们的 9100EM PCB ,能找到两个可能的地方 P1402 和 P1404标签处:

有时,你不会有这样一套很好的引脚,你必须要检查板子上的监测点,通常从最接近SoC的测试点开始是一个好主意。这里有一个WL530G的例子,通过板子上的不同测试点来发现串口。

在任何一种情况下,识别引脚的过程都是相同的。但是如果没有头部通常会需要更长的时间,因为可能会超过4个检测点需要去检查。

此时,P1402或P1404可能是串口头,或者它们都是串口头,又或者两者都不是串口头。 因此,我们将分别检查每个头部上的引脚,尝试去获得一些有用信息。

肉眼观察

首先,让我们仔细检查引脚,从P1402开始:

在PCB的正面最右侧的引脚被标记为1,这不是非常重要,但是在描述引脚编号的时候它给出了一个共同的参考框架。

在PCB的背面,我们看到引脚3有四条痕迹组成十字图案,它们连接在地线平面的附近。这很容易的将引脚3识别为地线(Ground)。

引脚2和4有细的痕迹连接到它们,而引脚1连接在较粗的痕迹上。宽的痕迹通常用于供电的,而窄的痕迹通常用于信号传输。这表明引脚1是Vcc,引脚2和4可能是收发(尽管我们不知道哪个是哪个)。

让我们看看P1404的头部:

这里,最左边的引脚被标记为1。再一次,我们看到引脚3连接在PCB背面接地。引脚4也有一个连接到它的细痕迹,所以它可能是传输或者接受引脚。

然而,P1404的另外两个引脚在PCB的正面或背面上没有连接到它们的可见痕迹。可能是它们没有连接到任何东西,但是更可能的是它们的痕迹连接在我们看不到的PCB中一个内层上。是时候使用万用表了。

识别接地引脚

连续性测试将小电流引入电路,如果有足够的电流从一个探针到另外一个探针(即电阻足够小),万用表将会发出可听见的音调,表明探针所接触的点是电连接的。[译者注:其实这里我们直接用万用表的蜂鸣档,也就是通断档位,也是这个效果]

我们要做的第一件事情是使用万用表在接地和每个头部上的所有引脚之间进行连续性测试。这会告诉我们哪些引脚直接连接到地线。我们会从P1402开始。

金属屏蔽是用于测试的便利接地点。将一个探针放在屏蔽上并将另外一个探针接触到引脚3,万用表会发出连续的可听音调,表示我们之前观察到引脚3是接地的。

对引脚2和4执行相同的测试会没有声音,所以我们知道这些引脚没有接地。

对P1404的引脚2,3,4 做相同连续性测试也会产生相同的结果。因此,我们知道了对于P1402和P1404,引脚3是接地的,引脚2和4不接地。

识别Vcc

Vcc不太重要,因为我们实际上不需要连接任何东西到Vcc,但是定位Vcc引脚是一个很好的练习,并且有助于消除Vcc引脚作为收发的可能。

基于痕迹的宽度,我们怀疑引脚1是Vcc,当电路板通电时,测量引脚1上的电压似乎证实了这一点:

在P1404的引脚1上也读出相同的电压,这表明P1402和P1404都将引脚1连接到Vcc。

识别Vcc的另外一种方法是在地线和可疑Vcc引脚之间执行连续性测试。虽然它可能会有点反直觉,但是通常这会导致非常短的嘟嘟声(尽管不是连续音调)。

Vcc的连续性测试表明在Vcc引脚和地线之间通常连接着一个滤波电容。这样做时为了消除PCB上电源线中的任何可能的噪声,并且这种滤波电容器可以在任何设计良好的电路板中使用。由于电容器的工作性质,它们将非常短暂地“通过”直流电,直到它们被充电到容量,此时它们将停止“通过”直流电并将“阻断”直流电流,从而在连续性测试中观察到导致短暂的蜂鸣声(值得一提的是,电流实际上并没有通过电容器,尽管它看着像是这样的)。

虽然它并不总是有效,但是连续性测试是比简单测试每个引脚上的电压更准确的方法。因为任意数量的引脚可能是相同的电压。请注意,你还需要一个高灵敏的万用表来进行连续性测试,为了保证测试的正确性。更便宜的产品在触发之前可能需要一秒或更长的时间,此时电容器已经充电。大多100美元范围内的万用表应该是足够了。

识别传输引脚

只要串口处于激活状态并且正在传输数据,传输引脚和农容易识别(如果不是,那么整个工作可能无论如何都是徒劳的)。电路板上的传输引脚将被拉高到和Vcc相同的电压(通常为3.3V)。当它传输数据位的时候,电压将下降到0V(发送空格),然后回到3.3V(发送标记)。当读取变化的直流电压时,数字万用表将最终显示采样电压的平均值,这意味着平均电压(万用表显示的)将在突发激活期间短暂下降。

传输引脚上的大多数活动通常发生在系统启动期间,当从bootloader、内核、系统的所有引导信息打印到串口时。通过在引导期间监控引脚2和4,我们应该可以轻松地识别哪个是传输引脚。让我们先看看P1402:

P1402引脚2和4的电压都是稳定无波动的3.3V。

这可不太好,所以让我们看看P1404头部,将从引脚2开始:

引脚2的电压数值在最初的几秒徘徊在40mV,然后它稳定在2.3V:

让我们看看引脚4:

引脚4的电压数值在最初几秒稳定在3.3V:

然后突然我们开始看到引脚4的电压数值快速并实质的变化:

P1404的引脚4存在一些活动,表明它实际上是一个有效数据引脚,很有可能是串口的传输引脚。

虽然这是识别传输引脚的有效方法,但是需要注意的是,如果串口仅仅传输少量数据,电压波动对于万用表来说太过短暂,你就要使用示波器或逻辑分析仪来捕获传输引脚上上的数据活动。然而这是很少见的,通常串口上都会有大量数据传输来让这个方法起作用。

识别接受引脚

明确识别接受引脚是最困难的,因为它没有独特的定义特征。我观察过各种系统的接受引脚的各种电压,包括:

  • 拉高到和Vcc相同的电压
  • 拉高到比Vcc低几百mV的电压
  • 左漂浮,在几百mV左右剧烈波动
  • 左漂浮几秒,然后在串口初始化时被拉高

由于我们在两个头部上只剩下一个未知引脚,我们知道只有P1404有效,通过排除法我们可以假设P1404上的引脚4是接受引脚。但是,有时可以将串行适配器单独连接到所有可能的接受引脚,运行minicom(Linux下的串口连接程序)按键盘的几个键,看看会发生什么。说到连接我们的串行适配器,让我们这样做。

连接UART适配器

便宜的USB-UART适配器很容易获得,并且在Linux上默认支持,它们只是作为标准的USB串口,可以和minicom、python等一起使用。我们需要将UART适配器连接到串口,方式如下:

  • 适配器的地线必须连接到串口的地线
  • 适配器的传输引脚必须连接到串口的接受引脚
  • 适配器的接受引脚必须连接到串口的传输引脚

实现这个的最简单方法是将分离头按大小焊接在P1404:

并使用一些公对母跳线连接串口和适配器之间的相应引脚:

发现波特率

有了我们的硬件,就可以开始检查串口协议设置了。串口可以有多种设置,我们需要知道所有设置才能和串口通信:

  • 什么是波特率?
  • 使用了多少数据位?
  • 使用了多少奇偶校验位?
  • 使用了多少停止位?

幸运的是,事实上的标准是使用8个数据位,没有奇偶校验位和1个停止位(缩写成8N1),所以只留下波特率是未知的。试错法是识别波特率的最快、最简单的方法。由于串口通常用于显示调试信息(即传输ASCII数据),并且只有少量可能的波特率,因此切换所有可能的波特率直到观察到可以理解的数据是切实可行的。

或者,至少这是理论上的工作方式。实际上,如果支持这样做的话,我使用的所有终端仿真程序都会使得动态更改波特率变得很麻烦。为了去解决这个问题,我写了一个名为baudrate的工具,它试图自动检测激活的传输串口波特率(如果你愿意,你也可以手动循环每个波特率)。完成后,它会保存一个与minicom兼容的配置文件,并能用你的minicom加载。

随着UART适配器的连接,让我们运行baudrate(我使用手动模式演示,但自动检测功能在一样有魅力):

1
2
3
4
5
6
7
eve@eve:~$ sudo ./baudrate.py -p /dev/ttyUSB0

Starting baudrate detection on /dev/ttyUSB0, turn on your serial device now.
Press Ctl+C to quit.


@@@@@@@@@@@@@@@@@@@@@ Baudrate: 115200 @@@@@@@@@@@@@@@@@@@@@

我们能改变波特率通过按上/下箭头将波特率改为下一个更高/更低的波特率:

1
2
3
4
5
6
7
@@@@@@@@@@@@@@@@@@@@@ Baudrate: 115200 @@@@@@@@@@@@@@@@@@@@@


@@@@@@@@@@@@@@@@@@@@@ Baudrate: 57600 @@@@@@@@@@@@@@@@@@@@@ <--- Down arrow decreases baud rate


@@@@@@@@@@@@@@@@@@@@@ Baudrate: 115200 @@@@@@@@@@@@@@@@@@@@@ <--- Up arrow increases baud rate

好的,现在让我们打开 9100EM 然后看看会发生什么:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@@@@@@@@@@@@@@@@@@@@@ Baudrate: 115200 @@@@@@@@@@@@@@@@@@@@@

Starting entry for CP1 @0xa3400000
memsize=52
CPU revision is: 00019641
Primary instruction cache 16kB, physically tagged, 4-way, linesize 32 bytes.
Primary data cache 16kB 4-way, linesize 32 bytes.
Linux version 2.4.21openrg-rmk1 #2 Thu Aug 28 19:30:48 CDT 2008
Determined physical RAM map:
User-defined physical RAM map:
memory: 03400000 @ 00000000 (usable)
On node 0 totalpages: 13312
zone(0): 4096 pages.
zone(1): 9216 pages.
zone(2): 0 pages.
Kernel command line: mem=52M
mips_counter_frequency:166666667
r4k_offset: 00196e6a(1666666)
Calibrating delay loop... 222.00 BogoMIPS
Memory: 44356k/53248k available (1568k kernel code, 8892k reserved, 6696k data, 4k init, 0k highmem)
Dentry cache hash table entries: 8192 (order: 4, 65536 bytes)
Inode cache hash table entries: 4096 (order: 3, 32768 bytes)
Mount cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 16384 (order: 4, 65536 bytes)
Checking for 'wait' instruction... unavailable.
POSIX conformance testing by UNIFIX
PCI: Probing PCI hardware on host bus 0.
Autoconfig PCI channel 0x801d19e0
Scanning bus 00, I/O 0x1ae00000:0x1b000001, Mem 0x18000000:0x1a000001
00:0e.0 Class 0200: 168c:001a (rev 01)
Mem at 0x18000000 [size=0x10000]
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
Starting kswapd
...

看起来我们尝试的第一个波特率115200是正确的(这并不奇怪,因为115200是实践中最常见的波特率之一)。按Ctl + C我们可以停止捕获并将设置保存到minicom配置文件,在这种情况下我将其命名为’9100em’:

1
2
3
4
5
6
7
Detected baudrate: 115200

Save minicom configuration as: 9100em

Configuration saved. Run minicom now [n/Y]? n

eve@eve:~$

进入shell

现在我们运行minicom:

1
eve@eve:~$ minicom 9100em

然后看看我们得到了什么:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
...
12/31 19:00:57 - Starting SoC reset sequence...
12/31 19:00:58 - Clink FS shared data area written
12/31 19:00:58 - CLNK_ETH_CTRL_RESET returned status 0 after 0.914 seconds
12/31 19:00:58 - FSUPDATE: Pass = 1, Tuned Freq = 1000 MHz (8)
12/31 19:01:10 - Clink Reset Cause :0x4 Reg:0x80240100 Dbg:0x0
12/31 19:01:10 - Starting SoC reset sequence...
12/31 19:01:11 - Clink FS shared data area written
12/31 19:01:11 - CLNK_ETH_CTRL_RESET returned status 0 after 0.903 seconds
12/31 19:01:12 - FSUPDATE: Pass = 1, Tuned Freq = 1150 MHz (14)

Username: admin
Password: *********

Wireless Broadband Router> help
Error: help should be called with at least 1 argument
help Show help for commands within this menu

Usage:
help all - show all available commands in the current level
help [category]... category - show commands in a certain category
help [category]... command - show detailed help for a specific command
help -s string - search for categories/commands containing the string

Availble help Categories
help upnp - show help about UPnP commands
help conf - show help about Read and write Wireless Broadband Router configuration data
help option_manager - show help about Option Manager
help fireball - show help about Fireball configuration and control
help cwmp - show help about CWMP related commands
help bridge - show help about API for managing ethernet bridge
help firewall - show help about Control and display Firewall and NAT data
help connection - show help about API for managing connections
help inet_connection - show help about API for managing internet connections
help misc - show help about API for Wireless Broadband Router miscellaneous tasks
help firmware_update - show help about Firmware update commands
help log - show help about Contorols Wireless Broadband Router logging behaviour
help dev - show help about Device related commands
help kernel - show help about Kernel related commands
help system - show help about Commands to control Wireless Broadband Router execution
help flash - show help about Flash and loader related commands
help net - show help about Network related commands
help cmd - show help about Commands related to the Command module

Returned -1
Wireless Broadband Router> help system

Command Category system - Commands to control Wireless Broadband Router execution
die Exit from Wireless Broadband Router and return ret
ps Print Wireless Broadband Router's tasks
entity_close Close an entity
etask_list_dump Dump back trace of all etasks
restore_default Restore default configuration
reboot Reboot the system
ver Display version information
print_config Print compilation configuration. Search for option if specified
exec Execute program
cat Print file contents to console
shell Spawn busybox shell in foreground
date Print the current UTC and local time
exit Exit sub menu
help Show help for commands within this menu

Returned 0
Wireless Broadband Router>

一些串口要求登录,另外有一些不要求。在这个案例中,登录只是设备的管理员用户名和密码,它将我们带入一个自定义命令行shell,我们可以用它来管理路由器。根据help的输出,system shell命令应该提供一个root权限的shell,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Wireless Broadband Router> system shell

BusyBox v1.01 (2005.09.07-07:38+0000) Built-in shell (lash)
Enter 'help' for a list of built-in commands.

/ # cat /proc/cpuinfo
system type : TWINPASS-E
processor : 0
cpu model : unknown V4.1
BogoMIPS : 222.00
wait instruction : no
microsecond timers : yes
tlb_entries : 16
extra interrupt vector : yes
hardware watchpoint : yes
VCED exceptions : not available
VCEI exceptions : not available
/ #

结论

这就是使用一个万用表和一些免费软件从逻辑上识别了串口的物理接口,发现了它的波特率并获得一个shell,我们可以用它来进一步探索系统。

CATALOG
  1. 1. 简介
  2. 2. 识别串口头
  3. 3. 肉眼观察
  4. 4. 识别接地引脚
  5. 5. 识别Vcc
  6. 6. 识别传输引脚
  7. 7. 识别接受引脚
  8. 8. 连接UART适配器
  9. 9. 发现波特率
  10. 10. 进入shell
  11. 11. 结论