Recent

Author Topic: CryptLib + SigSev (Runtime error 216) on program exit  (Read 654 times)

KennethH

  • Newbie
  • Posts: 6
CryptLib + SigSev (Runtime error 216) on program exit
« on: January 30, 2023, 06:00:05 pm »
Hi all...

Let me preface this with "I have an acceptable work-around"...

I am linking to CryptLib in a rather complex program that is throwing a mysterious run-time error on exit. After much stripping down, here is the MOST simple code that will throw the error:

Code: Pascal  [Select][+][-]
  1. program Test;
  2.  
  3. function cryptInit: Integer; stdcall; external 'CL64.DLL';
  4. function cryptEnd: Integer; stdcall; external 'CL64.DLL';
  5.  
  6. begin
  7.  
  8.   if cryptInit = 0 then
  9.     Writeln('Init!');
  10.  
  11.   cryptEnd;
  12.   Writeln('Complete');
  13.  
  14. end.
  15.  

This code runs fine in Windows 10 but throws the error on Windows 2012 Server R2.

Notes:
  • Compiled on FPC 3.04 and on FPC 3.2.2, as I read on this forum 3.0.4 has a bug that can cause this
  • Error only on that one OS. SAME code and SAME DLL work in Windows 10
  • Works fine in 2012 when compiled in 32-bit mode

Question to the forum: Am I missing any obvious compiler options that would help debug this? I've tried {$S+} and {$INLINE OFF}

Quote from: DebugLog
=library-loaded,id="C:\\Windows\\SYSTEM32\\cryptbase.dll",target-name="C:\\Windows\\SYSTEM32\\cryptbase.dll",host-name="C:\\Windows\\SYSTEM32\\cryptbase.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\SYSTEM32\\bcryptprimitives.dll",target-name="C:\\Windows\\SYSTEM32\\bcryptprimitives.dll",host-name="C:\\Windows\\SYSTEM32\\bcryptprimitives.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\SYSTEM32\\cryptsp.dll",target-name="C:\\Windows\\SYSTEM32\\cryptsp.dll",host-name="C:\\Windows\\SYSTEM32\\cryptsp.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\system32\\shell32.dll",target-name="C:\\Windows\\system32\\shell32.dll",host-name="C:\\Windows\\system32\\shell32.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\system32\\shlwapi.dll",target-name="C:\\Windows\\system32\\shlwapi.dll",host-name="C:\\Windows\\system32\\shlwapi.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\SYSTEM32\\SHCore.dll",target-name="C:\\Windows\\SYSTEM32\\SHCore.dll",host-name="C:\\Windows\\SYSTEM32\\SHCore.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\SYSTEM32\\profapi.dll",target-name="C:\\Windows\\SYSTEM32\\profapi.dll",host-name="C:\\Windows\\SYSTEM32\\profapi.dll",symbols-loaded="0",thread-group="i1"
=thread-created,id="2",group-id="i1"
~"[New Thread 5380.0x27ac]\n"
*running,thread-id="all"
=thread-exited,id="2",group-id="i1"
*stopped,reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",frame={addr="0x0000000000000000",func="??",args=[]},thread-id="1",stopped-threads="all"
(gdb)
<info program>
&"info program\n"
~"\tUsing the running image of child Thread 5380.0x2718.\n"
~"Program stopped at 0x0.\n"
~"It stopped with signal SIGSEGV, Segmentation fault.\n"

===WORK AROUND===

The following code does NOT throw the error. Because there was no change in the DLL, it leads me to search for the problem in FPC-side, not the within the DLL

Code: Pascal  [Select][+][-]
  1. program Test;
  2.  
  3. uses Windows;
  4.  
  5. type
  6.   CFunction = function: Integer; stdcall;
  7.  
  8. var
  9.   cryptInit, cryptEnd: CFunction;
  10.   H: THandle;
  11. begin
  12.  
  13.   H := LoadLibrary('CL64.DLL');
  14.   cryptInit := CFunction(GetProcAddress(H, 'cryptInit'));
  15.   cryptEnd := CFunction(GetProcAddress(H, 'cryptEnd'));
  16.  
  17.   if cryptInit() = 0 then
  18.     Writeln('Init!');
  19.  
  20.   cryptEnd();
  21.  
  22.   FreeLibrary(H);
  23.   Writeln('Complete');
  24.  
  25. end.
  26.  

I consider this an acceptable work-around but the programmer in me cannot let this go. Any help on compiler directives appreciated

KennethH

  • Newbie
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #1 on: January 30, 2023, 06:06:32 pm »
Note that I do not 100% rule out an error in the DLL.

For example, in cryptlib.pas that comes from their site, we see:

Code: Pascal  [Select][+][-]
  1. const
  2.   {$IFDEF WIN32}
  3.     cryptlibname = 'CL32.DLL';  { dynamic linkname for Windows (Delphi) }
  4.   {$ELSE}
  5.     cryptlibname = 'libcl.so';  { library name for Unix/Linux  (Kylix) }
  6.                  { symbolic link should be used for libcl.so -> libcl.so.3.x.y }
  7.   {$ENDIF}
  8.  
  9. function cryptInit: Integer;
  10. {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF} external cryptlibname;
  11.  
  12.  
  13. function cryptEnd: Integer;
  14. {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF} external cryptlibname;
  15.  

which does not play nicely in WIN64. So I had to make some corrections to their lib just to get it to run in Win10. I'm poking at the code right now in Visual Studio to see if I can spot other problem spots.

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #2 on: January 30, 2023, 06:11:36 pm »
Try appending the "name" at the end.
Fascal is not a case sensitive language. But u can specify the real name at the end.
......name 'theName'
U can even use index if u know it.
The only true wisdom is knowing you know nothing

KennethH

  • Newbie
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #3 on: January 30, 2023, 06:21:16 pm »
Try appending the "name" at the end.
Fascal is not a case sensitive language. But u can specify the real name at the end.
......name 'theName'
U can even use index if u know it.

Thank you, however still no-go

Code: Pascal  [Select][+][-]
  1. program Test;
  2.  
  3. function cryptInit: Integer; stdcall; external 'CL64.DLL' name 'cryptInit';
  4. function cryptEnd: Integer; stdcall; external 'CL64.DLL' name 'cryptEnd';
  5.  
  6. begin
  7.  
  8.   if cryptInit = 0 then
  9.     Writeln('Init!');
  10.  
  11.   cryptEnd;
  12.   Writeln('Complete');
  13.  
  14. end.  

Quote from: Output
Init!
Complete
Runtime error 216 at $0000000000000000
  $0000000000000000
  $00007FFDB166909A
  $00007FFDB16B381B
  $00007FFDD590C414
  $00007FFDD590B822
  $00007FFDD59084F8
  $00007FFDD5114F8A
  $0000000100007F0B
  $000000010000383F
  $000000010000162D
  $0000000100001646
  $0000000100007F70
  $00000001000015A0
  $00007FFDD5111412
  $00007FFDD5905504

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #4 on: January 30, 2023, 06:24:19 pm »
Looks like u r in 64bit mode.?

R u sure that is a 32bit dll?

I meant 64 bit
« Last Edit: January 30, 2023, 06:25:56 pm by jamie »
The only true wisdom is knowing you know nothing

KennethH

  • Newbie
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #5 on: January 30, 2023, 06:37:35 pm »
Looks like u r in 64bit mode.?

R u sure that is a 32bit dll?

I meant 64 bit

Confirming 64-bit.
Same .exe and same .dll work fine in Win10

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #6 on: January 30, 2023, 06:40:25 pm »
Well, the cryptinit fails, so you have to look for that....
Specialize a type, not a var.

KennethH

  • Newbie
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #7 on: January 30, 2023, 06:47:07 pm »
Well, the cryptinit fails, so you have to look for that....

That 0 is a success. From within the DLL code:

Code: C  [Select][+][-]
  1. #define CRYPT_OK                                0               /* No error */
  2.  

Also, for fun, I've nerfed the initialization code in the DLL

Code: C  [Select][+][-]
  1. C_RET cryptInit( void )
  2.         {
  3.                 return( CRYPT_OK );
  4.         }
  5.  
  6. C_RET cryptEnd( void )
  7.         {
  8.         return (CRYPT_OK);
  9.         }
  10.  

KennethH

  • Newbie
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #8 on: January 31, 2023, 09:50:29 pm »
Ok, everyone. FPC is off the hook. Turns out the library was invoking code from Win2k16+ that my 2k12 box didn't have.

This was occurring in PROCESS_DETACH which will be notoriously difficult for a debugger to snag onto.

But it worked in 32-bit :o
...Well, it's a null pointer operation (in C, not even managed code). 32-bit may have had garbage in there pointing the read operation somewhere friendly. Whereas in 64, Windows came down with the ban-hammer and said you most certainly cannot read there.

 

TinyPortal © 2005-2018