Open javierfileiv opened 4 years ago
Are these binary blobs taken from the firmware extracted from the windows installer?
I'm quite confident these blobs are pieces of code which Windows driver dynamically uploads and executes on the device. They are hard-coded inside the driver .dll.
How can I know which one is init_hardcoded , init_hardcoded_clean_slate, etc ?
You can use this project https://github.com/uunicorn/synaWudfBioUsb-sandbox to snoop on Windows driver to see which blobs are loaded into your device and when.
The firmware's name for 009a is 6_07f_lenovo_mis_qm.xpfwext
(extracted from nz3gf07w.exe
.
I will try and extract the blobs. Let's see how it goes.
Thanks @mjenny , could you please share after the extract? :)
@javierfileiv sure, if I'm able to extract them. :) I'm currently in the process of compiling wine.
I can assist you in finding the blobs if you can manage to get synaWudfBioUsb-sandbox running. In addition to the firmware file itself, you will also need to extract synawudfbiousb.dll from your Windows diver. If all good, wine64 a.exe will spit tons of output. Redirect it to a file and upload somewhere so I can have a look. Good luck.
@uunicorn I already have the DLL and the firmware extracted. I will let you know as soon as I have wine up and running.
I am currently compiling wine inside a VM running on my Lenovo X1 Extreme. Not sure if that will be sufficient. If not I will install Arch Linux or Linux Mint for a faster install. 😄
Hm... I should have tried to passthrough the fingerprint reader earlier. I guess Intel Secure Guard Extension is a problem or the fact that I have enabled WSL2 and have to go through Hyper-V.
@uunicorn do I have to put the firmware file somewhere to run a.exe
?
Both .xpfwext and .dll should be placed in the same directory with a.exe.
I'm no expert, but if you're running a host on Windows, it may be hard to pass the reader USB device to a Linux guest. Windows diver may have claimed the same device and could interfere with a communication. But yeah, IDK, I never tried that.
@uunicorn I installed Linux Mint for now. Will do everything over again. Am I still supposed to compile wine myself (regarding hacks)?
Yes. Hacks have a bunch of printfs sprinkled all over the crypto routines. Those are actually used to dump all the communication between a device and a driver. Including the missing blobs. Hacks also include a fake winusb.dll implementation which lets synawudfbiousb.dll talk to a real USB device. Vanilla wine does not have this DLL.
Which reminds me that you'd probably want to change this line before building Wine: https://github.com/uunicorn/wine/blob/7ed3db9743a525228fb6306ab0d8d0f8b4163e00/dlls/winusb/winusb.c#L16
I'm currently back to building wine with the aforementioned changes.
@uunicorn I successfully built wine
and it worked fine so far. However, I don't have a wine64
executable. And when running WINEARCH=~/.wine-fingerprint wine a.exe
I get a wine: Bad EXE format for Z:\home\mjenny\wine\a.exe.
.
I assume that a.exe
which I downloaded directly from your repo (I didn't build it myseld) is using 64-bit, right (a.exe: PE32+ executable (console) x86-64, for MS Window
)?
Do I have to build wine
differently?
Nvm, I missed --enable-win64
...
Ok, I have everything running.
@uunicorn how do I know that a.exe
was successfully run? I am now getting a Program Error
during execution.
There seems to be an Unhandled page fault
:
USB >>>>>>>>>> In DllMain reason=1
USB >>>>>>>>>> WinUsb_Initialize
wine: Unhandled page fault on read access to 0x00000040 at address 0x7f1005121a44 (thread 0009), starting debugger...
@uunicorn here is the link to the logfile: logfile.txt
@mjenny it looks like it crashed because it failed to find your USB device.
Can you check that the device vendor and the product id in
By default it is
#define MY_VENDOR 0x138a
#define MY_PRODUCT 0x0097
which corresponds to 0097 device. If you have a 009a, you should probably change MY_PRODUCT to 0x009a, but it would be best if you can double check with lsusb:
$ lsusb
...
Bus 001 Device 005: ID 138a:0097 Validity Sensors, Inc. <---- my device
...
$
how do I know that a.exe was successfully run?
a.exe should let you enroll a finger.
I should have known it better... I was thinking about changing #define MY_VENDOR
to 06cb
which is what my lsusb
is printing:
...
Bus 001 Device 003: ID 06cb:009a Synaptics, Inc.
...
I'll rebuild wine then and let you know how it goes.
@uunicorn
It looks better know. Do I have to run wine64
as root to be able to access the USB device?
0009:trace:reg:NtQueryValueKey (0x60,L"SignatureKeyPair",2,0x332d20,256)
USB >>>>>>>>>> In DllMain reason=1
USB >>>>>>>>>> WinUsb_Initialize
!!!!!!!!!!!! Found device 06cb:009a
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/003: Permission denied
libusb: error [_get_usbfs_fd] libusb requires write access to USB device nodes.
Failed 'libusb_open(dev_list[i], &info->dev)': -3 - LIBUSB_ERROR_ACCESS
0010:trace:reg:open_key ((nil),L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName",20019,0x7df700)
0010:trace:reg:open_key <- 0xb8
0010:trace:reg:open_key (0xb8,L"ActiveComputerName",20019,0x7df708)
0010:trace:reg:open_key <- 0x15c
0010:trace:reg:NtQueryValueKey (0x15c,L"ComputerName",2,0x7df750,44)
0010:trace:reg:open_key ((nil),L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName",20019,0x7df700)
0010:trace:reg:open_key <- 0x168
0010:trace:reg:open_key (0x168,L"ActiveComputerName",20019,0x7df708)
0010:trace:reg:open_key <- 0x15c
0010:trace:reg:NtQueryValueKey (0x15c,L"ComputerName",2,0x7df750,44)
002e:trace:reg:RegDeleteTreeW (0x24, L"Winedevice1")
002e:trace:reg:open_key (0x24,L"Winedevice1",20019,0x1c7fa98)
002e:trace:reg:open_key <- (nil)
0010:trace:reg:RegDeleteTreeW (0x24, L"Winedevice2")
0010:trace:reg:open_key (0x24,L"Winedevice2",20019,0x7dfaa8)
0010:trace:reg:open_key <- (nil)
I've got a custom udev rule:
/etc/udev/rules.d/10-fpreader.rules:ATTRS{idVendor}=="138a", ATTRS{idProduct}=="0097", OWNER="unicorn"
But you can chown it manually. It's gonna be reset after reboot or when device re-connects.
@uunicorn I chown
ed the device and the logfile.txt looks promissing: logfile.txt
However, I still was not able to enroll a finger.
>>>>>>>>>>> xfer Failed - LIBUSB_ERROR_NO_DEVICE
That could mean that device just finished pairing and has restarted. Chown again and give it another go. It may take a couple of tries.
Or may be not. I can't see it's sending any firmware. But the last message the host sent to a device was a "reboot" command (which caused USB device to disconnect):
USB a03700 >>>>>>>>>> WinUsb_WritePipe PipeID=1
>>> 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
rc=0 send=98
You may need to put the firmware file in some other place, where the driver is looking for it. Not sure where though.
I couldn't find anything in regards to that inside synaWudfBioUsbLenovoMiSSGXProd.inf
(which is the only inf
file I could find): synaWudfBioUsbLenovoMiSSGXProd.inf
What do you mean? Here it is:
[DestinationDirs]
...
WinBioSensorAdapterCopy=11, WinBioPlugins; copy to \Windows\System32\WinBioPlugins
FWextCopy=11
...
[FWextCopy]
6_07f_lenovo_mis_qm.xpfwext
...
Try copying it to \Windows\System32\WinBioPlugins in your Wine prefix. E.g ~/.wine/driver_c/Windows/System32/WinBioPlugins/ You may need to create WinBioPlugins directory.
Dang, I missed that completely...
It is now using the firmware file from what I can tel. However, the result is the same, no matter how many times I try. The pairing is working fine and it will be recognized as new USB device for which my user is still the owner.
ls -la /dev/bus/usb/001
Before the run:
total 0
drwxr-xr-x 2 root root 160 Jun 22 06:53 .
drwxr-xr-x 6 root root 120 Jun 22 05:56 ..
crw-rw-r-- 1 root root 189, 0 Jun 22 05:56 001
crw-rw-r-- 1 root root 189, 1 Jun 22 05:56 002
crw-rw-r-- 1 root root 189, 3 Jun 22 05:56 004
crw-rw-r-- 1 root root 189, 4 Jun 22 05:56 005
crw-rw-r-- 1 root root 189, 5 Jun 22 05:56 006
crw-rw-r-- 1 mjenny root 189, 16 Jun 22 06:53 017
After the run:
total 0
drwxr-xr-x 2 root root 160 Jun 22 06:54 .
drwxr-xr-x 6 root root 120 Jun 22 05:56 ..
crw-rw-r-- 1 root root 189, 0 Jun 22 05:56 001
crw-rw-r-- 1 root root 189, 1 Jun 22 05:56 002
crw-rw-r-- 1 root root 189, 3 Jun 22 05:56 004
crw-rw-r-- 1 root root 189, 4 Jun 22 05:56 005
crw-rw-r-- 1 root root 189, 5 Jun 22 05:56 006
crw-rw-r-- 1 mjenny root 189, 16 Jun 22 06:54 018
logfile.txt I'll continue to try.
Do you think that the new device number is the issue and that xfer
can no longer find the device?
No, host is requesting device to reboot before it disconnects. USB comms are fine. By the looks of it, the device was not partitioned properly yet. I'll have a closer look in a while, thanks for trying - some of the blobs are already in the output. Did you capture the output from all your attempts?
No, but I can create a few more and upload them if it helps.
Can you use factory-reset.py and try again? Try to log everything when running a.exe, as the device has a state and running it twice in a row may give different results.
Ok, I will try that. I moved the already uploaded logfile.txt on my server: logfile.txt
Looking at the logs, I'm pretty sure it's having troubles sending the firmware. Likely it still can't find the firmware file. Where have you copied it to?
I have copied it to ~/.wine-fingerprint/drive_c/windows/system32/WinBioPlugins/6_07f_lenovo_mis_qm.xpfwext
When I run factory-reset.py
I receive the following error:
~/python-validity$ python3 factory-reset.py
Traceback (most recent call last):
File "factory-reset.py", line 5, in <module>
usb.open()
File "/home/mjenny/python-validity/proto9x/usb.py", line 28, in open
self.dev.default_timeout = 15000
AttributeError: 'NoneType' object has no attribute 'default_timeout'
Try also copying it to ~/.wine-fingerprint/drive_c/windows/system32/ ~/.wine-fingerprint -- that is what your WINEPREFIX env variable is pointing at, right?
BTW: my env.sh
file looks like this:
#!/bin/bash
export WINEPATH=/usr/lib/gcc/x86_64-w64-mingw32/9.3-win32
export WINEPREFIX=~/.wine-fingerprint
export WINEDEBUG=trace+rsaenh,trace+reg,trace
It worked!! Can I Ctrl-C after an enrolment?
Yay. I think so. So, I guess copying it to system32 helped. Send some logs :)
Just to be sure, will the logfile.txt
contain any fingerprint data if I touched the sensor?
This is a log file with the fingerprint reader lit up (without me touching it): logfile7.txt
Yes it will, but if 009a is similar to 0097, your biometric data will be encrypted. But everything up to the actual scanning should be enough for now. Thanks!
This is with one enrolment (not my finger but it recognized the enrolment :smile: ): logfile6.txt
It would be nice if you can do a factory reset and start over, making sure that you log the output for each run. Some of the blobs only appear in case of a clean slate. Can you check that your USB vendor/product is present in proto*/usb.py before running the factory-reset.py?
I should have come up with this myself, sorry. :smile: Normally I am developing Java and React stuff.
I still get an error regarding the blobs.py
:
Traceback (most recent call last):
File "factory-reset.py", line 6, in <module>
factory_reset()
File "/home/mjenny/python-validity/proto9x/sensor.py", line 283, in factory_reset
assert_status(usb.cmd(reset_blob))
File "/home/mjenny/python-validity/proto9x/usb.py", line 57, in cmd
out = out()
File "/home/mjenny/python-validity/proto9x/blobs.py", line 27, in <lambda>
globals()[p] = lambda bname=p: __load_blob(bname)
File "/home/mjenny/python-validity/proto9x/blobs.py", line 22, in __load_blob
globals()[blob] = getattr(blobs, blob)
UnboundLocalError: local variable 'blobs' referenced before assignment
I know that I'll have to edit blobs.py
as well but therefore I would need the corresponding blobs inside blobs_9a.py
, right?
I already extended blobs.py
:
if usb.usb_dev().idVendor == 0x138a:
if usb.usb_dev().idProduct == 0x0090:
from . import blobs_90 as blobs
elif usb.usb_dev().idProduct == 0x0097:
from . import blobs_97 as blobs
if usb.usb_dev().idVendor == 0x06cb:
if usb.usb_dev().idProduct == 0x009a:
from . import blobs_9a as blobs
Could you already retrieve the blobs needed for the factory reset?
You're right. We just had this blob after the first attempt. But I get 404 for that log file now and I haven't saved it. It's the one which has:
USB a03700 >>>>>>>>>> WinUsb_WritePipe PipeID=1
>>> 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
rc=0 send=98
(this is a factory reset command)
Hm.... that's unfortunate, I have accidentally overwritten it...
Can I factory reset through the BIOS?
Sure, if you don;t mind rebooting
Ok, I have some more logfiles after the reset in the BIOS: logfile8.txt (without proper firmware) logfile9.txt (with proper fimware but error before enrolment) logfile10.txt (with proper firmware and enrolment
I guess the most interesting one will be logfile9.txt
.
There is one more thing which is the identification. For that a.exe needs to be recompiled.
Sure, let me know what to change and I'll recompile a.exe
.
Hi there, I'm trying to make work this fp.
I saw that there are blobs_90.py are blobs_97.py . Are these binary blobs taken from the firmware extracted from the windows installer?
How can I know which one is
init_hardcoded
,init_hardcoded_clean_slate
, etc ?Thanks for your reply