挑战:写一段自己退出的代码[关闭]


39

我正在搜索(是吗?)寻找立即退出的一段代码-这绝对是一种非常规的方式。

这并不意味着:System.exit((int) 'A');(Java)。

这可能意味着:

#!/usr/bin/env python3
# NOTE: This kills ALL RUNNING Python processes. Be careful!
def exit():
    import os
    os.system("killall python3")
    # Windows addon
    os.system("taskkill /im python.exe /f")
exit()

最受好评的答案胜出!所有语言,所有体系结构。

编辑:通过抛出异常退出将不再被接受!


3
但这并不是结束执行的常规方法...嗯,它是的替代方法exit(),但仍然是已实现的功能...
s3lph 2013年

13
这不是代码拖曳-我们知道我们想要这个答案。
利亚姆道森

6
关闭系统是否可以正常工作?
Hosch250 2013年

8
我曾经不小心使操作系统上的网卡变为DMA。发生这种情况时,您立即回到BIOS中,重新启动。
本杰克逊

3
我感觉像香农在这里击败了我们;)
璀璨之星

Answers:


44

bash,6个字符

exec [

exec用其他东西代替当前过程。[是我能找到的最短的命令,它是无害的(这是的别名test


另一个例外?
约翰内斯·库恩

不,只需exec执行[命令即可:)
Dennis Kaarsemaker 2013年

1
它为什么起作用?做什么?
s3lph 2013年

@the_Seppi它用[(aka测试)替换了当前进程
Timtech

~ $ echo $PATH/?-> /bin/X /bin/[ /bin/w。鱼壳给了我另外两个命令。w我认为很有趣。
Konrad Borowski

46

重击

echo "Turn off your computer or i'll wipe your harddrive..."
echo 3;sleep 1
echo 2;sleep 1
echo 1;sleep 1
dd if=/dev/random of=/dev/hda

尽可能快地终止程序;-)


10
因为这让我发笑,所以颇有争议。
迈克尔·斯特恩

5
最好不要在Linux上运行它。
kenorb 2014年

1
dd:/ dev / hda:找不到
Joshua

39

红码

(背景:Redcode是AK Dewdney在1984年推出的Core War编程游戏中使用的伪汇编语言。它通常大量使用自修改代码。几年前,我写了一篇很好的Redcode编程教程。 )

MOV 1, 0

这个单指令程序不仅会杀死自己,还会从内存中擦除自己的程序代码,而不会在内存中留下任何痕迹。

无聊,你说?毕竟,即使上面的程序没有覆盖其代码,它还是会死掉的。好的,这是在最终擦除自身并死亡之前先将整个核心擦拭干净的方法:

loop: MOV  ptr+1, >ptr 
      JMN  loop, loop
      SPL  1
      SPL  1
      MOV  ptr+1, >ptr
ptr:  DAT  0, 1

前两条指令实际上完成了大部分工作:这只是一个简单的复制/跳转循环,它将DAT 0, 0程序结束后的空白指令单元(初始化为)复制到每个后续单元(使用后递增间接寻址模式)>),直到指针最终回绕到内存的开头并覆盖MOV循环本身中的。一旦发生这种情况,JMN(JuMp如果不是零)就会检测到它并掉线。

问题在于,这仍然使JMN自身无法擦除。为了摆脱它,我们需要另一个MOV擦拭JMN...但我们需要另一种是手段MOV擦拭 MOV,等等。为了使整个程序消失无踪了,我们必须以某种方式安排一个MOV指令擦拭两者本身和至少一种其他指令。

这就是SPL进来的地方-它是Redcode中最怪异的操作码之一。基本上,这是“双向分支”指令。您会看到,Redcode VM代替了简单的“程序计数器”寄存器,就像任何普通的CPU一样,具有一个“进程队列”:指向要执行的指令的循环指针列表。通常,在每个周期中,将指令指针移出队列的头部,执行该指令,然后将下一条指令(除非有跳转或非法指令)压入队列的尾部。但SPL使两者的下一指令给定的目标指令(在的情况下SPL 1,是下一指令)被推动到所述队列中。

所有这一切的结果是,在SPL 1执行了两条指令之后,队列中现在有四个进程,全部与执行last有关MOV。这足以擦除JMNSPLMOV本身,并且还使ptr指令单元保持为DAT 0, 0—与周围的空核没有区别。

(或者,我们可以将ptr指令替换为MOV 1, 1,而之前的指令会将该指令转换为MOV 1, 0,因此也将自身擦除,就像上面的第一个程序一样。)

附言 如果要测试这些程序,请下载Redcode模拟器(又名MARS)。我建议使用CoreWin或古老的pMARS,尽管也有其他几种不错的模拟器。


这不是会引发访问冲突吗?
Danny Varod

12
违反访问权限?那是什么奇怪的方式?(严重地,Redcode在漂亮的抽象VM中运行。所有寻址都是相对的,地址空间是连续的(并且是循环的)并且每个地址都是有效的。)
Ilmari Karonen

MOV 1、0是否将1复制到地址0或相反?在所有汇编语言中,我都知道地址0是非法的(NULL地址)。
Danny Varod 2013年

4
语法为MOV source, dest。但是正如我所说,Redcode中的所有寻址都是相对的,因此该地址0实际上表示“该指令的地址”,而该地址1实际上表示“该指令的地址+ 1”。(并且绝对地址0在Redcode中无论如何都不是特别的;实际上,“所有相对寻址”设计的一个有趣的结果是,实际上Redcode程序不可能在内核中找到自己的绝对地址! )
Ilmari Karonen

2
伙计,我非常感谢你。我从未听说过核心战争。
seequ 2014年

32

C

#include <conio.h>  /* Computer-Operated Nuclear Installation Options */
int main () {
    clrscr();       /* Commence Launch (Remote Systems Console Request) */
    kbhit();        /* Keep Busy until hit */
}

请注意,这不是可移植的代码。它可与ART DS9000上的ZOG C 一起使用。我认为,使用非常规武器可以使该准则有资格应对这一挑战。如果您担心该段代码交付有效负载所花费的延迟不是立即生效的,请与我们联系以获取有关先发制人打击的建议。

发射的效果

在我的家用计算机上,它甚至无法编译-我没有正确的驱动程序和库。我听说有一些流行的C实现,该程序可以在其中编译并运行,但效果不那么引人注目,但是我从来没有尝试过的勇气。


2
最好的答案,放手!
矢量

3
+1。(0)1; 起初,我还以为@Gilles这里曳......但后来我查了ART公司的网页...它是那么当我意识到我是多么沉重触轮!
vaxquis 2014年

30

的JavaScript

window.location.replace("http://pieisgood.org");

只需导航到其他(美味)网站即可。:-)

打高尔夫球(10个字符):

location=1

7
mmmm,冰淇淋:P
波动率

28

C#

通过杀死除自身以外的所有进程来杀死自己。

foreach (Process p in Process.GetProcesses()) {
    string myexe = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
    if (p.ProcessName == myexe) continue;
    p.Kill();
}

为了给它加一点香料,我们可以PInvoke TerminateProcess而不是使用Process.Kill


4
+1是一种非常传统的方法,可以杀死其他所有事物,从而使您自己的程序与系统一起崩溃(或者至少我认为是这样吗?)。我在这台机器上没有C#运行时,但是我不得不问...在实践中,这最终会导致系统宕机还是只是所有正在运行的进程崩溃?(我认为C#程序自己调用了解释器,因此不依赖于特定的JIT / CIL进程的存在...)。 再次,出色的工作思考了“超越常规”(har har):)
突破

4
-1(如果我有代表):代码拖曳中的meta表示不允许破坏性答案,因为人们可能会在自己的机器上尝试使用破坏性答案。请参阅限制列表中的第二个项目符号:codegolf.stackexchange.com/tags/code-trolling/info-
凯文-恢复莫妮卡

没有管理员权限就无法杀死系统进程,不是吗?
Sarge Borsch 2013年

3
@Kevin 代码挑战代码拖曳是具有不同规则的不同标签。
osvein 2013年

3
@ user1981338:该问题最初具有代码滚动标签,但此后已被删除。现在标记已消失,+ 1。
凯文-恢复莫妮卡

21

重击-12个字符

:(){ :|:&};:

经典前炸弹。锁定计算机并强制用户(或管理员)重新启动。


5
无聊-但仍然是我个人的最爱。我用它来关闭实时系统
s3lph 2013年

3
它会尽可能多地启动自身,但这并没有停止。
marinus 2013年

1
但是它将启动尽可能多的进程,直到计算机崩溃并因此退出程序
s3lph 2013年

14
+1用于添加笑脸,例如:():|
ProgramFOX 2013年

1
@Kartik:如果没有第一个空格,则会出现语法错误。您可以消除第二个。
丹尼斯

20

Python(在旧笔记本电脑上)

在具有单核处理器和散热不良的旧笔记本电脑上:

while True:
    print("CPU Temperature rising")

几个小时后笔记本电脑爆炸(或仅关闭)时,该程序将无法运行。

(为获得最佳效果,请用毯子或其他东西包裹笔记本电脑)


18

红宝石

kill在* nix上运行的ruby / irb进程。

`kill #{$$}`

2
我喜欢这个的优雅。+1
门把手

18

苹果2基本

1 PRINT "HELLO"
2 POKE 2053,128
3 POKE 2054,58
4 GOTO 1

它用覆盖其指令之一END


这个如何运作?
约翰内斯

5
@Johannes:在Applesoft BASIC中,程序以令牌化形式存储在内存中。因为没有操作系统或内存保护,所以它总是存储在同一位置,没有什么可以阻止您写入该内存。因此,第POKE一个在END令牌上写一个令牌PRINT,然后第二个POKE在第一个上写一个命令终止符"。当GOTO执行时,它将结束运行END而不是,PRINT程序结束。
marinus 2013年

14

在组装中,类似这样的方法可能会起作用:

jmp 0

我记得编译了这个实际可行的DOS。当时,它重新启动了计算机。


请尝试 实际上,我将把它作为答案发布:P
朱利安·莱伯特

retf可以工作,我已经在一个答案中说了这:)它会杀死它,这是因为内存分段在现代操作系统上的工作方式(或者应该说不起作用)
chbaker0 2013年

»jmp 0«与DOS一起使用,“因为代码段的前两个字节是CD 20,或者是“ INT 20”(这是退出程序的代码)。»push 0; ret«会有相同的效果。
丹尼尔(Daniel)

13

的PHP

function quit(){unlink(__FILE__);posix_kill(getmypid(),15);}

效果:
删除糟糕的脚本文件,然后杀死程序。
将其中一个坏男孩丢入某个代码库中,以使人们感到困惑。


这不是有效的PHP语法。您尝试定义一个函数,quit但是参数列表是要运行的代码。尝试运行它时出现解析错误。
埃米尔Vikström

@EmilVikström-现在修复。
donutdan4114 2014年

12

C,9个字符

gcc不关心琐碎细节(例如main不是函数)的编译器和其他编译器一起编译。
x86平台上工作-该程序立即退出。

main=195;

195是ret指令的操作码。


4
对我来说是段错误。main位于,.data因为它是int而不是in .text,并且.data被加载到不可执行的页面中。
mniip 2014年

10

我一直想将其发布在某个地方,即使已经有一个可接受的答案,我也认为它适合这里。

int
main(int argc, char **argv)
{
        revoke(*argv);
}

这适用于任何4.3BSD之后的系统以及revoke以相同方式实现的其他系统。Linux虽然没有原型,但MacOS过去有,但仅在最新版本中返回错误。

revoke采用文件路径,并强行销毁对该文件的所有引用。这包括该文件的所有内存映射,甚至可执行文件本身。显然,您需要使用路径启动程序,如果它恰好在PATH中,则此方法将无效。

在大多数类unix的系统上应该可以使用的这种变化是:

#include <sys/mman.h>
#include <inttypes.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
        intptr_t ps = getpagesize();
        munmap((void *)(((intptr_t)main)&~(ps - 1)), ps);
}

我们只是取消映射页面的映射,main以便在调用munmap返回时,它无处可返回。对函数的调用munmap只是在页面边界上,并且返回会成功,因此有一点机会,因此,要完全确定这可行,我们可能必须首先尝试取消映射两个页面。

当然,这是同一主题的变体:

#include <sys/mman.h>
#include <inttypes.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
        intptr_t ps = getpagesize();
        munmap((void *)(((intptr_t)&ps)&~(ps - 1)), ps);
}

只需取消堆栈的映射,以便我们无处可去。与main取消映射相同的警告-我们可能需要取消映射两个页面,除了必须记住堆栈可能会变小(除非您使用的是PA-RISC或类似的其他奇怪的体系结构)。

从自己的脚下拉地毯的另一种方法:

#include <sys/resource.h>

int
main(int argc, char **argv)
{
        setrlimit(RLIMIT_CPU, &((struct rlimit){ 0 }));
        while(1);
}

它取决于操作系统,系统如何处理0秒的CPU限制以及完成CPU时间的频率。MacOS立即终止了该进程,Linux需要while循环,我尝试过的另一个系统即使有一秒钟的限制也没有执行任何操作,而while循环,我没有进一步调试。


9

SH

sudo kill -SEGV 1

在Linux上即时发生内核恐慌。删除所有进程,包括其自身

Cmd

pskill csrss.exe

Windows上的即时蓝屏。终止Client/Server Runtime SubSystem。必须安装Pskill。


killall init还工作吗?
s3lph 2013年

1
@the_Seppi 1.只有root级用户才能向init发送信号2. init仅在接收到信号11时才会引起内核恐慌(segmentation错误)
MultiplyByZer0

好的,谢谢...您知道如果使用会发生什么sudo killall init
s3lph 2013年

1
@the_Seppi是的,我知道,我以前尝试过。Init忽略它,因为init可以决定是否接收信号,因此它完全忽略SIGKILL。unix.stackexchange.com/questions/7441/…–
MultiplyByZer0

8

在C中(兼容的Windows / Linux /(也可能是Unix / Freed BSD)):

main;

用法示例:

在Windows下使用:

echo main; > main.c && cl /Fe:main.exe main.c

和Linux:

echo "main;" > main.c && gcc -w -o main main.c

假设已安装编译器并且在currenth PATH变量中。

编辑:从技术上讲,它在Linux上引发异常(由处理器引发),但在Windows上没有此类消息。因此,该条目可能无效。但是我认为这很酷:P

编辑:在x86汇编程序中(使用NAsm / YAsm)

global s
s:
    ret

编译:

(视窗)

nasm -f win32 -o test.obj test.asm
LINK /OUT:test.exe /SUBSYSTEM:CONSOLE /ENTRY:s test.obj

(Linux)

nasm -f elf32 -o test.obj test.asm
ld -o test -e s test.obj

不幸的是,这种方式还在Linux上产生了一个核心转储,因此我认为它在功能上等同于C方法。除了更有效。


1
哇!我只是用它编译的-Wall -Wextra -std=c99 -pedantic,根本没有警告。
ldrumm

我实际上想提出这个问题,但我决定反对,因为它与我对其他问题的解决方案(codegolf.stackexchange.com/a/8778/3103)是重复的。
Konrad Borowski

7

用Haskell愚蠢地处理事情:

import System.Exit

absolutely doThis = if True then doThis else undefined

unconventional doThat = do
  putStrLn "I could just do that"
  putStrLn "But I'm gonna print factorial of 100 first"
  putStrLn "There you go:"
  print $ fac 100
  doThat
  where fac n = foldl (*) 1 [1..n]

main = absolutely unconventional exitFailure

6

蟒蛇


使用multiprocessing模块,我们可以生成另一个线程,其任务是通过队列与原工艺进行沟通,告诉它何时退出:

import multiprocessing
import time
queue = multiprocessing.Queue()

def second_thread():
    while True:
        queue.put('quit')
        time.sleep(0.1)

second_ps = multiprocessing.Process(target = second_thread)
second_ps.start()

while True:
    msg = queue.get()
    if msg == 'quit':
        break
    time.sleep(0.1)

second_ps.join()

6

ANSI C

没有代码优化,以下程序退出的速度非常快-即使编译为有效程序,实际上也无法启动

#include<stdlib.h>
#include<stdio.h>

char tooLong[0x7CFFFFFF];

void main()
{
    printf("never executed.");
}

这可能取决于系统-如果可以启动,请评论。


“不再抛出异常退出!” 这包括内存不足错误
John Dvorak

2
@JanDvorak 错误和异常之间存在差异。
syb0rg 2013年

我认为该规则涵盖了两者。询问者可以澄清吗?而且,我认为Java特定的SO问题不是一个很好的参考,特别是在捍卫C解决方案时。
John Dvorak 2013年

9
该程序既不会引发错误,也不会在程序内部引起错误。系统无法处理。
约翰内斯

6

好的。如果System.exit在Java中不允许简单地调用,那么如何通过另一个线程的反射来调用它呢?

import java.lang.reflect.*;

public class Quit {
    public static void main(String[] args) throws Exception {
        final Method exit = System.class.getMethod("exit", new Class<?>[]{ int.class });
        new Thread(new Runnable() {
            @Override public void run() {
                try {
                    System.out.println("calling... " + exit);
                    exit.invoke(null, new Object[] { 0 });
                } catch (Exception e) { e.printStackTrace(); }
            }
        }).start();
        for (int i = 1; ; ++i) {
            System.out.println("counting... " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) { break; }
        }
    }
}

查找exit方法,产生一个新线程,然后递减计数直到该线程通过反射调用exit杀死进程。


倒数?看起来这取决于我。
贾斯汀

1
嗯,是的,很好。我应该说计数,或者只是说计数到退出为止。
戴维·康拉德

6

x86机器语言,1个字符

通常,您可以用一条RET指令制作一个可行的可执行文件

\xC3 

4
那怎么不合常规?
2014年

6

C(Linux)

自杀版

向自身发送一个SIGKILL。

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int main() 
{
    kill(getpid(),SIGKILL);

    printf("Not killed");
}

“ Tu quoque mi fili”版本

分叉,然后儿子杀死了父亲。

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int main() 
{
    if (!fork())
        kill(getppid(), SIGKILL);

    printf("Not killed");
}

5

佩尔

...

就这些。


说明:它引发异常Unimplemented并立即退出。


添加了解释。
PhiNotPi

3
我不知道,例外很无聊。

6
Invalif由于挑战的适应:没有例外
s3lph

我只是还没有写另一个答案。
PhiNotPi 2013年

5

批处理和调试

既老又好,可在DOS机器上工作以立即重启系统。值得一提的是,它是一个旨在由两个不同的不兼容的解释器解释的脚本。

reset.bat

goto start

rcs
ffff
rip
0000
g
:start
debug < reset.bat

批处理文件解释会跳过旨在调试的指令,并将其自身馈送给调试以进行解释。由于需要向其输入未知命令(即goto),因此goto需要清除后面的空行以清除debug结果中的错误。


1
我曾经做过与dec ax相同的事情;推斧 推bx; retf
moopet,2013年

3

爪哇

以下代码未经测试,仅在某些平台上有效。

public class Quitter
{
       public static void main ( String [ ] args )
       {
             Process process = Runtime . getRuntime ( ) . exec ( "reboot" ) ;
       }
}

45
那个可怕的空白是什么
门把手

7
在UNIX上,必须为sudo rebootWindowsshutdown /r /t 0
s3lph 2013年

2
在UNIX上,您只需要使用sudo执行该程序,而不是要执行的命令。
Johannes Kuhn

1
@ the_Seppi,@ JohannesKuhn就像我说的那样,它仅在某些平台上有效,并且我假设您将像那样调用它sudo java Quitter
emory

3
-1没有足够的白色空间!!!
vaxquis 2014年

3

电源外壳

get-process | stop-process -force

将其另存为“ lastresort.ps1”,它应该可以解决问题。

如果由于某些愚蠢的策略而导致脚本无法执行时遇到问题,请在执行脚本之前键入以下命令:

Set-ExecutionPolicy Unrestricted

从命令行运行也很好,无需另存为脚本。
Iszi 2013年

3

TI基本84

:;;::;banana\\sEnd\;:;1:If X=X-1 :eat banana juice and lol;;;::::;:thought you could EAT THINGS XD /// CRAZIEST ANSWER YET!!!

3

Python(OP的一种替代方法)

我认为Python的答案实际上并没有OP建议的要好,但是我不喜欢这么多行,所以这是与OP完全一样的操作,但仅一行:

exec(''.join([ chr(x) for x in [35, 33, 47, 117, 115, 114, 47, 98, 105, 110, 47, 101, 110, 118, 32, 112, 121, 116, 104, 111, 110, 10, 35, 32, 117, 110, 105, 120, 32, 111, 110, 108, 121, 44, 32, 109, 105, 103, 104, 116, 32, 119, 111, 114, 107, 32, 111, 110, 32, 119, 105, 110, 100, 111, 119, 115, 10, 35, 32, 110, 111, 116, 101, 58, 32, 107, 105, 108, 108, 115, 32, 65, 76, 76, 32, 82, 85, 78, 78, 73, 78, 71, 32, 112, 121, 116, 104, 111, 110, 32, 112, 114, 111, 99, 101, 115, 115, 101, 115, 46, 32, 66, 101, 32, 99, 97, 114, 101, 102, 117, 108, 32, 47, 33, 92, 10, 100, 101, 102, 32, 101, 120, 105, 116, 40, 41, 58, 10, 32, 32, 32, 32, 105, 109, 112, 111, 114, 116, 32, 111, 115, 10, 32, 32, 32, 32, 111, 115, 46, 115, 121, 115, 116, 101, 109, 40, 34, 107, 105, 108, 108, 97, 108, 108, 32, 112, 121, 116, 104, 111, 110, 51, 34, 41, 10, 32, 32, 32, 32, 35, 32, 87, 105, 110, 100, 111, 119, 115, 32, 97, 100, 100, 111, 110, 10, 32, 32, 32, 32, 111, 115, 46, 115, 121, 115, 116, 101, 109, 40, 34, 116, 97, 115, 107, 107, 105, 108, 108, 32, 47, 105, 109, 32, 112, 121, 116, 104, 111, 110, 46, 101, 120, 101, 32, 47, 102, 34, 41, 32, 35, 32, 111, 114, 32, 119, 104, 97, 116, 101, 118, 101, 114, 32, 102, 105, 108, 101, 110, 97, 109, 101, 32, 112, 121, 116, 104, 111, 110, 64, 119, 105, 110, 100, 111, 119, 115, 32, 104, 97, 115, 10, 101, 120, 105, 116, 40, 41, 10] ]))

您可以将其设为功能,它将为您完成工作。


3

我自己的想法,不参与

TIGCC(用于德州仪器TI-89,TI-89钛,TI-92 +,TI-V200)

void main(void) {
    unlink("quit");
    asm("trap #2");
}

TI-Basic适用于相同的计算器

quit()
:© lines starting with © are comments
:Prgm
:©DelVar quit
:Exec "4E424E750000"
:EndPrgm

程序的作用:首先,它将自身从RAM中删除。(不要将其放在ROM中,否则将无法使用...)它仍然可以运行,因为在执行时会创建并执行该程序的副本。 asm(trap #2);调用ASM命令4E424E750000,该命令用于重置计算器,删除其RAM(保持ROM不变)并重新安装所有应用程序。

编辑:刚刚测试了基本版本。它无法删除自己...


3

MS-DOS .com格式

它将无效指令(FFFF)写入内存,然后执行它们,使NTVDM崩溃。

十六进制

B8 FF FF A3 06 01

Debug.exe汇编语言

MOV AX, FFFF
MOV [0106],AX
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.