CISCO IOS (Part 4)
Par Mathieu le samedi 23 février 2008, 19:07 - Lien permanent
Every OS includes a memory manager. Current OS uses protected memory
architecture. The process x cannot read/write the memory of a process y. To
enable communication between process x and y, it requires different techniques
(Shared Memory, Message Queues, Pipes, Network Connections …). These techniques
enhance inter-processes security but reduce performance. The IOS does not
implement Shared Memory; any process can access all the memory without
restrictions. A process is free to communicate with another one by writing
directly into its memory. (Buffer Overflow = Crash, I’ll come back later on
this by explaining the Memory Block Architecture). The IOS can mark memory as
R/O or R/W. The IOS has memory pools, driven by the Pool Manager:
In the next post: The
Chunk Manager!
#show memory Head Total(b) Used(b) Free(b) Lowest(b) Largest(b) Processor 653B8C20 155481056 86243592 69237464 68168948 67670028 I/O EE800000 25165824 5269012 19896812 19819968 19871932Above, a processor and an I/O memory pool:
- Head : Start Address of the memory pool
- Total : Pool size in bytes
- Used : Total amount of bytes currently used in the pool
- Free : Total amount of bytes currently free in the pool
- Lowest : The history’s lowest amount of bytes free since last restart
- Largest : The Largest free contiguous memory block
#show region Region Manager: Start End Size(b) Class Media Name 0x0E800000 0x0FFFFFFF 25165824 Iomem R/W iomem:(iomem) 0x60000000 0x6E7FFFFF 243269632 Local R/W main 0x6000F000 0x632FFFFF 53415936 IText R/O main:text 0x63300000 0x64DFFCFF 28310784 IData R/W main:data 0x64DFFD00 0x653B8C1F 6000416 IBss R/W main:bss 0x653B8C20 0x6E7FFFFF 155481056 Local R/W main:heap 0x80000000 0x8E7FFFFF 243269632 Local R/W main:(main_k0) 0xA0000000 0xAE7FFFFF 243269632 Local R/W main:(main_k1) 0xEE800000 0xEFFFFFFF 25165824 Iomem R/W iomemThe Processor Memory Pool belongs to main:heap region. This region belongs to the main region starting at 0×60000000 and ending at 0×6E7FFFFF. The I/O Memory Pool belongs to iomem region starting at 0xEE800000 and ending at 0xEFFFFFFF. Within the main region:
- main:text : contains IOS’s code in R/O (IText)
- main:data : contains Initialized variables R/W (IData)
- main:bss : contains Uninitialized variables R/W (IBss)
- main:heap : contains standard local memory structures R/W
- iomem : contains devices memory (I/O bus memory)
#show memory processor Processor memory Address Bytes Prev Next Ref PrevF NextF Alloc PC what 65A817E0 0000000084 65A8175C 65A81864 001 -------- -------- 628215E8 Init 65A81864 0000001372 65A817E0 65A81DF0 001 -------- -------- 608E3218 Skinny Socket Server 65A81DF0 0000001156 65A81864 65A822A4 001 -------- -------- 608E3218 Skinny Socket Server
- Address : Start of block
- Bytes : Size of block
- Prev : Previous block Address (linkage)
- Next : Next Block Address (linkage)
- Ref : How many process are using this block?
- PrevF : Previous free block
- NextF : Next free block
- Alloc PC : Allocating Process
- What : Block owner’s process name
#show memory 0x65A81864 65A81860: AB1234CD 010B0000 66B4EBEC +.4M....f4kl 65A81870: 6395634C 608E3218 65A81DF0 65A817F4 c.cL`.2.e(.pe(.t 65A81880: 800002AE 00000001 605C3DD4 00000112 ........`=T.... ... 65A81DE0: FD0110DF }.._After some researches we can guess some of the fields from the Block’s header:
65A81860: [MAGIC ] [PID ] [? ] 65A81870: [PTR_NAME] [ALLOCPC] [NEXT ] [PREV+20d] 65A81880: [SIZE*] [REF ] [? ] [ DATA ->] ... 65A81DE0: [<- DATA] [MAGIC ]
- MAGIC_START is always 0xAB1234CD
- PID : Process ID
- [ PLACEHOLDER ]
- PTR PS_ NAME : Pointer to the Memory Block’s owner process name
- ALLOC_PC : Same value as in “show memory processor” command
- NEXT : Next Block Pointer
- PREV : Previous Block Pointer + 20d (pointing to the Next Block Pointer of the previous block)
- SIZE : The MSB (Most Significant Bit) of this Field is a flag where 1 states that the block is in use. The value read in this field differ from the one displayed using the “show memory processor” command. For both to be equals I need to do : (value read)*2+4 ????
- REF : How many process are using this block?
- [ PLACEHOLDER ]
- DATA : …
- MAGIC_END is always 0xFD0110DF (palindrome in hexadecimal)
#show process 0x0000010B [010B <> 0000] Process ID 267 [Skinny Socket Server], TTY 0 Memory usage [in bytes] Holding: 89644, Maximum: 109468, Allocated: 6601380, Freed: 6514500 Getbufs: 0, Retbufs: 0, Stack: 8908/12000 CPU usage PC: 60846DE4, Invoked: 26, Giveups: 1, uSec: 9384 5Sec: 0.00%, 1Min: 0.00%, 5Min: 0.00%, Average: 0.00% Age: 5007208 msec, Runtime: 244 msec State: Waiting for Event, Priority: NormalChecking the PTR PS_NAME field:
#show memory 0x6395634C 63956340: 536B696E Skin 63956350: 6E792053 6F636B65 74205365 72766572 ny Socket Server 63956360: 00000000 0A496E76 616C6964 20736B69 .....Invalid ski ->Skinny Socket ServerChecking that there is currently an end of block (must have the FD0110DF magic number):
0x65A81864 + 2*[SIZE]+4 + SIZEOF(MAGICSTART) + [HEADERSIZE] = 0x65A81864 + 0X560 + 0x4 + 0x24 #show memory 0x65A81DEC 65A81DE0: FD0110DF }.._Now let’s talk about the crash resulting from a Buffer Overflow: If we want to make a buffer overflow in a memory area, so writing more bytes than allocated for this area, we’ll overwrite the next block header thus breaking the IOS memory linkage mechanism. What a pity! Or not! The IOS constantly checks the memory structures, if it finds any inconsistency, it’s forcing a crash. So to success with a buffer overflow (crash free), you need to re-write a coherent header on the next block. Do not forget to add a “jmp” to your code to jump just after the next block header!
In the next post: The
Chunk Manager!