하드웨어 재밌다!
UART 포트 연결
telnet 이용
telnet
데몬이 실행되는 경우라면 바로 23번 포트로 접속하면 된다.UART
포트를 찾아서 연결하게 된다.RX
, TX
핀의 위치를 따라갈 수 없었다.GND
를 식별한 후 나머지 핀을 게싱해서 찾아야 했다.USB-to-TTL
시리얼 케이블이 망가질 각오 정도는 하고 임해야 한다..😢PuTTY
나 XShell
로 장치가 연결된 시리얼 포트와 Baudrate
를 지정해 주면, 쉘에 접속할 수 있다.115200, 57600, 38400, 19200, 9600
환경 : 공유기 (mips)
gdbserver
바이너리를 준비하여 공유기에 옮겨 주어야 한다.OpenWRT
툴체인 등을 통해 빌드할 수도 있고, 빌드가 된 바이너리를 이용할 수도 있다.gdbserver
바이너리가 존재한다는 가정 하에, 이를 공유기에 옮겨 주어야 한다.telnet
이나 nc
등을 이용해서 바이너리를 원격으로 전송한다. busybox
명령어에 nc
가 존재하면 먼저 nc
를 이용하는 것이 좋다.# find / -name 'gdbserver'
/media/sda1/gdbserver
/mnt
디렉토리에 마운트가 될 텐데, 그렇지 않은 경우도 있으니 잘 찾아보아야 한다./media/sda1
폴더 안에 USB 안의 파일들이 존재했다.Usage: gdbserver [OPTIONS] COMM PROG [ARGS ...]
gdbserver [OPTIONS] --attach COMM PID
gdbserver [OPTIONS] --multi COMM
COMM may either be a tty device (for serial debugging),
HOST:PORT to listen for a TCP connection, or '-' or 'stdio' to use
stdin/stdout of gdbserver.
PROG is the executable program. ARGS are arguments passed to inferior.
PID is the process ID to attach to, when --attach is specified.
Operating modes:
--attach Attach to running process PID.
--multi Start server without a specific program, and
only quit when explicitly commanded.
--once Exit after the first connection has closed.
--help Print this message and then exit.
--version Display version information and exit.
Other options:
--wrapper WRAPPER -- Run WRAPPER to start new programs.
--disable-randomization
Run PROG with address space randomization disabled.
--no-disable-randomization
Don't disable address space randomization when
starting PROG.
Debug options:
--debug Enable general debugging output.
--debug-format=opt1[,opt2,...]
Specify extra content in debugging output.
Options:
all
none
timestamp
--remote-debug Enable remote protocol debugging output.
--disable-packet=opt1[,opt2,...]
Disable support for RSP packets or features.
Options:
vCont, Tthread, qC, qfThreadInfo and
threads (disable all threading packets).
gdbserver
는 다양한 옵션이 존재한다.PID
(프로세스 ID)로 attach
할 수도 있다.PID
로 gdbserver
를 실행한 후, 리눅스 환경에서 리모트 디버깅을 시도할 것이다.# ps | grep telnet
8201 root 1336 S /bin/telnetd
ps
명령어로 디버깅을 수행할 대상 프로세스의 PID를 확인한다.# /media/sda1/gdbserver :8888 --attach 8201
Attached; pid = 8201
Listening on port 8888
gdbserver
를 실행한다. --attach
옵션 뒤에 PID
를 입력해야 한다.:8888
은 포트 번호이며, 자유롭게 지정해 주면 된다.환경 : Ubuntu 20.04
gdbserver
를 실행했으니 이제는 리눅스 환경에서 gdb
를 붙여 보자.$ sudo apt install gdb-multiarch
architecture
가 다른 경우 gdb-multiarch
를 설치해 주어야 한다.amd64
/ 공유기 환경 : mips
$ gdb-multiarch
# 실행 후
(gdb) set arc mips # 공유기 아키텍쳐
(gdb) target remote 192.168.0.1:8888 # 공유기에서 열어둔 포트 지정
gdb-multiarch
를 실행해 주고, 딱 두 가지 명령어만 입력하면 된다.(gdb) set arc mips
The target architecture is assumed to be mips
(gdb) target remote 192.168.0.1:8888
Remote debugging using 192.168.0.1:8888
Reading /bin/busybox from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /bin/busybox from remote target...
Reading symbols from target:/bin/busybox...
(No debugging symbols found in target:/bin/busybox)
Reading /lib/libc.so.0 from remote target...
Reading /lib/libgcc_s.so.1 from remote target...
Reading /lib/ld-uClibc.so.0 from remote target...
Reading symbols from target:/lib/libc.so.0...
(No debugging symbols found in target:/lib/libc.so.0)
Reading symbols from target:/lib/libgcc_s.so.1...
(No debugging symbols found in target:/lib/libgcc_s.so.1)
Reading symbols from target:/lib/ld-uClibc.so.0...
(No debugging symbols found in target:/lib/ld-uClibc.so.0)
Reading /lib/ld-uClibc.so.0 from remote target...
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
0x2aace484 in ?? ()
gdb
가 잘 붙은 것을 확인할 수 있을 것이다.# via the install script
## using curl
$ bash -c "$(curl -fsSL http://gef.blah.cat/sh)"
## using wget
$ bash -c "$(wget http://gef.blah.cat/sh -O -)"
# or manually
$ wget -O ~/.gdbinit-gef.py -q http://gef.blah.cat/py
$ echo source ~/.gdbinit-gef.py >> ~/.gdbinit
# or alternatively from inside gdb directly
$ gdb -q
(gdb) pi import urllib.request as u, tempfile as t; g=t.NamedTemporaryFile(suffix='-gef.py'); open(g.name, 'wb+').write(u.urlopen('https://tinyurl.com/gef-master').read()); gdb.execute('source %s' % g.name)
gef
를 설치하면 gdb-multiarch
실행시 gef
로 훨씬 편하게 디버깅을 수행할 수 있다.