Die Implementierung von Hersteller "X"

Vor einiger Zeit habe ich die Implementierungen der Funktion XpressDecode im NTLDR von Windows XP mit der des Sandman Projekts verglichen. Ich fand damals etliche Unterschiede. Aber da gibt es auch noch eine dritte Implementierung in einer bekannten kommerziellen Forensik-Software. Dieses Programm wurde im März 2008 veröffentlicht, etwa einen Monat später als der Sandman. Betrachten wir dieses Programm also einmal etwas genauer.

Wie schon mit den beiden anderen Implementierungen, so habe ich auch dieses Programm in IDA Pro disassembliert und dann sorgfältig in einen C-artigen Pseudo-Code überführt. Nun könnte ich die Implementierung von Microsoft mit der des Herstellers "X" vergleichen. Allerdings müsste ich dann die umfangreiche Untersuchung wiederholen. Schneller geht es, wenn man nur den rekonstruierten Sandman Code mit dem aus dem Hause "X" vergleicht. Hier sind die Unterschiede:

Nr. 1: In einigen komplexen Bedingungen wird aus dem Term
(Size1 == CompressedBlockSize)
der folgende
(CompressedBlockSize == Size1)
und
(Size1 == CompressedBlockSize)
wird zu
(CompressedBlockSize > Size1)

Offensichtlich wurden die beiden Seiten der (Un-)Gleichung vertauscht. Das kann auf eine unterschiedliche Notierung im Quelltext hindeuten. Andererseits wurde das Programm des Sandman-Projekts mit Visual Studio 2005 übersetzt, während Hersteller "X" einen Borland-Compiler einsetzt. Dieser kleine Unterschied ist also möglicherweise auch auf die "Handschrift" oder den "Stil" der beiden recht unterschiedlichen Compiler zurückzuführen. Ein funktionaler Unterschied ergibt sich daraus jedenfalls nicht.

Nr. 2: Nun werden einige Berechnungen angestellt. Zunächst wieder Sandman:
DecodeData.BufferLimit = DestinationBuffer + Size1;
DecodeData.CompressedBlockSize1 = CompressedBlockSize - 1;
DecodeData.CompressedBlockSize3 = CompressedBlockSize - 1;

und jetzt Hersteller "X"

DecodeData.BufferLimit = Size1 + DestinationBuffer;
tmp1 = CompressedBlockSize - 1;
DecodeData.CompressedBlockSize1 = tmp1;
DecodeData.CompressedBlockSize3 = tmp1;

In der zweiten Variante hat der Compiler einige CPU-Zyklen eingespart, indem er das Zwischenergebnis für eine spätere Verwendung in einem Register speichert.

Nr. 3: Und nochmal einige Berechnungen. Zuerst Sandman
if ((CompressedBlockSize + BlockEntry - DefaultOffset) > 0xe8)
   ...
   DecodeData.AdjustedPadding = CompressedBlockSize + BlockEntry - 0xe8;

und jetzt wieder Hersteller "X"

tmp2 = BlockEntry + CompressedBlockSize;
if ((tmp2 - DefaultOffset) > 0xe8)
   ...
   DecodeData.AdjustedPadding = tmp2 - 0xe8;

Abermals optimiert in der zweiten Variante der Compiler den Code etwas.

Um es zusammenzufassen: alle drei Unterschiede sind nur kosmetischer Natur, beeinflussen nicht das Ergebnis und sind höchstwahrscheinlich die Folge von Optimierungen der jeweiligen Compiler. Es gibt also keine funktionalen Unterschiede zwischen den Implementierungen des Sandman-Projekts und von Hersteller "X".

Wie ich aber bereits in einem früheren Beitrag gezeigt habe, enthält die Implementierung des Sandman-Projekts gegenüber dem Originalcode ein Dutzend Abweichungen und Fehler. Offensichtlich enthält das kommerzielle Programm genau die selben Fehler wie die Open-Source Software.

Archiv

Impressum

Dieses Blog ist ein Projekt von:
Andreas Schuster
Im Äuelchen 45
D-53177 Bonn
impressum@forensikblog.de

Copyright © 2005-2012 by
Andreas Schuster
Alle Rechte vorbehalten.
Powered by Movable Type 5.12