|
楼主 |
发表于 2007-5-24 14:51:59
|
显示全部楼层
这几天又在寝室猫着了,今天回来回下:
回2楼:
感谢2楼,没错,的确我研究过汇编语言的编译然后得出的,如果直接写出机器码会很烦,而且容易忘记,但是,每个机器指令我都参考了intel的手册自己重新汇编了一便。而且这个程序的确还得chmod才能运行。
这是我那篇文章中的具体编码方式一节:
最核心的应该算是那几条指令编码:
eax 的寄存器选择位为0, ebx的为3, 根据mov指令中的:
B8+ rd MOV r32, imm32 Move imm32 to r32.
以下两句:
movl $4, %eax
movl $1, %ebx
汇编为:
B8 04 00 00 00
BB 01 00 00 00
ECX的寄存器选择位为1.edx为2,第一句使用立即数寻址,虽然这是个变量,但是他存储的是地址。
从程序执行的角度来看,他存储的是字符串的的基地址。
所以下面两句:
movl $output, %ecx //随便取的名字。
movl $13, %edx
汇编为:
B9 XX XX XX XX (这里是字符串的首地址)
BA 0D 00 00 00
这是int指令的描述:
CD ib INT imm8 Interrupt vector number specified by immediate byte.
这句
int $0x80
被汇编为:
CD 80 (这里是一个字节啊,不是4个!)
movl $1, %eax
movl $0, %ebx
int $0x80
很容易写出还是上面的:
B8 01 00 00 00
BB 00 00 00 00
CD 80 00 00 //最后这俩是填充的。
回3楼:
是啊,这个我给记错了,13让我给弄成C了,你看上面的这节就知道原因了。多谢指正。
回4楼:
版主的意思我不太明白。我只定义了数据段和代码段分别存放数据和代码。我承认自己的水平有限。不知道是不是用ldt的基地址值去确定,因为低16位为长度,而数据段中那个字符串又放在开始,应该可以吧。我不知道对不对,希望请版主赐教。
回5楼:
这的确没啥意思,要是你学会用机器码写病毒就有意思了。开个玩笑。我学习机器码只是更深刻的了解x86的编码方式和程序的运行机理而已。
回6楼:
我并不是说你说的错,我承认,我的操作系统原理是不够强。但是我一直在努力学习,正是因为我无知,我才会去问, 虽然我研究linux内核很长时间,也只是停留在理论上的东西,整个学校,我连找个提问的都没有。说实话,我很感激你,因为你这么说证明我的确有错的地方,而且你愿意指出,这难道不好么。
回7楼:
你只是说,你做过没?
这个是用汇编写的,然后编译出来的,共611个字节。
00000000 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 .ELF............
00000010 02 00 03 00 01 00 00 00 74 80 04 08 34 00 00 00 ........t...4...
00000020 CC 00 00 00 00 00 00 00 34 00 20 00 02 00 28 00 ........4. ...(.
00000030 06 00 03 00 01 00 00 00 00 00 00 00 00 80 04 08 ................
00000040 00 80 04 08 96 00 00 00 96 00 00 00 05 00 00 00 ................
00000050 00 10 00 00 01 00 00 00 98 00 00 00 98 90 04 08 ................
00000060 98 90 04 08 0D 00 00 00 0D 00 00 00 06 00 00 00 ................
00000070 00 10 00 00 B8 04 00 00 00 BB 01 00 00 00 B9 98 ................
00000080 90 04 08 BA 0C 00 00 00 CD 80 B8 01 00 00 00 BB ................
00000090 00 00 00 00 CD 80 00 00 68 65 6C 6C 6F 20 77 6F ........hello wo
000000A0 72 6C 64 21 0A 00 2E 73 79 6D 74 61 62 00 2E 73 rld!...symtab..s
000000B0 74 72 74 61 62 00 2E 73 68 73 74 72 74 61 62 00 trtab..shstrtab.
000000C0 2E 74 65 78 74 00 2E 64 61 74 61 00 00 00 00 00 .text..data.....
000000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000F0 00 00 00 00 1B 00 00 00 01 00 00 00 06 00 00 00 ................
00000100 74 80 04 08 74 00 00 00 22 00 00 00 00 00 00 00 t...t...".......
00000110 00 00 00 00 04 00 00 00 00 00 00 00 21 00 00 00 ............!...
00000120 01 00 00 00 03 00 00 00 98 90 04 08 98 00 00 00 ................
00000130 0D 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 ................
00000140 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 ................
00000150 00 00 00 00 A5 00 00 00 27 00 00 00 00 00 00 00 ........'.......
00000160 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 ................
00000170 02 00 00 00 00 00 00 00 00 00 00 00 BC 01 00 00 ................
00000180 80 00 00 00 05 00 00 00 04 00 00 00 04 00 00 00 ................
00000190 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 ................
000001A0 00 00 00 00 3C 02 00 00 27 00 00 00 00 00 00 00 ....<...'.......
000001B0 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
000001C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001D0 74 80 04 08 00 00 00 00 03 00 01 00 00 00 00 00 t...............
000001E0 98 90 04 08 00 00 00 00 03 00 02 00 01 00 00 00 ................
000001F0 98 90 04 08 00 00 00 00 00 00 02 00 08 00 00 00 ................
00000200 74 80 04 08 00 00 00 00 10 00 01 00 0F 00 00 00 t...............
00000210 A5 90 04 08 00 00 00 00 10 00 F1 FF 1B 00 00 00 ................
00000220 A5 90 04 08 00 00 00 00 10 00 F1 FF 22 00 00 00 ............"...
00000230 A8 90 04 08 00 00 00 00 10 00 F1 FF 00 6F 75 74 .............out
00000240 70 75 74 00 5F 73 74 61 72 74 00 5F 5F 62 73 73 put._start.__bss
00000250 5F 73 74 61 72 74 00 5F 65 64 61 74 61 00 5F 65 _start._edata._e
00000260 6E 64 00 nd.
而用C写的比用汇编写的在我机器上不加任何选项直接编译有4678个字节。
我的有168个字节你说哪个快?哪个效率高。
回8楼:
感谢您提供的连接。这个程序不错。我会有时间好好研究下代码。
最后我来做个总结。
大家的争论和批评,对我来说的都是一种鼓励,而且我也很高兴,你们不知道,在学校里连个说话的都没,这里还能有人和我争论,给我挑毛病。这正验证了一句我自己的话“不较真,是对技术的不忠”。通过这个话题,让我学到了很多。
关于ELF的执行和编译,而且对编译器也有了更深一步的了解。比如,平时我们那些高级语言中所用的变量,其实都不过是个符号,而在实际的机器语言里,这些都是无所谓的,而被转化成了空间、地址。而在可执行程序中这些都是不必要的,编译器之所以把它们保留只是为了调试而已。甚至如果你可以自己指定程序入口,你可以不要_start, 不要main().
诚然,我时刻记得LINUX不是windows,二楼说的对,像windows那样随便就可以执行一段二进制的代码是不安全的,而且,DEBUG也是从DOS时代遗留下来的古董。LINUX从诞生之日起就已经不必再那么苦要调试机器码了。
最后,我还是想说件事,如果真想写类似DEBUG的程序,可能并不是办不到,ELF代码可以简单到只有一个ELF头,一个程序头,和代码,其他的程序头,节头都可以不要,只使用代码段并添加可写标记,而在代码段中通过跳转来跳过存储数据的地址。再利用调试器的技术编写。而且写程序确定一些地址进行替换,应该不是难事。相信应该可以做到吧!当然这种技术不是我能做到的。
呵呵!谢谢大家! |
|