Unicies에
, 또는 다른 곳에서는 당신이 execve
이하고 the man page specifies처럼 작동, 당신은 단지 ... 는 atoi
를 사용하여 저를 죽일 수 있습니다.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char** argv) {
(void) argc;
printf("arg: %s\n", argv[1]);
int count = atoi(argv[1]);
if (getchar() == 'y') {
++count;
char buf[20];
sprintf(buf, "%d", count);
char* newargv[3];
newargv[0] = argv[0];
newargv[1] = buf;
newargv[2] = NULL;
execve(argv[0], newargv, NULL);
}
return count;
}
예 :
$ ./res 1
arg: 1
y
arg: 2
y
arg: 3
y
arg: 4
y
arg: 5
y
arg: 6
y
arg: 7
n
7 | $
(7 리턴 코드였다).
순환하지도 않고 명시 적으로 반복하지도 않습니다. 대신 자기 자신을 호출하여 자체 메모리 공간을 새로운 버전의 자기 자신으로 대체합니다.
이런 식으로 스택은 다시 오버 플로우되지 않습니다. 단, 이전의 모든 변수는 재 호출과 마찬가지로 다시 선언됩니다. getchar
호출은 100 % CPU 사용을 방지합니다.
자동 업데이트 바이너리의 경우 런타임시 메모리에 전체 바이너리 (적어도 Unix가 좋아요, Windows에 대해 알지 못함)가 복사되므로 디스크의 파일이 변경되면 execve(argv[0], ...
호출 전에 디스크에있는 새 바이너리가 이전의 동일한 바이너리가 아닌 대신 실행됩니다.
으로 @CarstenS 인해 유닉스가, 파일 기술자가 fork
/exec
에 걸쳐 유지되어 설계되었다하는 독특한 방식으로, 코멘트에 지적 @bishop 및 전역 파일 기술자 누출 방지하기 위하여 결과 execve
으로 전화하시는 경우 execve
전에 닫거나 e
, FD_CLOEXEC
/O_CLOEXEC
으로 열어야합니다. 자세한 내용은 Dan Walsh's blog에서 확인할 수 있습니다.
출처
2016-10-13 17:44:27
cat
무엇을 하든지 코드에서'main()'을 호출하지 마십시오. – NathanOliver
"모든 변수를 수동으로 다시 시작"Wut? – Treycos
루프 사용을 고려 했습니까? –