flat assembler
Message board for the users of flat assembler.

Index > Windows > Call C function from FASM

Author
Thread Post new topic Reply to topic
dromenox



Joined: 11 Nov 2015
Posts: 3
dromenox 11 Nov 2015, 17:28
I'm trying to call a C function from a DLL made in FASM. How can I do that?

Test.asm
Code:
format PE GUI 4.0 DLL
entry DllEntryPoint

include 'INCLUDE/win32ax.inc'
section '.text' code readable executable

proc dwMain


 ; CALL [test] ;something like this

 ret
endp

proc DllEntryPoint hinstDLL,fdwReason,lpvReserved

  CMP [fdwReason], 1
  JNE .sai

  invoke CreateThread,NULL,NULL,dwMain,NULL,NULL,NULL;

  .sai:

    mov eax, TRUE
    ret
endp

section '.idata' import data readable writeable

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

  import kernel,\
    CreateThread, 'CreateThread'


section '.reloc' fixups data readable discardable
    


Test.c
Code:
#include <Windows.h>
void test()
{
    MessageBoxA(0, "inside c", "inside c", 0);
}
    
Post 11 Nov 2015, 17:28
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 11 Nov 2015, 21:58
Either statically or dynamically import. I'd chose the first one.

https://en.wikipedia.org/wiki/Dynamic-link_library#C


Also, the thread function expects one parameter.
Post 11 Nov 2015, 21:58
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20481
Location: In your JS exploiting you and your system
revolution 11 Nov 2015, 23:27
You need to export your functions with the export macro.

The following is the example DLL in the fasm download. Notice the use of 'export':
Code:
; DLL creation example

format PE GUI 4.0 DLL
entry DllEntryPoint

include 'win32a.inc'

section '.text' code readable executable

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

; VOID ShowErrorMessage(HWND hWnd,DWORD dwError);

proc ShowErrorMessage hWnd,dwError
  local lpBuffer:DWORD
        lea     eax,[lpBuffer]
        invoke  FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,[dwError],LANG_NEUTRAL,eax,0,0
        invoke  MessageBox,[hWnd],[lpBuffer],NULL,MB_ICONERROR+MB_OK
        invoke  LocalFree,[lpBuffer]
        ret
endp

; VOID ShowLastError(HWND hWnd);

proc ShowLastError hWnd
        invoke  GetLastError
        stdcall ShowErrorMessage,[hWnd],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',\
         ShowErrorMessage,'ShowErrorMessage',\
         ShowLastError,'ShowLastError'

section '.reloc' fixups data readable discardable    
Post 11 Nov 2015, 23:27
View user's profile Send private message Visit poster's website Reply with quote
dromenox



Joined: 11 Nov 2015
Posts: 3
dromenox 12 Nov 2015, 11:24
Thank you! But you do not understand me:
I want to call C from FASM and not vice versa.
Post 12 Nov 2015, 11:24
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20481
Location: In your JS exploiting you and your system
revolution 12 Nov 2015, 11:34
There are two ways to call C functions.

If it is a DLL you call then use 'cinvoke'. This is when you use the import as one does with the WIndows DLLs. Exactly the same usage as wsprintf.

If it is statically linked then use 'ccall'. This is where you use extrn and use a linker to make the exe file.
Post 12 Nov 2015, 11:34
View user's profile Send private message Visit poster's website Reply with quote
dromenox



Joined: 11 Nov 2015
Posts: 3
dromenox 12 Nov 2015, 11:43
revolution wrote:
There are two ways to call C functions.

If it is a DLL you call then use 'cinvoke'. This is when you use the import as one does with the WIndows DLLs. Exactly the same usage as wsprintf.

If it is statically linked then use 'ccall'. This is where you use extrn and use a linker to make the exe file.


I want to do just the DllEntryPoint with FASM and the rest of the code in C. I need to link the .OBJ files?
Post 12 Nov 2015, 11:43
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20481
Location: In your JS exploiting you and your system
revolution 12 Nov 2015, 11:48
dromenox wrote:
I want to do just the DllEntryPoint with FASM and the rest of the code in C. I need to link the .OBJ files?
Yes. Use format COFF (or similar) and link to the C output. You will have to tell the linker you want a DLL.
Post 12 Nov 2015, 11:48
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 12 Nov 2015, 11:48
dromenox
Yes, if you want both C and fasm to be compiled into a single dll.

_________________
Faith is a superposition of knowledge and fallacy
Post 12 Nov 2015, 11:48
View user's profile Send private message Reply with quote
knell



Joined: 13 Nov 2014
Posts: 3
knell 12 Nov 2015, 16:57
I'm newbie about linker, dynamic/static library and such, so correct me if I'm wrong, did Dromenox want it like this?
Code:
start:
      ...
      ...
      cinvoke  printf, stringFormat, message
      ...
      ...

section '.imports' import data readable
  library msvcrt, 'msvcrt'

  import msvcrt,\
      printf, 'printf'
....
    

As I know, to make a shared dll using gcc is simply done like this:
Code:
$ gcc -shared thecodes.c -o theout.dll    


And to use function that defined in theout.dll in fasm is simply done like example above.

(Edit: corrected to use cinvoke)


Last edited by knell on 12 Nov 2015, 22:32; edited 1 time in total
Post 12 Nov 2015, 16:57
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1678
Location: Toronto, Canada
AsmGuru62 12 Nov 2015, 17:58
I think you need cinvoke here.
Post 12 Nov 2015, 17:58
View user's profile Send private message Send e-mail Reply with quote
knell



Joined: 13 Nov 2014
Posts: 3
knell 12 Nov 2015, 22:31
Thanks for correction. I was going to ask what the different between invoke and cinvoke, but found it in docs.
Post 12 Nov 2015, 22:31
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.