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

Suggestion: Better method of tapping symbols #1

Closed
tgoddard opened this issue Jul 26, 2015 · 6 comments
Closed

Suggestion: Better method of tapping symbols #1

tgoddard opened this issue Jul 26, 2015 · 6 comments

Comments

@tgoddard
Copy link

Heya,

I've been looking for exactly what you're doing here for a proper monitor mode, and was going down the path of finding symbols to tap in to myself. Thanks to this, I've found the right places to tap, and the structure of those callbacks.

I have one suggestion from my own working - you could tap the unresolved symbols much more cleanly using linker options. Define the wrapper function like this:

void __wrap_ppEnqueueRxq(void *a)
{
    if (rx_func)
    {
        rx_func((struct RxPacket *)(((void **)a)[4]));
    }

    __real_ppEnqueueRxq(a);
}

Then set up the linker to intercept that with a wrap option:

LD_FLAGS = ... -Wl,-wrap=ppEnqueueRxq

This should avoid you having to re-compile the libraries, renaming symbols.

Cheers,

Tim

@ernacktob
Copy link
Owner

Hello Tim,
Thanks for the suggestion! I didn't know about this linker option. This will indeed be much cleaner than having to keep multiple copies of the SDK binaries.

As for the symbols, have you found something that can be used more reliably for monitor mode? I've been stuck on what I have for now, because the low level functions are pretty hard to understand...

@tgoddard
Copy link
Author

I haven't found anything more reliable yet. Have a couple of issues tapping in at that stage:

  • Receiver filtering has already happened somewhere, meaning we don't get packets addressed to others. Trying to find whether the filter happens in the wifi chip or in software.
  • The IEEE 802.11 MAC frame has a mangled first byte. Keeps showing up as 0x40, which isn't valid - first two bits should always be 0s. I can see probe requests in that, which I know should be 0x04 .

So far the call path I've identified up to that hook is:

  • un-exported code in libpp.a/lmac.o calls lmacRxDone
  • lmacRxDone calls ppEnqueueRxq

Not having much luck so far identifying the call chain beyond there, how it retrieves packets from the wifi module, etc. Slowly slowly.

@ernacktob
Copy link
Owner

Have you looked at my disas/pp/ files? I've been tracing the recv calls from the interrupt handler wDev_ProcessFiq (I think it is one because it was registered with ets_isr_attach at startup). I have also the feeling that packets might be processed in hardware because even the lower level funcs seem not to do any filtering based on mac address, implying incoming packets may have been filtered very early on... Though entering sniffer mode (wdev_go_sniffer) should presumably disable this filtering, but the packets get processed in a different path in that case, and might be truncated as mentionned in the Sniffer API.

EDIT: Though I've noticed they do a lot of flags checking. It is possible that one of these flags is set by the hardware if it detects a packet's dst MAC does not match the receiver's, but the packet might still be accessible before they drop it.

@tgoddard
Copy link
Author

Ah, that's quite a lot easier to read than objdump. It looks very much like that might be filtered in hardware. Looks like the code in wdev_go_sniffer is almost certainly configuring the hardware in to a sniffer mode - even have a no-op write at the end there which is probably triggering an action in hardware (likely reloading the running configuration from the other registers).

@ernacktob
Copy link
Owner

I've been focusing a lot on systematically decompiling the code from libpp.a to gain an understanding of their data structures and the path taken by incoming/outgoing packets.

On the receiving side, they have some interesting structs like this wDevCtrl in wdev.c which seems to keep various pointers to incoming packet queues, as well as one byte which I'm pretty sure represents whether promiscuous mode is on or off. Might be interesting to experiment with the effect of setting this byte to 1 without calling wdev_go_sniffer.

The wDev_SetMacAddress and wDev_SetRxPolicy might also be worth playing with. It looks like they control which mac address is used for filtering, and can be set to the broadcast address (and possibly to any other address).

Another test would be to tap into wDev_ProcessFiq itself and see how often it gets called with promiscuous mode on and off respectively. If there is a huge difference, it would mean the packets really do get filtered in hardware, and we probably can't do much for monitor mode, unless the sniffer API is lying to us and they're just truncating packets that are actually stored in full among the wDevCtrl queues.

@tgoddard
Copy link
Author

I've been playing around with setting the MAC address to be the same as other devices on the network to get traffic addressed to them. Interestingly though, I'm still only getting management packets, not data packets.

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