• XSS.stack #1 – первый литературный журнал от юзеров форума

Have fun with C language | Веселие с языком C

el84

(L2) cache
Пользователь
Регистрация
10.01.2023
Сообщения
326
Реакции
143
Депозит
0.00
[en]
Here in this topic we should share C code which help people to learn new things about syntax and also related subjects (eg: assembly concepts), I will start with a small code, most of people probably can guess what will happen when it runs, but its a very nice exercise to run it in a debugger like GDB and understand why this happens. The code should be compiled with those flags otherwise compiler optimizations/protections will prevent it to work properly.

[ru]
Здесь, в этой теме, мы должны поделиться C кодом C, который помогает людям узнать новые вещи о синтаксисе, а также связанных предметах (например, концепции сборки), я начну с небольшого кода, большинство людей, вероятно, могут догадаться, что произойдет, когда он работает, Но это очень хорошее упражнение, чтобы запустить его в отладчике, как GDB, и понять, почему это происходит. Код должен быть составлен с этими флагами, в противном случае оптимизация компилятора/защита предотвратит его работать должным образом.

Bash:
gcc -O0 -fno-stack-protector code.c -o code

code.c
C:
#include <stdio.h>
#include <stdlib.h>

void somefunc()
{
        puts("What happened?");
        exit(1);
}

void func()
{
        void (*reference[0])();
        1[reference] = somefunc;
        1[reference];
}

int main()
{
        func();
        return 0;
}
 
Пожалуйста, обратите внимание, что пользователь заблокирован
1[reference] = somefunc
Это забавный баян, но даже те люди, которые провели в обнимку с Цэ с десяток лет, бывают не в курсе, что:
C:
// запись:
array[1] = 10;
// просто синтаксический сахар над:
*(array + 1) = 10;
// поэтому, это тоже самое, что и:
1[array] = 10;
// так как от перестановки мест слагаемых сумма не меняется))
// в Цэ слишком любят указатели, чтобы не абьюзить их
 
Это забавный баян, но даже те люди, которые провели в обнимку с Цэ с десяток лет, бывают не в курсе, что:
C:
// запись:
array[1] = 10;
// просто синтаксический сахар над:
*(array + 1) = 10;
// поэтому, это тоже самое, что и:
1[array] = 10;
// так как от перестановки мест слагаемых сумма не меняется))
// в Цэ слишком любят указатели, чтобы не абьюзить их

[en]
Yes, you are completly right, and also yes, most of people is not aware of this syntax to index array. Another cool thing about this code is the fact that GCC, ignores the ISO and let you declare 0 sized arrays, like this one. Which is an array of function pointers with size 0.

[ru]
Да, вы полностью правы, а также да, большинство людей не знают об этом синтаксисе для массива индекса. Еще одна классная вещь в этом коде - тот факт, что GCC игнорирует ISO и позволяет объявить 0 массивов размером с 0, как этот. Который представляет собой массив указателей функций с размером 0.

void (*reference[0])();
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Чего вспомнил. Есть очень стремная вещь, которую сейчас уже, наверное, не встретишь, это такой своеобразный метод делать loop unrolling руками: https://en.m.wikipedia.org/wiki/Duff's_device - особенно мне ломает мозг вот эта штука:
C:
send(to, from, count)
register short *to, *from;
register count;
{
    register n = (count + 7) / 8;
    switch (count % 8) {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
            } while (--n > 0);
    }
}
 
[en]
Hey DildoFagins this magical thing you bring to the thread make me remember another one, from Clifford, he/she is a very smart person and also did his "Clifford Device", I just met his website seeking things about Verilog. He inspiration is Duff, but the code and example is very cool, Unfortunately the original website is broked but I managed to find it again on Wayback machine.

My code from the first post worked fine at your side? It just should output "What happened?" but still a very cool stack patching toy.

[ru]
Эй, DildoFagins, эта волшебная вещь, которую вы приносите в нить, заставляет меня вспомнить еще одну, от Клиффорда, он/она очень умный человек, а также сделал его «устройство Клиффорда», я только что встретил его сайт, ищущий вещи о Verilog. Вдохновение - это Дафф, но код и пример очень крутые, к сожалению, оригинальный веб -сайт придерживается, но мне удалось найти его снова на Wayback Machine.

Мой код с первого поста работал нормально на вашей стороне? Это просто должно вывести "что случилось?" Но все же очень классная игрушка для исправления стека.



 

Вложения

  • cliff device.png
    cliff device.png
    10.1 КБ · Просмотры: 47
[en]
Here is another classic one, Its was probably created in assembly in an lost context in long past, but still very interesting, its a way to compute multiplicative inverse of square root. Also know by some people as "Quake Fast InvSqrt" because its known to be used in the game.

[ru]
Вот еще один классический. Вероятно, он был создан на ассемблере в давно потерянном контексте, но все же очень интересный, это способ вычисления мультипликативного обратного квадратного корня. Также известен некоторым людям как «Quake Fast InvSqrt», потому что известно, что он используется в игре.


C:
float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;                       // evil floating point bit level hacking
    i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//    y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

    return y;
}


ref:
 
[en]
Thats a not so uncommon but maybe unknown to some people. The concept of constructors and destructors being used in C code, most of people knows the concept but from object oriented languages. The cool thing in C is that you use attributtes to define functions as constructors or destructor, and they run before main() code and after respectively. Here is a simple example using GCC. Even this idea is not being part of C standard, all the compilers support this in some way, using a constructor is also a good way to exploit a "lolbin" to load and run arbitrary code withouth using LD_PRELOAD.

[ru]
Это не так редко, но, возможно, неизвестно некоторым людям. Концепция конструкторов и деструкторов, используемых в коде C, большинство людей знают концепцию, но из объектно -ориентированных языков. Классовая вещь в C - это то, что вы используете атрибуты для определения функций как конструкторов или деструктора, и они запускаются до кода Main () и после соответственно. Вот простой пример с использованием GCC. Даже эта идея не является частью стандарта C, все компиляторы поддерживают это каким -то образом, использование конструктора также является хорошим способом использования «LOLBIN» для загрузки и запуска произвольного кода с помощью LD_PRELOAD.


C:
#include <stdio.h>

__attribute__((constructor)) void some_func(void)
{
        puts("Running as a constructor");
}

__attribute__((destructor)) void other_func(void)
{
        puts("Running as destructor");
}

int main(int argc, char **argv)
{
        puts("Running main() code");
        return 0;
}

output:

Bash:
$ ./a.out
$ ./a.out
Running as a constructor
Running main() code
Running as destructor

ref: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
 
Пожалуйста, обратите внимание, что пользователь заблокирован
У GCC/MinGW есть еще и __attribute__((cleanup(func))), который можно использовать для своего рода имитации RAII из C++. Смысл в том, что func будет вызвана, когда произойдет выход из scope, где объявлена переменная. Типа как вызов деструктора класса в С++. Это упрощает некоторые вещи и в некоторых случаях позволяет не городить цепочки if'ов с большой вложенностью, делая код проще и более читаемым. Но это не стандартная фишка, вроде она есть только в GCC/MinGW и, может быть, в Clang еще.
 
У GCC/MinGW есть еще и __attribute__((cleanup(func))), который можно использовать для своего рода имитации RAII из C++. Смысл в том, что func будет вызвана, когда произойдет выход из scope, где объявлена переменная. Типа как вызов деструктора класса в С++. Это упрощает некоторые вещи и в некоторых случаях позволяет не городить цепочки if'ов с большой вложенностью, делая код проще и более читаемым. Но это не стандартная фишка, вроде она есть только в GCC/MinGW и, может быть, в Clang еще.
[en]
Thats a nice one, I never had seen this before, So I choosed to give it a try with a simple example, that a useless code just to see what the compiler does, and in fact it will insert a call to the cleanup function exactly before restoring the previous stack frame, very nice compiler "hackery".

[ru]
Это хороший, я никогда не видел этого раньше, поэтому я предположил попробовать его с простым примером, что бесполезный код просто для того, чтобы увидеть, что делает компилятор, и на самом деле он вставит призыв к функции очистки Перед восстановлением предыдущей рамки стека очень хороший компилятор "Hackery".

clean.c:
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void cleanup_func(char **buffer)
{
        if (*buffer) {
                free(*buffer);
        }
}

void copy_and_print(char *str, size_t size)
{
        __attribute__((cleanup(cleanup_func))) char *buffer;
        buffer = malloc(size+1);
        strcpy(buffer, str);
        printf("buffer: %s\n", buffer);
}


int main(int argc, char **argv)
{
        if (argc < 2) {
                printf("usage: %s \"somestring herestring\"\n", argv[0]);
                return 1;
        }

        copy_and_print(argv[1], strlen(argv[1])+1);

        fcloseall();
        return 0;
}

Asm of copy_and_print()

Bash:
$ objdump --disassemble=copy_and_print

a.out:     file format elf64-x86-64


Disassembly of section .init:

Disassembly of section .plt:

Disassembly of section .text:

0000000000401190 <copy_and_print>:
  401190:       55                      push   %rbp
  401191:       48 89 e5                mov    %rsp,%rbp
  401194:       48 83 ec 20             sub    $0x20,%rsp
  401198:       48 89 7d e8             mov    %rdi,-0x18(%rbp)
  40119c:       48 89 75 e0             mov    %rsi,-0x20(%rbp)
  4011a0:       48 8b 45 e0             mov    -0x20(%rbp),%rax
  4011a4:       48 83 c0 01             add    $0x1,%rax
  4011a8:       48 89 c7                mov    %rax,%rdi
  4011ab:       e8 c0 fe ff ff          call   401070 <malloc@plt>
  4011b0:       48 89 45 f8             mov    %rax,-0x8(%rbp)
  4011b4:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  4011b8:       48 8b 55 e8             mov    -0x18(%rbp),%rdx
  4011bc:       48 89 d6                mov    %rdx,%rsi
  4011bf:       48 89 c7                mov    %rax,%rdi
  4011c2:       e8 79 fe ff ff          call   401040 <strcpy@plt>
  4011c7:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  4011cb:       48 89 c6                mov    %rax,%rsi
  4011ce:       bf 08 20 40 00          mov    $0x402008,%edi
  4011d3:       b8 00 00 00 00          mov    $0x0,%eax
  4011d8:       e8 83 fe ff ff          call   401060 <printf@plt>
  4011dd:       48 8d 45 f8             lea    -0x8(%rbp),%rax
  4011e1:       48 89 c7                mov    %rax,%rdi
  4011e4:       e8 7d ff ff ff          call   401166 <cleanup_func>
  4011e9:       90                      nop
  4011ea:       c9                      leave
  4011eb:       c3                      ret
 
[en]
Here is a nice question for people playing with C, some of you alread asked itself what runs before main()? And also How to code something in C without the compiler startfiles? And "C runtime" ?

[ru]
Вот хороший вопрос для тех, кто играет с C. Некоторые из вас уже задавались вопросом, что выполняется перед main()? А также Как что-то закодировать на C без компилятора запускает файлы? И "Время выполнения C"?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
А также Как что-то закодировать на C без компилятора запускает файлы? И "Время выполнения C"?
https://xss.pro/threads/76417/
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх