Skip to content

Commit 24424a8

Browse files
committed
add support for 06cb:00c9
1 parent c0efa1b commit 24424a8

2 files changed

Lines changed: 109 additions & 39 deletions

File tree

README.md

Lines changed: 102 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,39 @@
11
# Synaptics Tudor Match in Sensor (MiS) reverse engineering
22

3-
The fingerprint reader in my laptop (06CB:00FF) does not seem to support raw frame capture and export and to only support match on chip authentication and enrollment. This is likely the reason why the current libfprint library does not work with this sensor. The goal is to create a prototype driver. If you have any questions/additions, feel free to reach out/open an issue/merge request.
3+
The fingerprint reader in my laptop (06CB:00FF) does not seem to support raw
4+
frame capture and export and to only support match on chip authentication and
5+
enrollment. This is likely the reason why the current libfprint library does not
6+
work with this sensor. The goal is to create a prototype driver. If you have any
7+
questions/additions, feel free to reach out/open an issue/merge request.
48

59
### Building
610

7-
For building use a [cleaned version of libfprint](https://github.com/vojtapl/libfprint). You will also need to modify fprintd with [this patch](./libfprint/fprintd-load-store-persistent-data-from-device.patch).
11+
For building use a
12+
[cleaned version of libfprint](https://github.com/vojtapl/libfprint). You will
13+
also need to modify fprintd with
14+
[this patch](./libfprint/fprintd-load-store-persistent-data-from-device.patch).
815

916
### Some notes on not continuing development
1017

11-
This driver is not in active development anymore as it _just works_ and I currently do not have enough time to finish it. There are two or three major roadblocks which need to be overcome before I would consider publishing it: OpenSSL currently leaks memory (and I spent too long trying to figure out why it breaks things when the memory is freed), small FIXMEs in the codebase and writing tests.
18+
This driver is not in active development anymore as it _just works_ and I
19+
currently do not have enough time to finish it. There are two or three major
20+
roadblocks which need to be overcome before I would consider publishing it:
21+
OpenSSL currently leaks memory (and I spent too long trying to figure out why it
22+
breaks things when the memory is freed), small FIXMEs in the codebase and
23+
writing tests.
1224

1325
### Disclaimer
1426

15-
- THIS PROJECT IS EXPERIMENTAL. ALL WORK IS PROVIDED AS IS, WITH NO LIABILITY IN CASE SOMETHING GOES WRONG, e.g. you can format your sensor host partition and lose the Windows pairing data.
16-
- Please note that some things are not yet changed from to the current sensor, e.g. the iota patches.
27+
- THIS PROJECT IS EXPERIMENTAL. ALL WORK IS PROVIDED AS IS, WITH NO LIABILITY IN
28+
CASE SOMETHING GOES WRONG, e.g. you can format your sensor host partition and
29+
lose the Windows pairing data.
30+
- Please note that some things are not yet changed from to the current sensor,
31+
e.g. the iota patches.
1732

1833
### Most likely supported devices
1934

2035
- per synaWudfBioUsbUwp.inf
21-
- 06CB:00C9
36+
- 06CB:00C9 (tested)
2237
- 06CB:00D1
2338
- 06CB:00E7 (tested)
2439
- 06CB:00FF (tested)
@@ -33,45 +48,97 @@ This driver is not in active development anymore as it _just works_ and I curren
3348
### What does not work:
3449

3550
- Using the same pairing data/fingerprints in Windows and Linux.
36-
- This would require an equivalent function to Crypt(Un)ProtectData to encrypt the pairing data before writing to host partition on sensor. Or dumping the pairing data and storing them on Linux as well.
51+
- This would require an equivalent function to Crypt(Un)ProtectData to encrypt
52+
the pairing data before writing to host partition on sensor. Or dumping the
53+
pairing data and storing them on Linux as well.
3754

3855
### To-dos:
3956

4057
- common property
41-
- where does the common property come from
42-
-> where does the function highLevelSetCommonProptery get its params from
58+
- where does the common property come from -> where does the function
59+
highLevelSetCommonProptery get its params from
4360
- what is it for?
4461
- (not important) check for update and update of firmware update
4562
- (not important) find the newest driver version and check for differences
4663
- improve security
4764

4865
### Some notes on how does the sensor work
4966

50-
- Each enrollment is tied to a set of pairing data - template ID, finger ID, windows SID.
67+
- Each enrollment is tied to a set of pairing data - template ID, finger ID,
68+
windows SID.
5169

5270
### How to reverse-engineer a Windows fingerprint driver
5371

54-
- The first step is to find the name of the device with USB vendor and product IDs and search on the internet. Finding someone's work, even if the devices seem to be only a little bit similar, could be a huge time saver.
55-
- If no one has reverse-engineered the device yet (not even a similar one) then you will have to do it (it is fun though 😀).
56-
- As I only have experience with Synaptics's fingerprint devices, I will base this part on them.
57-
- Having downloaded the **latest** version of the driver (I cannot stress this enough - as some important bug fixes may be missing and you will not want to do this twice), you will want to find more information about it. For example in HP's driver there is a file `synaWudfBioUsbUwp.inf`, which contains all supported devices by USB vendor and product IDs and the driver version.
58-
- The next step is to find the `.dll` files and if there is more than one, than the one, which communicates with the sensor. My advice would be to open them in Ghidra and search in the `Defined String` for something like `usb`. If you find strings containing `WinUSB` you are onto something, if not look into the strings more, until you find something more relevant.
59-
- Another thing to look for is the driver's logging. For that search for `OutputDebugString`, `debug` ... If you find something, worthwhile, you will want to setup for driver debugging with WinDbg (there are other programs too, but this one worked for me; I prefer the newer version as it looks better), see [here](https://flylib.cjom/books/en/3.141.1.164/1/). Then launch WinDbg as administrator and attach to the `WUDFHost.exe` process, but beware there may be more and only one may output what you need. Now you should be greeted to a `ntdll!DbgBrekPoint`, press the `Go` button and hopefully something pops out in the `Command` window. If you get something, you can check the behavior during fingerprint enrollment/authentication/... If you get nothing, it may be, that the debug output is disabled (search in the strings for `IsDebuggerPresent`) or it is enabled via a registry entry.
60-
- Look for functions using the registry - `Reg...`, though in the Synaptics driver I have not found anything interesting.
61-
- Now the most time consuming part - trying to figure out how the driver works. I have only a single piece of advice - get to know the tool you are using, for Ghidra you should look into renaming functions/variables, editing function signatures, (automatically) creating structs, using included structs, naming constants, how to move quickly around functions and so on.
62-
- At some point you will want to see the data in different parts of the program or the data being sent.
63-
- If the sensor does not use encrypted connection, or you are interested only in the establishing of a TLS session (for decryption you would need to dump the keys from the program), you could use Wireshark. This program will show you the data which passes through a USB connection.
64-
- The other option is to add breakpoints and print the data, when a breakpoint is hit. See (here)[./reverse engineering/SP141455/WinDbg breakpoints/README.md] how to add breakpoints. Then to see what is in some register/memory/... use WinDbg with e.g. the `d <address>` command. To find where the value is stored, see the `Listing` window in Ghidra and then either the blue window at the start function containing offsets/register names for variables or the instruction parameters bellow.
65-
- for example we have `BLOB* R8:8 toSendBlob`, so (at least at some point) in the R8 register should be addres of a blob struct
66-
- we get the address with command `r r8` and with `dq [add address]` we can see the size and pointer to the data
67-
- to make it easier you can add commands together and get the output immediately, e.g. `db poi(@r8 + 8) Lwo(@r8)` prints only the blob data with the correct size (for more examples see (here)[./reverse engineering/SP141455/WinDbg breakpoints/breakpoints with data dump.txt])
68-
- remember to make it easier on yourself and add some description to the output with `.echo` or `.printf`
69-
- for more complete list of commands see (here)[http://www.windbg.info/doc/1-common-cmds.html] (It is not that hard one you get the hang of it.)
70-
- Hopefully now you should have enough notes to start working on a prototype driver.
72+
- The first step is to find the name of the device with USB vendor and product
73+
IDs and search on the internet. Finding someone's work, even if the devices
74+
seem to be only a little bit similar, could be a huge time saver.
75+
- If no one has reverse-engineered the device yet (not even a similar one) then
76+
you will have to do it (it is fun though 😀).
77+
- As I only have experience with Synaptics's fingerprint devices, I will base
78+
this part on them.
79+
- Having downloaded the **latest** version of the driver (I cannot stress this
80+
enough - as some important bug fixes may be missing and you will not want to
81+
do this twice), you will want to find more information about it. For example
82+
in HP's driver there is a file `synaWudfBioUsbUwp.inf`, which contains all
83+
supported devices by USB vendor and product IDs and the driver version.
84+
- The next step is to find the `.dll` files and if there is more than one, than
85+
the one, which communicates with the sensor. My advice would be to open them
86+
in Ghidra and search in the `Defined String` for something like `usb`. If you
87+
find strings containing `WinUSB` you are onto something, if not look into the
88+
strings more, until you find something more relevant.
89+
- Another thing to look for is the driver's logging. For that search for
90+
`OutputDebugString`, `debug` ... If you find something, worthwhile, you will
91+
want to setup for driver debugging with WinDbg (there are other programs too,
92+
but this one worked for me; I prefer the newer version as it looks better),
93+
see [here](https://flylib.cjom/books/en/3.141.1.164/1/). Then launch WinDbg as
94+
administrator and attach to the `WUDFHost.exe` process, but beware there may
95+
be more and only one may output what you need. Now you should be greeted to a
96+
`ntdll!DbgBrekPoint`, press the `Go` button and hopefully something pops out
97+
in the `Command` window. If you get something, you can check the behavior
98+
during fingerprint enrollment/authentication/... If you get nothing, it may
99+
be, that the debug output is disabled (search in the strings for
100+
`IsDebuggerPresent`) or it is enabled via a registry entry.
101+
- Look for functions using the registry - `Reg...`, though in the Synaptics
102+
driver I have not found anything interesting.
103+
- Now the most time consuming part - trying to figure out how the driver works.
104+
I have only a single piece of advice - get to know the tool you are using, for
105+
Ghidra you should look into renaming functions/variables, editing function
106+
signatures, (automatically) creating structs, using included structs, naming
107+
constants, how to move quickly around functions and so on.
108+
- At some point you will want to see the data in different parts of the program
109+
or the data being sent.
110+
- If the sensor does not use encrypted connection, or you are interested only
111+
in the establishing of a TLS session (for decryption you would need to dump
112+
the keys from the program), you could use Wireshark. This program will show
113+
you the data which passes through a USB connection.
114+
- The other option is to add breakpoints and print the data, when a breakpoint
115+
is hit. See (here)[./reverse engineering/SP141455/WinDbg
116+
breakpoints/README.md] how to add breakpoints. Then to see what is in some
117+
register/memory/... use WinDbg with e.g. the `d <address>` command. To find
118+
where the value is stored, see the `Listing` window in Ghidra and then
119+
either the blue window at the start function containing offsets/register
120+
names for variables or the instruction parameters bellow.
121+
- for example we have `BLOB* R8:8 toSendBlob`, so (at least at some point)
122+
in the R8 register should be addres of a blob struct
123+
- we get the address with command `r r8` and with `dq [add address]` we can
124+
see the size and pointer to the data
125+
- to make it easier you can add commands together and get the output
126+
immediately, e.g. `db poi(@r8 + 8) Lwo(@r8)` prints only the blob data
127+
with the correct size (for more examples see (here)[./reverse
128+
engineering/SP141455/WinDbg breakpoints/breakpoints with data dump.txt])
129+
- remember to make it easier on yourself and add some description to the
130+
output with `.echo` or `.printf`
131+
- for more complete list of commands see
132+
(here)[http://www.windbg.info/doc/1-common-cmds.html] (It is not that hard
133+
one you get the hang of it.)
134+
- Hopefully now you should have enough notes to start working on a prototype
135+
driver.
71136

72137
### Some notes on how to make a libfprint driver
73138

74-
- As I have not done anything similar before, the asynchronous driver design was quite daunting. If you have it the same, ignore it and write it synchronously (see the `*_sync` function variants).
139+
- As I have not done anything similar before, the asynchronous driver design was
140+
quite daunting. If you have it the same, ignore it and write it synchronously
141+
(see the `*_sync` function variants).
75142

76143
### Abbreviations used:
77144

@@ -84,5 +151,10 @@ This driver is not in active development anymore as it _just works_ and I curren
84151

85152
### Acknowledgment
86153

87-
- The driver is based on [Synaptics Tudor Sensors Reverse Engineering Project](https://github.com/Popax21/synaTudor/tree/rev) by Popax21 and his [Driver Relinking Project](https://github.com/Popax21/synaTudor/tree/relink)
88-
- This blog post: [Reversing a Fingerprint Reader Protocol](https://blog.th0m.as/misc/fingerprint-reversing/) by Thomas Lambertz was very helpful in the beginning.
154+
- The driver is based on
155+
[Synaptics Tudor Sensors Reverse Engineering Project](https://github.com/Popax21/synaTudor/tree/rev)
156+
by Popax21 and his
157+
[Driver Relinking Project](https://github.com/Popax21/synaTudor/tree/relink)
158+
- This blog post:
159+
[Reversing a Fingerprint Reader Protocol](https://blog.th0m.as/misc/fingerprint-reversing/)
160+
by Thomas Lambertz was very helpful in the beginning.

libfprint/libfprint/libfprint/drivers/syna_tudor_moc/syna_tudor_moc.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424

2525
/* WARN: current implementation starts a new TLS session on each device open */
2626

27+
#include "syna_tudor_moc.h"
2728
#include "communication.c"
2829
#include "device.h"
2930
#include "fpi-log.h"
3031
#include "fpi-ssm.h"
31-
#include "syna_tudor_moc.h"
3232
#include "tls.c"
3333
#include <gnutls/abstract.h>
3434
#include <gnutls/gnutls.h>
@@ -45,14 +45,12 @@ G_DEFINE_TYPE(FpiDeviceSynaTudorMoc, fpi_device_syna_tudor_moc, FP_TYPE_DEVICE)
4545

4646
// clang-format off
4747
static const FpIdEntry id_table[] = {
48-
// { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C9, },
49-
// { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00D1, },
50-
// { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00E7, },
51-
/* only 00FF is tested */
52-
// FIXME:
53-
// { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00FF, },
54-
// { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0124, },
55-
// { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0169, },
48+
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C9, },
49+
// { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00D1, },
50+
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00E7, },
51+
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00FF, },
52+
// { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0124, },
53+
// { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0169, },
5654
{.vid = 0, .pid = 0, .driver_data = 0}, /* terminating entry */
5755
};
5856
// clang-format on

0 commit comments

Comments
 (0)