-
Notifications
You must be signed in to change notification settings - Fork 489
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
libnet80211.a & libwpa.a are of unknown origin #4
Comments
wpa_supplicant upstream is here: http://w1.fi/wpa_supplicant/ . Note that some parts of wpa_supplicant code appear even in bootrom (well, those are more or less generic parts and may come form other origins). |
I know that @israellot did some hacking/analysis on net80211 part, I invited him to stay in touch: israellot/esp-ginx#2 , but so far didn't see him publish any details. |
I've found this: https://github.com/linux-rockchip/linux-rockchip/tree/d08bfac2cc274fe8a0d9b9c6a640886fc5bb3857/drivers/net/wireless/esp8089 |
Well, esp8089 Linux driver was brought up during the early days of esp8266.com. I don't think it gives us much: it consists of a) firmware as a binary C array (eagle_fw1.h/eagle_fw2.h) and then Linux side which communicate with that firmware over SPI. So, esp8266 SDK gives us much already (we could develop such a firmware which allows to communicate with host side over SPI - but we can develop many more types of firmwares).
Which libraries do you mean? If SDK, Xtensa is actually very nice, "classical" RISC architecture which doesn't have CISC-like crap as flags (like ARM has), and at the same time, doesn't have MIPS/SPARC style delay slots which are PITA for a human. So ironically, a good RISC assembly is actually more high-level than CISC stuff like x86.
Well, we should expect that whatever base was used for Espressif code, it was modified. So, we can't just expect that we can check each FreeBSD revision in a row until one "clicks". It won't happen. The talk is about finding a version which matches SDK code the best, then try to modify it to make it compatible with the rest of code. Finding "closest" revision isn't realistically doable by hand, but then automating it not trivial either. (Which makes it an interesting, challenging task, which is unfortunately a diversion from working on an open esp8266 SDK ;-) ). All in all, @israellot , please consider sharing notes on the steps you already tried - it either will allow someone else to continue them, or come up with another approach, knowing that one is not fruitful. |
A quick review of what I've done. It's not much but maybe it's a starting point. I took this function as a starting point: ieee80211_send_probereq , on most FreeBSD branches it has the same signature ( here's an example https://github.com/freebsd/freebsd/blob/01e375543f2cca888435d33af45404f00296ca0c/sys/net80211/ieee80211_output.c ) :
The only unknown is the * ieee80211_node* argument. It turns out the ESP has a basic config struct at the address _irom0_text_start+0xc, it appears everywhere on the disassembled code.
it became clear the ROM has two ieee80211_node structures, one for the soft ap, the other for the station client. One is on offset 16 from the main config struct, the other on offset 20.
Passing 1 returns a pointer to the access pointer node, 0 for the station ap. A second step would be writing a function in C that replicates the ieee80211_send_probereq, |
In my opinion, esp8266 future is unknown, insecure, to the point there's no much sense putting effort to reverse engineer so much of their internals. They might just dump 8266 and put 8277 in place next month. A serious SOC would start with an consistent and possible open source SDK. We like the ESP because it's cheap, period. But it comes with a price, not in dollars, that's is high. |
Hi @israellot, Thanks for posting your research, this is very interesting. Do you have any feeling on whether the fields in the ieee80211_node structures are the same as in the upstream mac80211? In lwIP the netif structure is a little bit modified for ESP. You make good points about the future of ESP. This is one of the reasons for choosing "open source above the MAC layer" as an initial goal - aiming for something achievable and useful in a reasonable timeframe, without too much spelunking into the lower layers. One hopeful thing is that whenever an "8277" eventually appears, it will probably have similar peripherals to 8266 so reverse engineering effort will probably not become obsolete overnight. Probably, anyhow! Cheers again, Angus |
+1 for sharing that info. Cannot help but to stick a shameless plug for https://github.com/pfalcon/ScratchABit
So, the config struct is not at _irom0_text_start+0xc, its address is there. The best way to treat "l32r" instruction in the r/o code as an alias for "movi". ScratchABit makes it all obvious:
(Disclaimer: with a patch ida-xtensa plugin, available on a request or later when time permits to push my changes.) |
That's certainly true.
I don't know what kind of pressure you have in mind. I tried to "apply pressure" to resolve GPL-which-should-be-there situation, it was pretty obvious problem, and it took quite an effort (as for an individual, working on that in hist free time as a hobby). But then it was successful, and didn't take that much of an effort and time. That means they do listen and even care a bit. I imagine it would be much worse with a typical western corporation (but then a western corpo unlikely did it "wrong" in the first place). But that doesn't mean that either a western or chinese corpo would just go an open up on somebody's wish - put yourself at the place, what would you do? |
Well, there're rumors that Espressif might open up a bit more - eventually. One good reason for that would be that a new chip coming out, sufficiently different, so opening up old code no longer will be much of "IP loss" ;-). |
You are right @pfalcon. It's a pointer, l32r is load realitive, I just messed up my writing. But I actually tried loading the pointers by hand and the result is the same. |
Taking a closer look, the eagle_lwip_getif should in fact return a struct netif pointer. |
@projectgus, @israellot : I've now cleaned up a bit my ida-xtensa changes described above and pushed to https://github.com/pfalcon/ida-xtensa ("pfalcon" branch). Once again, it's supposed to work with ScratchABit. |
Great @pfalcon ! Let me take a better look and try it here. Thanks for you help proving this tool! |
I don't know how useful this would be to you considering it still relies on the pp.a, and ppTxPkt, but I have jimmied the existing stack into sending arbitrary 802.11 packets of whatever kind I want. https://github.com/cnlohr/esp8266rawpackets/blob/master/user/esp_rawsend.c |
That's great @cnlohr ! Can you share your method as well? How did you proceed. |
I was puzzled by your question, but I think you are asking "how did [you] figure it out?" I spent about 40 minutes trying to reverse engineer the ppTxPkt function using ScratchABit. I tried calling it with many different paremeters, but it kept failing and rebooting the chip. Eventually I started to look for related functions, and figured "maybe ppRegisterTxCallback would pass a similar buffer" and in fact, it passed EXACTLY the parameter to ppTxPkt! So, I tried calling ppTxPkt with the same parameter I got from the TxCallback, and using wireshark in monitor mode, I was able to receive many, many SSID broadcasts. Once I saw that, I knew I had a winner, so I started printing all the bytes that were being passed in. When I saw pointers (4th byte = 3f) I followed them, When I saw what looked like an IEEE802.11 packet, I tried modifyingppRegisterTxCallbackc it, and that worked. Then, I had to figure out how to change the size. So, I kept watching packets intently looking for what changed when the size changed. I found one value, but that didn't seem to work to change, so I found another one too. By changing both values, I could change the Tx packet length. All in all, it took may 4 hours to hack? I am going to attempt to hack it to be able to use promiscuous mode while running as an AP, and I sort of have that now, but I can't seem to hook the original RX processor, and thus it doesn't seem to work right atm. :( |
If possible, please move this discussion back to the ESP8266 boards |
Creating this issue to track what we know about libnet80211.a & libwpa.a, which implement the (upper?) MAC layer and the WPA functionality.
The layer above is the IP stack in lwip, specifically the esp network interface code (in
lwip/esp_interface.c
). The layer below is radio-specific stuff in libpp.a.The symbols in libnet80211.a match pretty closely to an older revision of FreeBSD's net80211 module, but it may be via a fork taken from FreeBSD somewhere:
https://svnweb.freebsd.org/base/head/sys/net80211/?pathrev=234018
Some symbols in libwpa.a match closely to FreeBSD wpa, but it may come via somewhere else or have substantial Espressif additions (latter seems unlikely)?
https://svnweb.freebsd.org/base/head/contrib/wpa/wpa_supplicant/?pathrev=252726
I'm hoping to analyse the source revisions from FreeBSD SVN to find the revision which are "closest" to the contents of the binaries, in terms of symbols.
TODO also is to analyse the exact connections between libpp.a to see where it interacts with libnet80211.a & libwpa.a.
The text was updated successfully, but these errors were encountered: