Problemy z Przepełnieniem stosu w NET9.0

Problemy z Przepełnieniem stosu w NET9.0
K7
  • Rejestracja: dni
  • Ostatnio: dni
0

Net 9.0

Chce podpisać xml aby zalogować się do KSEF podpisem kwalifikowanym.

Nie znam zbyt dobrze NET 9.0 w NetFramework4.8 zrobiłem to niestety na komputerach klientów w Win11 nie działa.
Funkcje eksportowane do Delphi poprzez Interop

[UnmanagedCallersOnly(EntryPoint = "AuthorizeCertificate",
CallConvs = new[] { typeof(CallConvCdecl) })]

Przepisałem 99% na Net9.0, nie działa serializacja ani deserializacja using Newtonsoft.Json;

i teraz jak podpisać xml

Lib do podpisywania
FirmaXadesNetCore

funkcja podpisująca

Kopiuj
public static string PodpiszXmlKSeF(string xmlTresc)
{
    X509Certificate2 cert = WybierzCertyfikat();
    if (cert == null) return null;

    XadesService xadesService = new XadesService();
    SignatureParameters parameters = new SignatureParameters
    {
        SignaturePackaging = SignaturePackaging.ENVELOPED,
        SignatureMethod = SignatureMethod.RSAwithSHA256,
        DigestMethod = DigestMethod.SHA256,
        Signer = new FirmaXadesNetCore.Crypto.Signer(cert)
    };

    byte[] xmlBytes = Encoding.UTF8.GetBytes(xmlTresc);

    using (MemoryStream msIn = new MemoryStream(xmlBytes))
    using (MemoryStream msOut = new MemoryStream())
    {
        // 1. Podpisujemy strumień wejściowy
        var signatureDocument = xadesService.Sign(msIn, parameters);

        // 2. Zapisujemy wynikowy SignatureDocument do strumienia wyjściowego
        signatureDocument.Save(msOut);

        // 3. Konwertujemy bajty ze strumienia na string UTF-8
        return Encoding.UTF8.GetString(msOut.ToArray());
    }
}

i oczywiście

screenshot-20260325211634.png

Aplikacja zabijana

Nieważne co robię, ciągle ten komunikat.
Systemy Win 10, 11.

Problemem jest ta linijka.
// 1. Podpisujemy strumień wejściowy
var signatureDocument = xadesService.Sign(msIn, parameters);

Podpowiedzcie gdzie leży problem.

obscurity
  • Rejestracja: dni
  • Ostatnio: dni
3

To nie jest przepełnienie stosu (stack overflow) tylko przekroczenie buforu na stosie (buffer overflow).
Problem nie leży raczej w tej funkcji tylko w interop, pokaż jak eksportujesz i importujesz tę funkcję i jak z niej korzystasz, przekazywanie stringów między dll-kami potrafi przysporzyć problemów.
AI mówi że delphi nie ma żadnego kompatybilnego binarnie stringa z .NET i żebyś użył IntPtr + Marshal.PtrToStringUTF8.

Najpierw zawęź źródło problemu - czy aplikacja tak samo (nie) działa gdy wywołujesz kod .NET bezpośrednio (nie przez interop)?

K7
  • Rejestracja: dni
  • Ostatnio: dni
0

Możliwe, pokażę po 16 pokażę

Prawdę mówiąc nie mogę nawet zdebugować, ponieważ właściwa dll jest publikowana .

Dodatkowo błąd jest dokładnie w tej linijce.
Nie ma linijki nie ma błędu.

Oczywiście kilkanaście innych funkcji działa, to nie jest tak że inne nie działają i piszę dopiero pierwszą.

Najlepsze jest to że w Win11 nie ma nawet komunikatu.

Kod

Kopiuj
[UnmanagedCallersOnly(EntryPoint = "AuthorizeToken",
        CallConvs = new[] { typeof(CallConvCdecl) })]

    public static int AuthorizeToken(IntPtr url_IP,IntPtr nip_IP, IntPtr token_IP, IntPtr buffer, int bufferSize)
    {
        string url = Marshal.PtrToStringUni(url_IP);
        string nip = Marshal.PtrToStringUni(nip_IP);
        string token = Marshal.PtrToStringUni(token_IP);
...

        response = client.Execute(request);

        string text = response.Content ?? "";
        byte[] data = System.Text.Encoding.Unicode.GetBytes(text + "\0");
        int bytesToCopy = Math.Min(data.Length, bufferSize); 
        Marshal.Copy(data, 0, buffer, bytesToCopy);
        return text.Length; // długość znaków
}



Wykorzystanie w Delphi

Kopiuj

...
function AuthorizeToken(url: PWideChar; nip: PWideChar; token: PWideChar; Buffer: PWideChar; BufferSize: Integer): Integer; cdecl; external 'NKsef9.0.dll';
...


procedure TForm4.Button2Click(Sender: TObject);
var
  buf: array [0 .. 200000] of WideChar;
  len: Integer;
...

begin
  len := AuthorizeToken(PWideChar(url), PWideChar(Edit5.Text), PWideChar(Edit6.Text), buf, SizeOf(buf));
  Memo1.Text := buf;

end;



W memo1 mam xml

Powyższy kod działa. W ten sposób zrobione są wszystkie funkcje.

Na koniec w terminalu VS komenda
dotnet publish -c Release -r win-x86

i mam wszystkie funkcje gotowe do wykozystania prezez Delphi.

JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5052
0

Napisałem kiedyś kilka artykułów o Interop. Sprawdź to: https://masterbranch.pl/uzywamy-dll-pisanej-w-cpp-czesc-1/ Odpowiednikiem PWideChar w C++ będzie wchar_t *.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.