Jump to content

How does this work??

Gat Pelsinger
Go to solution Solved by Eigenvektor,
3 hours ago, Gat Pelsinger said:

@Eigenvektor

 

Wait, it's that insecure? I am advancing the pointer by 90, and basically overwriting some other's program memory? Or is Windows's layer protecting me from doing so but it still executes fine?

These days, yes.

 

Ever since the 80386, programs generally run in "protected mode". Every program gets its own virtual address space. So the pointer you get does not refer to any physical location in memory, but some location in your program's virtual address space. The operating system takes care of mapping that to a physical location, either in RAM or in swap. Which means you can't really interfere with memory owned by another program (but you can interfere with your own).

 

But if you're running outside protected mode (called "real mode") then yes, you can effectively use a pointer to access any arbitrary memory region. Writing there could lead from your program crashing to the OS crashing, to all manner of fun corruption. Which is why on a modern system typically only the kernel itself runs in that mode.

 

You have to keep in mind that C is a low level language. It's not quite on the same level as assembler/machine code, but pretty close to it. You're effectively telling the CPU what to do, writing values into registers, incrementing them, reading and writing from memory. So no one "programmed" pointers to be this way, this is simply how memory access works on a CPU.

 

Most higher level languages take things a step further. For example if you create an array list in Java and then try to access a value out of bounds, you'll be quickly met with an exception. But these types of checks aren't free. Basically any time you call a method, it will have to run some form of "if value > limit" check. While that's not a big issue on a modern CPU, it will take some CPU cycles to do that check. So in a tight loop you may be running millions of (potentially unnecessary) checks.

 

If you're programming in C, these checks simply aren't there, unless you include them yourself. This means you get the maximum possible speed, but you also have to pay much more attention that you're doing things correctly. It's up to you to ensure your program doesn't do things it's not supposed to. As the saying goes: With great power comes great responsibility.

// Online C compiler to run C program online
#include <stdio.h>
#include <stdlib.h>
int main() {
    // Write C code here
    void** a = malloc(1);
    //*a = 9000000000;
    a[90] = 90000000;
    printf("%d", a[90]);

    return 0;
}

I am only allocating 1 byte, but I am able to allocate way more than 255. also, I am able to access the index 90 which is not even possible. Pointers is going to be the death of me. Who is that idiot you coded this pointer garbage? Either he is a genius, or he accidently committed a mass genocide.

 

Btw, I was doing this because I am working on a small program simulating heap memory and applying my own garbage collector. I don't want the heap to be a static sized array, meaning fixed size of the elements. I want to be able to put any value of any data type inside it. Any ways to achieve will be helpful as I don't know where the hell to start from.

Microsoft owns my soul.

 

Also, Dell is evil, but HP kinda nice.

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Gat Pelsinger said:

Who is that idiot you coded this pointer garbage?

If you hit yourself with a hammer, it's not the responsibility of the toolmaker that you did so. You're expected to know how to wield it.

 

There's a reason higher level languages exist. They often include safeguards that ensure you can't do things like access arrays out of bounds. But that comes at a price (e.g. performance penalty). The lower level you go, the more you, as a developer have to pay attention.

 

You have to remember that a is simply a pointer to some arbitrary memory region and a[90] is basically just a shorthand expression for incrementing that pointer by 90, to give you access to some other memory region. The C compiler doesn't know whether that is an OK thing for you to do. It is your responsibility to know that.

 

Writing your own garbage collector is not a trivial task. The easiest way to get going with automatic memory management is to implement reference counting. However, this would be a lot easier with a language like C++ that has objects that come with destructors that can take care of releasing resources again.

 

To get real garbage collection you need some way to determine if a resource that was allocated is still referenced by the rest of the code and free it otherwise. You'll need to write some form of low level framework first that takes care of all the actual allocation and deallocation, then work on top of the framework to implement your actual program.

 

And since you're in C, there's no real way to enforce internal vs external access (like private/public would in C++), so you'll still need to be disciplined about working with your framework, rather than against it.

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

@Eigenvektor

 

Wait, it's that insecure? I am advancing the pointer by 90, and basically overwriting some other's program memory? Or is Windows's layer protecting me from doing so but it still executes fine?

Microsoft owns my soul.

 

Also, Dell is evil, but HP kinda nice.

Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, Gat Pelsinger said:
// Online C compiler to run C program online
#include <stdio.h>
#include <stdlib.h>
int main() {
    // Write C code here
    void** a = malloc(1);
    //*a = 9000000000;
    a[90] = 90000000;
    printf("%d", a[90]);

    return 0;
}

I am only allocating 1 byte, but I am able to allocate way more than 255. also, I am able to access the index 90 which is not even possible. Pointers is going to be the death of me. Who is that idiot you coded this pointer garbage? Either he is a genius, or he accidently committed a mass genocide.

 

Btw, I was doing this because I am working on a small program simulating heap memory and applying my own garbage collector. I don't want the heap to be a static sized array, meaning fixed size of the elements. I want to be able to put any value of any data type inside it. Any ways to achieve will be helpful as I don't know where the hell to start from.

Oh yeah ! 😮 

I coded professionnally in C like ... 35 years ago ?! and managing dynamic memory allocation was a kind of "extreme sports" as there's no safeguard anywhere !!

System : AMD R9 5900X / Gigabyte X570 AORUS PRO/ 2x16GB Corsair Vengeance 3600CL18 ASUS TUF Gaming AMD Radeon RX 7900 XTX OC Edition GPU/ Phanteks P600S case /  Eisbaer 280mm AIO (with 2xArctic P14 fans) / 2TB Crucial T500  NVme + 2TB WD SN850 NVme + 4TB Toshiba X300 HDD drives/ Corsair RM850x PSU/  Alienware AW3420DW 34" 120Hz 3440x1440p monitor / Logitech G915TKL keyboard (wireless) / Logitech G PRO X Superlight mouse / Audeze Maxwell headphones

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, Gat Pelsinger said:

@Eigenvektor

 

Wait, it's that insecure? I am advancing the pointer by 90, and basically overwriting some other's program memory? Or is Windows's layer protecting me from doing so but it still executes fine?

These days, yes.

 

Ever since the 80386, programs generally run in "protected mode". Every program gets its own virtual address space. So the pointer you get does not refer to any physical location in memory, but some location in your program's virtual address space. The operating system takes care of mapping that to a physical location, either in RAM or in swap. Which means you can't really interfere with memory owned by another program (but you can interfere with your own).

 

But if you're running outside protected mode (called "real mode") then yes, you can effectively use a pointer to access any arbitrary memory region. Writing there could lead from your program crashing to the OS crashing, to all manner of fun corruption. Which is why on a modern system typically only the kernel itself runs in that mode.

 

You have to keep in mind that C is a low level language. It's not quite on the same level as assembler/machine code, but pretty close to it. You're effectively telling the CPU what to do, writing values into registers, incrementing them, reading and writing from memory. So no one "programmed" pointers to be this way, this is simply how memory access works on a CPU.

 

Most higher level languages take things a step further. For example if you create an array list in Java and then try to access a value out of bounds, you'll be quickly met with an exception. But these types of checks aren't free. Basically any time you call a method, it will have to run some form of "if value > limit" check. While that's not a big issue on a modern CPU, it will take some CPU cycles to do that check. So in a tight loop you may be running millions of (potentially unnecessary) checks.

 

If you're programming in C, these checks simply aren't there, unless you include them yourself. This means you get the maximum possible speed, but you also have to pay much more attention that you're doing things correctly. It's up to you to ensure your program doesn't do things it's not supposed to. As the saying goes: With great power comes great responsibility.

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

i know NASA forbid dynamic memory allocation for all their spacecraft software. every single variable is to live in the stack so they get deallocated automatically. completely get rid of all the issues with memory leaks and segfault crashes.  

Sudo make me a sandwich 

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, wasab said:

i know NASA forbid dynamic memory allocation for all their spacecraft software. every single variable is to live in the stack so they get deallocated automatically. completely get rid of all the issues with memory leaks and segfault crashes.  

Not just NASA, pretty much every single embedded, safety critical, or hard real time application will be written this way regardless if they run on a platform with an MMU or not. 

CPU: Intel i7 - 5820k @ 4.5GHz, Cooler: Corsair H80i, Motherboard: MSI X99S Gaming 7, RAM: Corsair Vengeance LPX 32GB DDR4 2666MHz CL16,

GPU: ASUS GTX 980 Strix, Case: Corsair 900D, PSU: Corsair AX860i 860W, Keyboard: Logitech G19, Mouse: Corsair M95, Storage: Intel 730 Series 480GB SSD, WD 1.5TB Black

Display: BenQ XL2730Z 2560x1440 144Hz

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×