Problem mit Hex2bix. (cypress Tool)

Gast #5546669
Lesenswert?

Ich benutze das Tool schon sehr lange und kenne die Aufrufparameter. 
Unter XP funktioniert es immer noch auch in einer VM. Auf einem Win10 
System geht es leider nicht.
Das Tool würde ursprünglich mit MSC 6 übersetzt. Auch ein Neuübersetzung 
wie von cypress in einem Thread empfohlen hat nicht weitergeholfen.
Da ich mir das Fehlverhalten (es kommt ein Fehler bezüglich der 
Speicherzugriffe) nicht so recht erklären konnte habe ich den Debugger 
angeworfen und das näher angeschaut.

Letztendlich könnte ich das Problem auf malloc bei den Filenamen 
eingrenzen.
Im Code wird per malloc Speicher für die Filenamen angefordert
1
Outfilename=(char*)malloc(strlen(argv[i]+EXT_LENGTH));
2
strcopy(Outfilename,argv[i];
soweit so gut oder auch nicht ich kann da erst Mal nichts falsches 
erkennen und wie gesagt unter XP geht ja auch alles wie erwartet.
Wenn ich nun den Speicher nicht per malloc anfordern sondern die 
Filenamen als globale Variablen mit char[256] definiere funktioniert das 
Tool auch unter W10.

Nun zur eigentlichen Frage:
was passiert unter W10?  Wieso arbeitet malloc jetzt auf einmal anders?
Ist das vielleicht ein Emulation Problem von WOW64?
Allgemein gefragt :
Wie kann ich sowas für mich verhindern?

Noch ein Hinweis. Das Tool hat noch ein Problem mit Intel Hex 
Checksummen die werden nicht korrekt behandelt. Das ist aber eine andere 
Baustelle und sehr einfach zu fixen. In alten Versionen von Hex2bix 
wurde die checksum Prüfung einfach auskommentiert

falls von Interesse hier meine Aufrufparameter
..\..\tools\hex2bix -IR -O .\obj\outf.eep .\obj\infile.hex

Thomas
Angehängte Dateien:
Gast #5546697
Lesenswert?

Ja ich bin mir sicher und das ist wohl auch das Problem .... Manchmal 
sieht man halt den Wald vor lauter Bäumen nicht. Der Code ist ja im 
Anhang.
Die Frage bleibt trotzdem warum geht sowas unter XP?
 Danke für den Hinweis.
Thomas
Gast #5546704
Lesenswert?

Ach du... das sollte man aber patchen...
1
[...]
2

3
case 'O':
4
  i++;
5
  OutFilename = (char *)malloc(strlen(argv[i]+EXT_LENGTH+1));
6
  strcpy(OutFilename, argv[i]);
7
  cont = FALSE;
8
  break;
9

10
[...]
11

12
if (OutFilename == NULL)
13
{
14
  root_length = strcspn(InFilename,".");
15
  OutFilename = (char *)malloc(root_length+EXT_LENGTH);
16
  memcpy(OutFilename,InFilename,root_length);
17
  OutFilename[root_length] = 0;
18
  strcat(OutFilename,Extension[OutFileType]);
19
}
20

21
[...]
22

23
Image = (BYTE *)malloc(MEMORY_BUFFER_SIZE);
24
ImageMap = (BYTE *)malloc(MEMORY_BUFFER_SIZE+2);
25
memset(Image,MEM_FILL,MEMORY_BUFFER_SIZE);
26
memset(ImageMap,FALSE,MEMORY_BUFFER_SIZE);
27

28
[...]

Soweit ich das beim ueberfliegen sehe, wird nie geprueft, ob man 
ueberhaupt speicher bekommen hat. Da gehoert zu jedem malloc noch ein
1
if (ptr == NULL) {
2
  // FEHLER! Mach was sinnvolles, z.B. Fehlerbehandlung...
3
}
Gast #5546707
Lesenswert?

Thomas schrieb:
> Die Frage bleibt trotzdem warum geht sowas unter XP?

Vielleicht gibt der Kernel unter XP größere Adressbereiche zurück sodass 
der dann folgende Buffer Overflow Fehler unentdeckt bleibt. So kann man 
sich natürlich beliebige (Sicherheits-)Probleme einfangen. Es "geht" 
also nur zufällig. Also froh sein dass Win10 hier strenger ist und 
solche Fehler auffallen...
Gast #5546713
Lesenswert?

Und sowas
1
memset(ImageMap,FALSE,MEMORY_BUFFER_SIZE);
2
                ^^^^^
ist auch ganz dolle pfui! Wenn man den Speicher mit 0 fuellen will, dann 
sollte man auch hinschreiben, dass man 0 meint, und nicht 'false'...

Der ganze Code sollte mal ueberarbeitet werden. Ist ja gruselig...
Gast #5546750
Lesenswert?

Das der Code nicht so dolle ist war mir schon klar. Um ehrlich zu sein 
habe ich mir das nie angeschaut da ja alles bisher funktioniert hat. Ich 
habe halt immer die exe von Cypress verwendet.
Das ganze ist mir ja erst aufgefallen als ich die Entwicklermaschine 
getauscht hatte.
Ich finde das ganze schon ziemlich interessant. Hätte cypress nicht den 
Quellcode offengelegt, hätte ich das Tool selber nachprogrammieren 
müssen.

Meine Frage wie ich das für mich verhindern kann hat sich aber erledigt.

Thomas
Gast #5546781
Lesenswert?

Auch das hier:
1
    if (compressIIC)
2
        while((ImageMap[addr] || ImageMap[addr+1] || ImageMap[addr+2]) && (addr < MemSize) && (i++ < 0x3ff))
3
            ++addr;
4
    else
5
        while(ImageMap[addr] && (addr < MemSize) && (i++ < 0x3ff))
6
            ++addr;

Was CppCheck dazu sagt:
1
Summary: Array index 'addr' is used before limits check.
2

3
Message: Defensive programming:
4
The variable 'addr' is used as an array index before it is checked that
5
is within limits. This can mean that the array might be accessed out of
6
bounds. Reorder conditions such as '(a[i] && i < 10)' to '(i < 10 && a[i])'.
7
That way the array will not be accessed if the index is out of limits.
Das dieses Programm jemals (ansatzweise) korrekt funktioniert hat grenzt 
an Zauberei...
Gast #5546816
Lesenswert?

Naja an dem Tool wurde sehr oft rumgeflickt. Ich habe aleine 4 Versionen 
davon und bin mir nicht sicher ab ich die aktuellste Version habe. Da 
ich nur eine Teilmenge der Optionen bisher genutzt habe waren mir 
Optionen wie das compressed iic bisher egal.
Bei Cypress ist da alles auf obsolet gestellt. Ich will gar nicht wissen 
wie viele Programme noch im Umlauf sind die ähnliche Probleme haben.
Thomas
Persönliche Seite #5546839
Lesenswert?

Man kann Dateinamen in char-Arrays fester Länge unterbringen; dafür kann 
man das Macro MAX_PATH verwenden, das mit #include <windows.h> zur 
Verfügung steht.

Weder ist es für ein paar Dateinamen nötig, mit malloc zu arbeiten, noch 
ist es nötig, hier ein paar Bytes zu sparen und weniger als MAX_PATH 
anzufordern.

Um windows.h einbinden zu können, sollte man allerdings das enum "BOOL" 
entfernen, sonst dürfte es mit den enum-Werten TRUE und FALSE zu 
Konflikten kommen.
Gast #5546913
Lesenswert?

Das ist das schöne an "Undefined behaviour" (hier: das Schreiben auf 
nicht allokierten Speicher dank zu kleiner Allokation) - mal 
funktioniert's, mal stürzt es ab, mal produziert es klammheimlich 
falsche Ergebnisse, mal formatiert es deine Festplatte. Deswegen ist es 
wichtig, korrekte Programme zu schreiben, und nicht nur solche, die 
"bei mir ja funktionieren".
#5546968
Lesenswert?

Kaj schrieb:
> Und sowas
>
1
> memset(ImageMap,FALSE,MEMORY_BUFFER_SIZE);
2
>                 ^^^^^
3
>
> ist auch ganz dolle pfui! Wenn man den Speicher mit 0 fuellen will, dann
> sollte man auch hinschreiben, dass man 0 meint, und nicht 'false'...
>
> Der ganze Code sollte mal ueberarbeitet werden. Ist ja gruselig...

Da das Array ImageMap Booleans enthält, erscheint es mir richtig.
Es soll mit False initialisiert werden, nicht mit 0.
1
ImageMap[rec_addr+i] = TRUE;

und an anderer Stelle wird
1
addr < MemSize
als Schleifenabbruch genutzt und nicht zur Prüfung, dass der 
Eingabeparameter addr zu groß ist. Der wird durch den Kontext maximal 
addr == MemSize.
Nicht toll, aber dass es nur zufällig funktioniert... Na ja.

Kaj schrieb:
> Soweit ich das beim ueberfliegen sehe, wird nie geprueft, ob man
> ueberhaupt speicher bekommen hat.

Auch nicht toll. Aber wenn man die paar Byte nicht bekommt, dann hat man 
ein größeres Problem.

Natürlich ist der Source nicht das gelbe vom Ei. Aber der TO will es 
auch nur wieder zum Laufen bekommen. Nicht das Ziel aus den Augen 
verlieren.
Gast #5550186
Lesenswert?

Um das ganze abzuschließen im Anhang eine geänderte Version im Quelltext 
und compiliert
Sowie eine kleine Beschreibung dazu.
Es sind zwei Bugs behoben:
zum einen die Sache mit den Intel Hex checksum zum andern der Bug mit 
malloc bei -@O Filename.
Danke an alle die geholfen haben.

Thomas
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren