WHF-430 Wifi Adapter + Wifi Finder Reverse Engineering
(Featured: Linksys WUSB54G, Zyxel AG-225H, ConnecTec AG-225H, Allnet ALL-0298, Trendnet TEW-429UB)


   [ZyXEL WiFi Finder/Adapter]  


Now you can join our Mailing List to be informed when we post new updates!

E-Mail:    


Updates

1/22/08:  We got hackaday'd - how nice!  The kind folks at hackaday.com added us to their index of cool hacks, which stirred up a lot of interest in the project.  Thanks to all of you who sent comments and your own notes on the device.  In honor of the hackaday post, I've created a "Hackaday Vanity ROM" that you can find down below, as well as releasing v2 of the talker program that can erase and reprogram the WHFX30.  See the discussion below.

1/25/08:  I finally figured out how to talk to the "Firmware Upgrade Mode" bootloader using RS232 (USB Next!).  It's mildly interesting, but as I mentioned before it is only able to upload 16k of code due to the way the EEPROM is structured.  I've created another small program to upload bin files (or files from the firmware upgraders) to reprogram the device.  It is available down at the bottom of the page.

1/27/08:  We need a USB guru to help us!  Some things we are good at, and some we are not.  DeviceIOControl happens to be one of the ones we're not good at:  So we're enlisting the help of YOU, USB guru!  Our investigation of the firmware upgrader has led us to believe that it should not be hard to write our own updater to program the device via USB control.  But in our flailing attempts to get the device descriptor, we've only been able to frustrate ourselves and the wifi finder.  So drop us an email if you're able to help, and we will get down to specifics.

1/29/08:  Although we still have some development going on the USB side (for all those poor people who don't have logic-level RS232 interfaces), that is not the main intent of this project so it will be set aside for a while.  After investigating hundreds of MB of USB captures, we have a good idea how the PC talks to the ZD1211 and can have some short conversations ourselves.  But without ZD1211 documentation it will take too much effort to decipher each register location and it seems to be a big time sink.  I mean, really - we have 2 other methods of programming the device!  So we've started building the .asm files for the hotspot finder.  We're using Keil uVision, and will be distributing source and project files soon!

1/29/08:  Working on those .ASM files so you can compile the finder yourself with any mods you please.  Coming soon!

2/4/08:  We have uploaded the assembly file to fix a bad boot vector.  We used this to re-enable the ISP loader on our ZyXel device that suffered a bad flash.  The .ASM file can be used as the framework for your own replacement of the finder routines at 0x4000.  See the details below.

2/5/08:  We are now on digg.com.  Digg!    In other news, we have built a dual RS-232 interface to snoop the transactions that happen during hotspot finding.  There's a ton of packets to go through, but we've found the interesting area of the firmware up in the 0x6000's.  Stay tuned for more details on the scanning.

2/5/08:  We have found some really interesting things in our snoop of the RS232 communications between the WHFX and the ZD1211: Most notably, we upload a great deal of data from the WHFX to the ZD at the beginning of scanning.  This data comes from the WHFX EEPROM at somewhere around 0x7C60 (after the FF,FF's).  It's too big to be a command (as the other chatter consists of 1-byte replies from the WHFX) so we are guessing that it may be some sort of finder-specific setup stuff for the ZD.  This is fantastic, because as long as we can write some sort of hard data to the ZD, we can figure out a way to write to the "special" registers we want to fool with!  (the RX mask, and the hardware encryption registers for example)  The details of our findings will be updated later today.

2/18/08:  We are deep in both the WHFX30 and the ZD1211, and finding some very interesting items.  See the discussion below for all the details!

2/19/08:  Upon investigation of the packets sent by the ZD1211 during scanning, we find that the PROBE REQUEST packet is actually read directly from code EEPROM at location 0x7CC7.

3/15/08:  Although we are very busy these days, there has been some progress in modifing the probe request packets, and successful transmission of modified packets.  See the details below.  And never fear, the project is not at all abandoned!  Our work will be slow as we take care of other priorities, but will resume with a vengeance in a few weeks! 

4/2/08:  We decided not to post on April Fool's Day so there would be no suspicions of us joking around!  We have replaced the ZD1211's on-board EEPROM (a 24LC64) with our own socketed EEPROM and are currently experimenting with the device from both ends - see the details below!

8/21/09: Long time, no see!  We've shadowed the page here during an organization of our projects.  We've also figured out how to write the device without using LIBUSB, and learned a painful lesson on why you should not try to help random people that email and ask you to.  Some updates coming soon.



Introduction

As many of you will recognize, the format of this page is borrowed from the excellent work of J. Maushammer's page on this same device.  I have attempted to contact him, but was not successful: So John, if you want me to change the page, just say so!  Hopefully, we can all cooperate to extend the abilities of this cool little device.  So if any of you readers want to join in, I am available for email: wifi at openschemes.

This page is about several user's attempts to gain information on this wifi adapter/finder combo.  The ultimate goal would be to create a device that could find a wireless network, connect to it, and perform some task such as:

1) Checking if I have any email so I don't have to boot up the laptop at the airport!  Maybe even a crude email reader - who knows!

2) Checking news headlines, weather, or sports scores.

3) Acting as a standalone device for datalogging, or uploading some information to the web.

4) A remote portal for X10 control?

And the list goes on.  In essence, the combination of a microcontroller and a wifi interface is a cool starting point for many projects.  But we need to understand the device before we can even consider if any of these are possible.  For example: Even if we take control of the micro, can it control the wifi or is it just a dumb "listener"?  Maybe we'd be better off with a generic micro+802.11 board, but a $250 price tag is a little steep for such a small function.  Plus, the wifi finder contains it's own LiPo battery and charger: A nice, compact, low-cost system.


Overview and Discussion

All these devices are essentially the same product: A WHF-430.  From what I can tell, this product was originally designed by one of two Taiwanese companies: HLTech or U-Media, then the design was sold to other vendors for re-branding.  NOTE: Correct me if I'm wrong about the original designer here, folks.  The design was bought by Allnet networks and branded the Allnet Allspot 0298.  Second was ZyXel, calling it the AG-225H (as well as ConnecTec, calling it AG-225H).  Next was the Trendnet TEW-429UB.  And finally, the Linksys WUSBF54G.  Apparently, everyone wants one and so did I.  And once I'd seen Maushammer's site on his reverse engineering, I was hopelessly gripped by the desire to investigate and extend the capabilities of this clever little beast.

This device is mainly a 2-chip operation, with some other minor IC's for housekeeping and memory.  On the top board is the Zydas ZD1211 (now AR5007UG by Atheros).  That one is a very popular 54A/B/G wifi +USB chip, used all over the place in USB wifi sticks.  The Linux guys have even ported it like crazy, so full driver source is available at sourceforge.  I still don't have any datasheet for it, so if you happen to have the datasheet or development documents, please EMAIL ME!  On the bottom board is the mysterious WHFX30, as well as the LCD driver, charger, and DC-DC converter for powering the whole shebang.  The LCD driver is mildly interesting (it's info is helpful when looking at the firmware dumps) and although I did not find a datasheet for this exact product, I have been using the datasheet for the ST7565 with good results. 

I am pleased to say that I have solved the mystery of the WHFX30, but that is the topic of a longer discussion so we will meet him again later!  For now, let's continue our overview of the system-level stuff.

I have owned all but the Connectec and Allnet devices.  I began researching the device on the web, and downloading as much information as I could about them.  Pretty much, each one responds to a different USB designator but they are all compatible: By changing the USB designator in the driver .SYS file, you can force Windows to use any of the drivers for any of the products.  So by this method, I began loading each vendor's drivers and attempting firmware updates using any firmware updaters I could get my hands on.  No Luck!  The devices I was buying had newer firmware than was available in the updaters, so they wouldn't take it. My ZyXel is V:1.1.1.64 and my Trendnet is V:1.0.3.59.  I don't remember the Linksys firmware but it also refused to update so I returned it.  For your reference, I will mirror some old firmware updaters here unless the bandwidth becomes a burden.  I will not mirror the drivers, as they are available all over the place.

Allnet ALL-0298 updater for V:1.0.2.56FCC.  This version (1.0.2.56FCC) is a popular one, with some bugfixes and FCC requirements.  Mostly everyone released a 56FCC update.

ZyXel AG-225H updater for 1.0.2.56FCC.  This little self extractor is a pain.  You need to go and copy the files from it's directory before quitting, or they are deleted.  Nice cleanup, but hey - slow down, I want to play a little!

Trendnet 1.0.1.51 updater for Revision A Hardware.  Trend warns not to use it with other hardware.  I tried it on my C1 hardware and it would not update (even while single-stepping and patching the updater program using WIN32DASM), so it's fairly idiot-proof.  Basically just a way to get a peek at 1.0.1.51 firmware.

Trendnet 1.0.1.51 updater for Revision B Hardware.  Like they mention, not recommended for use with other hardwares.  Still I tried my C1 hardware and nothing happened.


Research

From the research I've done, I have found a few links to other sites and information on these devices.  Obviously, they're quite popular with the wardriving and warchalking folks - but for those of us who  don't need to leech off other people's wireless connections, there are still some good references available.

Maushammer's Site.  Already mentioned, but so far: He is the king of reversing this device.  First one to identify the processor as an 8051, and a really nice section on peeking at the firmware.

Steve M.'s page on the Allspot Device.  In German, so you may have to use Google translate on it.  This site has has some links to other clones, and he did a nice job researching the FCC ID's.

Generic FCC ID search.  Here you can look up FCC test reports from anything wireless sold in the US.  Good for tracking down who REALLY manufactured that device you just bought.  Sometimes schematics and cool internal photos are available, but not always: The vendor has a choice to make some documents confidential.  Like Steve M mentions, you can see the U-Media applications for this little wifi finder by searching for FCC ID SI5 and product code WUB410 or WUB210.  Kind of cool to look up all products from your favorite brands to see what new cell phones are coming out soon!

DSLReports forum discussion of the drivers, etc.

Wardriving forum discussion on the device.  Google Translate it, or read German if you are so inclined.

Linux Driver Discussion (ZD1211).  A nice history of the ZD1211 and Atheros chip

Forcing drivers for the stick.  Mac-based, but this is where I got the idea to just modify the .SYS files to load other vendor's drivers. 


Windows Side: Begin at the beginning

I have a bad (good?) habit of ignoring the manufacturer's install CD, and just fetching the drivers when Windows recognizes the new hardware.  This keeps all those annoying, ancillary programs from filling up my task bar and causing long boot-up times as dozens of stupid programs invade my console.  Usually, this is a good thing.  In the case of the WHF430, however, some resident software is needed to facilitate more sophisticated communication - this caused me a bit of annoyance when the firmware updaters from above failed to recognize the device.  Installing the drivers alone allowed the device to act as another wireless card, but when I ran the updaters I only got the message: "Network device not found!"

What a load of garbage!  I began by disassembling the updater programs and single-stepping through with a debugger.  After some time, I found that the updater was trying to use the ZDPNDIS5 service to start a conversation with the USB stick, but I did not have it running.  Well, the updaters came with ZDPNDIS5.SYS, so why not fire it up?  I moved it to the system folder and used the DOS command line to bring it to life.

C:\> net start ZDPNDIS5

The ZDPNDIS5  NDIS Protocol Driver service was started successfully.

Lo and behold, the firmware updater now found my device!  I later discovered that installing ANYBODY's full driver suite will allow the communication, which is much easier than forcing ZDPNDIS5 but not nearly as cool.  In my opinion, the least offensive set of drivers are ZyXel's AG-225H, with Allnet's a close second.  With ZyXel's suite, I have a nice quiet AG-225Hv2.exe running in the background and I can still control the wireless options with Windows Wireless Zero Config - the little "transmitting PC" icon down in the task bar.  A fair deal.

Even today, I have not debugged the mystery of why I cannot downgrade my firmware to 1.0.2.56 - the stick simply refuses the new firmware (even when I hex edit the version number to something higher than my own, and re-do the checksum).  But the updater seems limited to me, so I have moved on.  If any of you windows geniuses finds a way to get it running...  By all means, let us know!

Please don't think I have simply shunned the windows side.  In fact, I feel I've gone as far as I can in finding cool hidden features in these updaters.  I prefer the Allnet firmware updater, but the ZyXel is pretty good too.  The Trend has been stripped down a bit and takes some binary patching in order to get it to dump the device, so it ranks lower in the hackability category and probably won't be discussed much.

Our work will start with the .INI file for the updater: Either ZD2EP.INI for the Allnet updater, or AG225H_Firmware_Tool.INI for the ZyXel updater.  Our first job is to set the USB descriptor to whatever device we are currently working on.  In the [Adapter Information] section, you'll need to place your USB descriptor in MatchingDeviceID0.  Just comment (";") out any ones you don't want.  You can see here that I am working on the Trendnet device - it is not commented out

[ADAPTER_INFORMATION]
;MatchingDeviceId0=USB\VID_0ACE&PID_A211
;MatchingDeviceId0=USB\VID_157E&PID_3207
;MatchingDeviceId1=USB\VID_157E&PID_300a

;Trendnet
MatchingDeviceId0=USB\VID_157E&PID_300d

;Linksys
;MatchingDeviceId0=USB\VID_13B1&PID_0024

;Zyxel
;MatchingDeviceId0=USB\VID_0586&PID_3413

Next, we reveal some hidden options in the [Settings] section. Usually only the "Upgrade" and "Verify" options are listed, but there is a "Dump" option that you can find by looking through the disassembly of the updater program so we might as well add it here.  We turn on and off each option by setting it to 1 (for on) or 0 (for off).  I usually don't mess with sleep or wait time.  NOTE: Don't accidentally dump over top of a firmware file you may want later, it will be overwritten!  I mention this because the ZyXel firmware can automatically load the firmware file name from the INI file.

So the full settings suite is:

[Settings]
UpgradeEEPROM=0
UpgradeFLASH=0
VerifyEEPROM=0
DumpEEPROM=1
SleepTime = 0
Wait=5

NOTE: I am going by memory in this next section, and although I think that EEPROM refers to the WHFX30 and Flash refers to the ZD1211, I may have it backwards so be forewarned!  I say this because it seems counterintuitive: ZD1211 has a serial EEPROM attached, and the WHFX30 actually contains Flash memory.  I will double check it soon.

EEPROM refers to the WHFX30, and in my experience, it does not update due to a refusal from the WHFX30 bootloader.  Instead, you get a message "Please set the device to Firmware Upgrade Mode", even if it is obviously ALREADY in firmware upgrade mode.  Hopefully, in the future I'll figure out what the bootloader wants to hear and we will make some progress in writing via USB.  But in essence, the upgrader seems limited to a small range of the WHFX30's memory so it' may not be entirely useful.  I determined this by hex editing the "range" commands in the dump routine of the upgrader: No matter what you try to dump, it just looks like the 1.0.2.56 bin file that Maushammer discusses:  ZD1211 first, then (I think) Serial EEPROM, then a few blocks of WHFX30 code - never the WHFX30 init vectors (at hex 0000) and never the WHFX30 bootloader (as designated by the LACK of the string "Firmware Upgrade Mode..").  So my guess is that the updater is allowed to change the fonts, and a few routines having to do with reading and displaying the wifi stations detected.  It is not allowed to change the bootloader, nor the init vectors, nor a whole SHITLOAD of unused memory in the WHFX30.

Flash refers to the ZD1211, and happily updates (I think, I really don't care at the moment).  It appears that when the USB stick is first connected to a PC, the ZD1211 firmware blob is sent by the controlling PC anyway.  You can see this by running a USB monitor/logger program and simply inserting the device.  Blah Blah, get device descriptor, blah blah, then the firmware blob is sent.  So you are assured that when the device is attached to a PC, the ZD1211 is running the newest and shiniest firmware that you can get.  For standalone mode, you don't have the benefit of this on-demand firmware load, so I suspect that the flash refers to the serial EEPROM device that is connected to the ZD1211.  Probably, this contains another copy of the ZD1211 firmware that is used when the device is in standalone mode.  Maybe someday I'll put a scope on the serial EEPROM device to see if it is really being written by the updater.


First Attempts at Disassembly

Since I had failed to get the USB updater to write, I began inspecting the WHFX30 code in the 1.0.2.56 firmware file.  As Maushammer says, it's definately 8051 (or at least 805x) code.  His amazing work on finding the LCD font table still astounds me, and his efforts in disassembly got me started on the right track.  As it turns out, there is no bootloader in the firmware file: Only ZD1211 code and a measly chunk of WHFX30 code.  This pained me greatly, as I wanted to inspect the bootloader to determine why I could not update via USB.  In the course of my investigation, I found a few neat things that I might as well share here.

1) The LCD controller uses bit-banged SPI communication from the WHFX30.  There's a routine at 0x7740 that I called "Setup_LCD" that prepares a bunch of commands for the LCD controller, then shifts them out by calling a routine at 0x78B8 that I called "Shift to LCD".  We put each bit on port 1.3 and clock it into the ST LCD controller by raising and lowering P1.2.  P1.0 tells the LCD if we're sending a command or data.  It's very straightforward, and helped me to realize that this WHFX30 is 100% 8051, not some magical system on a chip that I'd never figure out.  LCD setup is straight from the ST datasheet.  Here it is in disassembly form.  I apologize for the ugly code, I will try to fix the formatting in the future.

seg002:7740 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
seg002:7740
seg002:7740
seg002:7740 Setup_LCD: ; CODE XREF: seg002:7080 p
seg002:7740 D2 90             setb P1.0
seg002:7742 C2 95             clr P1.5
seg002:7744 7F 2C             mov R7, #0x2C ; ','
seg002:7746 7E 01             mov R6, #1
seg002:7748 12 79 D3         lcall seg002_79D3
seg002:774B D2 95             setb P1.5
seg002:774D D2 94             setb P1.4
seg002:774F 7D A3             mov R5, #0xA3 ; 'ú'     ; Display NORMAL mode, not invert
seg002:7751 7F 01              mov R7, #1                  ; Send command byte
seg002:7753 12 78 B8         lcall Shift_to_LCD
seg002:7756 7D A0             mov R5, #0xA0 ; 'á'     ; ADC Select Normal
seg002:7758 7F 01              mov R7, #1                   ; Send command byte
seg002:775A 12 78 B8         lcall Shift_to_LCD
seg002:775D 7D C0            mov R5, #0xC0 ; '+'
seg002:775F 7F 01             mov R7, #1 ; Send command byte
seg002:7761 12 78 B8         lcall Shift_to_LCD
seg002:7764 7D 22             mov R5, #0x22 ; '"'     ; Voltage regulator setpoint
seg002:7766 7F 01             mov R7, #1                 ; Send command byte
seg002:7768 12 78 B8         lcall Shift_to_LCD
seg002:776B 7D 81             mov R5, #0x81 ; 'ü'
seg002:776D 7F 01             mov R7, #1                 ; Send command byte
seg002:776F 12 78 B8         lcall Shift_to_LCD
seg002:7772 7D 05             mov R5, #5
seg002:7774 7F 01             mov R7, #1                 ; Send command byte
seg002:7776 12 78 B8         lcall Shift_to_LCD
seg002:7779 7D 2F             mov R5, #0x2F ; '/'
seg002:777B 7F 01             mov R7, #1                 ; Send command byte
seg002:777D 12 78 B8         lcall Shift_to_LCD
seg002:7780 7D E0             mov R5, #0xE0 ; 'a'
seg002:7782 7F 01             mov R7, #1                 ; Send command byte
seg002:7784 12 78 B8         lcall Shift_to_LCD
seg002:7787 7D A4             mov R5, #0xA4 ; 'ñ'     ; Display all points normal. Not all points on (A5)
seg002:7789 7F 01             mov R7, #1                   ;  Send command byte
seg002:778B 12 78 B8         lcall Shift_to_LCD
seg002:778E 7D A6             mov R5, #0xA6 ; 'ª'      ; Set to normal polarity
seg002:7790 7F 01             mov R7, #1                   ; Send command byte
seg002:7792 12 78 B8         lcall Shift_to_LCD
seg002:7795 7D F8             mov R5, #0xF8 ; '°'
seg002:7797 7F 01             mov R7, #1                    ; Send command byte
seg002:7799 12 78 B8         lcall Shift_to_LCD
seg002:779C E4                 clr A
seg002:779D FD                 mov R5, A
seg002:779E 7F 01             mov R7, #1                    ; Send command byte
seg002:77A0 12 78 B8         lcall Shift_to_LCD
seg002:77A3 7D AF             mov R5, #0xAF ; '»'      ; Display ON command
seg002:77A5 7F 01             mov R7, #1                     ; Send command byte
seg002:77A7 02 78 B8         ljmp Shift_to_LCD
seg002:77A7                                                             ; End of function Setup_LCD
 

2) The UART is set up at x79B6.  115,200 I think.  I'll avoid the code for this one - you can go take a look if you want.

3) Both of these are called by a "Startup" routine at 0x7076.  We set up the UART, the LCD, then at 0x7094 we load the address of the power-on graphics (0x5BA7) and at 0x70A5 we copy from code memory into RAM in preparation for displaying the startup graphics. 

4) I found various other routines, like "Display_C_String" (my naming) at 0x74D1.  We use that one to display "Scanning.." and other big text.  Another routine I called "LCD_OFF" at 0x7A52 gets called by 0x706B after we load the string "Sleeping.." (Location: 0x63C3) and display the string using "Display_C_String".  The "Sleeping.." string is loaded at 0x75F5 and displayed at 0x7601.

Among various other routines.  After a week or so, I was getting burned out on commenting assembly code and had come to the firm conclusion that neither the bootloader ("Firmware Upgrade Mode") nor the "Self Test Mode" were contained here.  They were the most likely place for me to insert my own code (so it did not interfere with normal function) as well as the most interesting sections to me (So I could figure out why the USB updater was failing) and I was unable to find them.  I even considered that the strings may be encrypted, and searched for any section of 6 repeating bytes (like ...... in "Waiting......") as well as any 6 consecutive bytes.  Nothing.  It was not here.  So how the hell did they program these devices on the assembly line?  I had a few hypotheses.

1) The fun stuff was in ROM, with only a little bit of flash for updating routines.  UNLIKELY!  That's not the way that 8051's are made - it's too expensive to make all the masks for a chip that can be used for only one purpose.

2) The bootloader is programmed on the assembly line, maybe even by the OEM, and all these other companies like Trend and Linksys just get to toy with the mechanics of scanning for wifi stations.  This seemed a little more likely, but offered no assistance: The WHFX30 chip was a mystery.  No datasheets exist, and Trend and ZyXel are pretty tight about giving up any information on it.  I know where the serial port is, and I can trace VDD and GND.  But searching for any 8051 with these pin configurations would be like finding a needle in a haystack!


Serious Disassembly (In a matter of speaking)

Let me digress to talk about Integrated Circuits for a moment.  I'm an IC designer, and for those of you not familiar with the process: A chip is either drawn with schematics, or compiled (for digital stuff) using a language like Verilog or VHDL.  Then, the transistors or logic gates are placed by either a layout engineer or a place-and-route tool into a chip layout.  The layout is "fractured" into layers, and sent to the fab, where they essentially print each layer either into the silicon, or on the surface.  For example, metal wiring is placed on top: A sheet of metal is deposited over the whole wafer and covered with photoresist.  An image of the proper metal layer (there may be many!) is then exposed onto the photoresist just like developing a picture.  Any unwanted metal is not protected by the photoresist, so by dipping the wafer into a metal etching chemical: Poof!  You are left with one layer of IC wiring.

Now with thousands or millions of devices on a chip, some mistakes are always made.  I had just gotten a chip back where a layout guy accidentally connected two devices, and our error-checking program did not notice it.  I had 10,000 chips that didn't work, but I needed to bring a few to life so I could check to see if the rest of the circuit functions!  It's about $10,000 a mask to fix an error, so I don't want to send a new layer file out until I was sure that I did not need to make any other changes.  Enter the FIB lab:  For about $200-$500 an hour, there are labs that will etch a hole in the plastic package of your chip with fuming nitric and sulfuric acid, and then use a machine called a focused ion beam (or "FIB") to cut metal lines as well as stitch new connections anywhere you want.  FIB machines are million-dollar beasts that look like satellites, due to the gas inlets all over the place for things like Xenon Difloride (for etching) and Gallium and Tungsten (for depositing new wires).  Very cool, and the PC's that run them use cleverly-named software like "Microsurgery".  Hilarious!

Well I had been spending quite a bit of time at the FIB lab anyway, and I got the idea that maybe these guys could help me out a bit.  I paid them $50 out of my own pocket (well, it's only as much as the wifi finder cost itself!) and asked them to decap the WHFX30.  By "Decap", I mean "Decapsulation", a fancy term for etching a hole in the top of a chip package.  You could probably etch the top off yourself if you had hot nitric and sulfuric acid, but that shit splatters when etching the plastic package and will run all over the place, eating your board and ruining everything.  I consider it a $50 well spent because these fine fellows have another machine called a Decapper or a Jet-Etch, where your chip is held against a teflon gasket and hot acid is literally jetted into the opening.  It takes about 10 minutes total to grease and affix the gasket, jet etch it, then clean it up with some solvent and BOOM!  You got a hole in your chip but it still functions perfectly.  Where am I going with this? 

          Fig1: Alive and Scanning                                     Fig 2 - There's the inside                  Fig 3 - Hey, you got a hole in your chip!     Fig 4 - Microphotograph of the mystery chip logo

 

Beautiful, isn't it?!  A tiny billboard, much thinner than a human hair, right there on the surface.  It is typical to copyright the IC in order to prosecute those who attempt to strip each layer and copy your chip, and also common for the manufacturer to put their logo on the top metal layer.  Sometimes, we even put pictures or other goofy stuff just because it's cool, or if we happen to have the space.  You can go see a gallery of pictures found on IC's if you're interested.

So there she is folks, a Macronix 805x clone.  I have not yet identified the exact IC, but I have found the family and that's good enough.  This chip is most closely related to the MX108050 (Warning, big PDF datasheet) and looks to contain a whopping 64k of flash.  Holy crap!  We're only seeing a tiny fraction of that in our firmware updater - how do we get the goods?

 


Getting to the ISP Loader

If you read the datasheet, this device is similar to many other 8051 clones with flash memory in that the manufacturer provides a very basic, very low-level loader in order to program the device on the assembly line.  Typically, the PCB is stuffed and soldered and after some minimal testing to make sure that the power supply and other connections are good, we need to store our firmware into the chip.  Since we've already soldered it to the board, we can no longer use a parallel programmer so we rely on a serial loader to flash some life into the chip.  This is often called the ISP (In-System-Programming) loader, and that's what we'll call it here to differentiate it from the vendor's bootloader (Firmware Upgrade Mode).  Upon startup, if some some obscure sequence of events occurs, the chip will ignore the firmware held in EEPROM and run the ISP loader instead.  It would have been nearly impossible to access this loader without the datasheet, as we didn't even know what the pinout was, let alone the loader startup sequence!

But thankfully, on page 63-64 of the datasheet we find the beginnings of a discussion on the ISP loader.  In essence, if you hold the PSEN pin low, !EA and !ALE high while leaving reset we will hit the ISP loader and can do what we want to the full bank of EEPROM, including change any part of the firmware and add our own.  Obviously, this also means we can screw up the firmware, leaving our device useless so be forewarned!  Personally, I am assured that using the ISP loader, I can always re-flash the original BIN file and be back in off-the-shelf condition.

Now how to create this bizarre sequence of events?  We can see that the reset pin (RST, p10) has a capacitor to VDD.  This will create a little startup delay in which we are allowed to toy with the pins before the micro takes over and begins putting output on them.  We can also see (by tracing connections with a meter) than !EA is already tied to VDD - good, this makes our life easier.  Further, the datasheet suggests that we don't really NEED to pull !ALE high, but rather letting it float is OK.  This one we have to hope is good enough, because it's pretty hard to solder connections to all these little pins for a 2-millisecond command sequence.

So we're down to PSEN.  Initially, I held it to ground by momentarily stabbing it with a small wire while powering up the device.  It seemed to work OK, but when I checked it with a meter it was drawing 20mA - you don't want to do this because you will eventually burn out the PSEN port and then you're out of luck.  Tracing the board, I found a little 5k resistor from PSEN to pin 1 of the 10-pin connector up to the top board.  This one is called UNKNOWN_1 in Maushammer's site.  Could it be that the loader access is this easy?  Yes!  Just ground this pin upon power-up, and you will hit the precious ISP loader.  After power-up, continuing to ground this pin only draws about 0.6mA so I usually leave it grounded all the time.  And there you go: the secret loader formula:

1) Jumper J1 and J4 (PSEN to GND) on the 10-pin header.  You will need to connect this GND to the GND of your MAX232 board.

2) Use a MAX232 running at 3v (or 3.3v, but ideally it should be 3.0v) and connect it to J7 (TxD of MAX232, RxD of WHFX30) and J9 (RxD of MAX232, TxD of WHFX30).  Obviously the other side of the MAX232 will be connected to your PC serial port.

3) Power up the device, and send uppercase "U" a few times at any baud rate, 8n1, to allow the WHFX30 to sync up and detect the baud rate.  The ISP loader will begin echoing characters back to the serial port once it is ready.  So if you send a U and recieve a U, U are in the loader!  Haha I could not resist.  If you get garbage you're either not in the loader or your baud rate is too high for your long wires.  You can identify the loader because it will not update the LCD.  It will instead show whatever the last thing on the LCD was - either blank if the device has been off for a while, or the power-on graphic or "Scanning" or something.  Check this LCD behavior if you're not sure you're in the loader.  Take out the J1-J4 jumper and power up until it shows "Scanning" or something, then power down, install the jumper, and power up within a few seconds .  The next time you power up you won't get the power-on Graphics ("Hotspot Finder") but rather the last thing that was previously on the screen.  You are in the loader!

4) Momentarily rejoice in your fine skills, and begin working with the device using the commands starting on page 66 of the datasheet.

Fig 5 - About to chat with the Trend loader.
I was too lazy to build yet ANOTHER MAX232 board, so I just pried up the RxD and TxD pins
of a Keyspan USB-RS232 converter I had lying around.  It runs at 3.3v which should be OK for the 3v
WHFX30 port, is powered by USB, and was handy.  Note the J1/J4 jumper on the black GND wire, as well
as the RxD, TxD of the WHFX30 on J7, J9 respectively.  (Red, Yellow)


Making the Loader work

Now this is truly bizarre: The datasheet tells us that the loader will take either binary or ASCII commands, but I find that's not the case.  I find that it will only take binary commands, which makes normal ISP software useless (Unless I've missed something, like send a "U" for binary mode or some other character for ASCII mode??).  At any rate, although I had gotten to the loader I could not make it dump any data - boy was I frustrated!  I used two recommended pieces of software (WinISP and FlashMagic) but neither could get the device to respond properly.

I had started with hyperterminal, and so I went back to hyperterminal: Carefully typing in the "Miscellaneous Read Function" to dump the boot vector gave no response.  None of them did!  Had these evil manufacturers disabled all the cool loader functions?  Was it just echoing characters to entice me?  Was it a side effect of "Protect Mode"?  I mean - I had spent good money to decap this device, and I wanted some damn results!  It was at least supposed to give a '.' or an 'X' to tell me if the command's checksum was good or not.  Grrrrr.

In a funny twist of fate, I decided to echo garbage back to it to see if it got as frustrated as I did.  I started a command ":", and just held down the 0 key in an attempt to piss off the device.  After about 50-odd characters, I got back an "X"!  Woah - the loader is alive!  But why so many characters?  ASCII 0 should have meant 0-data length, so it should have X'd me after only a few characters.  Oh - now I saw the light!  If the device was in binary mode, ascii 0 would have meant hex 30 or decimal 48.  This could easily have lead to a 54-character buffer before the complaint.  I tried again with other miscellaneous characters, and you can see my debug notes here.

Intel Hex Record should be:
NN AAAA RR DD...DD CC <crlf>
NN - number of data bytes in record
AAAA - address
RR - Record type
DD - Data bytes
CC - checksum


Timing command does not work - expects many more bytes
??? IS the bootloader ONLY in binary mode??

:01000002000000000000000000000000000000000000000000000X
:01000002000000000000000000000000000000000000000000000X
:01000002000000000000000000000000000000000000000000000X

Sending a space ($20) shortens this
: 000000000000000000000000000000000000X

Exclamation ($21) takes one more byte
:!0000000000000000000000000000000000000X

Single Quote ($22) takes one more
:"00000000000000000000000000000000000000X

Backspace :, $08
Len:12
00 00 00 0000 00X

And there I had it: It was interpreting my ASCII as binary and looking for huge, invalid records.  I wrote a small VB program to convert an ASCII hex record to binary and send it, and finally got the precious dot response ('.' = Good Command Checksum).  The first successful communication was the read of the boot vector using the 05 function call.  Here's my VB string - you can laugh all you want, but it works!  I got back 0xFC, 0x2E: The boot vector was 0xFC00 (the default, no funny stuff in the loader) and the 0x2E was the dot response for successful command.  Dunno why the order is wrong, but it often happens like this so be aware.

Special Read: Boot Vector (Reads FC "2E" equal to FC00 - the Default~!)
mycommand = ":" & Chr(&H2) & Chr(&H0) & Chr(&H0) & Chr(&H5) & Chr(&H7) & Chr(&H2) & Chr(&HF0) & vbCrLf

MSComm1.Output = mycommand
 

It was at that point that I began writing a small VB program to dump the full 64k of EEPROM.  I have not tried to program anything, but I believe that this device has the full 64k of EEPROM, due to the fact that some data resides above 0x8000 hex (32k).  I've dumped both the TrendNet and the ZyXel devices with good success and am now comparing the firmware.  It's clear that this is the full dump, with jump vectors at 0x000 hex, and the interrupt service routines down in low memory.  The bootloader and test mode are revealed in the 0x2000's, so now maybe I can complete my task of getting the USB updater working - or even writing my own!

 


Work on the VB dumper

For those who are interested, here is the VB dumper.  To use it: I typically plug in the serial cable with the wifi finder off (but J1-J4 jumper installed), then run the program and power up the wifi finder.  The first button you want to use is "Find WHFX30", essentially it will try to send the "U" character and look for echo.  If you don't get anything, double check your TxD, RxD connections and then try a different baud rate if it still doesn't work.  As a last resort, try using Hyperterminal instead, and send the "U" yourself.  Once the loader comes alive, it will begin echoing all your characters back to you.

Once you have successfully found the WHFX30, you can "Dump WHF30" and show dat pointer - it should be 77837 bytes.  If you dump multiple times and get different dump sizes (different dat pointers) then your baud rate is too high or you're getting noise on the lines - power the finder down and start again with a lower baud rate.  Once you've got a good dump, you can save the entire buffer (including dump commands and all the address junk sent by WHFX30) by "Save Raw Dump to File" or you can strip out all the junk to get a perfect 64k bin file by using the "Save Cleaned Dump to File".  Yeah, I didn't make a clever file picker or add too many other features to my little dumper program: In fact, it was written in about an hour so if you don't like it: Write one yourself!

WHFX30 Dumper Executable (Version 1).

WHFX30 Talker v2 (Read/Erase/Write)  You can use this program to write basically ANY 8051 code to the WHFX30 for execution.  One caveat is that for now, it will only accept 64k bin files.

The source is too messy to release now, but beg if you want and perhaps I'll give it up.  Maybe next week I will clean up the code, and add the functions to actually WRITE TO the device.  That's a little harder because I need to read some data from the (Clean) bin file, generate the address and checksum and embed it into the command.  Not too challenging, but if you get it wrong you will write weird shit to weird places and there's no need to risk it right now.

And last, but not least: The bin files!  I assume that in some time, someone will complain and I'll have to take them down.  And essentially, it's less than ten seconds to dump your own so why ask me for mine?  But I'd like to see the bin's of any other wifi finders you happen to have (Like the Allnet, Linksys, or ConnecTec), or versions other than what is here so for the moment: I share, and ask you to do the same.

Trendnet V1.0.3.59 Full 64k Dump

ZyXel V1.1.1.64 Full 64k Dump

Trend 10359 Hackaday Vanity ROM (No Functional Change)  This is the standard Trend (Soccer version) ROM with the text string "Self Testing" Overwritten with "Hackaday 1-21-08" in order to commemorate the honor.  Well, really it's just a way to prove that there is no internal checksum on ROM, at least not in low memory.  So feel free to add your own routines or take over the self test routine.


Update: 1-21-08

Since the project was now posted on Hackaday.com, we were getting deluged with requests for a read/write program for the WHFX30.  Great minds must really think alike, because between replying to emails stirred up from the post we were working on the erase/rewrite routines in the talker program.  It's now working well and available above in the Dumper section. 

But with all good news comes bad news: The ZyXel device with the hole in it suffered a bad programming while we were debugging the write routines and the boot vector was not restored.  So now, we can't get into the ISP loader because the boot vector is pointing to 0000h instead of FC00h.  Damn!  We're attempting to erase it with huge (hours so far) doses of UV light - we'll let you know if it works but the metal fill patterns on the chip seems to be blocking the light so erasing will either be slow, or not work at all.  Maybe we can return it...  Does anyone know if etching a hole in a chip and screwing up the flash memory voids the warranty?  :-)

But we learned a lot, and we've successfully flashed the Trend device to it's own ROM, the ZyXel ROM, the Hackaday ROM, and a ROM that takes over the Self-Test routine in order to send stuff to the serial port.  All-in-all, it's going great and we're happy to know that the device doesn't mind us putting our own code into it's empty space.  Hint: There's a nice 2k block at 0x2B09 and acres of room up at 0x8100 but we've not yet tried to put any code up at 0x8100.

The talker program now has a crude manual explaining it's functions, and includes HEX2BIN so you can take .HEX files from your compiler and convert to .BIN for programming.  Cheers!

 

Update: 1-25-08

I've finally completed one of the first tasks I set about on: Using disassembly of the entire 64k ROM to decipher how to talk to the software bootloader.  It's actually quite easy, we use our RS232 board to chat with the device simply when it is in "Firmware Upgrade Mode" - no need to short J1 to enter the ISP loader.  I had often tried to talk to the software bootloader but thought it was just spewing garbage.  NOPE, that garbage is the actual communications it uses!  Try it: power up in firmware upgrade mode with your COM port at 115,200 8n1.  You'll see something like:

¦¦¦¦¦¦¦¦§§§§§§§§

Upon power up into Firmware Upgrade Mode, the finder sends 8 0x00 bytes to say it's alive.  Then it sends 8 0xA6 bytes to indicate it's about to erase 0xC000 block for scratchpad use.  Then 8 0xA7 bytes once the erasing is done.  Finally, you reach the command interpreter at 0x571 where it sends 8 0x11 bytes.  If it gets a bad command, it sends the 0x11's again, otherwise it continues on.

Once we get the 8 0x11's, we must send the two bytes 0xAA, 0x77 as some sort of password to get a command accepted.  Then we send the command byte.  Some interesting ones are: 0x5A - Erase the memory at 0x4000.  0xA5 - Recieve a new ROM file for programming.    There are more, but you have to look at the disassembly to figure them all out.  Maybe I'll post my notes sometime but they are too messy now. 

Since we really just want to upload ROMs, let's focus on the 0xA5 command.  Once the 0xA5 is sent, the bootloader replies with 8 0xA5's back to us and is then ready for byte-wise recieving to scratch pad EEPROM at 0xC000.  The communication is at 115,200 baud so we can just stream it from the PC to the bootloader.  If the checksum is good and the file has the correct UMDA header, the bootloader then erases the working finder routine at 0x4000-0x7FFF and copies the new finder ROM from the 0xC0000 block to the 0x4000 block.  It takes a few moments, but soon the LCD will be updated with the new ROM version and waits for you to hit a key before jumping to the finder.

Very safe, very inefficient.  Sadly since the EEPROM blocks are 16k each, we really limit ourselves using this routine.  You're not advised to erase a block of EEPROM with running code, obviously.  And we don't want to overwrite our finder until we know the new one is good, so we are left with the following memory management.

0x0000-0x3FFF:  Bootloader and Self Test - things that are never changed

0x4000-0x7FFF: The finder routine

0x8000-0xBFFF: I THOUGHT this was the finder, but it seems to be dead space maybe?  Perhaps it has cool functions we don't know about.  By interrupting different parts of the bootloader and then looking at the full 64k dump, I'm sure we can determine how it's used. 

0xC000-0xFFFF: Scratch pad EEPROM for storage of the new uploaded ROM.  We check it here before overwriting our working finder to ensure no screwups.

 

OK that's all for now.  Here is the software for uploading firmware via the software bootloader (Firmware Upgrade Mode) using RS232.  Read the enclosed howto for more information.  This program can either upload a raw 16k dump extracted from a 64k dump, or it can take the proper 16k block out of a 32k BIN file from one of the original firmware updaters. So yes, you can downgrade or change your version to any ROM you happen to have around, from any manufacturer.  But will they work?  Nobody knows but you!                   PS: USB is hopefully Coming Soon!

RS232 Firmware Upgrader  v1.0

 

Update: 2-4-08

As mentioned, here are the .ASM and .BIN files for the boot vector repair ROM.  You can use this assembly file as a generic framework for a "Finder Replacement".  It is uploaded through firmware upgrade mode, and therefore resides at 0x4000.  The firmware upgrade mode at 0x0000 is not changed, so feel free to put anything you want at 0x4000.  This code is executed any time you power up with no buttons held.  So in our case, the ZyXel device had it's BV cleared to 0x0000 and could not enter the ISP loader.  It would boot up, attempt to run the code at 0x4000 (but the device was completely blank up there) so after pitching an error it would start the firmware upgrade mode.  We uploaded this ROM to 0x4000 so once we powered up, the BV (boot vector) and SB (status byte) would be erased using our software and then BV would be re-programmed to the default of 0xFC.  And Presto: The ISP loader is again enabled when J4-J1 are shorted. 

We had a lot of requests for SOME sort of asm file that people could use as the start of their own framework, so enjoy!  We'll continue to add routines to our assembly file in case you'd like to try things such as accessing the serial port or printing to the LCD in your code.  At the moment, the assembly is still a bit crude:  We wanted to upload the file asap so others could get started, and making the file pretty is a second priority.  It will be cleaned up a bit soon enough, probably when we add some more routines to it. 

 

Update: 2-18-08

From our oscilloscope traces, we have investigated the startup sequence of the device and how the data is uploaded from WHFX to ZD1211.  Upon power-up when detached from the PC, the WHFX initiates a scan and waits for 0xCC to be transmitted by the ZD1211.  Upon receipt of the 0xCC, the WHFX then uploads 768 bytes from code EEPROM (starting at location 0x7C60 in the trend dump) to the ZD1211.  After receipt of the upload, the ZD1211 begins sending 128-byte scan packets.  After receipt of each packet, or to acknowledge the start of a new send, the WHFX sends an 0xEE byte to the ZD1211.  These scan packets consist of the sequence 0xAA, 0x00, then the channel as the next byte, and continue with the data.  It appears that some packets are sent multiple times, with slightly different data in the last 16-17 bytes.  We are investigating the WHFX30 source code to help us decode the scanning packets and determine the format of all of the data.  We have also been toying with the idea of an in-system debugger to read out the WHFX memory during scanning but have not completed the source code for the debugger hex file.

As a side note, our investigations of the ZD1211 have taken us again and again to the Linux development of a ZD1211 driver.  USB traces of hot-plugging the device shows us that basically the same bin file is uploaded by the PC that is typically stored in the ZD device and can be seen in the vendor's firmware upgrade files.  About 80% of this bin file is identical to the original Zydas firmware blob (zd1211_ub) that was provided to the Linux guys eons ago.  There has only been a small amount of ZD1211 disassembly done by some of the leaders of that development team, but it gives us a good start in determining what the differences are between a typical wifi USB stick and the hotspot finder:  IE - being commanded by the WHFX to scan, and the output of data to the serial port.  Both of these are items we are deeply interested in, so if you are interested in experimenting on the ZD1211 side you are welcome to contribute here as well. 

 

Update: 2-19-08

In a stroke of madness, it was proposed that perhaps the ZD1211 may just be acting as a receiver for the WHFX30.  Now that would be too easy, wouldn't it?  We don't think that this is exactly the case, but those 128-byte packets received by the WHFX30 during scanning are basically 802.11 frames.  We will assume that you either understand 802.11 frames, or are willing to go search and learn about them - the continuing discussion will refer to the typical components of frames without explanation.  There seems to be a little formatting done by the ZD1211, but for the most part the entire probe response packet is sent from the ZD1211 to the WHFX.  For example: Once the scan has begun, the start of a typical packet may look like

AA 00 01 ?? ?? NN NN NN NN NN NN SS SS TT TT TT TT TT TT TT TT 64 00 CC CC .......

Where AA xx yy is the preamble, yy being the channel number

?? ?? is not yet known, perhaps signal strength

NN... is the BSSID of the hotspot

SS is the sequence ID

TT..  is the timestamp

64 00 is 100ms timeout, as defined by our scan

CC CC is capability

The packet continues with SSID, supported rates, channel, ERP, Extended rates, and so on

Basically an entire probe request response is bundled up and sent to the WHFX30 for decoding.  Once this request is processed, the WHFX sends an EE byte the the ZD1211 to fetch the next one.

Now - even more interesting is the fact that the framework of the probe requests are stored in WHFX EEPROM and sent to the ZD1211 during that 768 byte data upload at the start of scanning.  There are two complete 64-byte probe requests (with different rates) stored in the EEPROM.  In the 64k trend dump, the first one is located at 0x7CC7 and begins with 40 00 3A 01.  Next comes the "All BSSID" mask of 6x FF's, and a very bizarre fake MAC address of 00 01 23 45 67 89.  NOTE: To hardcode a generic MAC address kind of seems like a bad idea to me, as two users could easily be scanning in the same room - they will be receiving each other's responses!  But the diligent ZD1211 probes with this fake MAC as well as receives all probe requests to the fake MAC.  Makes you wonder what else it may receive if some other device happens to be churning out fake requests with this MAC address.

So the scanning mysteries are getting more clear: Our probe request packet is sent out by the ZD1211, and the responses are passed back to the WHFX30 for interpretation and display.  It's cool to see actual wifi packets being passed back and forth between the chips - the dumber the ZD1211 is, the better for us.

We are now adding a new goal (although a difficult one, we think).  Determine what the rest of the ZD1211 upload data is!  We can disassemble the finder all we want, but basically we can do anything we please once we've got the two chips talking.  There has been a little talk of a firmware to simply dump the packets to screen, but we're still deciding if it's interesting enough to put our time into.

 

Update: 3-15-08

It is true, we have been mysteriously silent for a few weeks as members take care of other priorities and projects.  But that is not to say there has not been progress!  And as was mentioned above, we plan to resume in full force as soon as we are able.  For those wondering if they can still join in the fun - absolutely!  New members are always welcome and can ensure the progress is not slowed as one or two need to finish off other commitments.  Now on to the news:

We are convinced that the ZD1211 is following a very simple routine during scanning mode.  It consists of sending the pre-formed packet that was uploaded by the WHFX30 with a few modifications such as channel number, etc.  The ZD1211 is receiving data on the bogus MAC address of 00 01 23 45 67 89, rather than the unique MAC of the device.  This is great news for us, as it proves that we don't have to have any prior knowledge of the unique MAC, as well as it indicates that there is a "backdoor" in the ZD1211 that will pass any nonsense packets back and forth using this bogus MAC.  You can change the bogus MAC address located at 0x7CCB (0x3CCB in the 16k finder block) and the ZD1211 will happily transmit using this new bogus MAC although it will not accept packets back unless they are intended for the 00 01 23 45 67 89 MAC. 

So one of our new tasks is to get the ZD1211 into promiscuous mode by modifying the RX filter to FF .. . FF.  That simple task should prove the device can be successfully set to promiscuous mode as it will then act as a finder no matter what MAC address we are using.  Our second task (the one we have been spending the most time on) is to modify the packet to interesting types OTHER than probe request.   Of course, we tried to set it to an ARP request just for fun but the ZD1211 is still sending the hardcoded 32 bytes instead of the full length of the ARP request.  This aside, the short ARP request is indeed successfully transmitted as we are able to receive it on a separate PC running wireshark.  Fixing the packet length will require some tweaking, but this testing proves the potential of using the ZD1211 to blindly send and receive anything we like.  Now the real fun begins!

In addition, we are releasing the WHFX30 EEPROM Picture Viewer program.  This is a little tool that you can use to look at the bitmaps stored in the EEPROM bin files.  It is pre-set to open the "Hotspot Finder" image stored in the FCC bin file, but will work with any EEPROM bin file.

We are also releasing a slightly modified version of ZD1211 disassembler by Daniel Drake.  The original version (Get it here) does not read the file in binary mode and only partially disassembles the file.  Some aesthetic changes were made as well as hacking to get the C to compile under XP, but the code is basically all Daniel's and we do not take credit for it.

 

Update: 4-2-08

I'm sure you are all as suspicious as we are of that little 24LC64 serial EEPROM that is mounted on the ZD1211 board.  It of course, holds the ZD1211 software and is an obvious next stage of our attack.  Armed with the ZD1211 disassembler from above, we began poking about in this little chip to see the guts of how the ZD1211 is making these beacon packets.

First, we desoldered the 24LC64 and re-soldered it to a PCB for readout in our EPROM burner.  Not surprisingly, the dump of this chip is the same dump that is created using the vendor software to "Read EEPROM".  By carefully soldering in a socket to the 24LC64 pads on the ZD1211 PCB, we've created a general purpose development kit for experimentation with the ZD1211.  Lucky for us, the first four pins (the address pins, and ground pin) are all grounded so we simply soldered one whole side of our socket to the ground plane that exists on the PCB.  The other four pads were connected to the socket using very fine enamelled wire.  You will note that since we rotated the direction of the IC, we had to re-route the four wires so the top most wire on the socket (pin 8) goes to the bottom most pad of the PCB.  Check it out in this pic.

 

Fig 6 - Socket installed in the ZD1211 board.

 

The next task we started was to attempt to explain/debug the vendor USB updater.  By writing the new serial EEPROM with our EEPROM burner, we were able to downgrade the ZD1211 to several other versions (generously donated by members of the mailing list - thanks all!) of the ZD1211 software.  Keep sending those EEPROM dumps if you have them, the more the merrier!  But alas, we come down to the same conclusion:  Serial EEPROM can be read, but not written, using the vendor updater. 

The saga continues!  We now attempt to go deeper in debugging this faulty communication using LIBUSB.  By faking our VID/PID in a LIBUSB Drivers setup file, we can force the hotspot finder to use LIBUSB as it's driver.  That allows easy communications with the device at a pretty low level of USB communication.  We are currently able to duplicate the EEPROM read of the vendor software using LIBUSB, but duplicating the "write" portion gets us the same fail the vendor software gets: Output to /dev/null or something because the ZD1211 happily takes the data, but is unable to write it to the EEPROM.  All is not lost, as we have found that Daniel Drake's memtool is using a slightly different set of "passwords" in setting up an EEPROM write.  In fact, he uses an altogether different approach of writing some data to the ZD1211 RAM and then transferring it to the EEPROM using DMA.  Quite clever we feel, and this is probably the best way to use the USB connection to update both the 24LC64 serial EEPROM as well as the WHFX30 EEPROM.  For the WHFX30, the USB communication is even a bit more complex but not unreasonable.  You can see all the details in a combination of the disassembly of the vendor updater and the source code of Daniel Drake's memtool.  So that is where we are at: Busy getting prepared for a long trip, but gathering all the tools together for a massive hack session on board a 777.  So get your copies of LIBUSB and start poking around!  You can ask questions on the mailing list, and we will send out your question and our reply if it is relevant. 

Continued...  It is now 4-4-08, and we have corrected the problems with using Daniel Drake's memtool in windows.  Most of the issues seem to be with minor discrepancies between the linux and windows versions of libusb., as well as discrepancies between gcc and bloodshed dev-c++.  You can get Bloodshed Free C++ IDE for windows here.   We are releasing the source and compiled binary of winmemtool for your experimentation, including a ready-to-go bloodshed project file.   Writing to EEPROM works!  At the moment, we are only writing the header information (VID/PID in original memtool) but it is a great example of using non-vendor drivers to access both the ZD1211 and furthermore, the 24LC64.

To use winmemtool, you first need to switch from using the vendor drivers to using LIBUSB drivers.  So after uncompressing the LIBUSB drivers file from above (and changing the VID/PID in the .inf file if needed) you would simply go to device manager, select the hotspot finder and choose update driver.  Tell it not to search, you will choose the driver.  Select the driver yourself, and at the "Have Disk" option, browse to the .inf file from LIBUSB.  When your finder is re-installed as LIBUSB, it will not act as a wifi card but as a generic LIBUSB device.  We only want the LIBUSB drivers so we can hack at the device using memtool.  To revert back to the original drivers you will need to go back through device manager but this time just select the old driver from the list - there is no need to search for it using "Have Disk" as it will be stored by Win and listed for your easy selection. 

A very interesting fact is that the undocumented zd1211b_uphr is required for memtool's command interpretation.  The commands fail if this old ZyDAS firmware blob is not updated.  Although we were unable to get any information about the differences between uphr and the other ZyDAS firmware images, we are slowly merging together the efforts of the linux developers (who already have monitor mode access) and our own efforts.  So study up, and we will let you know our new progress soon!

 

 


To-Do List (In order of priority):

1) Determine the function of all data uploaded to ZD1211 at the start of scan.  At the moment, we have 103 unknown bytes, then two obvious probe request packets of 64 bytes each.  After the probe request packets comes more unknown data.  Is it commands?  Configuration data?  Who knows!?  It will be interesting to find out.

1) Extend the VB prog to read and write.  Maybe block-by-block would be cool, but main necessity is to write the entire EEPROM from a bin file (or .HEX file) as you'd get from a compiler.

DONE!  Talker v2 can now read, erase, and reprogram your device.  Time to fire up those assemblers and get to it!  Also, Loader v1.0 can load the 16k finder ROM located at 0x4000 from either a firmware upgrade file, or a 16k bin file.

0) Load our own code into different areas to determine if the WHFX30 minds when we add onto it's capabilities. 

DONE! The safest place to put large amounts of code is the 0x8000 block, and access is most straightforward when trapping right after the memory clear routine at either 0x0100 in the firmware upgrade routine or 0x4020 in the finder routine.  Inside the finder routine, there are only about 1400 bytes available (I know, not much) at location 0x4070.  But the 0x8000 block still looks fine (only available with ISP Loader): Unless we command the device to erase the 0x8000 block in the firmware upgrade mode, we are safe putting up to 16k of code here.  The 0xC000 block is still off limits as it is erased automatically upon entry into the firmware upgrade mode, to be used later as scratchpad memory.

2) Discover the secrets of the ZD1211, and determine if/how it would be possible to talk to a wifi station via the serial port from the WHFX30.  I guess this project is a bust if that's not possible, but I still have one more idea on some nefarious purposes for this device even if the 8051 is just a dumb listener.  wink wink!

3) Continue the disassembly of the full dump in order to recreate it in an .ASM file.  At the beginning, it's probably allowable to leave some stuff as unknown .DB, but we need the ability to add little patches here and there to extend the capabilities of this device.

4) Add INI capabilities to the talker program, so you don't have to keep changing settings from the default.

4) Figure out how to completely erase a device with a bad boot vector.  I suspect UV will do it, but so far: No luck

DONE!  Since our device had partial ROM already programmed, we had acess to firmware upgrade mode.  By uploading a small ROM to fix the boot vector, we restored the ZyXel device to normal operation.  No amount of UV worked for us due to the metal shielding.  Or maybe our UV (EEPROM Eraser) was simply too weak.

 

So if you want to help, you are more than welcome.  Email again is: wifi at openschemes.  Do I really need to add the dot com?  I doubt it, you're all smart folks.  I'd appreciate any assistance or info you could contribute to the project.  So good luck and happy hacking!

More to come soon, stay tuned!

Back to Openschemes Projects

 

(c) 2008, Openschemes