HP Ink Cartridge Expiration Patch

By dose | October 7, 2009
Under: Uncategorized
Comments: 33 Comments »

English-speaking users: Patch instructions are found at the end of the blog post.

Wir haben hier im Büro einen HP Businessjet Farbtintenstrahldrucker, welcher sich vor einigen Tagen plötzlich weigerte zu drucken. Als Statusinformation am Display des Druckers kam: “Tintenpatrone abgelaufen”.
Nach einigen Recherchen in Google fand ich dann eine Beschreibung der Problematik auf dieser Seite von HP.

HP versieht also scheinbar bei einigen seiner Druckermodelle die Tintenpatronen mit einem Chip, auf welchem das Ablaufdatum der Patrone gespeichert wird und wenn man die Patrone länger benutzt als 2 Jahre, dann verweigert der Drucker den Dienst und besteht auf den Tausch der entsprechenden Patrone.
Nachdem es für mich inakzeptabel ist, dass HP mir vorschreiben will, wie lang ich die Patrone benutzen darf, habe ich versucht, das Problem zu analysieren.

Im Internet finden sich etliche Seiten, welche diese Problematik beschreiben, beispielsweise dieser mit reichlichen Kommentaren versehene Blog Eintrag. Viele Leute lösen das Problem auf mechanische Weise, indem sie die Druckerbatterie entfernen und somit den Drucker resetten, was dazu zu führen scheint, dass dieser “vergisst”, dass die PAtrone abgelaufen ist. Auch das Abdecken des Chips der Patrone soll zum Erfolg führen. Der Tip eines Kommentarschreibers, dass man nach dem Einschalten des Druckers einmal mit zurückgestelltem Datum drucken muss und anschließend während der aktuellen Sitzung normal weiterdrucken kann, hat mich auf die Idee gebracht, dass das Ganze wohl auch einfach Softwaretechnisch zu lösen sein muss. Scheinbar bekommt also der Drucker das aktuelle Datum vom Treiber zugesendet und verwendet dies dann für seine Ablaufdatumsberechnung.

Folglich habe ich mir einmal angesehen, was der Druckertreiber dem Drucker so an Informationen sendet, indem ich den Anschlussport des Druckers in den Druckeroptionen auf FILE: umgestellt und mir die Rohdaten angesehen habe. Dabei sticht folgendes PJL Kommando heraus:

@PJL SET TIMESTAMP="20091005153634"

Hier wird also der aktuelle Zeitstempel an den Drucker übertragen und aufgrund von entsprechenden Versuchen mit modifizierten Dumpfiles konnte ich herausfinden, dass der Drucker auch ohne diesem PJL Kommando funktioniert und folglich keinen Fehler beim Drucken mehr anzeigt.
Kleiner Tip am Rande: Man kann dem Drucker Rohdaten senden, indem man den Drucker freigibt, ihn anschließend mittels

net use lpt1 \hostprinter

einem Port zuordnet und anschließend die Rohdaten mit

copy /b rawdump lpt1

sendet. Damit ist einfaches Testen möglich.

Folglich kann man das Problem also am Einfachsten lösen, indem man den Druckertreiber derart modifiziert, dass er den Zeitstempel nicht an den Drucker sendet. Leider ist jeder Druckertreiber anders aufgebaut, sodass dies keine universelle Lösung ist, auch wenn das einfache Überspringen der Kommandoausgabe sicher die “sauberste” Lösung darstellt. Durch weitere Versuche stellte sich jedoch auch heraus, dass der Drucker ungültige PJL-Kommandos stillschweigend ignoriert. Daher kann man also einen universellen Patch bauen, indem man einfach im Druckertreiber nach dem oben genannten PJL-String sucht und diesen leicht modifiziert (z.B. indem man das Schlüsselwort TIMESTAMP in TIMESTAMX ändert - schon erkennt es der Drucker nicht mehr).

Ich habe einen kleinen Patcher gebaut, welcher einige Druckertreiber “kennt” und dort das Senden des TIMESTAMPs einfach überspringt. Für alle HP Druckertreiber, die er nicht kennt, benutzt er die eben erwähnte universelle Methode, indem er einfach den TIMESTAMP-String ändert. Der Patcher kann die von ihm getätigten Änderungen auch wieder rückgängig machen, falls diese zu Problemen führen sollten. Ich hoffe, dass man das Problem damit umgehen kann und jemand den Patcher brauchen kann. 

Instructions for patching:

I have been notified that this patch may not work on other printer models (I can only confirm that it works on my HP Business Inkjet 2300). so I recommend that you first verify if your printer can be tricked by the following procedure:

1) Turn off your printer
2) Set back system date to prior to the printer cartridge expiration date
3) Turn your printer on again
4) Try to print
5) Reset system date to current date

If printing works with these steps then the driver patch should work too. If it doesn’t, there may be some extra safeguards in your printer model. Sorry.
I don’t own other HP printers with expiring cartridges that I can try out, so I can only hope that the trick works for your printer as well.

>> DOWNLOAD PATCH <<

1) Turn off your printer so that the internal date gets reset. At least this works for HP Businessjet.
2) Apply patch and check if at least one printer driver file gets patched.
3) Either restart the spooling service or restart your computer just to be sure that the patched driver DLL gets loaded.
4) Turn on your printer again and see if you can print with the expired cartridge.

Update 07.04.2010: Incorporated deden’s patch into the patcher, maybe this helps for some printer models…

Feedback via Comments is welcome.

Windows XP auf HP pavillon 1200eg

By dose | September 29, 2009
Under: Uncategorized
Comments: 1 Comment »

Heute hat mir mein lieber Cousin einen HP Pavillon 1200eg vorbeigebracht, welcher mit Microsot Windows Vista vorinstalliert ausgeliefert wird. Nachdem Vista ein langsames, ressourcenfressendes  System ist und er gern etwas mehr vom Gerät hätte, wollte er Microsoft Windows XP installieren. Das war aber gar nicht so einfach, da es auf der HP Seite keine XP Treiber zum Download gibt (einzig und allein das Programm zur Tastensteuerung gab es im Downloadbereich für Windows XP). Ich habe mir daher mühsam alle Treiber zusammensuchen und herausfinden müssen, wie man diese zum Laufen bringt (im Falle des Grafikkartentreibers braucht man sogar ein eigenes Patchprogramm, um die Treiber unter XP zum Laufen zu bringen). Und auch bei der Reihenfolge der Soundtreiberinstallation muss man aufpassen.
Lange Rede, kurzer Sinn: Wenn jemand auch so ein Gerät auf Windows XP umrüsten will, hier die notwendigen Schritte und das Treiberpaket zum Download:

 - Treiber aus SATA\ Unterverzeichnis in Windows XP Installationsmedium
   integrieren (z.B. mit nLite o.ä. Tools).
 - Windows XP wie gewohnt installieren
 - Chipsatztreiber aus 9-5_xp32-64_sb.exe installieren.
 - .NET Framework von Microsoft herunterladen und installieren
   (Wird leider von MobilityModder benötigt :-( )
 - 8-12_xp32_dd_ccc_wdm_enu_72271.exe installieren und dabei entpacken
   lassen. Sobald es entpackt ist kann man den Setup schließen, eventuelle
   Fehlermeldung vorerst ignorieren.
 - MobilityModder installieren (MMDotNETSetup.eXE),starten und auf
   Pfad zeigen, in welchen der Treiber entpackt wurde (meistens ein Unter-
   verzeichnis unterhalb von C:\ATI\SUPPORT, sofern C das Systemlaufwerk
   ist. Beispiel: C:\ATI\SUPPORT\8-12_xp32_dd_ccc_wdm_enu_72271),
   anschließend Modifikation starten.
 - Im besagten Verzeichnis nun die SETUP.EXE erneut ausführen, diesmal
   lässt sich der Treiber installieren.
 - Audiotreiber 9-9_xp32-64_hdmiaudio.exe installieren.
 - Audio Codec sp41593.exe installieren.
 - Netzwerkkartentreiber aus RTL8111-NonVista\ installieren.
 - WLAN-Treiber sp42654.exe installieren.
 - HP Quicklaunch-Buttons sp43616.exe installieren.
 - SD-Kartenlesertreiber aus JMB38X_WinDrv_R1.00.29_WHQL\ installieren.
 - Fernbedienungstreiber aus enecir_release_v2_5_1\ installieren.

Das vollständige Treiberpaket gibts hier direkt zum Download.

Debian auf RAID installieren

By dose | September 13, 2009
Under: Uncategorized
Comments: No Comments »

In einem vorherigen Artikel habe ich ja bereits beschrieben, wie man ein bestehendes Debian-System auf RAID1 migriert. Unlängst hatte ich wieder einen neuen Server aufzusetzen, und diesmal wollte ich natürlich gleich bei der Installation ein RAID einrichten. Interessanterweise ist das nichteinmal so trivial, wenn man nicht weiß, was der Installer erwartet, um die Option zum Anlegen eines RAIDs anzubieten. Folgender Blog-Eintrag hat das Ganze zum Glück recht gut beschrieben bzw. auf einen anderen Artikel verlinkt, welcher die einzelnen Schritte beschreibt:

http://lars-schenk.com/installation_debian_etch_auf_einem_software-raid_1_mit_sata_disks/92

Windows Ressourcenproblem

By dose | September 4, 2009
Under: Uncategorized
Comments: No Comments »

Schon seit Jahren ärgere ich mich über folgendes Problem unter Microsoft Windows:

Ich bin ein Benutzer, der viele Anwendungen gleichzeitig offen hat, meine Taskleiste ist oft 3 Zeilen lang. Da ich oft an verschiedenen Sachen arbeite ist es mir angenehm, wenn alle Fenster offen bleiben, sodass ich schnell wechseln kann. Dieser Arbeitsstil scheint Windows aber nicht unbedingt zu gefallen. Mit zunehmender Uptime hat Windows dann scheinbar langsam Probleme bei der Allozierung von GDI-Speicher. Menüzeilen können plötzlich nicht mehr erzeugt werden, Anwendungen stürzen ab, weil nicht geügend Speicher für GDI-Objekte zur Verfügung steht, etc. Besonders markant ist die beim Internet Explorer, wo sich dann keine neuen Fenster mehr öffnen lassen.
Was in diesem Fall meistens hilft ist das Schließen von Anwendungen. Aber leider bringt dies auch nur kurzfristige Abhilfe, weil bald sind die Ressourcen wieder verbraucht und dann gehen die Probleme wieder von vorn los. Im Endeffekt half in so einem Fall längerfristig gesehen nur ein Reboot. Ich habe mich dann immer gewundert, weil ansich noch genügend Hauptspeicher da war (es war garnicht viel ausgelagert) und auch die Anzahl der allozierten GDI-Handles lag durchaus im grünen Bereich.

Nun habe ich heute den Knowledge-Base Artikel KB126962 gelesen, hier steht, wie man die Größe des Desktop-Heaps in der Registry erhöht, um solche Probleme umgehen zu können.  Das löst zwar die Ursache nicht (warum wird scheinbar nicht genug vom Desktop heap freigegeben, obwohl man eh schon etliche Anwendungen geschlossen hat?), aber ist zumindest eine Symptombekämpfung. Ich hoffe mal, dass es was hilft.

Win32 Applikationen mit Bordmitteln debuggen

By dose | September 2, 2009
Under: Uncategorized
Comments: No Comments »

Kürzlich fragte mich jemand, wie man unter Windows mit Bordmitteln einen Memory dump von einem aktiven Prozess erstellen kann. Ich hatte da etwas im Hinterkopf, hab es aber auch nicht mehr genau gewusst. Ich wusste nur, dass es sowas die den guten, alten debug.com von DOS auch für Windows gab. Bin dann schließlich über diesen Blog-Eintrag gestolpert, und nun erinnere ich mich wieder: NTSD heißt der Windows-interne debugger.

Soda, jetzt ist das endlich ein für allemal im Blog festgeschrieben und notiert ; -)

Crack für Monkey Island 1 / Deutsch

By dose | August 22, 2009
Under: Uncategorized
Comments: 8 Comments »

Weil ich gerade so im SCUMM-Debugging drin bin, gibt’s hier auch als Bonus auch gleich einen Patch für Monkey Island 1 / Deutsch. Das Analyseschema ist dasselbe, was schon im vorherigen Post verwendet wurde, allerdings sind hier die Daten in einem LEC-File untergebracht und nicht in den separaten LFL-Files. Ich habe der Einfachheit halber einfach die Bytesequenz gesucht, da ich mir die Analyse der LEC-Files ersparen wollte. Ich habe wieder die Branches bei Erfolg und Fehler untersucht, diesmal sieht das Ergebnis so aus:

Falscher Code eingegeben:
(90:152:0×1BC): Script 152, offset 0×1bc: [3F] o5_drawBox()
(90:152:0×1C8): Script 152, offset 0×1c8: [9A] o5_move()
(90:152:0×1CD): Script 152, offset 0×1cd: [88] o5_isNotEqual()
(90:152:0×1D4): Script 152, offset 0×1d4: [14] o5_print()
(90:152:0×1D9): Script 152, offset 0×1d9: [14] o5_print()
(90:152:0×1E5): Script 152, offset 0×1e5: [AE] o5_wait()

Richtiger Code eingegeben:
(90:152:0×1BC): Script 152, offset 0×1bc: [3F] o5_drawBox()
(90:152:0×1C8): Script 152, offset 0×1c8: [9A] o5_move()
(90:152:0×1CD): Script 152, offset 0×1cd: [88] o5_isNotEqual()
(90:152:0×1F5): Script 152, offset 0×1f5: [14] o5_print()
(90:152:0×1FA): Script 152, offset 0×1fa: [27] o5_stringOps()

Die SCUMM V5-Files von Monkey Island sind nicht mit 0xFF werXORt, wie bei Loom, sondern mit 0×69. Der entsprechende Code befindet sich bei der EGA-Version auf Offset 3EA92 in DISK01.LCK:

3EA90: 6D 29 E1 63 68 DA 69 48 69 7D 96 66 49 69 7D 96

Das Ganze also nun wieder mit 0×69 verXORt ergibt:

3EA90:  04 40 88 0A 01 B3 00 21-00 14 FF 0F 20 00 14 FF

Man hat hier also ein o5_isNotEqual() und ersetzt es wieder durch einen Sprung an den richtigen Offset mittels o5_jumpRelative, welchen man vorher ja aus den 2 Branches berechnen konnte.
Fertig ergibt das dann flgende Modifikationen.

3EA90:  04 40 18 28 00 B3 00 21 00 14 FF 0F-20 00 14 FF

Wieder mit 0×69 verXORn und man hat einen fertigen Patch.
Bei der VGA-Version befinden sich die Bytes übrigens auf Offset 10959A. Noch Fragen?

Crack für LOOM / Deutsch

By dose | August 22, 2009
Under: Uncategorized
Comments: 1 Comment »

Beim Stöbern in meinen alten DOS-Spielen bin ich unlängst wieder auf das bekannte Adventure LOOM gestoßen.  Der “Kopierschutz” des Spiels besteht aus einem Doccheck, also der Abfrage von bestimmten Werten, welche im Handbuch abgedruckt sind.

Nachdem es doch etwas lästig ist, immer im Handbuch nachzuschlagen, wurde mein sportlicher Ehrgeiz geweckt und ich habe mich daher etwas näher mit der SCUMM-Engine beschäftigt. Nachdem der nachgebaute SCUMM-Interpreter SCUMMVM die Handbuchabfrage auch umgeht (zumal der Hersteller dies bei einigen Versionen sogar selbst gemacht hat) habe ich hier eigentlich keine Bedenken, meine Untersuchungsergebnisse zu veröffentlichen.

Mithilfe der SCUMMVM kann man im Debug-Modus die interpretierten VM-Kommandos mitschreiben lassen und bekommt damit ungefähr eine Idee, wo die Abfrage für den Kopierschutz zu finden ist. Zuerst muss SCUMMVM mitgeteilt werden, dass sie den Kopierschutz nicht umgehen soll, sonst wird dieser stillschweigend übersprungen. Dies geschieht mittels des Eintrags copy_protection=true in %APPDATA%\ScummVM\scummvm.ini Danach kann man die Ausgabe von SCUMMvm auf STDOUT in eine Protokolldatei umleiten, indem man scummvm >log.txt startet. Jetzt muss noch der DEBUG-Modus aktiviert werden, damit die Kommandos mitgeschrieben werden. Dies geschieht mit CRTL+D. Auf der Debug-Konsole aktiviert man die Protokollierung mittels debug +opcodes Nun noch ein continue und einmal den falschen Code eingegeben. Analysiert man das Protokoll, so erkennt man folgende Abfrage:

(69:203:0×1670): Script 203, offset 0×1670: [62] o5_stopScript()
(69:203:0×1672): Script 203, offset 0×1672: [2C] o5_cursorCommand()
(69:203:0×1674): Script 203, offset 0×1674: [2C] o5_cursorCommand()
(69:203:0×1676): Script 203, offset 0×1676: [A8] o5_notEqualZero()
(69:203:0×167B): Script 203, offset 0×167b: [46] o5_increment()
(69:203:0×167E): Script 203, offset 0×167e: [48] o5_isEqual()
(69:203:0×1685): Script 203, offset 0×1685: [2A] o5_startScript()

Nun benötigt man noch einen Vergleichswert, was passiert, wenn man den richtigen Code eingibt:

(69:203:0×1670): Script 203, offset 0×1670: [62] o5_stopScript()
(69:203:0×1672): Script 203, offset 0×1672: [2C] o5_cursorCommand()
(69:203:0×1674): Script 203, offset 0×1674: [2C] o5_cursorCommand()
(69:203:0×1676): Script 203, offset 0×1676: [A8] o5_notEqualZero()
(69:203:0×17C3): Script 203, offset 0×17c3: [48] o5_isEqual()
(69:203:0×17CA): Script 203, offset 0×17ca: [2A] o5_startScript()

Offensichtlich wird also an Offset 0×1676 in der Datei 69.lfl auf die Gültigkeit der Eingabe geprüft und dementsprechend erfolgt dann ein Sprung ins Spiel.

Sucht man nun an besagtem Offset die von SCUMMvm gelisteten Kommandos, so wird man nicht wirklich fündig:

166F: 9D 33 D3 FD D3 FB 57 90 72 B7 FE B9 9C FF B7

 Merkwürdig… Des Rätsels Lösung findet sich dann nach einigem Suchen im SCUMMVM Wiki: In der Version V3 OldBundle, welche das Spiel benutzt, sind die Dateien mit 0xFF verXORt. Also einfach mal mit XOR arbeiten, und siehe da:

166F: 62 CC 2C 02 2C 04 A8 6F 8D 48 01 46 63 00

Rot sind hier die einzelnen Kommandos wie oben beschrieben. Wenn also die Variable 6F 8D nicht 0 ist, dann wurde der Code falsch eingegeben und er wiederholt die Abfrage. Das Ziel ist es also, die Variable 6F D8 auf 0 zu setzen und das Spiel anschließend zu starten. Mithilfe der SCUMM Opcodeliste tauscht man nun das o5_notEqualZero gegen ein o5_move und füllt die Variable mit 0. Weiters kann man sich aus den Aufzeichnungen des Vorgangs, bei welchem der Code angenommen wurde, den Offset zum Sprungziel errechnen und entsprechend ein o5_jumpRelative Kommando einfügen, um das Spiel starten zu lassen. Und schon hat man den Kopierschutz “ausgehebelt”.
Gepatcht ergeben sich dann also folgende Opcodes:

166F: 62 CC 2C 02 2C 04 1A 6F 8D 00 00 18 4C 01

Die blauen bytes sind hierbei die geänderten Bytes. Wenn man das Ganze nun noch mit 0xFF verXORt, so hat man dann einen funktionierenden Crack.

Netzwerkverbindungen trennen bei Systemfehler 1219

By dose | August 6, 2009
Under: Uncategorized
Comments: No Comments »

Unter Windows kommt es ja öfters vor, dass man mal schnell über UNC-Pfad auf einen Server zugreift. Da erscheint dann ein Dialog, in welchem man Benutzername und Kennwort angeben soll, um sich am Server zu authentifizieren.

Nun kann es vorkommen, dass, sofern man sich mit einem gültigen Benutzernamen angemeldet hat, man sich auf dem Server mit einem anderen Benutzernamen anmelden will aber Windows zeigt natürlich den Dialog zur Eingabe von Benutzername und Kennwort nicht mehr an, da man sich ja schon mit einem gültigen Konto angemeldet hat.

Nachdem man über einen UNC-Pfad operiert hat gibt es auch keine zugewiesenen Laufwerksbuchstaben für Netzlaufwerke, die man trennen könnte und so endet dann jeder Verscuh, sich mit einem anderen Bentuzernamen anzumelden mit Systemfehler 1219: “Mehrfache Verbindungen zu einem Server oder einer freigegebenen Ressource von demselben Benutzer unter Verwendung mehrerer Benutzernamen sind nicht zulässig.”

Die Lösung ist eigentlich naheliegend, trotzdem habe ich für meinen Teil etwas gebraucht um draufzukommen, nachdem ja kein LAufwerksbuchstabe zugeordnet war. Am Commandprompt:

net use

Das zeigt mal alle Verbindungen an, auch welche ohne Laufwerksbuchstabe nur mit UNC-Pfad (Steht in der Spalte Remote). Für jede Verbindung dann einfach ausführen:

net use [UNC-Pfad] /delete

und schon kann man sich mit dem Server wieder neu verbinden.

Windows XP in Terminalserver verwandeln

By dose | May 5, 2009
Under: Uncategorized
Comments: No Comments »

Bin neulich zufällig über folgenden Link gestolpert. Ist zwar nicht wirklich legal, aber eine interessante Möglichkeit:

http://deepxw.blogspot.com/2009/04/universal-termsrvdll-patch.html

Damit kann man die Remotedesktop-Funktionen von Windows XP besser nutzen. Und so gaaanz illegal ist es ja nun auch nicht, denn Microsoft hat in der frühen Beta von Windows XP SP2 die Beschränkung auf eine Verbindung schonmal aufgehoben gehabt. Aber das ist eine andere Geschichte…

Überschreitung der Maximalen Pfadlänge und Explorer

By dose | April 28, 2009
Under: technical stuff
Comments: No Comments »

Heute hatte ich bei einem Kunden einen interessanten Fall:
Dieser hatte in seinem “Eigene Bilder” Verzeichnis in verschiedneen Unterverzeichnissen Bilddateien abgespeichert.

In einigen Unterordnern wurde bei Bildern kein Vorschaubild angezeigt. Weiters gab es keine Möglichkeit, die Datei umzubenennen (Beep bei F2), auch kopieren, ausschneiden, verschieben usw. war nicht möglich. Im Kontextmenü fehlte ebenfalls der Menüpunkt “Eigenschaften”. Öffnen der Datei war natürlich auch nicht möglich, weder mit Doppelklick noch mit “öffnen”.
In der Eingabeaufforderung wurde die Datei mit dem dir Kommando angezeigt, bei attrib jedoch nicht. cacls * stoppte bei der ersten problematischen Datei mit einer Fehlermeldung.
Versuchte man im “Öffnen”-Dialog einer Applikation, die Datei zu öffnen, so wurde vermeldet, dass diese nicht gefunden werden kann.

Ein chkdsk lieferte keine Probleme im Dateisystem.
Beim Vergleich der funktionierenden und nicht funktionierenden Dateien fiel mir auf, dass nur Dateien mit relativ langen Dateinamen betroffen waren. Der Ordner, in dem die Dateien gespeichert waren, hatte ebenfalls einen relativ langen Nnamen. Als Programmierer fiel mir aufgrund dieser Gemeinsamkeiten dann irgendwann die MAX_PATH Konstante ein. Die gibt die maximale Länge eines Verzeichniseintrags, aber gleichzeitig auch die Maximallänge eines Pfades an! Nimmt man nun den tatsächlichen Pfad zum Eigene Dateien Verzeichnis und die Ordnernamen zusammen, so wurde die maximale Pfadlänge überschritten und damit funktionierte das Ganze dann nicht mehr, was zu den merkwürdigen Symptomen führte. Die Probe aufs Exempel: Kürzung des Ordnernamens (Dateiname kann ja nicht editiert werden bei Überschreitung): Siehe da, plötzlich konnte man die Dateien wieder verwenden.

Also: Falls die oben genannten Symtome auftreten, einfach mal die Pfadlänge prüfen.