Lazarus

Programming => Packages and Libraries => Topic started by: karmacomposer on March 31, 2021, 07:42:28 pm

Title: Help with sending library functions to another program
Post by: karmacomposer on March 31, 2021, 07:42:28 pm
Hello.  I need help.  I have created a bunch of procedures and functions that need to be in a .dll that can then be loaded and used across multiple units in the same overall program.

Here is the simple .dll I created to store some simple strings:

Code: [Select]
library serverInfo;

var
  User: pChar;
  Pass: pChar;
  Loc: pChar;

procedure getUser();
begin
  User := 'myUsername';
end;
exports
         User;

procedure getPass();
begin
  User := 'myPassword';
end;
exports
         Pass;

procedure getLoc();
begin
  Loc := 'http://www.someurl.com';
end;
exports
         Loc;

end.

and here is the program code:

Code: [Select]
unit unitGetServerInfo2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, dynlibs;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);

  private
    { dynamically linking }
    hLib: TlibHandle;

  public

  end;

var
  Form1: TForm1;
  hndlDll: TLibHandle = dynlibs.NilHandle;
  User: pChar;
  Pass: pChar;
  Loc: pChar;
  Username: pChar;
  Password: pChar;
  Location: pChar;

implementation

function getUser(var User: pChar): pChar; cdecl;
begin
   hndlDll:= LoadLibrary('serverInfo.dll');
   Username := User;
   showmessage(Username);
end;

function getPass(var Pass: pChar): pChar; cdecl;
begin
   hndlDll:= LoadLibrary('serverInfo.dll');
   Password := Pass;
   showmessage(Password);
end;

function getLoc(var Loc: pChar): pChar; cdecl;
begin
   hndlDll:= LoadLibrary('serverInfo.dll');
   Location := Loc;
   showmessage(Location);
end;

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  getUser(User);
  getPass(Pass);
  getLoc(Loc);
end;

end.

What am I doing wrong/omitting? Nothing is passed - nothing shows up in the showmessage prompt.

Thank you for your help.

Mike

Title: Re: Help with sending library functions to another program
Post by: GetMem on March 31, 2021, 08:11:33 pm
@karmacomposer

1. You did not check the value of hndlDll
2. If hndlDll >0 then you should call GetProcedureAddress(hndlDll , 'getUser')

Please check the attached project from this link: https://forum.lazarus.freepascal.org/index.php/topic,53621.msg396954.html#msg396954 .
 
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on March 31, 2021, 08:41:33 pm
Hey karmacomposer,

Don't let me detract you from what GetMem told you. He's more right than wrong :P

I just wanted to ask some, maybe dumb, questions:
Why are you doing this with *.dlls?
Is it to hide those secrets on compiled binary, like some kind of security by obscurity?
Is it to then distribute that *.dll as some sort of an unlock key when someone purchases a license?

The example code you provided as made me quite curious of your intentions. I'm feeling quite cat'ish :)

Cheers,
Gus
Title: Re: Help with sending library functions to another program
Post by: karmacomposer on March 31, 2021, 11:53:23 pm
@karmacomposer

1. You did not check the value of hndlDll
2. If hndlDll >0 then you should call GetProcedureAddress(hndlDll , 'getUser')

Please check the attached project from this link: https://forum.lazarus.freepascal.org/index.php/topic,53621.msg396954.html#msg396954 .

Thank you.  I will try that tomorrow when I am coding.  I assume I do the same for the other functions.

Mike
Title: Re: Help with sending library functions to another program
Post by: karmacomposer on March 31, 2021, 11:55:36 pm
Hey karmacomposer,

Don't let me detract you from what GetMem told you. He's more right than wrong :P

I just wanted to ask some, maybe dumb, questions:
Why are you doing this with *.dlls?
Is it to hide those secrets on compiled binary, like some kind of security by obscurity?
Is it to then distribute that *.dll as some sort of an unlock key when someone purchases a license?

The example code you provided as made me quite curious of your intentions. I'm feeling quite cat'ish :)

Cheers,
Gus

While the code above is not part of our security product (created in another, more secure language), there is quite a lot of functions and procedures that are and I need to distribute them
as some kind of protected library.  Since you can decompile a .dll fairly easily, we will be obsfucating and encrypting the compiled code and then
distributing it. So, yes, it is intended to be a locked library that clients can use without getting to the actual source code.

Mike
Title: Re: Help with sending library functions to another program
Post by: karmacomposer on April 01, 2021, 06:41:56 pm
I tried what you suggested:

Code: [Select]
unit unitGetServerInfo2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, dynlibs;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);

  private
    { dynamically linking }
    hLib: TlibHandle;

  public

  end;

var
  Form1: TForm1;
  hndlDll: TLibHandle = dynlibs.NilHandle;
  User: pChar;
  Pass: pChar;
  Loc: pChar;
  Username: pChar;
  Password: pChar;
  Location: pChar;

implementation

function getUser(var User: pChar): pChar; cdecl;
begin
   hndlDll:= LoadLibrary('serverInfo.dll');
   if hndlDll>0 then GetProcedureAddress(hndlDll , 'getUser');
   Username := User;
   showmessage(Username);
end;

function getPass(var Pass: pChar): pChar; cdecl;
begin
   hndlDll:= LoadLibrary('serverInfo.dll');
   if hndlDll>0 then GetProcedureAddress(hndlDll , 'getPass');
   Password := Pass;
   showmessage(Password);
end;

function getLoc(var Loc: pChar): pChar; cdecl;
begin
   hndlDll:= LoadLibrary('serverInfo.dll');
   if hndlDll>0 then GetProcedureAddress(hndlDll , 'getLoc');
   Location := Loc;
   showmessage(Location);
end;

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  getUser(User);
  getPass(Pass);
  getLoc(Loc);
end;

end.

and it did not work, nor did it throw an error.

How can I make this work please?

Thank you.

Mike
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on April 01, 2021, 06:50:53 pm
Hey Mike,
I tried what you suggested:
[snipped code]
and it did not work, nor did it throw an error.
How can I make this work please?

Im sorry Mike, but you didn't do everything GetMem told you to:
@karmacomposer

1. You did not check the value of hndlDll
2. If hndlDll >0 then you should call GetProcedureAddress(hndlDll , 'getUser')

Please check the attached project from this link: https://forum.lazarus.freepascal.org/index.php/topic,53621.msg396954.html#msg396954 .

You didn't call GetProcedureAddress(hndlDll , 'getUser').

Are you sure you had a good look at the project attached on the post that GetMem gave you?

Cheers,
Gus
Title: Re: Help with sending library functions to another program
Post by: karmacomposer on April 01, 2021, 07:00:48 pm
Hey Mike,
I tried what you suggested:
[snipped code]
and it did not work, nor did it throw an error.
How can I make this work please?

Im sorry Mike, but you didn't do everything GetMem told you to:
@karmacomposer

1. You did not check the value of hndlDll
2. If hndlDll >0 then you should call GetProcedureAddress(hndlDll , 'getUser')

Please check the attached project from this link: https://forum.lazarus.freepascal.org/index.php/topic,53621.msg396954.html#msg396954 .

You didn't call GetProcedureAddress(hndlDll , 'getUser').

Are you sure you had a good look at the project attached on the post that GetMem gave you?

Cheers,
Gus

My mistake.  I corrected it and then tried again - still not working.

Code: [Select]
unit unitGetServerInfo2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, dynlibs;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);

  private
    { dynamically linking }
    hLib: TlibHandle;

  public

  end;

var
  Form1: TForm1;
  hndlDll: TLibHandle = dynlibs.NilHandle;
  User: pChar;
  Pass: pChar;
  Loc: pChar;
  Username: pChar;
  Password: pChar;
  Location: pChar;

implementation

function getUser(var User: pChar): pChar; cdecl;
begin
   hndlDll:= LoadLibrary('serverInfo.dll');
   if hndlDll>0 then GetProcedureAddress(hndlDll , 'getUser');
   Username := User;
   showmessage(Username);
end;

function getPass(var Pass: pChar): pChar; cdecl;
begin
   hndlDll:= LoadLibrary('serverInfo.dll');
   if hndlDll>0 then GetProcedureAddress(hndlDll , 'getPass');
   Password := Pass;
   showmessage(Password);
end;

function getLoc(var Loc: pChar): pChar; cdecl;
begin
   hndlDll:= LoadLibrary('serverInfo.dll');
   if hndlDll>0 then GetProcedureAddress(hndlDll , 'getLoc');
   Location := Loc;
   showmessage(Location);
end;

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  getUser(User);
  getPass(Pass);
  getLoc(Loc);
end;

end.

I could not find any attached project in that link.

Help is appreciated.

Mike
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on April 01, 2021, 07:10:53 pm
Hey Mike,

I wasn't gonna say anything more, but after having a look at the code that GetMem linked to (https://forum.lazarus.freepascal.org/index.php?action=dlattach;topic=53621.0;attach=41897), it's quite apparent that you did nothing that he suggested, well apart from that single if statement, and then came back to bitch about it.

If I read GetMem's code correctly you need to:

So you did not do any of those things.

And again:
My mistake.  I corrected it and then tried again - still not working.

You did not correct anything since you completely failed to understand what to do with GetProcedureAddress().

I could not find any attached project in that link.

I'm sure that what you want to say is: I didn't even try to look.

Because I found it immediately (https://forum.lazarus.freepascal.org/index.php?action=dlattach;topic=53621.0;attach=41897), downloaded it, unzipped it and had a look at it.

You on the other hand want us to do the leg work for you. That's not what this forum is about.
We give you help, so you can help yourself. We don't do Homework for you!!

Cheers,
Gus

PS: I've linked the code twice. I hope that's enough for you to have a look at it and THEN come back if you still have issues.
Title: Re: Help with sending library functions to another program
Post by: karmacomposer on April 01, 2021, 07:17:58 pm
Hey Mike,

I wasn't gonna say anything more, but after having a look at the code that GetMem linked to (https://forum.lazarus.freepascal.org/index.php?action=dlattach;topic=53621.0;attach=41897), it's quite apparent that you did nothing that he suggested, well apart from that single if statement, and then came back to bitch about it.

If I read GetMem's code correctly you need to:
  • Declare the signature of the functions inside the DLL.
  • Load the library just once, which make absolute sense, why the heck load it for each call!?!?
  • Get the function address into the var you're gonna use with GetProcedureAddress() by typecasting it to the appropriate signature.
  • Call the function through the variable set in the step before.

So you did not do any of those things.

And again:
My mistake.  I corrected it and then tried again - still not working.

You did not correct anything since you completely failed to understand what to do with GetProcedureAddress().

I could not find any attached project in that link.

I'm sure that what you want to say is: I didn't even try to look.

Because I found it immediately (https://forum.lazarus.freepascal.org/index.php?action=dlattach;topic=53621.0;attach=41897), downloaded it, unzipped it and had a look at it.

You on the other hand want us to do the leg work for you. That's not what this forum is about.
We give you help, so you can help yourself. We don't do Homework for you!!

Cheers,
Gus

PS: I've linked the code twice. I hope that's enough for you to have a look at it and THEN come back if you still have issues.

While I appreciate the help, I do not appreciate the tone.  I wrote the initial code.  Obviously, I did it wrong.  I am asking for help.  I don't need sanctimonious remarks from someone who must enjoy belittling people who ask for help.  And NO, I could not find the attached file, so obviously I do not know how the forum attaches files.  If someone would point it out to me, I would download it and study it.

Do me a favor GUS and do not help me any more.  I'd hate to be in a class with you if you were the instructor.

Anyone else, thank you.

Mike
Title: Re: Help with sending library functions to another program
Post by: karmacomposer on April 01, 2021, 07:23:01 pm
If you were referring to plugin.zip, that is why I could not find it.  Again, I appreciate the help, but if someone would have just said "download plugin.zip at this link" I would have found it immediately.

I'll study that file and see if I can do this on my own.

I wrote an entire security program in another language, so I am not an idiot.  I just don't know how to grab functions and procedures from a .dll file.  I even watched videos, took classes on Pascal and all they teach is how to do rudimentary stuff. I am writing the code, but I ask for help if I get stuck since this is about the ONLY resource for Lazarus other than Stack Overflow and the Wiki.

Thanks again.

Mike
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on April 01, 2021, 08:24:53 pm
Hey Mike,

I don't turn on The Tone just willy nilly.
I turn on The Tone when the person that is being helped makes a small to no effort to pay attention to what is being said to him/her.
I turn on The Tone when the person has been advised, in a normal and helpful tone, more than once, and still cries wolf.

GetMem sent you a link that would land you in his exact message, that's what the #msg396954 at the end of the URL makes the browser do.
You then had only to look at the space between his message and the next to find the link to plugin.zip.
Right after any message you find the attachment area:

It's all over the forum and I'm sure you've stumbled upon it many times before.

What I don't appreciate is someone that has been given polite instruction on how to be helped, then turns around and complains I have a tone when you have failed to do the legwork.
I'm sorry if you feel entitled to anything. You're not. We help here if everything is civil. Entitlement is not being civil.
Like you said, you're not stupid, but contrary to that is all the evidence of your previous interaction. Don't you agree?

I linked to the file TWICE and it took you TWO quoted replies to even acknowledge it. With that kind of evidence from you, you wanna tell me I can't conclude something suspicious about you?
How am I to be convinced that you're NOT stupid after that?

I sincerely hope that, NOW, that you have the code you can help yourself and finish your endeavour. No ill feelings.
Just pay attention to your environment next time, Kay?

Cheers,
Gus
Title: Re: Help with sending library functions to another program
Post by: GetMem on April 01, 2021, 08:49:02 pm
@karmacomposer

See attached project.
1. Build the dll(serverinfo subfolder)
2. Run the project
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on April 01, 2021, 08:58:56 pm
Hey GetMem,

See attached project.

Awwww, GetMem, you are such a softy!!! ;-P

I just ended scalding him because we don't do homework and you gone-n-dun it :D

Oh, well Mike, you got lucky GetMem is such a nice guy and did the legwork for you :P
I hope you thank him appropriately !!

Cheers,
Gus
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on April 01, 2021, 09:02:14 pm
Hey Mike,

If after the effort GetMem put on for you, you turn around and say you can't find the bloody file, I'll pop up from your monitor and do a Jethro Gibbs on you by slapping the back of that head of yours !!

Cheers,
Gus
Title: Re: Help with sending library functions to another program
Post by: GetMem on April 01, 2021, 09:13:21 pm
@Gustavo 'Gus' Carreno
Quote
Awwww, GetMem, you are such a softy!!! ;-P
You sound like my wife.  :)
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on April 01, 2021, 09:21:10 pm
Hey GetMem,

You sound like my wife.  :)

ROTFL!!!!
Well, you are and you've captured my heart. I might even forget I'm strait and ask you out on a date ;-D

And don't forget to tell your wife that she's a really lucky lass !!

Cheers,
Gus
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on April 02, 2021, 03:27:04 am
Hey Mike,

Oooops, I forgot to reply to this one...

[snip] (created in another, more secure language) [snip],

There is no such thing as levels of secure between compiled languages.
They all have to abide by the same rules and produce a binary that is compatible with the operating system they'll run on.
What makes any programming secure or insecure is the element between the chair and the keyboard.

To be honest, if we're talking about "security", Pascal is one of the most "secure" languages on the market.
Why, you ask?
Well, let's see:

Rust is probably the most "secure" one at the moment. It's a new language that's trying hard to not make the mistakes of the past. And it has good memory and string handling embedded.

But, the element between the chair and the keyboard can still make programs in these languages that are completely insecure.
Strong typing and good string handling is not a silver bullet!!

[snip] some kind of protected library. [snip]

I would like to know what you call a protected library.
Like I said about the binaries, also the dynamic libraries have to follow an established format so that any program can load them.
The only protection you get is the fact that a compiled anything does not decompile into the original code.
It does, nonetheless, disassemble into assembly, and with that you can recreate the original source with a bit of patience and know how.
So again, what is a protected library?

Since you can decompile a .dll fairly easily, we will be obsfucating and encrypting the compiled code and then
distributing it. So, yes, it is intended to be a locked library that clients can use without getting to the actual source code.

I would really like to know how you will be obfuscating and encrypting a dynamic library. If you do that, I'm afraid that you'll invalidate the established format that they have to be written on.
But let's say that you do obfuscate and/or encrypt said dynamic library, you then still have to provide, in each program that uses the dynamic library, the means(a key and the code to de-obfuscate/de-encrypt) to reverse that in order to be usable.
That means that you locked the door, but left the key on the lock. That pretty much invalidates the exercise, no?

The way you're looking at this security issue is rather naive. Just think, if all that techno-bable you said could be possible, don't you think that someone had done it before?
Ask around and find for yourself. There is no 100% guaranteed way of securing your code. Just less easy to do it.

Cheers,
Gus
Title: Re: Help with sending library functions to another program
Post by: karmacomposer on April 02, 2021, 05:47:07 pm
@karmacomposer

See attached project.
1. Build the dll(serverinfo subfolder)
2. Run the project

Thank you very much for this.  I will investigate what makes this work.  Lazarus (Free Pascal) works so differently when it comes to external files and I just could not find very much information explaining it clearly.  I work best by examples.

My big problem will be creating very large functions which currently work in their pascal units but I need to offload them to a .dll and still be able to call them and get a result.  That was what this test was for.

I need to study TFarProc, TFunc and TLibHandle to see how they work in this context.  Everything else seems straight forward.

Again, thank you.

Mike
Title: Re: Help with sending library functions to another program
Post by: karmacomposer on April 02, 2021, 05:53:20 pm
Hey Mike,

Oooops, I forgot to reply to this one...

[snip] (created in another, more secure language) [snip],

There is no such thing as levels of secure between compiled languages.
They all have to abide by the same rules and produce a binary that is compatible with the operating system they'll run on.
What makes any programming secure or insecure is the element between the chair and the keyboard.

To be honest, if we're talking about "security", Pascal is one of the most "secure" languages on the market.
Why, you ask?
Well, let's see:
  • It's a strong typed language, the opposite of many interpreted ones
  • It has a managed string implementation, the opposite of C/C++ that produce most of the buffer overflows
  • Since one if it's premises was to be close to a natural language(English) as possible, it's rather readable by nature

Rust is probably the most "secure" one at the moment. It's a new language that's trying hard to not make the mistakes of the past. And it has good memory and string handling embedded.

But, the element between the chair and the keyboard can still make programs in these languages that are completely insecure.
Strong typing and good string handling is not a silver bullet!!

[snip] some kind of protected library. [snip]

I would like to know what you call a protected library.
Like I said about the binaries, also the dynamic libraries have to follow an established format so that any program can load them.
The only protection you get is the fact that a compiled anything does not decompile into the original code.
It does, nonetheless, disassemble into assembly, and with that you can recreate the original source with a bit of patience and know how.
So again, what is a protected library?

Since you can decompile a .dll fairly easily, we will be obsfucating and encrypting the compiled code and then
distributing it. So, yes, it is intended to be a locked library that clients can use without getting to the actual source code.

I would really like to know how you will be obfuscating and encrypting a dynamic library. If you do that, I'm afraid that you'll invalidate the established format that they have to be written on.
But let's say that you do obfuscate and/or encrypt said dynamic library, you then still have to provide, in each program that uses the dynamic library, the means(a key and the code to de-obfuscate/de-encrypt) to reverse that in order to be usable.
That means that you locked the door, but left the key on the lock. That pretty much invalidates the exercise, no?

The way you're looking at this security issue is rather naive. Just think, if all that techno-bable you said could be possible, don't you think that someone had done it before?
Ask around and find for yourself. There is no 100% guaranteed way of securing your code. Just less easy to do it.

Cheers,
Gus

The main language I use that I consider very secure is because the source code can be encrypted before the compile stage and the resulting executable cannot be disassembled or decompiled - the resulting code is encrypted and therefore useless to outside attempts.

No other language offers this that I know of.  Pascal is the next best and I needed to convert our security software to allow for web languages - which every client asked for.  With the other language, we would have to create the entire project, GUI and all.  This way, the client can use any front end language and we can interface with it using XML (post/get) and SSL for transit. Once it hits our middleware/core, we can then encrypt and store the data as per our normal system.

To say it's not been easy is an understatement.  I used to code in Pascal back in Borland days, but I am very, very rusty.  My last software I created with Pascal was called Rocket and was a advanced web browser (for its time) way back in the days of 56k dialup.

The language I have been using for over 20 years since then is called Livecode and is what allows me to encrypt the source before compilation, making it extremely resilient to cracking and hacking.

Mike
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on April 02, 2021, 06:22:01 pm
Hey Mike,

The language I have been using for over 20 years since then is called Livecode and is what allows me to encrypt the source before compilation, making it extremely resilient to cracking and hacking.

I had a look at the LiveCode web site and from a quick look, granted not a deep dive into the subject, it looks to me that it's an interpreted language or a compile to byte code language(a la .NET).

I was comparing compiled to compiled. You're comparing compiled to whatever LiveCode is. It's not apples to apples is it?

You can obfuscate and encrypt all you want, but the binary that runs the obfuscated/encrypted code still has, in plain old assembler, the procedure and the key to undo all that and then JIT compile or whatever it does to run your code.
Again, with a bit of patience and a good Hex Editor, you can get ALL your source back. At least with a compiled binary, you have to manually recreate the source by hand. This LiveCode scenario just gives you all the code back.

To be honest, no one in it's right mind will attempt any hacking and cracking of, either a compiled binary or your LiveCode thingamajig if it doesn't pay off immensely.
So in reality, compiled or LiveCode, have the same level of security.
Unless you're doing top secret military contract, what you're saying is nothing more than Marketing bable to get clients to pay more cash.

Just my 2c.

Cheers,
Gus
Title: Re: Help with sending library functions to another program
Post by: Gustavo 'Gus' Carreno on April 02, 2021, 06:35:46 pm
Hey Mike,

No other language offers this that I know of.  Pascal is the next best and I needed to convert our security software to allow for web languages - which every client asked for.  With the other language, we would have to create the entire project, GUI and all.  This way, the client can use any front end language and we can interface with it using XML (post/get) and SSL for transit. Once it hits our middleware/core, we can then encrypt and store the data as per our normal system.

What you're describing here is your typical OAuth2 secured, REST Service behind some kind of LAMP stack, but with XML(old and on it's way out) instead of JSON.
This should be tackled from a web centric tools approach, and yes, Object Pascal is not the best tool for the project here.
And I'm guessing, neither is LiveCode.

I'm guessing that your superiors decided on your current path due to the legacy code that has piled up, right? Or just because you don't have Web competency in your programmer's pool.

From what you're telling me, you're about to re-invent the wheel, but 5 years too late and having to catch up. Not a good place to be... Microsoft tried that with smartphones and had to give up...

But hey, it's their money, they can waste it as they see fit :)

Cheers,
Gus
TinyPortal © 2005-2018