Как программа смотрит в памяти?

Я сделал небольшой пример из тестирования .net lib с помощью ironRuby: http://khebbie.dk/post/2008/08/Example-of-using-ironRubys-mini_rspec-library.aspx

9
задан sharkin 20 November 2009 в 11:24
поделиться

6 ответов

Might this be what you are looking for:

http://en.wikipedia.org/wiki/Portable_Executable

The PE file format is the binary file structure of windows binaries (.exe, .dll etc). Basically, they are mapped into memory like that. More details are described here with an explanation how you yourself can take a look at the binary representation of loaded dlls in memory:

http://msdn.microsoft.com/en-us/magazine/cc301805.aspx

Edit:

Now I understand that you want to learn how source code relates to the binary code in the PE file. That's a huge field.

First, you have to understand the basics about computer architecture which will involve learning the general basics of assembly code. Any "Introduction to Computer Architecture" college course will do. Literature includes e.g. "John L. Hennessy and David A. Patterson. Computer Architecture: A Quantitative Approach" or "Andrew Tanenbaum, Structured Computer Organization".

After reading this, you should understand what a stack is and its difference to the heap. What the stack-pointer and the base pointer are and what the return address is, how many registers there are etc.

Once you've understood this, it is relatively easy to put the pieces together:

A C++ object contains code and data, i.e., member variables. A class

class SimpleClass {
     int m_nInteger;
     double m_fDouble;

     double SomeFunction() { return m_nInteger + m_fDouble; }
}

will be 4 + 8 consecutives bytes in memory. What happens when you do:

SimpleClass c1;
c1.m_nInteger = 1;
c1.m_fDouble = 5.0;
c1.SomeFunction();

First, object c1 is created on the stack, i.e., the stack pointer esp is decreased by 12 bytes to make room. Then constant "1" is written to memory address esp-12 and constant "5.0" is written to esp-8.

Then we call a function that means two things.

  1. The computer has to load the part of the binary PE file into memory that contains function SomeFunction(). SomeFunction will only be in memory once, no matter how many instances of SimpleClass you create.

  2. The computer has to execute function SomeFunction(). That means several things:

    1. Calling the function also implies passing all parameters, often this is done on the stack. SomeFunction has one (!) parameter, the this pointer, i.e., the pointer to the memory address on the stack where we have just written the values "1" and "5.0"
    2. Save the current program state, i.e., the current instruction address which is the code address that will be executed if SomeFunction returns. Calling a function means pushing the return address on the stack and setting the instruction pointer (register eip) to the address of the function SomeFunction.
    3. Inside function SomeFunction, the old stack is saved by storing the old base pointer (ebp) on the stack (push ebp) and making the stack pointer the new base pointer (mov ebp, esp).
    4. The actual binary code of SomeFunction is executed which will call the machine instruction that converts m_nInteger to a double and adds it to m_fDouble. m_nInteger and m_fDouble are found on the stack, at ebp - x bytes.
    5. The result of the addition is stored in a register and the function returns. That means the stack is discarded which means the stack pointer is set back to the base pointer. The base pointer is set back (next value on the stack) and then the instruction pointer is set to the return address (again next value on the stack). Now we're back in the original state but in some register lurks the result of the SomeFunction().

I suggest, you build yourself such a simple example and step through the disassembly. In debug build the code will be easy to understand and Visual Studio displays variable names in the disassembly view. See what the registers esp, ebp and eip do, where in memory your object is allocated, where the code is etc.

10
ответ дан 4 December 2019 в 13:03
поделиться

Для понимания структуры кадра стека вы можете обратиться к http://en.wikipedia.org/wiki/Call_stack

Он дает вам информацию о структуре стека вызовов, о том, как локальные, глобальные, обратный адрес хранятся в стеке вызовов

1
ответ дан 4 December 2019 в 13:03
поделиться

На самом деле - вы не уйдете далеко в этом вопросе, имея хотя бы немного знаний в Ассемблере. Я бы порекомендовал реверсивный (обучающий) сайт, например OpenRCE.org.

0
ответ дан 4 December 2019 в 13:03
поделиться

Какой огромный вопрос!

Сначала вы хотите узнать о виртуальной памяти . Без этого все остальное не будет иметь смысла. Короче говоря, указатели C / C ++ не являются адресами физической памяти. Указатели - это виртуальные адреса. Есть специальная функция ЦП (MMU, блок управления памятью), которая прозрачно отображает их в физическую память. Только операционная система может настраивать MMU.

Это обеспечивает безопасность (нет значения указателя C / C ++, которое вы можете сделать, чтобы оно указывало на виртуальное адресное пространство другого процесса, если только этот процесс не намеренно разделяет с вами память) и позволяет ОС делать некоторые действительно волшебные вещи, которые мы сейчас принимаем как должное (например, прозрачно переставлять часть памяти процесса на диск, а затем прозрачно загружать ее обратно, когда процесс пытается ее использовать).

Процесс ' s адресное пространство (также известное как виртуальное адресное пространство или адресуемая память) содержит:

  • огромную область памяти, зарезервированную для ядра Windows, к которой процессу не разрешено касаться;

  • области виртуальной памяти, которые " unmapped ", т.е. там ничего не загружается, этим адресам не назначена физическая память, и процесс выйдет из строя, если попытается получить к ним доступ;

  • разделяет различные модули (файлы EXE и DLL), которые были загружены (каждый из они содержат машинный код, строковые константы и другие данные); и

  • любую другую память, которую процесс выделил из системы.

Обычно сейчас процесс позволяет библиотеке времени выполнения C или библиотекам Win32 выполнять большую часть сверхнизкоуровневого управления памятью, включая настройку:

  • ] стек (для каждого потока), где хранятся локальные переменные и аргументы функции и возвращаемые значения; и

  • куча, в которой память выделяется, если процесс вызывает malloc или выполняет новый X .

Подробнее о структуре стека читайте в вызове соглашения . Чтобы узнать больше о том, как устроена куча, прочтите о реализациях malloc . В общем, стек действительно является стеком, структурой данных «последний пришел - первым ушел», содержащей аргументы, локальные переменные и случайные временные результаты, и не более того. Поскольку программе легко писать сразу за концом стека (распространенная ошибка C / C ++, в честь которой назван этот сайт), системные библиотеки обычно следят за тем, чтобы рядом со стеком была неотображенная страница. Это приводит к мгновенному сбою процесса при возникновении такой ошибки, поэтому он ' Намного легче отлаживать (и процесс завершается прежде, чем он сможет нанести еще какой-либо ущерб).

Куча на самом деле не куча в смысле структуры данных. Это структура данных, поддерживаемая библиотекой CRT или Win32, которая берет страницы памяти из операционной системы и распределяет их каждый раз, когда процесс запрашивает небольшие фрагменты памяти через malloc и другие. (Обратите внимание, что ОС не управляет этим на микроуровне; процесс может в значительной степени управлять своим адресным пространством, как он того захочет, если ему не нравится то, как это делает CRT.)

Процесс также может запрашивать страницы непосредственно из операционная система, используя API, например VirtualAlloc или MapViewOfFile .

Есть еще кое-что, но я лучше остановлюсь!

Куча на самом деле не куча в смысле структуры данных. Это структура данных, поддерживаемая библиотекой CRT или Win32, которая берет страницы памяти из операционной системы и распределяет их каждый раз, когда процесс запрашивает небольшие фрагменты памяти через malloc и другие. (Обратите внимание, что операционная система не управляет этим на микроуровне; процесс может в значительной степени управлять своим адресным пространством, как ему заблагорассудится, если ему не нравится то, как это делает CRT.)

Процесс также может запрашивать страницы непосредственно из операционная система, используя API, например VirtualAlloc или MapViewOfFile .

Есть еще кое-что, но я лучше остановлюсь!

Куча на самом деле не куча в смысле структуры данных. Это структура данных, поддерживаемая библиотекой CRT или Win32, которая берет страницы памяти из операционной системы и распределяет их каждый раз, когда процесс запрашивает небольшие фрагменты памяти через malloc и другие. (Обратите внимание, что операционная система не управляет этим на микроуровне; процесс может в значительной степени управлять своим адресным пространством, как ему заблагорассудится, если ему не нравится то, как это делает CRT.)

Процесс также может запрашивать страницы непосредственно из операционная система, используя API, например VirtualAlloc или MapViewOfFile .

Есть еще кое-что, но я лучше остановлюсь!

структура данных, поддерживаемая библиотекой CRT или Win32, которая берет страницы памяти из операционной системы и распределяет их каждый раз, когда процесс запрашивает небольшие фрагменты памяти через malloc и другие. (Обратите внимание, что ОС не управляет этим на микроуровне; процесс может в значительной степени управлять своим адресным пространством, как он того захочет, если ему не нравится то, как это делает CRT.)

Процесс также может запрашивать страницы непосредственно из операционная система, используя API, например VirtualAlloc или MapViewOfFile .

Есть еще кое-что, но я лучше остановлюсь!

структура данных, поддерживаемая библиотекой CRT или Win32, которая берет страницы памяти из операционной системы и распределяет их каждый раз, когда процесс запрашивает небольшие фрагменты памяти через malloc и другие. (Обратите внимание, что операционная система не управляет этим на микроуровне; процесс может в значительной степени управлять своим адресным пространством, как ему заблагорассудится, если ему не нравится то, как это делает CRT.)

Процесс также может запрашивать страницы непосредственно из операционная система, используя API, например VirtualAlloc или MapViewOfFile .

Есть еще кое-что, но я лучше остановлюсь!

4
ответ дан 4 December 2019 в 13:03
поделиться

Возможно, это не самая точная информация, но MS Press предоставляет несколько примеров глав книги Inside Microsoft® Windows® 2000, Third Edition , содержащих информацию о процессах и их создание вместе с изображениями некоторых важных структур данных.

Я также наткнулся на этот PDF-файл , который суммирует некоторую из вышеуказанной информации в красивой диаграмме.

Но вся предоставленная информация больше из с точки зрения ОС и не слишком подробно описывают аспекты приложения.

0
ответ дан 4 December 2019 в 13:03
поделиться

Еще одна хорошая иллюстрация http://www.cs.uleth.ca/~holzmann/C/system/memorylayout.pdf

1
ответ дан 4 December 2019 в 13:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: