C - как (* (void (*) ()) кодировать); запустить в программе на C без какого-либо вызова - PullRequest
0 голосов
/ 29 октября 2018

Для запуска произвольных собранных шестнадцатеричных инструкций в программе на С обычно требуется привести данные в виде указателя на функцию и затем вызвать такой указатель.

Обычное использование

int main(){    
    void (*ret)() = (void(*)())code;
    ret();
    return 0;
}

Однако я также натолкнулся на другой способ достижения той же самой задачи как таковой

Рассматриваемый вопрос

int main() {
    (*(void (*)()) code);
    return 0;
}

Может кто-нибудь помочь объяснить:

  1. Разница между двумя случаями
  2. Почему второй случай работает без какого-либо вызова

Проблема возникает, когда трудно отследить шестнадцатеричный код инструкции в отладчике, таком как GDB, без фактического вызова шестнадцатеричного кода в сценарии второго случая.

** * 1028 1029 * Редактировать

Протестированная программа была скомпилирована с помощью gcc и с параметрами: -fno-stack-protector -z exexcstack

машина проверена и версия gcc:

gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)

1 Ответ

0 голосов
/ 29 октября 2018

Второй кусок кода не будет работать. Неиспользованный дереф - это неоперация. Это эквивалентно пустой функции. Если вы хотите избежать переменной, используйте ((void (*)())code)().

Пример:

extern char *code;
void run()
{
    void (*ret)() = (void(*)())code;
    ret();
}
void run0()
{
    (*(void (*)()) code);
}
void empty()
{
}
void novar()
{
    ((void (*)())code)();
}

Разборка (x86_64) примера:

ex.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <run>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    $0x10,%rsp
   8:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax        # f <run+0xf>
   f:   48 89 45 f8             mov    %rax,-0x8(%rbp)
  13:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
  17:   b8 00 00 00 00          mov    $0x0,%eax
  1c:   ff d2                   callq  *%rdx
  1e:   90                      nop
  1f:   c9                      leaveq 
  20:   c3                      retq   

0000000000000021 <run0>:
  21:   55                      push   %rbp
  22:   48 89 e5                mov    %rsp,%rbp
  25:   90                      nop
  26:   5d                      pop    %rbp
  27:   c3                      retq   

0000000000000028 <empty>:
  28:   55                      push   %rbp
  29:   48 89 e5                mov    %rsp,%rbp
  2c:   90                      nop
  2d:   5d                      pop    %rbp
  2e:   c3                      retq   

000000000000002f <novar>:
  2f:   55                      push   %rbp
  30:   48 89 e5                mov    %rsp,%rbp
  33:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax        # 3a <novar+0xb>
  3a:   48 89 c2                mov    %rax,%rdx
  3d:   b8 00 00 00 00          mov    $0x0,%eax
  42:   ff d2                   callq  *%rdx
  44:   90                      nop
  45:   5d                      pop    %rbp
  46:   c3                      retq   

https://gcc.godbolt.org/z/lEo5ga

...