Vitaly Chipounov and George Candea
School of Computer & Communica3on Sciences
RevNIC
Reverse Engineering of Binary Device Drivers
Drivers: Hard to Write and Hard to Port
•
Drivers are o@en closed source Por3ng from exis3ng drivers is difficult•
Devices rarely come with an interface specificaDon Hard to write a driver from scratch•
SpecificaDons are o@en incomplete and buggy Buggy driver implementa3on jeudi, 15 avril 2010ExisDng SoluDons
•
EmulaDng source OS (VMs, NDISwrapper...) Run‐3me overhead, hard to maintain•
Making drivers from specificaDons (Termite) Requires formal specifica3ons•
Manual trace analysis, decompilaDon Tedious, imprecise jeudi, 15 avril 2010http://bplteensofwa.files.wordpress.com/2009/07/computer.jpg
x86 PC Virtual
Machines
FPGA
Windows Linux KitOS μC/OS II Windows
RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on traces jeudi, 15 avril 2010RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on traces jeudi, 15 avril 2010RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on traces jeudi, 15 avril 2010RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on traces jeudi, 15 avril 2010High Coverage Driver Exerciser
•
Hand‐cra@ed workload is not enoughint irq_handler(device_t *dev) { status = hw_read(STATUS_REG); if (status == RX){ pkt_size = hw_read(RX_SIZE_REG); if (pkt_size < 1514) { recv_packet(dev); }else { drop_packet(dev); } }else if (status == TX) { ... } } jeudi, 15 avril 2010
•
Boundary condiDons•
Error recovery codeint irq_handler(device_t *dev) { status = hw_read(STATUS_REG); if (status == RX){ pkt_size = hw_read(RX_SIZE_REG); if (pkt_size < 1514) { recv_packet(dev); }else { drop_packet(dev); } }else if (status == TX) { ... } } jeudi, 15 avril 2010
int irq_handler(device_t *dev) { status = hw_read(STATUS_REG); if (status == RX){ pkt_size = hw_read(RX_SIZE_REG); if (pkt_size < 1514) { recv_packet(dev); }else { drop_packet(dev); } }else if (status == TX) { ... } } jeudi, 15 avril 2010
int irq_handler(device_t *dev) { status = hw_read(STATUS_REG); if (status == RX){ pkt_size = hw_read(RX_SIZE_REG); if (pkt_size < 1514) { recv_packet(dev); }else { drop_packet(dev); } }else if (status == TX) { ... } } jeudi, 15 avril 2010
status == RX
pkt_size < 1514 status == TX
... ... drop
packet receivepacket
F T
int irq_handler(device_t *dev) { status = hw_read(STATUS_REG); if (status == RX){ pkt_size = hw_read(RX_SIZE_REG); if (pkt_size < 1514) { recv_packet(dev); }else { drop_packet(dev); } }else if (status == TX) { ... } } jeudi, 15 avril 2010
High coverage automated driver exerciser
status == RX
pkt_size < 1514 status == TX
... ... drop
packet receivepacket
F T
int irq_handler(device_t *dev) { status = hw_read(STATUS_REG); if (status == RX){ pkt_size = hw_read(RX_SIZE_REG); if (pkt_size < 1514) { recv_packet(dev); }else { drop_packet(dev); } }else if (status == TX) { ... } } jeudi, 15 avril 2010
Device Drivers ndis.sys explorer.exe msvcrt.dll advapi32.dll ntdll.dll ... ... ... Applications and libraries Windows Kernel rtl8139.sys ... user32.dll jeudi, 15 avril 2010
Exercising Windows NIC Drivers
NICDRIVER.SYS IniDalize(...) QueryInformaDon(...) SendPacket(...) HandleInterrupt(...) Unload(...) ... jeudi, 15 avril 2010Exercising Windows NIC Drivers
NICDRIVER.SYS IniDalize(...) QueryInformaDon(...) SendPacket(...) HandleInterrupt(...) Unload(...) ... jeudi, 15 avril 2010Exercising Windows NIC Drivers
IniDalize(...)
Exercising Windows NIC Drivers
IniDalize(...)
☹ ☺ ☹ ☹ ☹ ☺
☹
Exercising Windows NIC Drivers
IniDalize(...) ☹ ☺ ☹ ☹ ☹ ☺ ☹ ☺ jeudi, 15 avril 2010IniDalize(...)
☹ ☺ ☹ ☹ ☹ ☺
☹
☺
IniDalize(...) ☹ ☺ ☹ ☹ ☹ ☺ ☹ Send(..., Packet, ...) ☺ jeudi, 15 avril 2010
IniDalize(...) ☹ ☺ ☹ ☹ ☹ ☺ ☹ Send(..., Packet, ...) ☺ 001a706650e3... jeudi, 15 avril 2010
IniDalize(...) ☹ ☺ ☹ ☹ ☹ ☺ ☹ ☹ ☺ ☹ ☹ ☹ ☺ ☹ Send(..., Packet, ...) ☺ α β γ δ ε ϛ... jeudi, 15 avril 2010
☹ ☺ ☹ ☹ ☹ ☺ ☹ ☹ ☹ ☺ ☹ Send(..., Packet, ...) ☺ α β γ δ ε ϛ... jeudi, 15 avril 2010
☹ ☺ ☹ ☹ ☹ ☺ ☹ ☹ ☹ ☺ ☹ Send(..., Packet, ...) Interrupt ☺ α β γ δ ε ϛ... jeudi, 15 avril 2010
☹ ☺ ☹ ☹ ☹ ☺ ☹ ☹ ☹ ☺ ☹ Send(..., Packet, ...) Interrupt HandleInterrupt(...) ☺ α β γ δ ε ϛ... jeudi, 15 avril 2010
☹ ☺ ☹ Send(..., Packet, ...) HandleInterrupt(...) Interrupt jeudi, 15 avril 2010
☹ ☺ ☹ Send(..., Packet, ...) HandleInterrupt(...) Unload(...) Interrupt jeudi, 15 avril 2010
RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on traces jeudi, 15 avril 2010RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac,on traces jeudi, 15 avril 2010Hardware InteracDon Traces
Trace Files•
ExecuDon tree•
Machine instrucDons•
Memory accesses•
Register values•
(Memory‐Mapped) I/O Virtual Machine Guest OS Original Binary Driver Driver Exerciser jeudi, 15 avril 2010RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac,on traces jeudi, 15 avril 2010RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on traces Traces ➔ C code jeudi, 15 avril 2010ExecuDon Tree
BB 4 BB 1 BB 2 BB 3 BB 5 BB 6 BB 7
ExecuDon Tree Sequences ofbasic blocks
Trace #1
BB 4 BB 1 BB 2 BB 3 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7
ExecuDon Tree Sequences ofbasic blocks
Trace #1 Trace #2
BB 4 BB 1 BB 2 BB 3 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 ExecuDon Traces Trace #1 Trace #2 jeudi, 15 avril 2010
BB 4 BB 1 BB 2 BB 3 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 BB 4 BB 1 BB 2 BB 3 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 ExecuDon Traces Trace #1 Trace #2 jeudi, 15 avril 2010
BB 4 BB 1 BB 2 BB 3 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 BB 4 BB 1 BB 2 BB 3 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 ExecuDon Traces Trace #1 Trace #2 jeudi, 15 avril 2010
CFG BB 1 BB 2 BB 3 BB 4 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 Trace #1 Trace #2 BB 1 BB 2 BB 3 BB 4 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 jeudi, 15 avril 2010
CFG BB 1 BB 2 BB 3 BB 4 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 jeudi, 15 avril 2010
uint32_t function_0001(...) { BB1: BB2: BB3: BB4: BB5: BB6: BB8: BB9: BB7: } CFG BB 1 BB 2 BB 3 BB 4 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 jeudi, 15 avril 2010
uint32_t function_0001(uint32_t param1, uint32_t param2) { /* ... */ BB1: goto BB2; BB2: v1 = read_port(param1); BB3: v2 = read_port(param2); BB4: if (v1 & 0x21) goto BB8; BB5: write_port(param2, 0x1234); BB6: goto BB7; BB8: write_port(param1, 0x4567); BB9: goto BB7; BB7: } CFG BB 1 BB 2 BB 3 BB 4 BB 5 BB 6 BB 7 BB 8 BB 9 BB 1 BB 2 BB 3 BB 4 BB 7 jeudi, 15 avril 2010
RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on traces Traces ➔ C code jeudi, 15 avril 2010RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on tracesTraces ➔ C code C code ➔ driver
Device Driver Structure
•
Hardware‐facing funcDons Automa3cally synthesized by RevNIC•
OS‐facing funcDons Provided by the driver template jeudi, 15 avril 2010Driver
Template Hardware
InteracDon Code
Templates contain OS‐ specific boilerplate Linux Network Driver Template int pci_nic_init(...) {
/* Allocate device resources */
i = pci_enable_device (pdev); if (i) {
... }
ioaddr = pci_resource_start (pdev, 0); irq = pdev->irq;
if (request_region (ioaddr, ADDR_RANGE, DRV_NAME) == NULL) { ...
}
/* * Insert device detection code here
* --- */
/* Allocate private memory */
dev = alloc_netdev(...); if (!dev) {
... }
/* Register entry points */
... }
Templates contain OS‐ specific boilerplate Linux Network Driver Template int pci_nic_init(...) {
/* Allocate device resources */
i = pci_enable_device (pdev); if (i) {
... }
ioaddr = pci_resource_start (pdev, 0); irq = pdev->irq;
if (request_region (ioaddr, ADDR_RANGE, DRV_NAME) == NULL) { ...
}
/* * Insert device detection code here
* --- */
/* Allocate private memory */
dev = alloc_netdev(...); if (!dev) {
... }
/* Register entry points */
... }
/* Allocate private memory */
dev = alloc_netdev(...); if (!dev) {
... }
/* Register entry points */
... }
int pci_nic_init(...) {
/* Allocate device resources */
i = pci_enable_device (pdev); if (i) {
... }
ioaddr = pci_resource_start (pdev, 0); irq = pdev->irq;
if (request_region (ioaddr, ADDR_RANGE, DRV_NAME) == NULL) { ...
}
/* * Insert device detection code here
* --- */
/* Allocate private memory */
dev = alloc_netdev(...); if (!dev) {
... }
/* Register entry points */
... }
int pci_nic_init(...) {
/* Allocate device resources */
i = pci_enable_device (pdev); if (i) {
... }
ioaddr = pci_resource_start (pdev, 0); irq = pdev->irq;
if (request_region (ioaddr, ADDR_RANGE, DRV_NAME) == NULL) { ...
}
/* * Insert device detection code here
* --- */
Placeholders for hardware interacDon
/* Allocate private memory */
dev = alloc_netdev(...); if (!dev) {
... }
/* Register entry points */
... }
int pci_nic_init(...) {
/* Allocate device resources */
i = pci_enable_device (pdev); if (i) {
... }
ioaddr = pci_resource_start (pdev, 0); irq = pdev->irq;
if (request_region (ioaddr, ADDR_RANGE, DRV_NAME) == NULL) { ...
}
/* * Insert device detection code here
* --- */ if (hw_checkdevice(ioaddr) < 0) { v1 = read_port(ioaddr); if (!(v1 & 1)) { goto lbl0; } write_port(ioaddr, 0); lbl0: write_port(ioaddr, 1); } jeudi, 15 avril 2010
RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on traces jeudi, 15 avril 2010RevNIC
SyntheDc Driver NIC Driver Template Virtual Machine Guest OS Original Binary Driver Driver Exerciser RevNIC Code Synthesizer Hardware interac3on traces insmod revnic_driver.ko jeudi, 15 avril 2010•
QEMU virtual machine1•
x86‐to‐LLVM translator•
KLEE symbolic execuDon engine2ImplementaDon
1 F. Bellard. QEMU, a Fast and Portable Dynamic Translator. In USENIX 2005.
2 C. Cadar et al. KLEE: Unassisted and automa3c genera3on of high‐coverage tests for
complex systems programs. In OSDI 2008.
EvaluaDon
‣
RevNIC can port network drivers between•
different OS plaiorms•
different hardware architectures‣
SyntheDc drivers have good performance jeudi, 15 avril 2010Reverse Engineered Drivers
Driver Size1 AMD PCNet 35 KB Realtek RTL8139 20 KB SMSC 91C111 19 KB Realtek RTL8029 (NE2000) 18 KB 1 80% of Linux 2.6.26 NIC drivers are smaller than 35KB jeudi, 15 avril 2010Target Plaiorms
http://bplteensofwa.files.wordpress.com/2009/07/computer.jpg
Windows Linux KitOS μC/OS II Windows
Target Plaiorms
http://bplteensofwa.files.wordpress.com/2009/07/computer.jpg
x86 PC
RTL8139
Windows Linux KitOS μC/OS II Windows
Target Plaiorms
http://bplteensofwa.files.wordpress.com/2009/07/computer.jpg x86 PC VMware QEMU PCnet, NE2000 RTL8139Windows Linux KitOS μC/OS II Windows
Target Plaiorms
http://bplteensofwa.files.wordpress.com/2009/07/computer.jpg x86 PC VMware QEMU FPGA4U PCnet, NE2000 SMSC 91C111 RTL8139Windows Linux KitOS μC/OS II Windows
EffecDveness
‣
RevNIC reverse engineers all relevant funcDonality•
IniDalizaDon, sending, recepDon, shutdown, DMA, etc. jeudi, 15 avril 2010Performance
0 20 40 60 80 100 0 200 400 600 800 1000 1200 1400 Throughput (Mbps)UDP Packet Size (Bytes) Windows→KitOS Windows→Windows Linux Original Windows→Linux Windows Original jeudi, 15 avril 2010
Performance
0 20 40 60 80 100 0 200 400 600 800 1000 1200 1400 Throughput (Mbps)UDP Packet Size (Bytes) Windows→KitOS Windows→Windows Linux Original Windows→Linux Windows Original jeudi, 15 avril 2010
Performance
0 20 40 60 80 100 0 200 400 600 800 1000 1200 1400 Throughput (Mbps)UDP Packet Size (Bytes) Windows→KitOS Windows→Windows Linux Original Windows→Linux Windows Original jeudi, 15 avril 2010
Performance
0 20 40 60 80 100 0 200 400 600 800 1000 1200 1400 Throughput (Mbps)UDP Packet Size (Bytes) Windows→KitOS Windows→Windows Linux Original Windows→Linux Windows Original jeudi, 15 avril 2010
PorDng Effort
PorDng Effort
80% basic block coverage ~20 min Zero manual effort Virtual Machine Guest OS Original Binary Driver Driver Exerciser jeudi, 15 avril 2010PorDng Effort
RevNIC Code Synthesizer 80% basic block coverage ~20 min Zero manual effort ~1 min Zero manual effort Virtual Machine Guest OS Original Binary Driver Driver Exerciser jeudi, 15 avril 2010PorDng Effort
NIC Driver Template RevNIC Code Synthesizer 80% basic block coverage ~20 min Zero manual effort ~1 min Zero manual effort Few hours ‐ 5 days One‐Dme effort Virtual Machine Guest OS Original Binary Driver Driver Exerciser jeudi, 15 avril 2010PorDng Effort
SyntheDc Driver (e.g., Linux) NIC Driver Template RevNIC Code Synthesizer 80% basic block coverage ~20 min Zero manual effort ~1 min Zero manual effort Few hours ‐ 5 days One‐Dme effort Virtual Machine Guest OS Original Binary Driver Driver Exerciser jeudi, 15 avril 2010PorDng Effort
Device Manual (Linux)Manual (Linux) RevNICRevNIC Device
Persons Span Persons Span
RTL8139 18 4 years 1 1 week 91C111 8 4 years 1 4 days NE2000 5 2 years 1 5 days
PCNet 3 4 years 1 1 week
RevNIC speeds up driver development
PorDng Effort
Device Manual (Linux)Manual (Linux) RevNICRevNIC Device
Persons Span Persons Span
RTL8139 18 4 years 1 1 week 91C111 8 4 years 1 4 days NE2000 5 2 years 1 5 days
PCNet 3 4 years 1 1 week
RevNIC speeds up driver development
PorDng Effort
Device Manual (Linux)Manual (Linux) RevNICRevNIC Device
Persons Span Persons Span
RTL8139 18 4 years 1 1 week 91C111 8 4 years 1 4 days NE2000 5 2 years 1 5 days
PCNet 3 4 years 1 1 week
Mostly fixing undocumented
quirks
RevNIC speeds up driver development
PorDng Effort
Device Manual (Linux)Manual (Linux) RevNICRevNIC Device
Persons Span Persons Span
RTL8139 18 4 years 1 1 week 91C111 8 4 years 1 4 days NE2000 5 2 years 1 5 days
PCNet 3 4 years 1 1 week
RevNIC speeds up driver development
RevNIC
•
Reverse engineering of driver’s state machine from interacDon traces•
High‐coverage reverse engineering through symbolic execuDon•
Using symbolic hardware for reverse engineering without access to original devices jeudi, 15 avril 2010RevNIC
•
Reverse engineering of driver’s state machine from interacDon traces•
High‐coverage reverse engineering through symbolic execuDon•
Using symbolic hardware for reverse engineering without access to original deviceshttp://reveng.epfl.ch
jeudi, 15 avril 2010