TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #769 5.51K
Ответ
#опытным

Ну что. Пора раскрывать карты.

Правильных ответов здесь несколько(не зря был квиз с множественным ответом) и все зависит от версии компилятора и опций компиляции. Интереснее всего смотреть, что получится при использовании например gcc9 без опций.

А получится вот что. Программа успешно скомпилируется и на консоли появится сообщение:

You are the best!


Да, да. Это она про вас, наши подписчики.

Дело вот в чем. Есть такой варнинг в gcc: warning: 'main' is usually a function [-Wmain].
Погодите, main "обычно" является функцией. Это что, может быть не так?

В С нет или не было прям жесткого требования на тип символа main. Он в целом может быть и массивом:
char main[10];

хоть указателем на функцию:
void (main)();


И вот здесь начинается пространство для экспериментов. Адрес main - это место, с которого код начинается исполняться. Если мы каким-то образом запихаем инструкции ассемблера в массив, то мы сможем выполнить код в такой программе!

Ну а дальше дело техники. Пишем прокси программу:

void main() {
__asm__ (
// print You are the best!
"movl $1, %eax;\n" /* 1 is the syscall number for write */
"movl $1, %ebx;\n" /* 1 is stdout and is the first argument */
// "movl $message, %esi;\n" /* load the address of string into the second argument*/
// instead use this to load the address of the string
// as 16 bytes from the current instruction
"leal 16(%eip), %esi;\n"
"movl $18, %edx;\n" /* third argument is the length of the string to print*/
"syscall;\n"
// call exit (so it doesn't try to run the string Hello World
// maybe I could have just used ret instead
"movl $60,%eax;\n"
"xorl %ebx,%ebx; \n"
"syscall;\n"
// Store the You are the best! inside the main function
"message: .ascii \"You are the best!\\n\";"
);
}


Компилируем ее и запускаем gdb для дизассемблирования main:
(gdb) disass main
Dump of assembler code for function main:
0x0000000000001129 <+0>: endbr64
0x000000000000112d <+4>: push %rbp
0x000000000000112e <+5>: mov %rsp,%rbp
0x0000000000001131 <+8>: mov $0x1,%eax
0x0000000000001136 <+13>: mov $0x1,%ebx
0x000000000000113b <+18>: lea 0x10(%eip),%esi # 0x1152 <main+41>
0x0000000000001142 <+25>: mov $0x12,%edx
0x0000000000001147 <+30>: syscall
0x0000000000001149 <+32>: mov $0x3c,%eax
0x000000000000114e <+37>: xor %ebx,%ebx
0x0000000000001150 <+39>: syscall
0x0000000000001152 <+41>: pop %rcx
0x0000000000001153 <+42>: outsl %ds:(%rsi),(%dx)
0x0000000000001154 <+43>: jne 0x1176 <__libc_csu_init+6>
...


Ну и пожалуйста. Слева четко видим шестнадцатиричные числа, которые и представляют собой тело функции main.

Единственное, что осталось - вывести эти числа в десятиричной форме по 4 байта, как инты:

(gdb) x/16dw main
0x1129 <main>: -98693133 -443987883 440 113408
0x1139 <main+16>: -1922629632 4149 1227264 84869120
0x1149 <main+32>: 15544 266023168 1970231557 1701994784
0x1159 <main+48>: 1701344288 1936024096 -1878384268 258392925


Делаем из этих чиселок массив и готово! Закодированная программа будет выполняться.

В более новых версиях компиляторов эту лавочку прикрыли, потому что на gcc10 и более такая прога сегфолтится.

Но в любом случае, очень прикольно, что есть такая возможность.

Можете поиграться с кодом на годболте. Также можно почитать статью, в которой автор подробно расписал историю исследования возможности так писать код.

Благодарю @PyXiion за предоставление материалов для этого поста.

Be amazed. Stay cool.

#fun #OS
  • ❤‍🔥 55
  • 🤯 20
  • 🔥 11
  • ❤ 8
  • 👍 6
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →