AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Von PChar nach UINT

Ein Thema von MathiasSimmack · begonnen am 26. Mai 2004 · letzter Beitrag vom 26. Mai 2004
Antwort Antwort
MathiasSimmack
(Gast)

n/a Beiträge
 
#1

Re: Von PChar nach UINT

  Alt 26. Mai 2004, 14:37
btw: Hier der Hintergrund der ganzen Geschichte. Auf www.licenturion.com/xp/ gibt es den Quellcode eines Tools, mit dem man u.a. aus dem Produktschlüssel von Windows XP die Produkt-ID (die in der Registry gespeichert ist) berechnen kann. Das heißt, das Programm zeigt den relevanten Teil dieser ID an, so dass man vergleichen kann. So sieht man auch sehr schön, wo dieser Schlüssel eigentlich steckt.
Der Nutzwert hält sich damit zwar in Grenzen, aber man könnte ja mal versuchen, das Verfahren umzukehren. Sprich: aus der ID wieder den Schlüssel generieren. Das würde mich noch interessieren. Evtl. gibt es aber auch eine einfachere Möglichkeit, den Schlüssel zu ermitteln.

Wie dem auch sei, hier wäre also das Ergebnis in Delphi, wobei ich gleich noch die Produkt-ID aus der Registry auslese und ebenfalls anzeige.
Delphi-Quellcode:
procedure ShowProdKey(const ProdKey: pchar);

  function CheckDigit(const uVal: UINT): UINT;
  var
    uSum,
    uCopy : UINT;
  begin
    uSum := 0;
    uCopy := uVal;

    while(uCopy <> 0) do
    begin
      uSum := uSum + (uCopy mod 10);
      uCopy := uCopy div 10;
    end;

    Result := uVal * 10 + 7 - (uSum mod 7);
  end;

var
  s : string;
  reg : TRegistry;
  uVal1,
  uVal2 : UINT;
begin
  // die Produkt-ID aus der Registry ermitteln
  s := '';
  reg := TRegistry.Create(KEY_READ);
  if(reg <> nil) then
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if(reg.OpenKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion',
      false)) then
    try
      s := reg.ReadString('ProductId');
    finally
      reg.CloseKey;
    end;
  finally
    reg.Free;
  end;

  // den berechneten Wert holen, ...
  uVal1 := PUINT(ProdKey)^;

  // ... & umrechnen
  uVal1 := uVal1 and $7fffffff;
  uVal1 := uVal1 shr 1;

  uVal2 := CheckDigit(uVal1 mod 1000000);
  uVal1 := uVal1 div 1000000;

  // die tatsächlich gespeicherte und die errechnete
  // Produkt-ID anzeigen
  MessageBox(0,pchar(Format(
    'Your product ID should be XXXXX-%.3u-%.7u-XXXXX.' + #13#10 +
    'Your reported product ID is %s',
    [uVal1,uVal2,s])),'ShowProdKey',MB_OK or MB_ICONINFORMATION);
end;


function DecodeProdKey(ProdKey: string; var pResult: string;
  iResLen: integer): integer;
const
  ValidDigits = 'BCDFGHJKMPQRTVWXY2346789';
var
  k,
  m,
  Aux,
  NumDigits : integer;
begin
  Result := -1;

  if(length(ProdKey) <> 29) then
  begin
    Writeln('Warning: Product key has non-standard length.');
    exit;
  end;

  if(length(ProdKey) mod 6 < 1) then
  begin
    Writeln('Product key has invalid length.');
    exit;
  end;

  SetLength(pResult,iResLen);
  ZeroMemory(@pResult[1],length(pResult));

  NumDigits := length(ValidDigits);

  // Bindestriche entfernen, & in Großbuchstaben konvertieren
  ProdKey := StringReplace(ProdKey,'-','',[rfReplaceAll]);
  ProdKey := UpperCase(ProdKey);

  for k := 1 to length(ProdKey) do
    if(ProdKey[k] <> '') then
    begin
      // Position des aktuellen Zeichens ermitteln, ...
      Aux := pos(ProdKey[k],ValidDigits);
      if(Aux = 0) then
      begin
        Writeln('Invalid character in group');
        exit;
      end;

      // ... aber um Eins verringern, weil sonst die
      // Berechnung nicht stimmt (das liegt daran,
      // dass das Zeichen-Array "ValidDigits" im
      // C-Programm ja auch ein PChar ist und daher
      // bei Null beginnt)
      dec(Aux);

      // und das ist die Berechnung ... furchtbar! ;o)
      for m := 1 to length(pResult) do
      begin
        Aux := Aux + BYTE(pResult[m]) * NumDigits;
        pResult[m] := CHR(Aux and 255);
        Aux := Aux shr 8;
      end;
    end;

  Result := 0;
end;
Aufzurufen:
Delphi-Quellcode:
var
  output : string;
begin
  DecodeProdKey(Edit1.Text { <-- WinXP-Schlüssel eingeben },output,15);
  ShowProdKey(pchar(output));
end;
Und hier zum Vergleich mal der Original-C-Code:
Code:
unsigned int CheckDigit(unsigned int Val)
{
   unsigned int Sum, Copy;

   Sum = 0;
   Copy = Val;

   while (Copy != 0)
   {
      Sum += Copy % 10;
      Copy /= 10;
   }

   return Val * 10 + 7 - (Sum % 7);
}

void ShowProdKey(unsigned char *ProdKey)
{
   unsigned int Val1, Val2;

   Val1 = *(unsigned int *)ProdKey;
   Val1 &= 0x7fffffff;
   Val1 >>= 1;

   Val2 = CheckDigit(Val1 % 1000000);
   Val1 /= 1000000;

   printf("Your product ID should be XXXXX-%.3u-%.7u-XXXXX.\n", Val1, Val2);
}


int DecodeProdKey(char *ProdKey, unsigned char *Result, int ResLen)
{
   static char *ValidDigits = "BCDFGHJKMPQRTVWXY2346789";
   int i, k, m, Groups;
   int Aux, NumDigits;

   if (strlen(ProdKey) != 29)
      fprintf(stderr, "Warning: Product key has non-standard length.\n");

   if (strlen(ProdKey) % 6 < 1)
   {
      fprintf(stderr, "Product key has invalid length.\n");
      return -1;
   }

   memset(Result, 0, ResLen);
   
   NumDigits = strlen(ValidDigits);
   
   Groups = (strlen(ProdKey) + 5) / 6;

   for (i = 0; i < Groups * 6; i += 6)
   {
      for (k = 0; k < 5 && ProdKey[i + k] != 0; k++)
      {
         if (ProdKey[i + k] >= 'a' && ProdKey[i + k] <= 'z')
            ProdKey[i + k] -= 32;

         for (m = 0; ValidDigits[m] != 0; m++)
            if (ProdKey[i + k] == ValidDigits[m])
               break;

         if (ValidDigits[m] == 0)
         {
            fprintf(stderr, "Invalid character in group '");

            for (k = 0; k < 5 && ProdKey[i + k] != 0; k++)
               fprintf(stderr, "%c", ProdKey[i + k]);

            fprintf(stderr, "'.\n");
            return -1;
         }

         Aux = m;
         m = 0;

         do
         {
            Aux += Result[m] * NumDigits;
            Result[m++] = (unsigned char)(Aux & 255);

            Aux >>= 8;
         }
         while (m < ResLen);
      }

      if (ProdKey[i + k] != '-' && ProdKey[i + k] != 0)
      {
         fprintf(stderr, "Expected '-' character after group '");

         for (k = 0; k < 5 && ProdKey[i + k] != 0; k++)
            fprintf(stderr, "%c", ProdKey[i + k]);

         fprintf(stderr, "'.\n");
         return -1;
      }
   }

   return 0;
}
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:54 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