justcallmekoko / ESP32Marauder

A suite of WiFi/Bluetooth offensive and defensive tools for the ESP32
5.35k stars 591 forks source link

Sniffing causes marauder to crash #5

Closed justcallmekoko closed 4 years ago

justcallmekoko commented 4 years ago

When sniffing for WiFi or Bluetooth devices, you can expect anywhere between several seconds and 15 minutes of run time before Marauder crashes.

This is caused by a synchronization issue with reading and writing print statements to a buffer to be used by the touch screen. I have employed a binary semaphore, but it is not 100% effective.

The semaphore just makes a crash less likely to happen but it can happen at any moment while sniffing.

tobozo commented 4 years ago

Maybe Running a SPI bus at 5MHz while a RF task is capturing data has its own drawbacks?

#define SPI_FREQUENCY   5000000

Anyway, I had similar problems on the ESP32BLECollector, all went away by giving up the loop() function along with using semaphore mutexes.

Since the loop() task has the highest priority, it is more prone to conflict with other tasks and cause crashes, so it's neutered to avoid that.

void loop() {
  vTaskSuspend(NULL);
}
justcallmekoko commented 4 years ago

@tobozo The issue only occurs when reading and writing to/from a SimpleList instance.

I load string into the SimpleList and unload them to be printed to the screen. The issue comes when the list has a read and write that happen at the same time.

If I remove the code where it loads the string into the SimpleList, no crash. Additionally there is no crash if I only remove the code that removes the string from the SimpleList.

As long as there aren't conflicting read/write against the SimpleList, everything is good. I set up a semaphore to fix the issue but every now and then, the two running processes will hit a sweet spot where the checks fail and both processes think the SimpleList is available to be written to or read from and that's when the crash occurs.

tobozo commented 4 years ago

@justcallmekoko been trying to replicate the problem and got this exception:

0x40091352: multi_heap_assert at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap.c line 380
:  (inlined by) get_prev_free_block at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap.c line 187
0x40092180: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 707
0x400923b1: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 707
0x40091352: multi_heap_assert at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap.c line 380
:  (inlined by) get_prev_free_block at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap.c line 187
0x40091901: multi_heap_free_impl at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap.c line 380
0x40091dfe: multi_heap_free at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c line 315
0x40084dc6: heap_caps_free at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c line 131
0x40085381: _free_r at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/syscalls.c line 42
0x400e879f: String::invalidate() at ~/.arduino15/packages/esp32/hardware/esp32/1.0.4/cores/esp32/WString.cpp line 857
0x400e87ad: String::~String() at ~/.arduino15/packages/esp32/hardware/esp32/1.0.4/cores/esp32/WString.cpp line 857
0x400d53fe: WiFiScan::beaconSnifferCallback(void*, wifi_promiscuous_pkt_type_t) at /tmp/arduino_build_227450/sketch/WiFiScan.cpp line 1032
0x401f2c8e: ppProcessRxPktHdr at ?? line ?
0x40095319: ppTask at ?? line ?
0x4008e8c9: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 355 (discriminator 1)

can you confirm these are the symptoms I should be looking for if I want to help with this issue ?

justcallmekoko commented 4 years ago

I am going to ask a big brain question here...how did you get this output. Did you just enable a debug level? I will let you know what my output is as soon as I get in front of my computer.

tobozo commented 4 years ago

I'm using the ESP Exception decoder and pasting there the output coming from the serial when the crash occurs.

From the decoded stack hinting at a String::invalidate() and the top error (multi heap assert) it looks exactly like what you're initiallty describing.

[edit] I'm in an area where the average wifiscan devices count is 80, so any error that should happen will happen fast.

[edit2] spare some tft.init() with this:

  // If we don't do this, the text and button coordinates will be off
  //display_obj.tft.init();
  display_obj.scrollAddress( 0 );
justcallmekoko commented 4 years ago

edit 2: I like the way you think. If you don't mind, you can totally do a pull request if you want to add some fixes, features, and enhancements. At the very least, I will try out the scrollAddress(0); suggestion.

I have been trying to get more involved in the github community and I am starting to get familiar with contributions and what not.

The multi heap assert sounds familiar but it has been a while since I have tried to reproduce the error. I have been thinking of just adding a padding time between when it tries to write to the SimpleList and when it tries to remove from it even though the semaphore should have fixed that

tobozo commented 4 years ago

LinkedList is still maintained and does not seem to make the ESPMarauder crash.

Both libraries are using the same syntax so it's only a matter of s/SimpleList/LinkedList/g

I guess the original version from spacehuhn wasn't thread safe (as it didn't need to be on ESP8266).

I have made some local changes that I could share indeed, they may not all be relevant as I had to make the code comply to my own Chimera Core build by dropping TFT_eSPi and TFT_Buttons.

This project could easily work on different hardware profiles (e.g. digitalRead() buttons, no capacitive touch), the ESP32-Chimera-Core can make all the settings and profiles loaded/activated depending on what board was selected in the menu, this means M5Stack, Odroid-Go, DDuino32XS (from Dstike), TTGO-T4, and any upcoming profile.

justcallmekoko commented 4 years ago

I would definitely love to see this running on the TTGO and M5.

I will try using LinkedList. I was unaware it is thread safe so that might work out perfectly. Since the syntax is the same, the transition should be pretty easy

justcallmekoko commented 4 years ago

@tobozo Testing with LinkedList now. Got it to compile and flash. I am running a beacon sniffer right now in a busy (much WiFi) apartment complex.

justcallmekoko commented 4 years ago

It appears to be fixed. It's has been scanning non stop for 3 hours. I will probably close this issue after more testing.

justcallmekoko commented 4 years ago

Switching SimpleList to LinkedList fixed the problem. Ran scan over night and did not crash.