Tyilo
Tyilo

Reputation: 30102

c library x86/x64 assembler

Is there a C library for assembling a x86/x64 assembly string to opcodes?

Example code:

/* size_t assemble(char *string, int asm_flavor, char *out, size_t max_size); */

unsigned char bytes[32];
size_t size = assemble("xor eax, eax\n"
                       "inc eax\n"
                       "ret",
                       asm_x64, &bytes, 32);

for(int i = 0; i < size; i++) {
    printf("%02x ", bytes[i]);
}

/* Output: 31 C0 40 C3 */

I have looked at asmpure, however it needs modifications to run on non-windows machines.

I actually both need an assembler and a disassembler, is there a library which provides both?

Upvotes: 17

Views: 8513

Answers (7)

Tyilo
Tyilo

Reputation: 30102

Keystone seems like a great choice now, however it didn't exist when I asked this question.

Upvotes: 2

user4872223
user4872223

Reputation: 101

There is a library that is seemingly a ghost; its existance is widely unknown:

XED (X86 Encoder Decoder)

Intel wrote it: https://software.intel.com/sites/landingpage/pintool/docs/71313/Xed/html/

It can be downloaded with Pin: https://software.intel.com/en-us/articles/pintool-downloads

Upvotes: 10

GrayFace
GrayFace

Reputation: 1381

I'm using fasm.dll: http://board.flatassembler.net/topic.php?t=6239 Don't forget to write "use32" at the beginning of code if it's not in PE format.

Upvotes: 1

kirbyfan64sos
kirbyfan64sos

Reputation: 10727

You might want libyasm (the backend YASM uses). You can use the frontends as examples (most particularly, YASM's driver).

Upvotes: 2

oakad
oakad

Reputation: 7585

Here you go:

http://www.gnu.org/software/lightning/manual/lightning.html

Gnu Lightning is a C library which is designed to do exactly what you want. It uses a portable assembly language though, rather than x86 specific one. The portable assembly is compiled in run time to a machine specific one in a very straightforward manner.

As an added bonus, it is much smaller and simpler to start using than LLVM (which is rather big and cumbersome).

Upvotes: 2

Carl Norum
Carl Norum

Reputation: 224864

Sure - you can use llvm. Strictly speaking, it's C++, but there are C interfaces. It will handle both the assembling and disassembling you're trying to do, too.

Upvotes: 2

Mason Hemmel
Mason Hemmel

Reputation: 185

Write the assembly into its own file, and then call it from your C program using extern. You have to do a little bit of makefile trickery, but otherwise it's not so bad. Your assembly code has to follow C conventions, so it should look like

          global _myfunc 
_myfunc:  push ebp               ; create new stack frame for procedure 
          mov ebp,esp            ;
          sub esp,0x40           ; 64 bytes of local stack space 
          mov ebx,[ebp+8]        ; first parameter to function 
          ; some more code 
          leave                  ; return to C program's frame
          ret                    ; exit

To get at the contents of C variables, or to declare variables which C can access, you need only declare the names as GLOBAL or EXTERN. (Again, the names require leading underscores.) Thus, a C variable declared as int i can be accessed from assembler as

extern _i 
mov eax,[_i]

And to declare your own integer variable which C programs can access as extern int j, you do this (making sure you are assembling in the _DATA segment, if necessary):

    global _j 
_j        dd 0

Your C code should look like

extern void myasmfunc(variable a);

int main(void)
{
    myasmfunc(a);
}

Compile the files, then link them using

gcc mycfile.o myasmfile.o

Upvotes: 0

Related Questions