Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing stack updates

Tags:

c

stack

pointers

I'm trying to go into some deep of stack allocation, so I intended to obtain a stack configuration like this:

0x000009 -> 0,
0x000005 -> 1,
0x000001 -> 2,
...

here is the code:

int main(){

    int i;
    int j;
    int pseudoarray;

    printf("address of i \t\t%p\n",&i);
    printf("address of j \t\t%p\n",&j);
    printf("address of pseudoarray \t%p\n\n",&pseudoarray);

    for(i =0;i<10;i++){

        *((&pseudoarray)-i)=i;
        printf("Written at \t%p value \t%d\n\n",(&pseudoarray)-i, i);

        for(j =0; j<10;j++){
            printf("Read at \t%p value \t%d\n",(&pseudoarray-j), *((&pseudoarray-j)));
        }
        printf("\n\n\n");
    }

    printf("\n%d times done",i);

    return 0;
}

However it writes only up to the third cell, and then nothing is written.

Here is what it prints (printings from 6^th operation of writing to 10 is the same as 5):

C:\Users\Halib\OneDrive\Documents\Corsi\Corso C>plain.exe
address of i            0061FF1C
address of j            0061FF18
address of pseudoarray  0061FF14

Written at      0061FF14 value  0

Read at         0061FF14 value  0         <-- wrote a 0 here
Read at         0061FF10 value  4200912
Read at         0061FF0C value  4201019
Read at         0061FF08 value  4201019
Read at         0061FF04 value  6422280
Read at         0061FF00 value  4214946
Read at         0061FEFC value  4199673
Read at         0061FEF8 value  6422312
Read at         0061FEF4 value  -2
Read at         0061FEF0 value  157728263



Written at      0061FF10 value  1

Read at         0061FF14 value  0
Read at         0061FF10 value  1         <-- wrote a 1 here
Read at         0061FF0C value  4201019
Read at         0061FF08 value  4201019
Read at         0061FF04 value  6422280
Read at         0061FF00 value  4214946
Read at         0061FEFC value  4199673
Read at         0061FEF8 value  6422312
Read at         0061FEF4 value  -2
Read at         0061FEF0 value  157728263



Written at      0061FF0C value  2

Read at         0061FF14 value  0
Read at         0061FF10 value  1
Read at         0061FF0C value  2
Read at         0061FF08 value  2
Read at         0061FF04 value  6422280
Read at         0061FF00 value  4214946
Read at         0061FEFC value  4199673
Read at         0061FEF8 value  6422312
Read at         0061FEF4 value  -2
Read at         0061FEF0 value  157728263



Written at      0061FF08 value  3

Read at         0061FF14 value  0
Read at         0061FF10 value  1
Read at         0061FF0C value  2
Read at         0061FF08 value  2          <-- I expected 3 here
Read at         0061FF04 value  6422280
Read at         0061FF00 value  4214946
Read at         0061FEFC value  4199673
Read at         0061FEF8 value  6422312
Read at         0061FEF4 value  -2
Read at         0061FEF0 value  157728263



Written at      0061FF04 value  4

Read at         0061FF14 value  0
Read at         0061FF10 value  1
Read at         0061FF0C value  2
Read at         0061FF08 value  2
Read at         0061FF04 value  6422280    <-- expected 4 here
Read at         0061FF00 value  4214946
Read at         0061FEFC value  4199673
Read at         0061FEF8 value  6422312
Read at         0061FEF4 value  -2
Read at         0061FEF0 value  157728263



Written at      0061FF00 value  5

Read at         0061FF14 value  0
Read at         0061FF10 value  1
Read at         0061FF0C value  2
Read at         0061FF08 value  2
Read at         0061FF04 value  6422280
Read at         0061FF00 value  4214946
Read at         0061FEFC value  4199673
Read at         0061FEF8 value  6422312
Read at         0061FEF4 value  -2
Read at         0061FEF0 value  157728263

EDIT:

code modified: attempt:

int i;
int j;
int pseudoarray;

printf("address of i \t\t%p\n",&i);
printf("address of j \t\t%p\n",&j);
printf("address of pseudoarray \t%p\n\n",&pseudoarray);


for(i =0;i<10;i++){

    *((&pseudoarray)+i)=i;
}

    printf("\n\n");

for(j =0; j<10;j++){
        printf("Read at \t%p value \t%d\n",(&pseudoarray+j), *((&pseudoarray+j)));
    }

return 0;

produced following output:

address of i            0061FF1C
address of j            0061FF18
address of pseudoarray  0061FF14



Read at         0061FF14 value  0
Read at         0061FF10 value  1
Read at         0061FF0C value  2
Read at         0061FF08 value  2
Read at         0061FF04 value  6422280
Read at         0061FF00 value  4214921
Read at         0061FEFC value  4199645
Read at         0061FEF8 value  6422312
Read at         0061FEF4 value  -2
Read at         0061FEF0 value  -498040528

Could someone help me out? Thanks a lot.

like image 951
Alberto Tiraboschi Avatar asked Nov 25 '19 14:11

Alberto Tiraboschi


People also ask

How do I update my servicing stack?

Servicing stack updates can be delivered with Windows Update, or you can perform a search to install the latest available at Servicing stack update for Windows 10. Once a servicing stack update is installed, it cannot be removed or uninstalled from the machine.

What is servicing stack update for Windows 10?

Servicing stack updates (SSUs) make changes to how updates are installed and cannot be uninstalled from the device. This update replaces the previously released SSU update that is included in KB5011831. For a list of the files that are provided in this update, download the file information for SSU version 19041.1704.

What is SSU in Microsoft?

This update makes quality improvements to the servicing stack, which is the component that installs Windows updates. Servicing stack updates (SSU) makes sure that you have a robust and reliable servicing stack so that your devices can receive and install Microsoft updates.


1 Answers

The writing hasn't stopped working, but your way of printing the values is corrupting them. Assume that your stack pointer is normally at 0061FF08. When you go to call printf() in your inner loop, it is going to emit code that looks something like:

...
      push  %r0   / assume it computed *(&pseudoarray-j) int r0
      push  %r1   /  assume it computed &pseudoarray-1 into r1
      push  %r3   /  fmt string
      call  printf
      add   $12, %sp
 ....

So, this just over-wrote some of your pseudoarray[-j] entries, because almost universally stacks grow down. It is complicated by ABIs preferring certain stack alignments, so you can get away with it for a few words, but once you escape that you are done.

If you want to cause some real chaos, don't subtract from pseudoarray, add to it, so you will over-write bits of the calling frame for the function you are in. Incidentally, this is how buffer overflows & similar mechanisms hijack programs. ps: When a compiler allocates stack space to a program, it typically issues a sequence like this near the top:

func:
    push  %frame     / save the frame pointer register
    mov   %sp, %frame  / save the stack end pointer.
    sub   $num, %sp    / this allocates space for local vars.

and to return:

mov  %frame, %sp
pop  %frame
ret

so during the code generation part of the function, it is free to emit sequences like:

push   %r0
call   tolower
add    $4, %sp

which modify the stack, and permit tolower to construct its own stack frame. Stack memory below the current stack pointer may be temporarily usable, but it is difficult to synchronize this with the compiler. If you wanted to experiment with it:

void play() {
   int    save[10];
   int    i;
   int    temp;
   for (i = 0; i < 10; i++) {
         (&temp)[-i] = 1 << i;
   }
   for (i = 0; i < 10; i++) {
          save[i] = (&temp)[-i];
   }
   for (i = 0; i < 10; i++) {
          printf("%d vs %d\n", save[i], (&temp)[-i]);
   }
}

Notes:

  1. This isn't really C. The #UB people will flash the evil eye and spout gibberish when they see this.
  2. To the degree that this will not generate consistent results, and is a bad way to program, they are right.
  3. This is discovery, which is a valid use of compiler.
  4. You may have to carefully tune your compiler options with incantations like -O0, -std=c90, to get it to behave itself.
like image 111
mevets Avatar answered Nov 15 '22 08:11

mevets