Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WinDivert.send() raises exception if LastError is nonzero #32

Open
strictlymike opened this issue Mar 24, 2018 · 3 comments
Open

WinDivert.send() raises exception if LastError is nonzero #32

strictlymike opened this issue Mar 24, 2018 · 3 comments

Comments

@strictlymike
Copy link

If a prior Windows API function call changes the last error value for the thread, pydivert.windivert.WinDivert raises an exception of the same value. I was originally calling an API that I noted was causing GetLastError() to return 87, and I thought it was a coincidence that WinDivert.send() was raising an exception that, when printed, read:

[Error 87] The parameter is incorrect.

But after some testing, I learned that calling SetLastError(0) after calling the (unrelated) Windows API I was using yields a successful invocation of WinDivert.send() regardless of the result of this other Windows API call.

Here is an example where I have deliberately called SetLastError(1234) within a dev branch of FakeNet-NG just prior to invoking the send() method of a WinDivert object:

03/24/18 03:12:17 PM [          Diverter] ERROR: Failed to send outbound external UDP packet
03/24/18 03:12:17 PM [          Diverter]   UDP 192.168.159.132:137->192.168.159.2:137
03/24/18 03:12:17 PM [          Diverter]   [Error 1234] No service is operating at the destination network endpoint on the remote system.

I surmise that either pydivert or WinDivert is relying on the value of GetLastError() in at least one case where it has not yet called any Windows APIs that would call SetLastError(ERROR_SUCCESS).

@ffalcinelli
Copy link
Owner

Quite strange, I could call SetLastError(0) prior to call the actual binding as a, let me say, temporary solution to this. When I'll have a bit more time to spend upon this I'd like to check if the driver itself behaves in the same way, so probably this could be redirected to the WinDivert project.

@strictlymike
Copy link
Author

Looking more closely, I think it might be raise_on_error / wrapper within windivert_dll (see pydivert/windivert_dll/__init__.py) that makes the implicit assumption that LastError will be cleared after exiting in the success case, when I found that its may in fact depend on a previous API call.

@strictlymike
Copy link
Author

To be clear, I think the solution you proposed (calling SetLastError(0) before calling the actual binding) is appropriate given the fact that raise_on_error is expecting the value of GetLastError() to indicate the success or failure status of this operation.

strictlymike added a commit to mandiant/flare-fakenet-ng that referenced this issue May 1, 2018
# 1.4.0:
* Refactor FakeNet-NG to unify Windows and Linux packet handling
* Remove Proxy Listener UDP stream abstraction to prevent issue where
  subsequent clients do not receive response packets because the proxy listener
  continues to send them to the old (expired) ephemeral port for the previous
  client
* Stop flag command-line support for rudimentary IPC-based start/stop
  automation
* Integration test script for MultiHost and SingleHost mode
* Fixed Errno 98 (`TIME_WAIT`) issue with `RawTcpListener`
* WinDivert `GetLastError` exception work-around for [WinDivert issue
  #32](ffalcinelli/pydivert#32)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants