이 난독화된 C코드는 메인() 없이 실행된다고 주장하지만 실제로는 어떤 역할을 합니까?
#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m##s##u##t
#define begin decode(a,n,i,m,a,t,e)
int begin()
{
printf("Ha HA see how it is?? ");
}
으로 「」라고 하는 입니까?main
C 언어에서는 실행 환경을 프리스탠딩과 호스트라는2개의 카테고리로 정의합니다.두 실행 환경 모두 프로그램 부팅을 위한 환경에 의해 함수가 호출됩니다.
독립형 환경 프로그램 시작 기능은 호스트 환경에서 정의해야 하는 구현과 함께 정의될 수 있습니다.main
정의된 환경에서 프로그램 부팅 기능이 없으면 C의 어떤 프로그램도 실행할 수 없습니다.
ㅇㅇㅇㅇㅇㅇ는main
는 프리프로세서 정의에 의해 숨겨집니다. begin()
로 will will will will will will will 。decode(a,n,i,m,a,t,e)
앞으로 더 확대될 것이다main
int begin() -> int decode(a,n,i,m,a,t,e)() -> int m##a##i##n() -> int main()
decode(s,t,u,m,p,e,d)
는 7개의 파라미터를 가진 파라미터화된 매크로입니다.는, 이음음음음 replace replace음 replace replace 。m##s##u##t
m, s, u
★★★★★★★★★★★★★★★★★」t
는th 교체 목록에서 사용되는 4, 1st, 3, 2 파라미터입니다rdnd.
s, t, u, m, p, e, d
1 2 3 4 5 6 7
나머지는 아무 소용이 없다.인수가 전달되었습니다.decode
"a,n,i,m,a,t,e"이기 때문에 식별자는m, s, u
★★★★★★★★★★★★★★★★★」t
로 m, a, i
★★★★★★★★★★★★★★★★★」n
각각 다음과 같다.
m --> m
s --> a
u --> i
t --> n
도 한번 써보세요.gcc -E source.c
출력의 끝은 다음과 같습니다.
int main()
{
printf("Ha HA see how it is?? ");
}
★★★★★★★★★★★★★★★★★★.main()
함수는 실제로 프리프로세서에 의해 생성됩니다.
해당 프로그램이 호출합니다.main()
매크로의 확장에 의해, 그러나 당신의 가정은 결함이 있습니다.-그것은 전화할 필요가 없습니다.main()
전!!
말하면,, C프로그램이 할 수 .main
★★★★★★ 。main
이 모든 것은c library
는, 독자적인 초기화가 끝난 후에, 에의 투신다고 상정하고 있습니다. 뛰어들어요.main
「라고 _start
메인 없이 조립만 실행하는 매우 유효한 프로그램을 항상 가질 수 있습니다.이것 좀 보세요.
/* This must be compiled with the flag -nostdlib because otherwise the
* linker will complain about multiple definitions of the symbol _start
* (one here and one in glibc) and a missing reference to symbol main
* (that the libc expects to be linked against).
*/
void
_start ()
{
/* calling the write system call, with the arguments in this order:
* 1. the stdout file descriptor
* 2. the buffer we want to print (Here it's just a string literal).
* 3. the amount of bytes we want to write.
*/
asm ("int $0x80"::"a"(4), "b"(1), "c"("Hello world!\n"), "d"(13));
asm ("int $0x80"::"a"(1), "b"(0)); /* calling exit syscall, with the argument to be 0 */
}
의 내용을 기기의내 compile compile compile compile compile compile compile compile compile로 정리합니다.gcc -nostdlib without_main.c
하는 것을 Hello World!
인라인 어셈블리에서 시스템콜(인터럽트)을 발행하는 것만으로 화면에 표시됩니다.
이 문제에 대한 자세한 내용은 ksplice 블로그를 참조하십시오.
하나 점은 '하다', '작성하다', '작성하다'가 수 입니다.main
기호는 C 함수에 해당합니다.예를 들어 다음과 같은 매우 유효한 C 프로그램을 사용할 수 있습니다.이 프로그램은 Warnings 수준을 높였을 때만 컴파일러가 윙윙거립니다.
/* These values are extracted from the decimal representation of the instructions
* of a hello world program written in asm, that gdb provides.
*/
const int main[] = {
-443987883, 440, 113408, -1922629632,
4149, 899584, 84869120, 15544,
266023168, 1818576901, 1461743468, 1684828783,
-1017312735
};
배열의 값은 화면에 Hello World를 인쇄하기 위해 필요한 절차에 대응하는 바이트입니다.이 프로그램의 상세한 내용에 대해서는, 이 블로그의 투고를 봐 주세요.여기서 저도 먼저 읽습니다.
이 프로그램들에 대해 마지막으로 한 가지 알려드리고 싶습니다.C언어 사양에 따라 유효한 C프로그램으로 등록이 되어 있는지는 알 수 없지만, 사양 자체를 위반해도 컴파일하여 실행하는 것은 매우 가능합니다.
누군가가 마술사처럼 행동하려고 한다.그는 우리를 속일 수 있다고 생각해요.하지만 우리 모두 알다시피, c 프로그램의 실행은main()
.
그int begin()
로 대체됩니다.decode(a,n,i,m,a,t,e)
프리프로세서 스테이지의 1 패스에 의해서.그리고 또...decode(a,n,i,m,a,t,e)
m##a#i#n으로 대체됩니다.매크로 콜의 위치 관련성에 의해s
값이 .a
.저도 마찬가지예요.u
'와 'i'로.t
'으로 . 해서m##s##u##t
될 것이다main
에관,에 요.##
매크로 확장의 기호이며, 전처리 연산자로 토큰 붙여넣기를 수행합니다.매크로가 확장되면 각 '##' 연산자의 양쪽에 있는 2개의 토큰이 단일 토큰으로 결합되어 '##'과 매크로 확장의 2개의 원래 토큰이 대체됩니다.
을 못 믿겠다면 할 수 .-E
flag. 후 flag 를 볼 수 . 전처리 후 컴파일 처리를 중지하고 토큰 붙여넣기 결과를 볼 수 있습니다.
gcc -E FILENAME.c
decode(a,b,c,d,[...])
는 첫 하기 위해 를 "shuffle" 합니다.dacb
(3일)를 들면, 「 」입니다.decode(a,n,i,m,[...])
는 .main
'는 다음과 같습니다.begin
매크로는 다음과 같이 정의됩니다.
때문에 '이러한'은begin
'마크로'로 정의됩니다.main
.
예에서는 " " 입니다.main()
이 실제로 왜냐하면begin
가 '마크로'로 입니다.decode
m#s#u#t는 m#s#u#t이다. 확장 ##
하면 '어느 때 보다'라는 main
부터에서decode
. 이것은 추적:트레이스입니다.
begin --> decode(a,n,i,m,a,t,e) --> m##parameter1##parameter3##parameter2 ---> main
속임수입니다그냥 속임수야 이건에 없다.main()
하지만 이름을 사용하여, 단,이름을 사용합니다.main()
들어 프로그램의 입력 기능 C프로그래밍 언어로 필요하지 않다.C프로그래밍 언어에서는 프로그램 입력 기능이 필요하지 않기 때문입니다.그것은 당신의 운영 체제 및 하나의 도구들의 연결에 달려 있다.사용의 운영 system과 그 툴의 하나인 링커에 의해서 다릅니다.
Windows에서는 Windows에서는, 반드시 다음의 기능을 사용하는 것은 아닙니다를 사용하지 않는다.main()
Microsoft 툴 체인에서도 사용할 수 있지만, 또는 를 사용할 수 있습니다.Linux 에서는, 다음과 같이 사용할 수 있습니다._start
.
언어 자체가 아니라 운영체제 도구로서의 링커에게 달려 있습니다.독자적인 엔트리 포인트를 설정해, 실행 가능한 라이브러리를 작성할 수도 있습니다.
언급URL : https://stackoverflow.com/questions/36449358/this-obfuscated-c-code-claims-to-run-without-a-main-but-what-does-it-really-d
'programing' 카테고리의 다른 글
Kotlin 어레이를 Java varargs로 변환 (0) | 2022.07.29 |
---|---|
명령줄에서 Maven Javadoc 플러그인을 비활성화하려면 어떻게 해야 합니까? (0) | 2022.07.29 |
2.0에서 선택한 데이터 테이블 항목을 페이지별로 확인하는 방법은 무엇입니까? (0) | 2022.07.29 |
Vuex: 모든 상태 데이터를 로컬 속성에 매핑하려면 어떻게 해야 합니까? (0) | 2022.07.29 |
:: Java 8의 (이중 콜론) 연산자 (0) | 2022.07.29 |