C Cheat Sheets

NOTICE:

This document will be continuously updated with the latest features and improvements. You can contribute to the project if you find any issues or have any suggestions.

ASM tricks

#include <stdio.h>
#include <stdint.h>
__asm (
".section .rodata\n"
"nop\n"
".incbin \"/etc/passwd\"\n"
);
int main() {
return 0;
}
// without main in c but in asm
#include <stdio.h>
asm(".global main;main:leaq h(%rip),%rdi;call puts;retq");
char h[] = "Hello, World!";

See ASM tricks implementation.

Bypass Symbols

Diagraphs

/*
Diagraphs:
<% : {
%> : }
<: : [
:> : ]
%: : #
%:%: : ##
<%: : {#
%>% : }#
*/
%:include <stdio.h>
int main()
<%
char s<::> = "I love Digraphs! Thx MisTrale";
puts(s);
return 0;
%>

Trigraphs

/*
Trigraphs:
??= : #
??/ : \
??' : ^
??( : [
??) : ]
??! : |
??< : {
??> : }
??- : ~
Note: Les trigraphes nécessitent le flag -trigraphs avec GCC
(par défaut désactivés depuis GCC 4.7+)
*/
??=include <stdio.h>
int main()
??<
char s??(??) = "I love Digraphs! Thx MisTrale";
puts(s);
return 0;
??>

Main Without -{}#%>?!

[[gnu::section(".text")]] char main[] = "\xeb\x17\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x59\x31\xd2\xb2\x0d\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe4\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\x0a";
can be : __attribute__((section(".text")))

See Bypass Symbols implementation.

Good To Know

Preprocessing tricks:

// Leak file
#include "/etc/passwd"
// variable without type (only work in global)
a;
s="hello";
int main(void) {
printf("%d:%s", a, s);
return 0;
}

Create char & strings

#include "stdio.h"
// Macros for creating strings
#define STR(x) #x
#define CAT(a, b) a##b
#define HELLO_CAT "he" "llo"
int main(void) {
// 1. Concatenation of string literals
char s[] = "h""e""l""l""o";
Every string assignation can be used by a char table like : {..., ..., ..., ..., ...}
puts(s);
// 2. Character table
char p[] = {'h', 'e', 'l', 'l', 'o'};
puts(p);
// 3. Octal escape sequences
char octal[] = "\150\145\154\154\157";
puts(octal);
// 4. Hexadecimal escape sequences
char hex[] = "\x68\x65\x6C\x6C\x6F";
puts(hex);
-
! Depends of the compilor !
+
// 5. Universal character names
+
char unicode[] = "\u0068\u0065\u006C\u006C\u006F";
+
puts(unicode);
// 9. Using macros with stringify
char macro_str[] = STR(hello);
puts(macro_str);
// 10. Using macros with concatenation
char macro_cat[] = HELLO_CAT;
puts(macro_cat);
return 0;
}

Create int

#include <stdio.h>
int main() {
const int h = (((__STDC__)*(__STDC__+__STDC__)+(__STDC__+__STDC__)+(__STDC__+__STDC__)*(__STDC__+__STDC__)+(__STDC__+__STDC__)+(__STDC__+__STDC__)) + (__STDC__)) * ((__STDC__+__STDC__)+(__STDC__+__STDC__)) * (__STDC__+__STDC__);
const int e = (__CHAR_BIT__ +__LITTLE_ENDIAN__+ __LITTLE_ENDIAN__)*(__SIZEOF_POINTER__+__STDC_HOSTED__+__STDC_HOSTED__) + __STDC_HOSTED__;
const int l = (__SCHAR_MAX__)-(((__BOOL_WIDTH__+__FLT16_MAX_10_EXP__))-(__STDC_UTF_16__-__SIZEOF_PTRDIFF_T__));
const int o = (__INT_FAST64_WIDTH__*__GCC_ATOMIC_WCHAR_T_LOCK_FREE)-(__SHRT_WIDTH__+__FLT16_HAS_INFINITY__);
printf("%s\n", (char []){h, e, l, l, o, 0});
}

See Good To Know implementation.

Without Alphabeat

// gcc -Wl,--entry=_ -nostartfiles -w -O0
(*$)();
(*$__)();
_(){
$__= 84884400; // 0x50f3bb0 -> mov $rax, 0x3b; syscall
$=_+11; // move to execve
$("\057\142\151\156\057\142\141\163\150", 0, 0); // $("/bin/bash", 0, 0)
}

See Without Alphabeat implementation.

Without Lower Letters

// echo "" | gcc -dM -E -
to see avaible macro
#include <stdio.h>
#include <stdlib.h>
int main() {
__WINT_TYPE__ L = (__SCHAR_MAX__)-(((__BOOL_WIDTH__+__FLT16_MAX_10_EXP__))-(__STDC_UTF_16__-__SIZEOF_PTRDIFF_T__));
__WINT_TYPE__ S = ((__DBL_DECIMAL_DIG__+__DBL_DIG__)*(__FLT_RADIX__))+__DBL_MANT_DIG__-__FLT_RADIX__;
__WINT_TYPE__ DASH = (__INT_FAST32_WIDTH__)-(__FLT16_MIN_EXP__);
__WINT_TYPE__ SLASH = DASH + __PIC__;
__WINT_TYPE__ A = __INTMAX_WIDTH__+__STDC__;
__WINT_TYPE__ SPACE = __INT_LEAST32_WIDTH__;
// CAN ALSO WORK WITH __STRING(LS)
printf("%s\n", __STRING(LS));
system((__INT8_TYPE__ []){L, S, SPACE, DASH, L, A, SPACE, SLASH, 0});
you need to retrieve the offset
}

See Without Lower Letters implementation.

Without Parenthese

int main(void)
{
static char place;
static char* sh = "/bin/sh";
long long gadget = 0x050F5A5E5F3BB0;
// syscall(0x3b, "/bin/sh", NULL, NULL)
char *buf[0];
buf[0] = buf[0];
buf[2] = &place - 0x2eda; // Ajustez cette valeur pour obtenir la bonne adresse
buf[3] = sh;
buf[4] = 0;
buf[5] = 0;
return 0;
}

See Without Parenthese implementation.