flat assembler
Message board for the users of flat assembler.

Index > Windows > about fasm dll calling from delphi, need help

Author
Thread Post new topic Reply to topic
senolc_eht



Joined: 22 Mar 2004
Posts: 57
Location: Indonesia
senolc_eht 14 Nov 2009, 00:47
i have this code in fasm
Code:
; DLL creation example

format PE GUI 4.0 DLL
entry DllEntryPoint

include 'win32a.inc'
section '.data' data readable writeable

text db 'Sad Song',0

section '.text' code readable executable

proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
        mov     eax,TRUE
        ret
endp

proc ShowLastError stdcall uses esi edi ebx, outBuffer
locals
   add1 dd ?
endl
       mov esi,[outBuffer]
      invoke MessageBox,NULL,[esi],NULL,MB_OK
      mov     esi, text
      mov     edi, [outBuffer];
      mov     edi,[edi]
       mov ecx,4
       .loop:
       push ecx
       mov al,byte[esi]
       mov byte [edi],al   ; <======= make access violation ..?
       pop ecx
       loop .loop
       xor eax,eax
       ret
endp

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL'

  import kernel,\
         GetLastError,'GetLastError',\
         SetLastError,'SetLastError',\
         FormatMessage,'FormatMessageA',\
         LocalFree,'LocalFree'

  import user,\
         MessageBox,'MessageBoxA'

section '.edata' export data readable

  export 'ERRORMSG.DLL',\
         ShowLastError,'ShowLastError'

section '.reloc' fixups data discardable
    


and this code in delphi
Code:
procedure TForm1.btn1Click(Sender: TObject);
var s :string;
begin
  s := 'Happy song';
  ShowLastError(s);
  application.MessageBox( PChar(s),'text',MB_OK);;
end;
    


when i try to write "sad song" into s variable in delphi i get and exception "access violation".
can anybody help me..?


regard
Senolc_eht

_________________
sorry if i always asking.....
Post 14 Nov 2009, 00:47
View user's profile Send private message Yahoo Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20458
Location: In your JS exploiting you and your system
revolution 14 Nov 2009, 01:16
What is the value of edi when you get the access violation?
Post 14 Nov 2009, 01:16
View user's profile Send private message Visit poster's website Reply with quote
senolc_eht



Joined: 22 Mar 2004
Posts: 57
Location: Indonesia
senolc_eht 14 Nov 2009, 01:20
how to know the value of edi ?

i just assuming

Code:
mov     edi, [outBuffer]; 
mov     edi,[edi]
    


is same with this just use edi as pointer

Code:
mov esi,[outBuffer] 
invoke MessageBox,NULL,[esi],NULL,MB_OK
    


with esi..

then i just write to edi...

regard
Senolc_eht
Post 14 Nov 2009, 01:20
View user's profile Send private message Yahoo Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 14 Nov 2009, 01:28
Could you upload the Delphi executable? (I don't have a Delphi compiler at hand right now).
Post 14 Nov 2009, 01:28
View user's profile Send private message Reply with quote
senolc_eht



Joined: 22 Mar 2004
Posts: 57
Location: Indonesia
senolc_eht 14 Nov 2009, 01:33
this the delphi executable but watch out about virus, couse i don't use antivirus...

regard

senolc_eht


Description:
Download
Filename: Project1.zip
Filesize: 185.41 KB
Downloaded: 185 Time(s)


_________________
sorry if i always asking.....
Post 14 Nov 2009, 01:33
View user's profile Send private message Yahoo Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 14 Nov 2009, 01:53
Yes, what I imagined but though it wasn't possible in Delphi, you are trying to write to a constant.

Try doing the following modification:
Code:
procedure TForm1.btn1Click(Sender: TObject);
var s: string;
begin
  s := 'Happy song';
  s[1] := 'H'; { I'm expecting the compiler will create a new copy (read-write this time) of the string }
  ShowLastError(s);
  application.MessageBox( PChar(s),'text',MB_OK);;
end;
    


That may solve the access violation but you'll still have the problem that the allocated space may not be enough (so the access violation and/or memory corruption may occur in a later iteration of the loop).

I don't remember much of Delphi but you should pass a PChar and pre-allocated with enough memory. If I remember right, the String type has a length field and in the Assembly code you are not handling it so better stick with PChar which is easier (them consist of the string only and are NULL terminated so there are no extra structures, only the array of chars is present).
Post 14 Nov 2009, 01:53
View user's profile Send private message Reply with quote
senolc_eht



Joined: 22 Mar 2004
Posts: 57
Location: Indonesia
senolc_eht 14 Nov 2009, 02:24
i guess this work

Code:

; DLL creation example

format PE GUI 4.0 DLL
entry DllEntryPoint

include 'win32a.inc'
section '.data' data readable writeable

text db 'Sad Song',0

section '.text' code readable executable

proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
        mov     eax,TRUE
        ret
endp

proc ShowLastError stdcall uses esi edi ebx, outBuffer
locals
   add1 dd ?
endl
       mov esi,[outBuffer]
       inc esi                                ;<==== another question why i should do this
      invoke MessageBox,NULL,esi,NULL,MB_OK
      mov     esi, text
      mov     edi, [outBuffer];
      inc edi
      invoke lstrlen,esi
      mov ecx,eax
      .loop:
      push ecx
           mov al, byte [esi]
           mov byte [edi],al
      inc esi
      inc edi
      pop ecx
      loop .loop
      mov byte [edi],0
      ;invoke lstrcpy,edi,esi
      xor eax,eax
       ret
endp

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

 include 'api\kernel32.inc'
 include 'api\user32.inc'

section '.edata' export data readable

  export 'ERRORMSG.DLL',\
         ShowLastError,'ShowLastError'

section '.reloc' fixups data discardable
    


with delphi like this
Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);

  private
    { Private declarations }
  public

    { Public declarations }
  end;
  procedure ShowLastError(s1:Pointer);stdcall; external 'ERRORMSG.DLL' name 'ShowLastError';
var
  Form1: TForm1;


implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
var s :string[255];
    s1 : string;
begin
  s := 'Happy song';
  ShowLastError(@s);
  s1 := s;
  application.MessageBox(PChar(s1),'text',MB_OK);;
end;

end.
    


another question why should do this

Code:
  mov esi,[outBuffer]
       inc esi                                ;<==== another question why i should do this
      invoke MessageBox,NULL,esi,NULL,MB_OK
    


and thanks for the help..

regard
Senolc_eht

_________________
sorry if i always asking.....
Post 14 Nov 2009, 02:24
View user's profile Send private message Yahoo Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20458
Location: In your JS exploiting you and your system
revolution 14 Nov 2009, 03:53
What is the format of outBuffer? Is it a length byte followed by the text? Perhaps the Delphi manual can help you to answer the question?
Post 14 Nov 2009, 03:53
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 14 Nov 2009, 05:10
When you constraint the size of the string in Delphi the first character (stringVar[0]) is the string length actually (inherited from Turbo Pascal), for that reason the compiler won't allow you to define strings larger than 255 chars this way.

Additionally take in mind you cannot rely on having the last char as NULL neither, it is not required for the string type.

Delphi has some support for C's "char *", you better use it.
Post 14 Nov 2009, 05:10
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 14 Nov 2009, 16:18
I use length-prefixed strings all the time. They're much better in most cases. Alas, not for the Windows API Sad
Post 14 Nov 2009, 16:18
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 14 Nov 2009, 17:34
Unless them are guaranteed to be NUL terminated I found that them can be a little bit annoying to process.

Example:

Code:
; Tests if NUL terminated string does not contains chars other than digits
nulString:
mov dl, [eax]
inc eax
sub dl, '0'
cmp dl, 9
jbe nulString

xor eax, eax
cmp dl, -'0'
sete al

ret

; Tests if Turbo Pascal string does not contains chars other than digits
pascalString:
mov cl, [eax]
jmp .checkLength

.loop:
inc eax
mov dl, [eax]
sub dl, '0'
cmp dl, 9
ja .retZero

.checkLength:
sub cl, 1
jnc .loop

mov eax, 1
ret

.retZero:
xor eax, eax
ret    
Post 14 Nov 2009, 17:34
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.