Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zugriffsverletzung in SHA-1 Code (https://www.delphipraxis.net/117224-zugriffsverletzung-sha-1-code.html)

cmrudolph 14. Jul 2008 14:41


Zugriffsverletzung in SHA-1 Code
 
Hi,
ich habe mir mal das RFC 3174 geschnappt und in Delphi eine Funktion geschrieben, die über einen Speicherbereich den SHA-1 Hash berechnet.
Das Ergebnis ist auch korrekt, nur bekomme ich eine Zugriffsverletzung, wenn ich größere Daten hashen möchte.
Ich habe beispielsweise den Puffer mit 4194209 4194304 Bytes (4 MB) gefüllt. Beim 16376. Byte bekomme ich jedoch eine Zugriffsverletzung.
Um das ganze am Code zu zeigen, hier die Funktion:
Delphi-Quellcode:
type
  THash = Array [0..4] of Cardinal;
  PHash = ^THash;
.
.
.
procedure SHA1(data: Pointer;const mlen_lo:Cardinal;hash: PHash);
  function rollL(k: Cardinal;const amount: Byte): Cardinal;
  var
    l: Cardinal;
  begin
    l:=k shl amount;
    k:=k shr (32-amount);
    Result:=l or k;
  end;
var
  W: Array [0..79] of Cardinal;
  h0,h1,h2,h3,h4: Cardinal;
  a,b,c,d,e: Cardinal;
  temp,i,n: Cardinal;
  t: Byte;
  paddeddata: Pointer;
  pposB: PByte;

  padc: Byte;
  m_lenbits: Cardinal;

  mb: Byte;
begin
  h0 := $67452301;
  h1 := $EFCDAB89;
  h2 := $98BADCFE;
  h3 := $10325476;
  h4 := $C3D2E1F0;

  paddeddata:=GetMemory(mlen_lo+72);
  CopyMemory(paddeddata,data,mlen_lo);
  pposB:=paddeddata;
  inc(pposB,mlen_lo);
  pposB^:=$80;
  inc(pposB);

  padc:=64-(mlen_lo+9) mod 64;
  if padc>0 then begin
    for t:=1 to padc do begin
      pposB^:=$00;
      inc(pposB);
    end;
  end;
  n:=(mlen_lo+padc+9) div 64;

  m_lenbits:=mlen_lo shl 3;
  PCardinal(pposB)^:=$00000000;
  inc(pposB,4);
  pposB^:=m_lenbits shr 24;
  inc(pposB);
  pposB^:=m_lenbits shr 16;
  inc(pposB);
  pposB^:=m_lenbits shr 8;
  inc(pposB);
  pposB^:=m_lenbits;
  pposB:=paddeddata;

  //Beginn Debugcode
  for i:=0 to 4096 do begin
    for t:=0 to 15 do begin
      mb:=pposB^;
      if mb=0 then;
      if Cardinal(pposB)=431800320 then
        ShowMessage(IntToStr(i));
      inc(pposB);
    end;
  end;

  pposB:=paddeddata;
  //Ende Debugcode

  for i:=0 to n-1 do begin
    for t:=0 to 15 do begin
      try
      //hier kommt die Zugriffsverletzung
      W[t]:=pposB^ shl 24;
      inc(pposB);
      W[t]:=W[t] or (pposB^ shl 16);
      inc(pposB);
      W[t]:=W[t] or (pposB^ shl 8);
      inc(pposB);
      W[t]:=W[t] or pposB^;
      inc(pposB);
      except showmessage(IntToStr(Cardinal(paddeddata))+' '+IntToStr(Cardinal(pposB)));
      end;
    end;

    for t:=16 to 79 do begin
      W[t]:=rollL(W[t-3] XOR W[t-8] XOR W[t-14] XOR W[t-16],1);
    end;

    a:=h0;
    b:=h1;
    c:=h2;
    d:=h3;
    e:=h4;

    for t:=0 to 19 do begin
      temp:=rollL(a,5) + ((b AND c) OR ((NOT b) AND d)) + e + W[t] + $5A827999;

      e:=d;
      d:=c;
      c:=rollL(b,30);
      b:=a;
      a:=temp;
    end;
    for t:=20 to 39 do begin
      temp:=rollL(a,5) + (b XOR c XOR d) + e + W[t] + $6ED9EBA1;

      e:=d;
      d:=c;
      c:=rollL(b,30);
      b:=a;
      a:=temp;
    end;
    for t:=40 to 59 do begin
      temp:=rollL(a,5) + ((b AND c) OR (b AND d) OR (c AND d)) + e + W[t] + $8F1BBCDC;

      e:=d;
      d:=c;
      c:=rollL(b,30);
      b:=a;
      a:=temp;
    end;
    for t:=60 to 79 do begin
      temp:=rollL(a,5) + (b XOR c XOR d) + e + W[t] + $CA62C1D6;
     
      e:=d;
      d:=c;
      c:=rollL(b,30);
      b:=a;
      a:=temp;
    end;

    FreeMemory(paddeddata);

    h0:=h0+a;
    h1:=h1+b;
    h2:=h2+c;
    h3:=h3+d;
    h4:=h4+e;
  end;

  hash^[0]:=h0;
  hash^[1]:=h1;
  hash^[2]:=h2;
  hash^[3]:=h3;
  hash^[4]:=h4;
end;
Die Zeilen 64-76 sind Debugcode. Die Zugriffsverletzung kommt bei Adresse 431800320 in Zeile 82. Ich habe versucht, den Wert vorher in eine andere Variable zu übertragen, also statt der direkten Zuweisung in das Array W erst in eine tempvariable. Doch dann kommt die Zugriffsverletzung bei dieser Operation.

Der Debugcode zeigt aber, dass der Speicher eigentlich zugreifbar sein müsste. Ich lasse mir im Debugcode auch den Wert an dieser Adresse ausgeben lassen, der stimmt auch mit den Eingabedaten überein.

Irgend etwas muss ich übersehen haben. Ich bin für jede Hilfe dankbar.

mfG,
Christian

Edit: die Bytezahl stimmte nicht, auch wenn es wohl nicht von Belang ist. Aber der Korrektheit halber...
Edit2: Da ich nicht wusste, dass man die Zeilennummern nicht immer sieht, habe ich den Quellcode um drei kleine Kommentare erweitert und die Zeilennummern unter dem Code angepasst.

mkinzler 14. Jul 2008 15:02

Re: Zugriffsverletzung in SHA-1 Code
 
In welcher Zeile

cmrudolph 14. Jul 2008 15:06

Re: Zugriffsverletzung in SHA-1 Code
 
Die Zugriffsverletzung kommt in Zeile 79, wie es oben auch steht ;)

RavenIV 14. Jul 2008 15:08

Re: Zugriffsverletzung in SHA-1 Code
 
Zitat:

Zitat von cmrudolph
Die Zugriffsverletzung kommt in Zeile 79, wie es oben auch steht ;)

Super.
Und welche Zeile ist das genau?
Was steht da für Code drin?
Ich fang bestimmt nicht an Zeilen zu zählen... :-(

dominikkv 14. Jul 2008 15:11

Re: Zugriffsverletzung in SHA-1 Code
 
sind die bei euch nicht durchnummeriert?
Delphi-Quellcode:
<<-- hier steht ne 1
Delphi-Quellcode:
      W[t]:=pposB^ shl 24;

RavenIV 14. Jul 2008 15:12

Re: Zugriffsverletzung in SHA-1 Code
 
Zitat:

Zitat von dominikkv
sind die bei euch nicht durchnummeriert?

Nein ich seh keine Zeilennummern.

Kann man das irgendwo einstellen?
Aber eigentlich will ich die Zeilennummern auch nicht sehen.

cmrudolph 14. Jul 2008 15:17

Re: Zugriffsverletzung in SHA-1 Code
 
Ich habe nicht gewusst, dass man die Zeilennummern deaktivieren kann. (Die Option ist unter DP Info & Services -> erw. Profil bearbeiten -> Thread und Forenansicht -> Zeilennummern)

Nun ja, der besagte Quellcode wurde jetzt ja gepostet. Die Zeilennummern sollen jetzt nicht das Problem sein.

Hier noch einmal ein Auszug mit einem Kontext:
Delphi-Quellcode:
  for i:=0 to n-1 do begin
    for t:=0 to 15 do begin
      try
      W[t]:=pposB^ shl 24;
      inc(pposB);
      W[t]:=W[t] or (pposB^ shl 16);
      inc(pposB);
      W[t]:=W[t] or (pposB^ shl 8);
      inc(pposB);
      W[t]:=W[t] or pposB^;
      inc(pposB);
      except showmessage(IntToStr(Cardinal(paddeddata))+' '+IntToStr(Cardinal(pposB)));
      end;
    end;
Es ist die Zeile direkt unter dem "try".

dominikkv 14. Jul 2008 15:19

Re: Zugriffsverletzung in SHA-1 Code
 
ähm, ok, ich sehe gerade das die bei mir nur durchnummeriert werden wenn man den Quelltext "aufklappen" kann. Also oben bei meinem Beitrag steht doch keine 1 :pale:
Ich habe bei "erw. Profil bearbeiten" hier in der DP "Code-Folding" und "Zeilennummern" aktiviert.

cmrudolph 14. Jul 2008 15:50

Re: Zugriffsverletzung in SHA-1 Code
 
Tut mir Leid, dass ich euch bemüht habe, ich habe den Fehler nun gefunden.

Es ist die kleine Zeile
Delphi-Quellcode:
FreeMemory(paddeddata);
, die ein Stück zu hoch gerutscht ist. Sie gehört eigentlich hinter das darauf folgende end und ist somit nicht mehr in der Schleife.

mfG,
Christian


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:52 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz