Do NOT install KB2724197, KB2732488 and KB2707511 on Windows XP
It recently came to my attention that some Windows Update in July ruined EMS Support in the NTVDM DOS Virtual machine in Windows XP resulting in the loss of High Memory Support in DOS. As Microsoft still didn’t fix this really severe issue, I want to warn you about these patches and advise you to NOT install them.
KB2707511 causes a problem, so that NTVDM crashes, if a DOS/Win16 Appliction tries to interface with named pipes or to change the video mode. KB2732488, which gets prepended to KB2724197 tries to fix the problem but with that, it ruins high memory and EMS support and therefore causes even more trouble for the user.
You can check yourself if you are affected by issuing a
mem /C
in the command shell. If you don’t see high memory support, it’s likely that you are affected by the bad updates and should remove them.
Building a fully-featured D-Link DCS-2130 Firmware
After my previous adventures with firmware unpacking, I decided to take a closer look at the DCS-2130 IP camera that I have. I looked for a way to extend the camera’s firmware to allow streaming in .flv format. I don’t know if I can accomplish this and have time for it, but as a first step, I wanted to build my own firmware, as D-Link thankfully offered GPL-sources for it.
However these sources are hard to get as download nearly always aborts after approx. 500 MB. Thankfully, this fella was so kind to mirror the firmware on his FTP, so that I was able to download it.
After having a closer look at the sources, I saw that they were nearly complete, so one should be able to modify and extend the firmware, as it really compiles to a full image. The NIPCA-Streaming services and other things are directly built into the boa HTTP server (look at DCS-2130/apps/public/boa-0.94.13/src).
When I tried to compile the firmware, I noticed that the mtdutils supplied didn’t compile because of some missing acl.h header file. I fixed the problem by editing the Makefile and adding -DWITHOUT_XATTR to the CPPFLAGS.
Now I was able to complie the firmware, but I noticed, that it just shipped with a firmware upload page, not with the real D-Link webinterface. This isn’t really dramatic, as all NIPCA-Services are directly built into the boa HTTP server, but what if you want to use the original webinterface as a starting point for your extensions?
So I had a look at their original firmware file, as I thought that I may be able to extract it from there. Unfortunately it was crypted (I don’t know why they are doing this…)!
But as the GPL firmware toolkit was able to build such a crypted image, I examined the host_mkfm tool from the firmware/ subdirectory, which creates the firmware images. From the firmware.conf file in this directory, I learned, that the firmware image consists of multiple sections with a certain section type (AUTO, JFFS2, YAFFS or NONE).
I disassembled the host_mkfm utility and checked the routines for creating the firmware image. It seems that they are using a vernam-chiffre with one-time-pads hardcoded into the file for encryption. The encryption works on WORDs (=2 bytes). They have 3 tables of variable length that they are iterating through and XORing the contents of each of them. This value then gets XORed with a special scramble-value (random seed) which can differ between the firmware files. It can be passed to the utility via the -s parameter. There is another parameter, the so-called machine_code which can also be passed to the utility via -m. Per default, both the values are 0x2021.
After XORing it with this machine code, it’s finally XORed with the respective WORD in the firmware to be scrambled.
A firmware has a 16byte header, which consists of a 4byte Signature (also seems to differ for various firmware versions, for this firmware, it’s 0xAA7EC55B), followed by 4 bytes that specify the size. Then there are 2 bytes for a checksum, 2 bytes for the scramble value mentioned above, some unknown 2 byte value and finally 2 bytes for the machine_code.
As the header contains the encryption parameters scramble and machine_code, it’s encoded differently: It’s just XORed with the word that is at the machine_code position in the header. If there is a 0 at this position, it’s XORed with the default 0x2021. After decrypting the header, you can decode the rest of the file using the algorithm I described.
After the file is decrypted, you can parse its contents. As mentioned above, it is divided into multiple sections. The file starts with a section list where each entry has a total of 64 bytes. Each section header starts with a 0xA55A signature. The next byte is the mtd specified in the firmware.conf file. The next byte is specifying the section type (see my list if section types above). The next 4 bytes specify the size of the section. The next 4 bytes specify the offset mentioned in the firmware.conf in 16k blocks. The rest of the section header is probably unused and usually padded with nulls.
Armed with this knowledge I gathered from reverse-engineering the utility, I was able to write my own unpacker for their firmware: decode_fw.c
The next challenge was to be able to mount the JFFS2 file system image. I found a shellscript on the maemo-page which did the job (but only the kernel-memory version works, the block device version results in garbled images). I modified the script a bit and it works: mount_jffs2.sh
Create an fs-Subdirectory and mount the image with
./mount_jffs2.sh <Imagename>.
Be sure to unmount the image correctly with
./mount_jffs2.sh <Imagename> unmount
after you are done, don’t just use umount!
So now I was able to extract the original D-Link webinterface. The firmware installer usually copies the stuff from apps/fs/www.7315 to firmware/www, then packs it into www.jffs2 and the firmware packager host_mkfm then creates a section for it in the firmware image according the the firmware.conf file. Therefore the contents of the mounted jffs2-image need to be put into apps/fs/www.7315
Unfortunately the Makefile doesn’t do a recursive copy and the original image contains a subdirectory, so I also needed to modify the cp to cp -r in the www.7315: section of the ~/gpl/DCS-2130/apps/fs/Makefile
Now that I fixed that, I was finally able to build my own firmware image using the original D-Link webinterface. But I didn’t dare to flash it into my device yet, so use it at your own risk!
I wrote a little shellscript that should do most of the work described here, to make it easier for you: build_2130.sh.txt
After this journey into firmware modding, I examined a lot of D-Link and TRENDnet firmwares and made unpacker scripts for them. It’s interesting the TRENDnet and D-Link cameras are mostly based on the same development systems, so the table may also be an interesting comparison between the models of the 2 manufacturers.
I published the table and my unpacker scripts at http://dose.0wnz.at/ipcams/
Have fun!
I’d love to hear from your unpacking experiences in the comments section. Have fun!
Unpacking Trendnet IP camera firmware
Auch wenn ich normalerweise meine Blog-Einträge auf Deutsch schreibe, so werde ich diesen Artikel ausnahmsweise in Englisch verfassen, da er möglicherweise auch für andere Leute interessant sein könnte:
Recently, I had a little project which involved video streaming from IP cameras. I checked various cameramodels whether they suit my needs. So I also tried to check their linux-based firmware and find out how the cameras are working.
The cameras I evaluated can be controlled by the NIPCA API.
I found some interesting blogs that deal with some Trendnet camera models, i.e.:
http://hackingthetrendnet312w.blogspot.co.at/
This blog describes how you can compile your own programs for the Trendnet 312W and how to even modify the image using overlays. Great read!
Another interesting blog entry deals with the D-Link 2121 which also seems
to be based on the same subsystem exposing the NIPCA API:
http://newsoft-tech.blogspot.co.at/2010/09/d-link-dcs-2121-and-state-of-embedded.html
As for me, I wanted to unpack the firmware of a Trendnet TV-IP572PI camera.
As I learned from other firmware reversing sites, there is a nice little utility called binwalk, which analyzed images for potential signtures of emebdded files (i.e. CramFS filesytems etc.). However using binwalk on this firmware image, which you can download from their website, didn’t reveal anything. When I had a look at it, I saw that it containd a shellscript as a loader, which in turn calls an embedded utility called ddPack, like it is also mentioned in the DCS-2121 blog post. This utility basically uses the firmware, which starts after the marker “=== Firmware Boundary ===” in the file.
I found out that the text string in the real firmware image looked “crippled” somehow. After taking a closer look, I realized, that the image is in Big Endian format, so every 32bit doubleword is swapped.
So in order to analyze and unpack it, you first have to swap the bytes in the image first. The dd utility offers an option to swap words, but not doublewords (some versions may have an option for this, however the version shipped with Debian Linux doesn’t have one).
So I wrote a few lines of C-code to swap the image.
After that, binwalk analysis succeeds and finds a gzipped image in it. If you extract and unzip it, you find another gzipped image in the resulting file. If you unzip that one too, you finally end up with a cpio-archive which you can unpack and voilá: Here is the filesystem from the firmware image.
This all also applies to the D-Link DCS-942L camera, which is also based on that firmware.
I wrote a litte shellscript to unpack the firmware: unp_fw_TV-IP572PI.sh
I also have a TV-IP512P available. The firmware in there seems to be easier to unpack, the image isn’t in Big Endian format and just contains a cramfs that you can extract and mount.
Here is the unpacker script for that one: unp_fw_DCS-56×5.sh
I hope that this information is useful to anyone who is messing around with Trendnet camera firmware. For further information about unpacking various camera firmwares, please visit my site about this topic.
LocaleNameToLCID for Windows Mobile
Ich musste heute aus einer Konfigurationsdatei eine Sprachinformation heraus parsen, welche die Sprache der Benutzeroberfläche angibt. Normalerweise benötigt man für sowas ja eine LCID, die Sprache war allerdings als Locale Name (Culture Name) angegeben, also sprich z.B. “de” für Deutsch.
Jetzt gibt es in Windows zwar die Funktion LocaleNameToLCID, diese ist aber erst auf dem Desktop Windows ab Windows Vista verfügbar (bzw. über eine backport-Library auch unter XP), jedoch nicht auf Windows Mobile. Folglich musste ich mir selbst eine simple derartige Funktion schreiben.
Der Code dafür befindet sich hier
Dump Tortoise SVN Passwords
Nach der Migration eines SVN-Repositorys habe ich festgestellt, dass ich leider eines der Passwörter eines Repositorys nicht mehr wusste. Ich hatte es allerdings in meinem lokalen TortoiseSVN gespeichert.
Glücklicherweise gibt es eine Möglichkeit, das Passwort wieder auszulesen.
Folgender Artikel erklärt, wie es geht:
http://stackoverflow.com/questions/3883129/extract-tortoisesvn-saved-password/4794471#4794471
Hier wird auch auf das Programm ” TortoiseSVN Password Decrypter” verwiesen, dies ist jedoch ein Programm, welches auf dem unsäglichne .NET Framework basiert und ist damit für mein System ungeeignet, welches ich von .NET Bloat freihalten möchte.
Ich habe daher beschlossen, die entsprechende Funktionalität selber nachzuprogrammieren. Dies gestaltet sich eigentlich sehr einfach, herausgekommen ist ein schönes, kleines C-Programm. Hier der Source:
http://dose.0wnz.at/scripts/cpp/tscnpwdec.c
EDIT: Auf Wunsch gibts hier auch die kompilierte Version:
Windows Mobile debugger memory exhaustion
Heute hatte ich ein interessantes Problem mit meiner Windows Mobile Applikation. ICh habe es durch fehlerhafte Programmierung geschafft, den Windows Mobile Debugger des Visual Studio 2005 zu crashen.
Das Problem war, dass ich eine Funktion in einer fremden Library mehrfach aufgerufen habe und diese Funktion hat jedesmal einen Thread gestartet. Dadurch habe ich eine riesige Menge Threads generiert. Pro Thread muss der Debugger natürlich Speicher reservieren, was dazu führt, dass ihm der Speicher irgendwann mal ausgeht, wenn da hunderte Threads starten und sich wieder beenden, vorher aber schon wieder neue Threads gestartet werden…
Interessanterweise führte das Ganze aber nicht zu einem OOM, sondern der Debugger stürzte irgendwann mal ab. Hierfür dürfte ein fehlender Check im Debugger-Code von C:\Programme\Microsoft Visual Studio 8\SmartDevices\Debugger\bin\eDE.dll schuld sein (und das trotz installiertem SP1). Der Crash tritt an folgender Stelle auf:
6EDC070E 83C0 08 ADD EAX,8 6EDC0711 3BC7 CMP EAX,EDI 6EDC0713 74 1C JE SHORT eDE.6EDC0731 6EDC0715 8B30 MOV ESI,DWORD PTR DS:[EAX]
EAX = 8, EDI = 0
Wir schließen daraus, dass EAX hier nicht auf 0 geprüft wird sondern nur der Wert auf Offset 8 der Struktur, was schulssendlich zu einem Crash führt. Ich hab das Ganze gefixt, indem ich das ADD EAX, 8 hinter den Check verschoben habe, sodass nun der Zeiger auf 0 gprüft wird (dafür aber der Wert auf Offset 8 nicht mehr). Dies bewirkte immerhin, dass der Debugger nicht mehr crasht, scheinbar ist also doch die Wahrscheinlichkeit höher, dass der Strukturzeiger fehlt:
6EDC070E 3BC7 CMP EAX,EDI 6EDC0710 74 1F JE SHORT eDE.6EDC0731 6EDC0712 83C0 08 ADD EAX,8
Falls also jemand einen Crash in eDE.dll beim Debuggen hat, kann er meinen Patch theoretisch ausprobieren, vielleicht hilft es ja was.
Speed up DecompressImageIndirect
Die Funktion DecompressImageIndirect der imgdecmp.dll kann unter Windows Mobile dazu verwendet werden, um z.B. JPG Bilder als Bitmap zu dekomprimieren.
Über die Funktionsweise dieser undokumentierten Funktion gab z.B. folgender Artikel auf unsupportedsoftware.com Auskunft:
http://www.unsupportedsoftware.com/products/dev/imgdecmp.htm
Leider ist die Seite zumindest derzeit offline (eventuell hat der Eigentümer die Domain nicht verlängert). Ich habe daher ein Backup der ImgDecMP.zip online gestellt, welche auch eine Anleitung zur Verwendung der Funktion beinhaltet.
Was mir aufgefallen ist, und was eventuell ganz interessant sein dürfte, ist, dass die Bibliothek bei jedem Dekomprimierungsvorgang 2 Bibliotheken nachlädt, sofern diese nicht geladen sind, und nach getanener Arbeit wieder entlädt. Dies ist zwar hinsichtlich Speicherverbrauch sehr löblich, birgt jedoch das Problem, dass die Dekomprimierung der Bilder eher langsam läuft. Benötigt man die Funktion also mehr als einmal, so kann es sich lohnen, besagte Bibliotheken beim Programmstart manuell zu laden und so im Speicher zu behalten. In der Initialisierungsphase der Applikation also folgendes laden:
LoadLibrary(_T("Imaging.dll")); LoadLibrary(_T("zlib.dll"));
InitCommonControls() und seine Tücken
Unlängst hatte ich das Problem, dass ich ein Windows-Programm entwickelt habe, welches einige Common Controls verwendet. In alter (16bit) Gewohnheit habe ich die Common Controls mit dem Funktionsaufrauf InitCommonControls() initialisiert.
Mein Programm lief einwandfrei unter Windows XP, aber unter Windows 2000 bekam ich beim Laden eines Dialogs, welcher das SysDateTimePick32 Control nutzte, die Fehlermeldung: “Fensterklasse nicht gefunden”.
In der oben verlinkten Dokumentation zu InitCommonControls() steht bereits die Warnung, dass bei den Controls der Version 5 nur die ICC_WIN95_CLASSES initialisiert werden. In meiner alten MSDN-Version von 1998 war diese Warnung jedoch nicht enthalten.
Folgende Seite bietet eine schöne Aufschlüsselung, was in welcher Windows Version geladen wird:
Also: Wenn möglich, auf 32bit Windows immer InitCommonControlsEx() verwenden und nicht vergessen, die entsprechenden Flags richtig zu setzen.
pure-ftpd logfile Timestamp
Mir ist aufgefallen, dass Pure-ftpd <1.0.22 in seinen Logfiles auf einem unserer Produktivserver die Zeitstempel immer in UTC angegeben hat, statt in der lokalen Zeitzone.
Der Grund dafür dürfte sein, dass der Server über xinetd gestartet wurde und innerhalb des Environments keine Zeitzoneneinstellung zu lesen ist, da dieser chrooted ausgeführt wird und daher /etc/localtime nicht gelesen werden kann.
Hierzu habe ich eine Artikel in der Novell Knowledge Base unter der Nummer 7002717 gefunden.
Die Lösung besteht nun darin, das TZ-Environment beim Start über xinetd zu setzen. Hierzu muss man für meine Zeitzone dann folgende Zeile in der xinetd.d Konfigurationsdatei für ure-ftpd hinzufügen:
env = TZ=CET
Vielleicht hilft der Tip ja jemandem, der seinen pure-ftpd auch nciht so einfach updaten kann.