Выполненный шеллкод завершает основную программу

Я пытаюсь выполнить шелл-код в области памяти. Пока это работает, я столкнулся с другой проблемой прямо сейчас: программа main-c завершается после того, как я вызвал программу шеллкода. Есть ли (простой) способ обойти это, кроме работы с потоками?

Я думаю, что это как-то связано с mov rax, 60 и последующими syscall, выходящими из программы. Верно?

Основной C-код

#include <string.h>
#include <sys/mman.h>

const char shellcode[] = "\xeb\x1e\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x5e\xba\x0d\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05\xe8\xdd\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21";

// Error checking omitted for expository purposes
int main(int argc, char **argv)
{
  // Allocate some read-write memory
  void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

  // Copy the shellcode into the new memory
  memcpy(mem, shellcode, sizeof(shellcode));

  // Make the memory read-execute
  mprotect(mem, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC);

  // Call the shellcode
  void (*func)();
  func = (void (*)())mem;
  (void)(*func)();

  // This text will never appear
  printf("This text never appears");

  // Now, if we managed to return here, it would be prudent to clean up the memory:
  // (I think that this line of code is also never reached)
  munmap(mem, sizeof(shellcode));

  return 0;
}

Основа шеллкода (ассемблер (Intel))

global _start

_start:
    jmp message

code:
    mov     rax, 1
    mov     rdi, 1
    pop     rsi
    mov     rdx, 13
    syscall

    mov    rax, 60
    mov    rdi, 0
    syscall

message:
    call code
    db "Hello, World!"

person Marvin    schedule 11.05.2017    source источник


Ответы (2)


imo, самый простой способ - создать двоичный файл, а затем выполнить exec (). и если вам нужен вывод из этого, настройте трубы.

person testfile    schedule 11.05.2017
comment
Я хочу выполнить код из сегмента памяти, это проще с шеллкодом, верно? Есть другие идеи? - person Marvin; 11.05.2017

Я действительно узнал это сам. Если кому-то интересно, простое решение заключалось в изменении кода ассемблера следующим образом:

global _start

_start:
    jmp message

code:
    mov     rax, 1
    mov     rdi, 1
    pop     rsi
    mov     rdx, 13
    syscall

    ret        # Instead of "mov.., mov..., syscall"

message:
    call code
    db "Hello, World!"
person Marvin    schedule 11.05.2017
comment
Код jmp-call-pop должен работать без инструкции ret. По крайней мере, у меня это работает, используя более простую программу C. Кроме того, эта инструкция ret может в конечном итоге иметь непредвиденные последствия, поскольку она выталкивает адрес (или что-то еще) из вершины стека. Так как ваш код C выполняет этот раздел кода, без установки фрейма стека в коде сборки, ваша следующая инструкция может привести к сбою программы; тем самым побеждая намерение шеллкода. - person InfinitelyManic; 11.05.2017
comment
@InfinitoManic Я перевел все это на ассемблерный код ARM (так как это было то, что мне действительно нужно), это не работает. Пропуск ret (или в ARM bx lr) вызывает ошибку сегментации. - person Marvin; 12.05.2017
comment
Вы имеете в виду, что вы перенесли код x86-64 в код ARMv7 - верно? Правильно ли выполняется ваш код ARM в вашей основной программе на C? - person InfinitelyManic; 12.05.2017
comment
@InfinitoManic Мы портировали код ARM, но сам код работает. Мы используем следующее: mov r0, #1 mov r1, string mov r2, #12 mov r7, #1 swi 0 mov r7, #1 swi 0 string: .ascii "Hello, World" Мы преобразовали это в шеллкод, но он все еще существует в нашей основной программе C. Если не указать последний системный вызов или заменить его на bx lr, произойдет ошибка сегментации. Любые идеи? - person Marvin; 15.05.2017
comment
Просто исправил, когда я выполняю этот код внутри другой программы, нам нужно что-то другое, чем mv r7, #0 и swi 0. Вместо этого я добавил push {r0-r7, lr} в начале и pop {r0-r7, pc} и bx lr в конце вместо системного вызова. Это работает, когда, как кажется, выполняется в другой программе. - person Marvin; 15.05.2017