Memory Corruption caused by illegal array access in Linux -- cause of segmentation fault

Source: Internet
Author: User

2012-02-05 wcdj

1. Stack knowledge required for debugging

2. Memory Corruption caused by illegal array access


Stack knowledge required for debugging

Stack is one of the memory regions in which the program stores data. It features a LIFO (last in first out, last in first out) data structure, that is, the data that is put in the later is first retrieved for backup. The operation to store data in the stack is called push (push), and the data retrieved from the stack is called pop (POP ). Stack is used to save automatically assigned variables dynamically. In addition, the stack is used to pass function parameters and save the return address and return value.

 #include <stdio.h> #include <ctype.h> #include <stdlib.h> #define MAX (1UL << 20)  typedef unsigned long long u64; typedef unsigned int u32;  u32 max_addend = MAX;  u64 sum_till_MAX(u32 n) {     u64 sum;     n++;     sum = n;      if (n < max_addend)         sum += sum_till_MAX(n);      return sum; }  int main(int argc, char** argv) {     u64 sum = 0;      if ((argc == 2) && isdigit(*(argv[1])))         max_addend = strtoul(argv[1], NULL, 0);          if (max_addend > MAX || max_addend == 0) {         fprintf(stderr, "Invalid number is specified\n");         return 1;     }      sum = sum_till_MAX(0);     printf("sum(0..%lu) = %llu\n", max_addend, sum);      return 0;                                                           }

Calculate the sum from 0 to 10:

$ Gcc-O sum-G sum. c

$./SUM 10

Sum (0 .. 10) = 55

Relationship between function call and stack-Changes of stack before and after function call

On the stack, the parameters passed to the function, the caller's return address, the upper stack frame pointer, and the automatic variables used inside the function are saved in sequence. In addition, the stack is also used to temporarily save registers when processing some functions. Each function has this information, calledStack frame(Stack
Frame ). In this case, you need to set the starting address of the stack frameFrame pointer (FP). In addition,Stack pointer (SP)Always point to the top of the stack.

Invalid array access causes Memory Corruption

One of the Typical Bugs caused by incorrect Array Operations is buffer overflow, that is, writing data out of the allocated memory space. In particular, if such bugs occur in the buffer zone on the stack, they may lead to security vulnerabilities. Therefore, many preventive measures and countermeasures have emerged, for example, you can specify the buffer size to write security functions, source code check tools, and compiler alarms during build. Even so, such bugs happen from time to time.

The following is a simple example:

#include <stdio.h>#include <string.h>char szInfo[] = "Oops! here is a buffer overflow, wcdj";void func()                                             {    char buf[5];    strcpy(buf, names);}int main(){    func();    return 0;}

Compile:

Gcc-wall-g-o hack28 hack28.c

Open coredump:

Ulimit-C Unlimited

Run:

Gerryyang @ wcdj :~ /Test/hack>./hack28

Segment error (coredumped)

Gerryyang @ wcdj :~ /Test/hack> ls-RTL

Total 160 K

-RW-r -- 1 gerryyang users 186 hack28.c

-Rwxr-XR-x 1 gerryyang users 7986 hack28

-RW ------- 1 gerryyang users 1474562012-02-05 Core

To debug the program:

Gerryyang @ wcdj :~ /Test/hack> GDB hack28 Core

Gnu gdb 6.6

Copyright (c) 2006 free softwarefoundation, Inc.

GDB is free software, covered by the gnugeneral Public License, and you are

Welcome to change it and/or distributecopies of it under certain conditions.

Type "show copying" to see theconditions.

There is absolutely no warranty forgdb. Type "show warranty" Fordetails.

This GDB was configured as "i586-suse-linux "...

Using host libthread_db library "/lib/libthread_db.so.1 ".

 

Warning: Can't read pathname for load map: input/output error.

Reading symbols from/lib/libc. so.6...... done.

Loaded symbols for/lib/libc. so.6

Reading symbols from/lib/ld-linux.so.2... done.

Loaded symbols for/lib/ld-linux.so.2

Core was generated by './hack28 '.

Program terminated with signal 11, segmentation fault.

#0 0x73692065 in ?? ()

(GDB) BT

#0 0x73692065 in ?? ()

#1 0x62206120 in ?? ()

#2 0x65666675 in ?? ()

#3 0x766f2072 in ?? ()

#4 0x6c667265 in ?? ()

#5 0x202c776f in ?? ()

#6 0x6a646377 in ?? ()

#7 0xbfb48600 in ?? ()

#8 0xb7e5a89c in _ libc_start_main () from/lib/libc. so.6

Backtrace stopped: Previous frame inner tothis frame (upt stack ?)

(GDB) x/I 0x73692065

0x73692065: cannot access memory at address 0x73692065

(GDB) x/I 0x62206120

0x62206120: cannot access memory at address0x62206120

(GDB)

Backtrace cannot be correctly displayed. In this case, backtrace is unreliable. Because the content displayed by backtrace is probably not actually tracked. That is, the Code suddenly jumps to or calls the wrong address 0x73692065, resulting in segmentation fault.

Note: It is difficult to place programs and shared memory on the address displayed on Stack frames #0 and #1. In most Linux releases of the i386 architecture, the program is located near the address 0x08000000, and the shared library is located after the address 0xb0000000. Therefore, remember what address will be located in the program and shared library under standard conditions in the debugging object environment and it will be very convenient to read backtrace.

(GDB) x/30C $ sp

0xbfb48660: 32 ''97 'a '32' '98 'B' 117 'u'000000' f'000000' f'000000' e'

0xbfb48668: 114 'r'32' '000000' o '000000' v '000000' e '000000' r'000000' f'000000' l'

0xbfb48670: 111 'O' 119 'w'44', '32' '000000' w'99 'C' 119 'D' 100 'J'

0xbfb48678: 0' \ 0'-122 '\ 206'-76'''-65 '0000'-100 '\ 234'-88 'l'

Sp-15 (GDB) x/30C $

0xbfb48651: 31 '\ 037'-8 'ø '79' o '000000' o '000000' P '000000' s '33 '! '32''

0xbfb48659: 104 'h'000000' e '000000'101 'E' 32 ''105 'I '123'32''

0xbfb48661: 97 'a '32' 98 'B' 117 'u'000000' f'000000' f'000000' e '000000' R'

0xbfb48669: 32 '000000' o '000000' v '000000' e '000000' R '000000' f'

(GDB) P (char *) $ sp-15

$1 = 0xbfb48651 "\ 037 ø oops! Here is abuffer overflow, wcdj"

Sp-15 (GDB) x/30 W $

0xbfb48651: 0x6f4ff81f 0x20217370 0x65726568 0x20736920

0xbfb48661: 0x75622061 0x72656666 0x65766f20 0x6f6c6672

0xbfb48671: 0x77202c77 0x006a6463 0x9cbfb1_0x01b7e5a8

0xbfb48681: 0x04000000 0x0cbfb487 0x3dbfb487 0x00b7f9cc

0xbfb48691: 0x90000000 0x01b7f8f6 0x01000000 0xf4000000

0xbfb486a1: 0xc0b7f81f 0x00b7fabc 0xd8000000 0x80bfb0000

0xbfb486b1: 0x6140be86 0x0048efa8 0x00000000 0x00000000

0xbfb486c1: 0x70000000 0xcdb7fa20

Find the place where the data 0x700002065 is incorrectly written. It is important to check whether the data is a part of the string, because one typical case of mistakenly writing data into the address is string replication. It is difficult to predict the length of the input string. If the buffer is too small and the check for the length of the input string is incomplete, this situation may occur. Considering that the i386 architecture is littleendian, it is suspected that part of the string "... EIS..." has been written. This assumption is then verified. First, the stack pointer points to almost all strings before and after the space. Therefore, writing this string to the wrong position on the stack is highly likely, and the Code shows that the Buf is only 5 bytes long, the copied string exceeds this length, leading to buffer overflow.

Through the above analysis, the cause of the error is that the space written by strcpy () to the string is originally used to save the space that returns the main () address. Therefore, after func () ends, main () is returned () when the "... E is... "The corresponding 0x700002065 value is used as the return address of the function, resulting in segmentation fault.

In this example, the address is a part of the string, which is easier to judge, but it is more difficult to investigate if the value is incorrectly written. Even so, if that value often appears in the program, you can narrow down the scope of the investigation to the part where the value is used.

You can also use the objdump tool.

Gerryyang @ wcdj :~ /Test/hack> objdump-shack28

Hack28: File Format elf32-i386

. Interp content:

8048154 2f6c6962 2f6c642d 6c696e75782e736f/lib/ld-linux.so

8048164 2e3200

......

Contents of. Got. PLT section:

8049644 78950408 00000000 X ...............

8049654 16830408 26830408 ....&...

. Data section content:

8049660 00000000 00000000 70950408 00000000 .......

8049670 00000000 00000000 0000000000000000 ................

8049680 4f6f7073 21206865 72652069 73206120 oops! Here is

8049690 62756666 6572206f 766521366c6f772c buffer overflow,

80496a0 20776364 6a000000 wcdj...

Content of the. comment section:

......

Summary

The process of determining whether the memory content is damaged can be performed according to certain steps, but finding the cause of the damage must rely on a certain sense and experience.

 

Reference: Debug hacks

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.