Author Topic: Calling C functions from ASM  (Read 12967 times)

Offline montraydavis

  • Jr. Member
  • *
  • Posts: 6
Calling C functions from ASM
« on: January 15, 2011, 02:51:20 PM »
Hello. I am trying to figure out how to call C functions from assembly. I understand calling ASM from C ( via inline assembly ), but not sure how to do this the other way around.

For instance

Code: [Select]
//C code - hello.c

int sayhello(){
     printf("Hello!");
}

Code: [Select]
;Assembly file - main

[extern sayhello]
call sayhello

I want to link the two above, and have the assembly call "sayhello", which is located in the C code.

Thanks in advance. ( I hope this makes sense )

Online Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Calling C functions from ASM
« Reply #1 on: January 15, 2011, 04:19:11 PM »
Well, your C file ought to "#include <stdio.h>" for printf. Your .asm file wants to have "global main" and "extern sayhello" in it... and "main:" and probably "ret". Other than for Linux, you probably want underscores on "_main", etc... in the asm file - don't need 'em in the .c file. You can spell it that way in the source, or Nasm will add 'em if you add "--prefix _" to the command line. You've pretty much got it.

Best,
Frank


Offline montraydavis

  • Jr. Member
  • *
  • Posts: 6
Re: Calling C functions from ASM
« Reply #2 on: January 16, 2011, 11:43:59 AM »
Well, your C file ought to "#include <stdio.h>" for printf. Your .asm file wants to have "global main" and "extern sayhello" in it... and "main:" and probably "ret". Other than for Linux, you probably want underscores on "_main", etc... in the asm file - don't need 'em in the .c file. You can spell it that way in the source, or Nasm will add 'em if you add "--prefix _" to the command line. You've pretty much got it.

Best,
Frank



Thanks, but there seems to be a problem. I am compiling as 'binary' (and yes, I absolutely need binary for other purposes), and it says that extern isn't supported in binaries. :\

Online Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Calling C functions from ASM
« Reply #3 on: January 16, 2011, 01:49:19 PM »
Yes, that's a problem! "Impossible" is a really big word, but what you propose is "highly impractical".

The "-f bin" format doesn't support "extern" 'cause it's a feature of a linkable file format, and "-f bin" doesn't generate linkable objects. You could, in theory, "hand build" an object file format header with "-f bin"... but once you ran a linker on it, it would no longer be a flat binary file. Depending on why you "absolutely need binary for other purposes", this might be acceptable, or not.

If you "really need binary", perhaps you don't really need to call a C function. I'd go so far as to say you definitely don't "need" to call a C function, but it may be "inconvenient" to avoid it.

Where is "printf" when this is going on? In a dynamic library? It might be possible to write an equivalent of "LoadLibrary" and "GetProcessAddress" into your binary file. In theory, it should be possible to write code to find some other function (C or not) wherever it may be, load it into memory (if it isn't already in memory), possibly apply relocations, and execute it. I doubt if you want to do this. Almost certainly easier to emulate the C function!

I think you want to abandon either "binary file" or "call C". Which one, probably depends on what you're trying to do. What environment is this program intended to run in?

Best,
Frank


Offline QUASAR

  • Jr. Member
  • *
  • Posts: 4
Re: Calling C functions from ASM
« Reply #4 on: January 17, 2011, 07:44:08 PM »
If you want to use some kind of shellcode or self-modifying code you need to compile your asm code using nasm and "-f bin" option and then dump it to binary form using "xxd" or similar command, then include resulting hex bytes in C source. Great book "Hacking: The Art of Exploitation" will provide you some examples.

Offline b.zaar

  • New Member
  • Posts: 1
Re: Calling C functions from ASM
« Reply #5 on: February 06, 2011, 09:07:39 PM »
The best way to link asm and C is to compile them to a common object file format first and then link them with something like gnu ld into a binary file. I've used this same method to make a x86 boot loader.