2013-02-13 -loader
来源:互联网 发布:软件概要设计 编辑:程序博客网 时间:2024/05/18 20:31
目前已经成功将100扇区的512bytes内容拷贝到物理地址0x10000上,详见下面memory dump:
磁盘上hex:
memory dump:<bochs:18> xp /512bx 0x10000[bochs]:0x0000000000010000 <bogus+ 0>: 0xbe 0x01 0x00 0x00 0x00 0x00 0x10 0x000x0000000000010008 <bogus+ 8>: 0x00 0x00 0x01 0x00 0x10 0x00 0x00 0x000x0000000000010010 <bogus+ 16>: 0xb8 0x12 0x00 0x89 0xc5 0xb9 0x10 0x000x0000000000010018 <bogus+ 24>: 0xb8 0x01 0x13 0xbb 0x0c 0x00 0xb2 0x000x0000000000010020 <bogus+ 32>: 0xcd 0x10 0x62 0x79 0x65 0x62 0x79 0x650x0000000000010028 <bogus+ 40>: 0x20 0x6c 0x6f 0x61 0x64 0x65 0x72 0x2c0x0000000000010030 <bogus+ 48>: 0x20 0x68 0x65 0x72 0x65 0x27 0x73 0x200x0000000000010038 <bogus+ 56>: 0x63 0x6c 0x69 0x65 0x6e 0x74 0x51 0x510x0000000000010040 <bogus+ 64>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010048 <bogus+ 72>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010050 <bogus+ 80>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010058 <bogus+ 88>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010060 <bogus+ 96>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010068 <bogus+ 104>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010070 <bogus+ 112>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010078 <bogus+ 120>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010080 <bogus+ 128>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010088 <bogus+ 136>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010090 <bogus+ 144>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010098 <bogus+ 152>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100a0 <bogus+ 160>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100a8 <bogus+ 168>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100b0 <bogus+ 176>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100b8 <bogus+ 184>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100c0 <bogus+ 192>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100c8 <bogus+ 200>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100d0 <bogus+ 208>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100d8 <bogus+ 216>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100e0 <bogus+ 224>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100e8 <bogus+ 232>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100f0 <bogus+ 240>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000100f8 <bogus+ 248>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010100 <bogus+ 256>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010108 <bogus+ 264>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010110 <bogus+ 272>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010118 <bogus+ 280>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010120 <bogus+ 288>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010128 <bogus+ 296>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010130 <bogus+ 304>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010138 <bogus+ 312>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010140 <bogus+ 320>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010148 <bogus+ 328>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010150 <bogus+ 336>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010158 <bogus+ 344>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010160 <bogus+ 352>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010168 <bogus+ 360>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010170 <bogus+ 368>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010178 <bogus+ 376>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010180 <bogus+ 384>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010188 <bogus+ 392>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010190 <bogus+ 400>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x0000000000010198 <bogus+ 408>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000101a0 <bogus+ 416>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000101a8 <bogus+ 424>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000101b0 <bogus+ 432>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000101b8 <bogus+ 440>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000101c0 <bogus+ 448>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x00000000000101c8 <bogus+ 456>: 0x51 0x51 0x51 0x51 0x51 0x51 0x00 0x000x00000000000101d0 <bogus+ 464>: 0xe0 0x83 0x45 0x75 0xae 0x22 0xf4 0x760x00000000000101d8 <bogus+ 472>: 0x93 0xea 0x4e 0x76 0x64 0xf7 0x12 0x000x00000000000101e0 <bogus+ 480>: 0xc4 0x01 0x2f 0x00 0x00 0x00 0x2f 0x000x00000000000101e8 <bogus+ 488>: 0x00 0x00 0x00 0x00 0x10 0xf7 0x12 0x000x00000000000101f0 <bogus+ 496>: 0x09 0x00 0x92 0x00 0x8e 0x07 0x00 0x000x00000000000101f8 <bogus+ 504>: 0xfe 0xff 0xff 0xff 0xe0 0x83 0x45 0x75<bochs:19> c
00017826178i[CPU0 ] LOCK prefix unallowed (op1=0x53, modrm=0x00) 《----这个还需要确认下为何
00017826182i[CPU0 ] LOCK prefix unallowed (op1=0x53, modrm=0x00)
以上问题发现是代码前后物理地址不一致造成,属于笔误,走读一遍即可发现。
不过修改后发现存在下面悲剧的问题,乱码问题,瞄一眼基本可以判断存在越界读取字符串的问题(还好不是越界写内存)
可是,哪里存在越界读取呢?重新走读了下代码,感觉没啥大问题(当然,只是建立在现有单薄的汇编基础上。。。囧)
SECTION header vstart=0program_length dd program_endcode_entry dw start ;段内偏移 dd section.code_1.start ;段起始地址realloc_tbl_len dw (header_end-code_1_segment)/4code_1_segment dd section.code_1.startheader_end:SECTION code_1 align=16 vstart=0start:mov ax, msgmov bp, axmov cx, 28mov ax, 0x1301mov bx, 0x000cmov dl, 0int 10hjmp $msg: db "byebye loader, here's client"times 400 db "Q"program_end
没办法,只能单步大法了,没有太多背景知识,也只能这样子了。。。
火速断点到mov ax,msg处:
<bochs:5> sNext at t=17826173(0) [0x0000000000010010] 1001:0000 (unk. ctxt): mov ax, 0x0014 ; b81400<bochs:6> u /2000010010: ( ): mov ax, 0x0014 ; b8140000010013: ( ): mov bp, ax ; 89c500010015: ( ): mov cx, 0x001c ; b91c0000010018: ( ): mov ax, 0x1301 ; b801130001001b: ( ): mov bx, 0x000c ; bb0c000001001e: ( ): mov dl, 0x00 ; b20000010020: ( ): int 0x10 ; cd1000010022: ( ): jmp .-2 ; ebfe00010024: ( ): bound di, ds:[bx+di+101] ; 62796500010027: ( ): bound di, ds:[bx+di+101] ; 6279650001002a: ( ): and byte ptr ds:[si+111], ch ; 206c6f0001002d: ( ): popa ; 610001002e: ( ): jb .+44 ; 6465722c00010032: ( ): and byte ptr ds:[bx+si+101], ch ; 20686500010035: ( ): jb .+101 ; 726500010037: ( ): daa ; 2700010038: ( ): jnb .+32 ; 73200001003a: ( ): arpl word ptr ds:[si+105], bp ; 636c690001003d: ( ): outsb dx, byte ptr gs:[si] ; 656e0001003f: ( ): jz .+81 ; 7451<bochs:7>由反汇编可以看到:字符串的具体段内偏移首地址是0x0014,那么掐指一算,实际物理地址应该就是cs基址*0x10 + 0x0014 = 0x1001 * 0x10 + 0x0014 = 0x10024
火速继续dump memory看一把:
<bochs:7> xp /48bx 0x10024[bochs]:0x0000000000010024 <bogus+ 0>: 0x62 0x79 0x65 0x62 0x79 0x65 0x20 0x6c0x000000000001002c <bogus+ 8>: 0x6f 0x61 0x64 0x65 0x72 0x2c 0x20 0x680x0000000000010034 <bogus+ 16>: 0x65 0x72 0x65 0x27 0x73 0x20 0x63 0x6c0x000000000001003c <bogus+ 24>: 0x69 0x65 0x6e 0x74 0x51 0x51 0x51 0x510x0000000000010044 <bogus+ 32>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x510x000000000001004c <bogus+ 40>: 0x51 0x51 0x51 0x51 0x51 0x51 0x51 0x51<bochs:8>熟悉的0x62出现,没错的呀,就是字符串”byebye。。。”的ascii值呀~~ 怎么看也没有字符串越界读取呀~
重新走读了一遍又一遍的代码
无解,无解,无解,无解。
最后,没辙,习惯性的sreg一把,扫一遍所有段寄存器吧:
<bochs:8> sreges:0x1000, dh=0x00009301, dl=0x0000ffff, valid=1 Data segment, base=0x00010000, limit=0x0000ffff, Read/Write, Accessedcs:0x1001, dh=0x00009301, dl=0x0010ffff, valid=1 Data segment, base=0x00010010, limit=0x0000ffff, Read/Write, Accessedss:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedds:0x1000, dh=0x00009301, dl=0x0000ffff, valid=7 Data segment, base=0x00010000, limit=0x0000ffff, Read/Write, Accessedfs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedgs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1tr:0x0000, dh=0x00008b00, dl=0x0000ffff, valid=1gdtr:base=0x00000000000fa1a7, limit=0x30idtr:base=0x0000000000000000, limit=0x3ff<bochs:9>
发现唯一有疑点的地方就是ds和cs不一致。一开始不以为然,这个不一致也正常,存在各个段,基址不一样很正常。但是,这个client的代码本身就是一个段,这个让我有点疑点,如果以cs为基址进行偏移,肯定不会存在这种越界读取的问题,难道是这个字符串以ds基址进行offset了?没有任何依据的情况下,走投无路的情况下,大胆猜测也是一种必须,计算一把,如果以ds 0x1000作为基址进行偏移,那么实际进行读取的字符串起始地址为:0x10000+0x0014 = 0x10014,继续dump一把memory,偏移量为28bytes
<bochs:9> xp /48bx 0x10014[bochs]:0x0000000000010014 <bogus+ 0>: 0xc5 0xb9 0x1c 0x00 0xb8 0x01 0x13 0xbb0x000000000001001c <bogus+ 8>: 0x0c 0x00 0xb2 0x00 0xcd 0x10 0xeb 0xfe0x0000000000010024 <bogus+ 16>: 0x62 0x79 0x65 0x62 0x79 0x65 0x20 0x6c0x000000000001002c <bogus+ 24>: 0x6f 0x61 0x64 0x65 0x72 0x2c 0x20 0x680x0000000000010034 <bogus+ 32>: 0x65 0x72 0x65 0x27 0x73 0x20 0x63 0x6c0x000000000001003c <bogus+ 40>: 0x69 0x65 0x6e 0x74 0x51 0x51 0x51 0x51<bochs:10>
发现不对劲了~ 上面标红处出现了熟悉的acsii,再数了一下从第一个0x62前偏移了多少个bytes,刚好有0x10个,而cs和ds刚好也相差0x10,难道真的就是用ds计算这个字符串的偏移?????混蛋!!!
立马修改代码,出事情况下把ds和cs赋成一样(0x1001),见下:
SECTION code_1 align=16 vstart=0start:mov ax, csmov ds, axmov ax, msgmov bp, axmov cx, 28mov ax, 0x1301mov bx, 0x000cmov dl, 0int 10hjmp $但是!但是! 结果还是没有变化。。。。
怒了,怒了,重新回翻下刚才sreg的记录,发现es也是0x1000,然后这个时候才突然发现ES不是用于字符串处理的目的串的基址寄存器吗?
这次小心翼翼的把es也赋成和cs一样(如果还不行,那真的没辙了。。。)
果真!直接运行一把,熟悉的该死的本该出现的字符串终于显示在bochs上了:
附上正确的代码:
SECTION header vstart=0program_length dd program_endcode_entry dw start ;段内偏移 dd section.code_1.start ;段起始地址realloc_tbl_len dw (header_end-code_1_segment)/4code_1_segment dd section.code_1.startheader_end:SECTION code_1 align=16 vstart=0start:;bug-fix: 需要把es,ds和cs统一起来mov ax, csmov ds, axmov es, axmov ax, msgmov bp, axmov cx, 28mov ax, 0x1301mov bx, 0x000cmov dl, 0int 10hjmp $msg: db "byebye loader, here's client"times 400 db "Q"program_end:
心得:
在缺乏足够的知识使用汇编让字符串在终端显示的情况下,终于通过单步大法和大胆胡猜进行定位这个越界显示的问题。这次是运气,有一定的规律可以寻找,下次复杂点估计就歇菜了,所以汇编基础还是得继续夯实,本科大三学习的汇编啊,混蛋,全还回去 了~
最后附上jmp far [0x04]这个含义理解:
Jmp far ds:0x04 实际含义:从ds取出段基址* 0x10,然后再加上0x04偏移,访问该地址为起始地址,长度为2个双字节,其中第一个双字保存到cs中,后一个双字保存到ip中。然后jmp的地址就是cs*0x10
我们来计算下:
1. 首先通过sreg查看ds的内容:为0x1000
<bochs:7> sreges:0x1000, dh=0x00009301, dl=0x0000ffff, valid=1 Data segment, base=0x00010000, limit=0x0000ffff, Read/Write, Accessedcs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=3 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedss:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedds:0x1000, dh=0x00009301, dl=0x0000ffff, valid=7 Data segment, base=0x00010000, limit=0x0000ffff, Read/Write, Accessedfs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedgs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1tr:0x0000, dh=0x00008b00, dl=0x0000ffff, valid=1gdtr:base=0x00000000000fa1a7, limit=0x30idtr:base=0x0000000000000000, limit=0x3ff
2. 然后计算 ds:0x04 = 0x1000 * 0x10 +0x04 = 0x10004,所以要取出的实际jmp地址的起始偏移地址为0x10004,接下去要做的就是dump内存,查看实际值:
<bochs:9> xp /10bx 0x10004 [bochs]:0x0000000000010004 <bogus+ 0>: 0x00 0x00 0x01 0x10 0x00 0x00 0x01 0x000x000000000001000c <bogus+ 8>: 0x01 0x10<bochs:10>
3. 重新排列这2个双字(4字节,32位):见下,越顶上地址越高。得到实际的32位值为:0x10010000,然后把高位的2个字节给cs(0x1001),低位的2个字节给ip(0x0000)
0x10
0x01
0x00
0x00
0x1001 0000
4. 重新排列这2个双字(4字节,32位):见下,越顶上地址越高。得到实际的32位值为:0x10010000,然后把高位的2个字节给cs(0x1001),低位的2个字节给ip(0x0000)
5. 所以jmp far [0x04] === jmp farcs:0x0000 == jmp 物理地址0x1001 * 0x10 = jmp 0x10010,我们预测,跳转后,ds的内容还是为0x1000.cs的内容为0x1001,ip的内容为0x0000,实际情况如下:
<bochs:12> sNext at t=17826173(0) [0x0000000000010010] 1001:0000 (unk. ctxt): mov ax, 0x0014 ; b81400<bochs:13> sreges:0x1000, dh=0x00009301, dl=0x0000ffff, valid=1 Data segment, base=0x00010000, limit=0x0000ffff, Read/Write, Accessedcs:0x1001, dh=0x00009301, dl=0x0010ffff, valid=1 Data segment, base=0x00010010, limit=0x0000ffff, Read/Write, Accessedss:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedds:0x1000, dh=0x00009301, dl=0x0000ffff, valid=7 Data segment, base=0x00010000, limit=0x0000ffff, Read/Write, Accessedfs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedgs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1 Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessedldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1tr:0x0000, dh=0x00008b00, dl=0x0000ffff, valid=1gdtr:base=0x00000000000fa1a7, limit=0x30idtr:base=0x0000000000000000, limit=0x3ff<bochs:14> rrax: 0x00000000_00001001 rcx: 0x00000000_00090000rdx: 0x00000000_00000000 rbx: 0x00000000_00000010rsp: 0x00000000_0000fffe rbp: 0x00000000_00000000rsi: 0x00000000_000e0064 rdi: 0x00000000_00000000r8 : 0x00000000_00000000 r9 : 0x00000000_00000000r10: 0x00000000_00000000 r11: 0x00000000_00000000r12: 0x00000000_00000000 r13: 0x00000000_00000000r14: 0x00000000_00000000 r15: 0x00000000_00000000rip: 0x00000000_00000000eflags 0x00000012: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf AF pf cf<bochs:15>
- 2013-02-13 -loader
- 02 orange loader 源码
- Loader
- Loader
- Loader
- loader
- loader
- Loader
- loader
- Loader
- loader
- Loader
- loader
- Loader
- Loader
- loader
- Loader
- Loader
- Java容器集合类的区别用法
- (2)Java正则表达式学习
- 在Eclipse中关联Java中文API
- 高效能程序工具之grep
- 利用jQuery和JS实现奇偶行背景颜色自定义效果
- 2013-02-13 -loader
- 美国12个最酷创业公司总部
- eclipse3.7中文字符太小解决方案
- hibernate的select 读取结果集的两种显示方法
- sleep和wait有什么区别?
- CentOS 6.3安装极点五笔输入法
- 初识python多线程(转+实例)
- C#中的readonly与const区别
- “奇点”临近:2045,人类永生