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>






原创粉丝点击