Short one, incase you want to write assembly functions and use these in C, maybe to speed up some things or just circumvent AV’s by not calling hooked functions

first you should at least somewhat understand assembly (you can find resources for learning here: ) there are multiple ways you can write assembly in c.

Lets start with “Inline Assembly”

This is probably the most usefull for smaller things, altho gcc’s inline assembly is very complicated and hard to read (in my opinion), its still somewhat usefull, lets use this example: I just want to get the PEB (Process Environment Block) (on an x64 system) I can just do this:

1
2
3
4
5
6
7
8
9
int main() {
    uintptr_t peb_addr;
    __asm__ (
        "mov %%gs:(0x60), %0"
        : "=r" (peb)
    );

    PEB* peb = (PEB*)peb_addr;
}

in this example I use inline assembly to get the address of the PEB (stored at the offset 0x60 from gs) and then cast it to a pointer to the PEB structure (which can be found in winternl.h)

this way of writing assembly is convinient for small things like the above example, but its very annoying to use for entire functions, So lets move on to

“External” Assembly

Here we write our assembly code in a seperate file (I like to use the .s or .asm extension) lets make a function to add two numbers together (again x64 assembly), I will also use intel syntax because I prefer it over AT&T syntax

asm.s

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
.intel_syntax noprefix      ;;# tell gcc to use intel syntax
.global add                 ;;# make label add accessible to the linker

add:
    push    rbp             ;;# function prolouge
    mov     rbp, rsp
    sub     rsp, 0x30

    mov     eax, ecx        ;;# ecx is the first 
    add     eax, edx        ;;# add esi to eax (value of edi) and store result in eax

    add     rsp, 0x30       ;;# function epilouge
    pop     rbp
    ret

main.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#include <stdio.h>

extern __fastcall int add(int, int);
int main(void) {
    int a = 0xc;
    int b = 0xd;

    int c = add(a, b);
    printf("%d + %d = %d\n", a, b, c);

    return 0;
}

we define the function as __fastcall, altho it is not needed since that is the default calling convention on Windows 10 (x64)

Ok, so now comes compilation, with inline assembly it was as simple as just compiling your c file like normal. Now that we have a seperate file containing our Assembly code we need to somehow compile this file aswell… which actually is really simple

1
2
3
4
$ gcc -masm=intel ./asm.s ./main.c -o main
$ ./main
11 + 12 = 23
$

you may notice that I added -masm=intel which is not needed, but I do it anways