作为程序员,我们都将一个非常酷的程序组合在一起,或者以一种有趣的方式将一些硬件拼凑在一起来解决问题.今天我在考虑那些黑客以及它们中的一些是如何被现代技术弃用的(例如,你不再需要破解你的Tivo添加网络端口).在软件世界中,我们现在将在网页上拖放的内容视为理所当然,但不久之前,这也是一个非常令人兴奋的黑客攻击.
我见过的最好的硬件黑客之一是几年前一家电信公司的前同事完成的.他的办公室里有一台小型便携式电视机,他在工作的整天都会看着它.为了逃脱它,他将一个开关连接到通过他的桌子下面的脚激活的开/关.
您个人见过或做过的最酷的硬件或软件是什么?你现在正在做什么黑客攻击?
所述的quake3平方根倒数和所述MIT魔术/更多魔术开关通常使这些列表.
我记得这个黑客是由Bob Smith编写的,他曾做过旧的DOS时代的内存管理器,名为386MAX(或"386 to the Max").它不是产品的一部分,它是一个小小的实用程序,他掀起并张贴在某个地方.然而,在网上我唯一可以找到的这种技术是1996年11月 Robert Collins 的DDJ Undocumented Corner专栏.
在英特尔引入CPUID指令之前,很难检查系统上CPU的确切类型和修订级别.事实证明,在386及更高版本的大多数版本中,实际上有一个CPU ID,但它只在一个特定时间可见:在EDX寄存器中重置处理器之后.(假设计算机的BIOS是唯一对此有合法兴趣的软件).
问题:如果我们不是BIOS,普通程序如何检索此寄存器值?
这个hack依赖于IBM PC兼容计算机的六种不同特性.他们如下:
从IBM AT及更高版本开始,有一种方法可以独立禁用总线上的A20地址线.
大多数计算机没有安装在BIOS ROM下面的非常高的内存地址中的RAM.
当您读取没有安装内存的内存位置时,大多数IBM PC总线计算机返回0xFF.
0xFF 0xFF 0xFF等是Intel CPU上的非法操作码.
如果在内存中安装异常处理程序,它将在这个时代(386到486)的大多数CPU上进行软重启.
在软复位或硬复位时,Intel处理器跳转到可寻址存储器顶部的地址,减去16个字节,这就是BIOS ROM放置在那里的原因.
该计划结合了所有这些琐事的知识,以实现目标.
结果是DOS命令行程序,它执行以下操作:
安装了非法的操作码异常处理程序
关掉总线上的A20地址线
软重启CPU(我认为这是通过BIOS调用)
当软重启发生时,处理器将尝试跳转到内存顶部减去16个字节,这是ROM启动代码所在的位置.但是,由于A20关闭,它实际上会跳到内存的顶部减去16个字节减去1兆字节.在大多数PC上,那里没有RAM.因此它将从这个不存在的RAM中获取一系列0xFF字节,并尝试执行它.这会产生非法的操作码异常.
然后,他的异常处理程序将获取EDX(CPUID)的值,并将其存放在他可以找到的地方.然后它会清理混乱(重新打开A20,从保护模式转回到DOS的实模式)并将控制权返回到原始代码.
当它奏效时,它是天才.Voila,这是一个简单的命令行DOS程序,可以为您提供CPUID值.
当然,那里不可避免地存在"不太兼容"的PC,当你运行它时会崩溃.呃,好吧.
嗯,这不是最酷的,但它对程序员来说绝对有趣.
我们为简历数据库项目构建了一个临时查询构建器.它有一些ajaxy部分,基本的想法是,如果你在页面上改变任何东西,搜索会自动重新运行.(它是由所有UI小部件的onBlur事件触发的)
所以我们没有真正使用"搜索"或"运行查询"按钮.这使用户感到困惑.所以我们添加了一个什么都没做的搜索按钮.它只是坐在那里.
它的工作原理是因为每次单击搜索按钮时,您刚刚开启的字段中的onBlur事件都会触发.
这使我们的用户群非常高兴.简单的事情.
这不是我做过的黑客攻击,而是我很久以前工作过的人告诉我的事情(他实际上做了黑客攻击).
他似乎为盲人和需要阅读文本文件的人工作.所以他想出了如何将文本文件翻译成盲文并使用各种字符打印出来.并且:
当时的打印机是冲击打印机,因此当打印字符时,打印机构足以打印纸张,留下可以感觉到的印象.由于在纸张背面形成印模,他不得不打印倒置后向盲文,这样当纸张转动时它是正确的.
当然,阅读行为消除了萧条,因此它是一次性读取机制,但我一直认为这是一个非常酷的黑客.
在进行iPhone的逆向工程工作时,我发现基带中的一个漏洞(处理电话和载波锁的芯片)可以让你随意写零.虽然这起初看起来毫无用处,但很快就会发现这可能比我原先想象的要多得多.通过ARM的工作方式,可以通过在目标中写入单个零来使某些跳转无效,从而使执行路径始终继续向前.这使得软件可以解锁,但很快就被更强大的黑客所取代,这种黑客可以让你完全重新刷新基带.
不管它现在多么无用,仍然为这个黑客感到骄傲.
我在大学里用气动阀门做了一个8分频计数器,以便免除其余的气动课程.
它是如此微不足道的事情,但是当我第一次看到这个代码时(由我的同事开发)我感到震惊,因为这是我从未想过的(我添加的评论):
cglobal x264_sub8x8_dct_sse2, 3,3 ;3,3 means 3 arguments and 3 registers used .skip_prologue: call .8x4 add r0, 64 ;increment pointers add r1, 4*FENC_STRIDE add r2, 4*FDEC_STRIDE .8x4: SUB_DCT4 2x4x4W ;this macro does the actual transform movhps [r0+32], m0 ;store second half of output data movhps [r0+40], m1 ;the rest is done in the macro movhps [r0+48], m2 movhps [r0+56], m3 ret
它通过一次做8x4组来完成4个8x8块变换.但它不会粘贴代码两次(这会浪费代码大小),也不会有8x4函数并调用它两次.也没有循环.相反,它调用"函数",然后递增指针,然后"直接"进入它并再次执行.
它得到了两全其美:没有函数调用超出原始的开销(因为指针r0,r1和r2在SUB_DCT4中没有增加)并且没有代码重复,也没有循环开销.
今年夏天我写了一个叫做SatelliteRush的游戏.这是一款适用于带有Java和GPS的手机的突围游戏.它可以以两种模式播放:"无聊模式"和"卫星模式".在无聊模式下,您可以像往常一样使用按钮移动球拍,但在卫星模式下,它使用手机的GPS接收器.你来回跑,桨随你一起移动.
我只在索尼爱立信W760i上进行了测试,并且由于GPS位置更新相当缓慢且不准确,因此效果相当不错.
到目前为止,我已经制作了这个游戏的"技术测试版",所以它不是很好看或易于使用.但如果您有带Java的GPS手机,可以在此处下载:http: //www.lysator.liu.se/~padrone/temporary/SatelliteRushTest/
编辑:
Android版现已推出Android版免费应用:https: //market.android.com/details?id = se.nekotronic.satelliterush
达夫的装置.这算数了吗?:)
Duffs Device,针对上述问题.
梅尔的故事.铁杆黑客.
我有一台早期的Commodore 64计算机,需要为它编写汇编代码.
问题是,C64没有汇编程序(要么就是这个,要么我买不起).
所以我通过在书中查找6502操作码并用原始字节创建程序来编写汇编程序.
在某些时候,它能够将汇编代码作为输入,并组装成一个程序.
我的一个朋友为他在BASIC的PET写了一个反汇编程序.我使用这个程序来反汇编我的汇编程序,然后能够使用我的汇编程序来组装它自己的更新版本.
哦,在过去我们不得不跳过的箍:)
最酷的黑客(它真的不是一个真正意义上的黑客,但它通过以及上面的一些答案)我曾经创建过我的Apple // e.
参考手册中有一行说$ C010是'任意关键'标志.
事实证明这是真的.尽管有内置的密钥重复硬件,但$ C010软开关的高位会告诉您密钥是否已关闭.
他们没有告诉你什么,每个人都发现困难的方法是没有可靠的方法来找出按键是什么键.
如果你写了一个小装配程序......(原谅我的错误,我的6502装配很生锈)
:1 lda $C010 cmp #$80 bcc :1 ; branch if less than? I forget how to do that. lda $C000 jsr $FDF0 ;output the accumulator value to the screen
所以它会循环,直到您按下一个键并通过从$ C000键盘读取开关加载来输出密钥.
但是,如果你运行该程序,它将无法正常工作.
当你拿着一把钥匙的时候肯定会打印出来的东西,当你不在的时候什么都没有,但是公交车上的某个地方有点滞后(我想,我不是硬件家伙)所以如果你按'f'你得到很多f.但如果你停下来,然后按'g',你会在切换到'g'之前得到一堆'f'.
你可以在苹果中看到这个问题的证据] [Gauntlet的版本,你会向一个方向移动,如果你试图向第二个方向移动,你会向原来的方向移动一点,直到你通过滞后.
它没有任何意义,因为读取$ C000总是100%准确,除非你首先扣除$ C010.
我发现这个问题引人入胜,经过数周的演奏后,我终于找到了我仍然认为是我写过的最酷的节目.
程序本身没有任何意义,它做了一些无用的ORA,但由于某种原因它起作用,并且在查询$ C010后它从$ C000产生了正确的值.
这很酷,我写了一篇关于nibble杂志的文章,他们接受了这篇文章但从未发表过(因为他们已经破产或因为这篇文章读起来像是15岁的时候写的),我在那里写了一个替代品.键盘输入程序并将其连接到每个人调用以获得键盘输入的零页面位置,并且我能够以编程方式更改键盘重复延迟和重复率,这是因为它连接到硬件中是不可能的.当然,Apple // e当时正在走出困境,但至今仍是我最酷的黑客.
2010年3月2日更新:通过一些旧文章,我发现了我的小装配程序的打印输出.我在这里张贴它,看看是否有人能弄清楚它为什么会起作用,所以它将永远以某种方式以数字形式供奉......
$0300 AD 10 C0 LDA $C010 ; load accumulator with any-key-down flag $0303 29 80 AND #$80 ; keep only high bit flag $0305 0D 00 C0 ORA $C000 ; OR accumulate with keyboard soft switch $0308 10 F9 BPL $0303 ; erm, I forget exactly which branch this is $030A 09 80 ORA #$80 ; turn the high bit on $030C 20 ED FD JSR $FDED ; print char in accumulator $030F 4C 00 30 JMP $0300 ; start again.
毫无疑问,为什么这应该有效,但确实如此.或者做到了.25年前.
快速反向平方根 - 一个奇怪的小程序,以某种方式设法计算某事物的平方根,但你从来没有想过从它看.
http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
我的一个朋友用更新,更快的OEM主板取代戴尔的主板.然而,他无法使用电源按钮和其他前面板工作 - 连接器尺寸不同,引脚布局不同.我拿了一堆备用跳线和备用电线,然后逐个连接正确的引脚.无需焊接:)
代码方面,我一直留下深刻的印象.我一直以为没有优雅的方法来确定一个fork
ed孩子是否成功exec
编辑,但确实存在.
儿童:
execvp(argv[0], argv); errval = errno; write(data->fd, &errval, sizeof(errval));
父:
socketpair(AF_UNIX, SOCK_STREAM, 0, fds); flag = fcntl(fds[1], F_GETFD) | FD_CLOEXEC; fcntl(fds[1], F_SETFD, flag); pid = clone(child, NULL, SIGCHLD, NULL); if(pid < 0){ ... } close(fds[1]); /* Read the errno value from the child, if the exec failed, or get 0 if * the exec succeeded because the pipe fd was set as close-on-exec. */ n = read(fds[0], &ret, sizeof(ret)); if (n < 0) { ... } else if(n != 0){ /* exec failed */ } else { /* exec succeeded */ }
Steve Wozniak的磁盘控制器.
特斯拉的设备创造了人造闪电(42米或130英尺)的记录,科罗拉多斯普林斯的所有灯都熄灭了.
我们在一些据称是俄罗斯黑客的小公司受到了损害.我自己和其他一些开发人员想看看如何,所以我从我们的服务器上下载了我见过的最优雅的PHP脚本,并立即从我们的实时机器中删除它.
这是一种名为c99shell的特洛伊木马,它做得如此之少,以至于同时它既可怕又美丽.这个东西有一个嵌入式GUI,图像使用base64从PHP输出,所以一切都是自包含的.功能列表生病了!这个东西可以启动shell,扫描连接字符串,锁定自己以及攻击者的许多其他有用的东西.
它过去挺美.
办公室里的每个人都认为我很疯狂,但实际上,这段代码确实有很多想法.他们保持文件大小较小,以便隐藏那些讨厌的上传限制,甚至还有一个base64编码的电子邮件通知,收集了攻击者的所有信息.
在黑色的星期天哈克.
我会告诉你,但如果我承认,他们可能会要求我的高中毕业证书;)
回到DOS的时代,我写了一个脚本程序来演示我公司的软件.此脚本程序将启动应用程序,然后在应用程序顶部弹出窗口,使用动画类型描述其某些功能,然后关闭窗口,向应用程序提供按键,等待应用程序显示正确的屏幕,然后弹出更多的窗户.它有自己的脚本语言甚至脚本编辑器,因此我可以中断脚本,编辑它,然后继续运行它.最好的部分是它运行在我们的应用程序的未修改版本之上.
整个演示应用程序是用C语言和汇编语言编写的.它挂钩了计时器和键盘中断,以便与应用程序进行交互.我写了一切,包括窗口库.
在大学演讲期间,我曾经为psion 3a编写了一个简单的dos式命令行.它只能做基本的目录列表,浏览,复制和移动,但它看起来部分 - 全屏小字体.
哦,我为68008编程pong,输入电位器和输出示波器.使用开发板并不是那么难,但是在osc上播放它有一些很酷的东西.
我写了一个简单的Windows批处理文件,让我在一台速度很慢的机器上快速播放与我的音乐库(f:驱动器)上的某些模式匹配的曲目(在这台机器上打开iTunes大约需要3分钟!).它通过findstr
命令支持正则表达式,并使用mplayer播放曲目.我所要做的就是按Windows + R键入:
play u2
要么:
play "neighbo.+rhood"
要么:
play "blink[0-9][0-9][0-9]"
批处理文件就像这样,在play.bat
.
cd /d f: findstr /I /R %1 dirlist.txt > playlist.txt mplayer -playlist playlist.txt
mplayer和play.bat都应添加到您的路径中.
当然不是我做的,但最近我遇到它看起来很酷:
C#中的自我印刷生活游戏
几十年来,康威的生命游戏一直让计算机科学家着迷.虽然它的规则非常简单,但康威的宇宙产生了各种各样的滑翔机,宇宙飞船,振荡器,滑翔机和其他形式的"生命".自我打印程序是同样好奇,而且 - 相当令人惊讶 - 在计算理论中占有重要地位.
结合两者会发生什么?你即将发现,但有一件事是肯定的:极客因素应该很高.
我写了一个包含生命游戏网格的C#程序.程序将游戏网格推进到下一代并打印出自己的副本,并更新网格.您可以获取输出,使用C#编译器进行编译,运行它,然后您将获得下一代游戏.您可以迭代该过程,或手动更改初始网格状态."
请点击上面的链接获取源代码.