Форум программистов, компьютерный форум CyberForum.ru

RAM, чтение и запись в RAM, Pointer ы - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Misterkat
 Аватар для Misterkat
7 / 7 / 0
Регистрация: 16.11.2012
Сообщений: 83
24.07.2013, 06:37     RAM, чтение и запись в RAM, Pointer ы #1
Так! Начну сразу с проблемы.
Допустим есть приложение "какая-то хрень.exe", а в нем есть переменная допустим "32" с типом integer(int), а проблема заключается в том, что переменная находится каждый раз в разном участке памяти! . Ну ладно, нашел я что такое Pointer - Некий адрес+смещение = нужный адрес! Вроде бы все нишьяГ, но находим снова проблему:
поинтер начинается с адреса, который должен найтись по СУПЕРПУПЕРСЛОЖНОЙФОРМУЛЕ: "какая-то хрень.exe+нулевое смещение = некий адрес". И так, кто еще не понял, вопрос заключается в следующем: как определить начальный адрес приложения? Имею ввиду:
0x00000 - начало озу
... - всякие программы
0x001d0 - начало выделенной озу под "какая-то хрень.exe" - То, что нужно узнать.
...
0xFFFFFF
ЗЫ:На всякий случай кину сорс:
main.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <windows.h>
#include <TlHelp32.h>
#include "MemoryManager.h"
#include <gdiplus.h>
 
#pragma comment(lib, "gdiplus.lib")
 
#define ID_BUTTON1 3000
#define ID_BUTTON2 3001
#define ID_BUTTON3 3002
#define ID_EDIT1 2000
 
 
HINSTANCE hInst;
char* szClassName = "ClassOFTheWindow";
char* szWindowName = "Sniper Elite Multiplayer Trainer";
 
WCHAR Health[32];
WCHAR Ammo[32];
WCHAR Grenades[32];
 
 
void GdiPaint(HDC hdc)
{
    Gdiplus::Graphics graphics(hdc);
    Gdiplus::SolidBrush brush(Gdiplus::Color::Chocolate);
    Gdiplus::Pen BrushPen(Gdiplus::Color::Aqua);
    Gdiplus::FontFamily fontFamily(L"Times New Roman");
    Gdiplus::Font font(&fontFamily, 24, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel);
    Gdiplus::PointF HealtTextPos(10.0f, 20.0f);
    Gdiplus::PointF AmmoTextPos(10.0f, 75.0f);
 
    graphics.DrawString(Health, -1, &font, HealtTextPos, &brush);
    graphics.DrawString(Grenades, -1, &font, AmmoTextPos, &brush);
}
 
int RegClass(WNDPROC Proc, LPCTSTR szName)
{
WNDCLASS WindowClass; 
WindowClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; 
WindowClass.cbClsExtra = WindowClass.cbWndExtra = 0; 
WindowClass.lpfnWndProc = Proc; 
WindowClass.hInstance = hInst; 
WindowClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); 
WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW); 
WindowClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); 
WindowClass.lpszMenuName = (LPCSTR)NULL; 
WindowClass.lpszClassName = szName; 
return RegisterClass(&WindowClass);
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
static short cx; 
static short cy; 
static short left; 
static short top;
 
HWND hEdit;
switch(msg)
{
 case WM_CREATE: { 
      
      return 0;
      }
 case WM_PAINT: {
      PAINTSTRUCT ps;
      HDC hdc = BeginPaint(hwnd, &ps);
      GdiPaint(hdc);
      EndPaint(hwnd, &ps);
      
      return 0;
      }
 case WM_MOVE: { 
      left = LOWORD(lParam);
      top = HIWORD(lParam);
      return 0;
      }
 case WM_SIZE: { 
      cx = LOWORD(lParam);
      cy = HIWORD(lParam);
      return 0;
      }
 case WM_COMMAND: { 
      switch(LOWORD(wParam))
      {   
        case ID_BUTTON1: {
             MemoryManager* MM = new MemoryManager("sniperelite.exe");
             DWORD offsets[3] = {0x438, 0x30, 0x328};
             DWORD offsetsAmmo[3] = {0x4c, 0x16c, 0x18};
             DWORD offsetsGrenades[3] = {0x594, 0x174, 0x20};
             
             wsprintfW(Health, L"Proccess ID = %d \nЖизни: %d(0x%X)         ", MM->GetPID(),
                (DWORD)MM->ReadPointer(0x1dc0e28, offsets, 3).toFloat(), MM->ReadPointer(0x1dc0e28, offsets, 3, true).toDword());
             
             wsprintfW(Ammo, L"\nПатроны: %d(0x%X)", MM->ReadPointer(0x1088F4F8, offsetsAmmo, 3).toDword(), MM->ReadPointer(0x1088F4F8, offsetsAmmo, 3, true).toDword());
             InvalidateRect(hwnd, NULL, true);
 
             wsprintfW(Grenades, L"\nЛимонки: %d(0x%X)", MM->ReadPointer(0x100f5830, offsetsGrenades, 3).toDword(), MM->ReadPointer(0x100f5830, offsetsAmmo, 3, true).toDword());
             InvalidateRect(hwnd, NULL, true);
             return 0; 
             }
      }
      return 0;
      }
 case WM_DESTROY: {
      PostQuitMessage(0);
      return 0;
      }
 }
 return DefWindowProc(hwnd, msg, wParam, lParam);
}
 
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
 MSG msg;
 HWND hwnd;
 HWND hButton1;
 Gdiplus::GdiplusStartupInput gdiplusStartupInput;
 ULONG_PTR gdiplusToken;
 if(!RegClass(WndProc, szClassName))
                       return FALSE;
 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
 hwnd = CreateWindow(szClassName, szWindowName, WS_OVERLAPPEDWINDOW, 0, 0, 400, 200, NULL, NULL, hInst, NULL);
 if(!hwnd)
          return FALSE;
 
 hButton1 = CreateWindow("button", "Обновить", WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON, 100, 125, 100, 25, hwnd, (HMENU)ID_BUTTON1, hInst, NULL);
 
 ShowWindow(hwnd, SW_SHOW);
 UpdateWindow(hwnd);
 
 while(GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 Gdiplus::GdiplusShutdown(gdiplusToken);
 return msg.wParam;
}
MemoryManager.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#define MAXBUFFER_SIZE 255
class MemoryManager
{
public: 
        MemoryManager(char* pName)
        {
         this->pName = pName;  
         UpdatePID();                  
        }
        ~MemoryManager();
        
        void UpdatePID()
{
      HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      PROCESSENTRY32 pInfo;
      pInfo.dwSize = sizeof(PROCESSENTRY32);
      
      if(Process32First(SnapShot, &pInfo))
      {
           while(Process32Next(SnapShot, &pInfo))
                   {
                    if(_stricmp(pName, pInfo.szExeFile) == 0)
                    {
                     pID = pInfo.th32ProcessID;
                     CloseHandle(SnapShot);
                     break;
                    }
                   }
      }
 
}
 
MemoryManager& ReadMemory(DWORD adress, DWORD size)
{
      memset(buffer, 0, MAXBUFFER_SIZE);
      DWORD OLDPROTECT = 0;
      
      HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
      VirtualProtectEx(hProcess, (void*)adress, size, PAGE_EXECUTE_READWRITE, &OLDPROTECT);
      ReadProcessMemory(hProcess, (void*)adress, buffer, size, NULL);
      VirtualProtectEx(hProcess, (void*)adress, size, OLDPROTECT, &OLDPROTECT);
      CloseHandle(hProcess);
      return *this;
}
 
void WriteMemory(DWORD adress, void* content, DWORD size)
{
      DWORD OLDPROTECT = 0;
      
      HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
      VirtualProtectEx(hProcess, (void*)adress, size, PAGE_EXECUTE_READWRITE, &OLDPROTECT);
      WriteProcessMemory(hProcess, (void*)adress, content, size, NULL);
      VirtualProtectEx(hProcess, (void*)adress, size, OLDPROTECT, &OLDPROTECT);
      CloseHandle(hProcess);
}
 
DWORD toDword()
{
      DWORD buf = 0;
      memcpy(&buf, buffer, sizeof(DWORD));
      return buf;
}
 
MemoryManager& ReadPointer(DWORD adress, DWORD* offset, DWORD nOffsets, bool getAddr = false)
{
        for(int i = 0; i < nOffsets; i++)
       {
       if(i == nOffsets - 1)
            {
             if(getAddr == true)
                {
                 DWORD buff = adress + offset[i];
                 memcpy(buffer, &buff, sizeof(DWORD));
                 return *this;
                }
            }
        adress = ReadMemory(adress + offset[i], sizeof(DWORD)).toDword();
       }
       return *this;
}
 
 
 
char* toStringA()
{
      DWORD len = strlen((char*)buffer);
      static char buff[MAXBUFFER_SIZE];
      memset(buff, 0, MAXBUFFER_SIZE);
      strncpy(buff, (char*)buffer, len);
      return buff;
}
float toFloat()
{
      float buf = 0.f;
      memcpy(&buf, buffer, sizeof(float));
      return buf;
}
DWORD GetPID(){return pID;}
private:
        char* pName;
        DWORD pID;
        byte buffer[MAXBUFFER_SIZE];
};
Добавлено через 6 часов 53 минуты

Не по теме:

Да ну.... Ребята, ну ответьте, пожалуйста. Тема уходит в ж*пу ведь.

Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.07.2013, 06:37     RAM, чтение и запись в RAM, Pointer ы
Посмотрите здесь:

C++ Чтение/запись
Удаление антивируса из RAM C++
C++ Почему программа в Windows может использовать лишь 1792 мегабайта RAM?
delete[] *pointer vs. delete pointer и утечка памяти C++
Чтение и запись C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kukurudza
105 / 86 / 6
Регистрация: 29.08.2012
Сообщений: 539
24.07.2013, 06:55     RAM, чтение и запись в RAM, Pointer ы #2
Цитата Сообщение от Misterkat Посмотреть сообщение
И так, кто еще не понял, вопрос заключается в следующем: как определить начальный адрес приложения? Имею ввиду:
0x00000 - начало озу
... - всякие программы
0x001d0 - начало выделенной озу под "какая-то хрень.exe" - То, что нужно узнать.
может это глупый вопрос: а так вообще в принципе можно сделать?
вроде как ядро делит память динмически под каждое приложения и те адреса памяти, на которые у вас указывают ваши указатели ВНУТРИ программы на самом деле совсем другие в реальной ОЗУ. и этим занимается ядро. мож ошибаюсь конечно... у интеловских процов вроде даже появилась какая-то технология, которая позволяет без лишних тактов из динамических (замаскированных системой) адресов доставать именно реальные в ОЗУ. но это мое мнения в коем я не совсем уверен.
Misterkat
 Аватар для Misterkat
7 / 7 / 0
Регистрация: 16.11.2012
Сообщений: 83
24.07.2013, 07:39  [ТС]     RAM, чтение и запись в RAM, Pointer ы #3
Цитата Сообщение от Kukurudza Посмотреть сообщение
а так вообще в принципе можно сделать?
Ну ведь трейнеры же пишут люди.
Цитата Сообщение от Kukurudza Посмотреть сообщение
вроде как ядро делит память динмически под каждое приложения
Похоже, что вы не поняли моей просьбы. Я имею ввиду, что мне нужно узнать как получить начальный адрес выделенной под приложение памяти. То есть вот например у приложения есть некий диапазон памяти, допустим от 0x04B2C7B8 до 0x0C0E00E4. Так ведь? Если так, то мне нужно узнать(при помощи С++) 0x04B2C7B8.
Если вы мне пытаетесь доказать, что 0x04B2C7B8 будет после перезапуска приложения уже не 0x04B2C7B8, то тут напрасно, ибо я и сам это понимаю. И мне нужно неким чудодейственным методом вычислить это значение, после перезапуска приложения(желательно на С++).
Kukurudza
105 / 86 / 6
Регистрация: 29.08.2012
Сообщений: 539
24.07.2013, 07:50     RAM, чтение и запись в RAM, Pointer ы #4
Не буду я с вами спорить ибо сам в этой теме плаваю.
Цитата Сообщение от Misterkat Посмотреть сообщение
допустим от 0x04B2C7B8 до 0x0C0E00E4. Так ведь?
вот в том то и дело что вроде как не так. а если я в какой то момент решил внутри приложения выделить еще памяти, а реально за моим приложением уже давно кто-то хорошенько разместился? тогда этого "кого-то" смещать вперед на столько, сколько я хочу выделить? внутри вашего приложения вы видите память от 0x00000000 до 0xffffffff в 32х разрядной системе, а уж как спроецирует ядро эти ячейки на реальную память, надо спрашивать у ядра. у вас в машине вообще может и не быть 4х гигабайт а только 128 мегабайт, все остальное будет свапаться на ХДД. я это к тому что например у вас есть переменная, которая записана по адресу (внутри вашей программы) 0x00000001, а в реальности она записана по адресу 0x57291837 (в ОЗУ), есть вторая переменная, которая записана по адресу 0x00000002 (внутри программы), и нифига это не значит что в реальности она записана по адресу 0x57291838 (в ОЗУ). не?
Misterkat
 Аватар для Misterkat
7 / 7 / 0
Регистрация: 16.11.2012
Сообщений: 83
24.07.2013, 09:32  [ТС]     RAM, чтение и запись в RAM, Pointer ы #5
Цитата Сообщение от Kukurudza Посмотреть сообщение
вот в том то и дело что вроде как не так. а если я в какой то момент решил внутри приложения выделить еще памяти, а реально за моим приложением уже давно кто-то хорошенько разместился? тогда этого "кого-то" смещать вперед на столько, сколько я хочу выделить? внутри вашего приложения вы видите память от 0x00000000 до 0xffffffff в 32х разрядной системе, а уж как спроецирует ядро эти ячейки на реальную память, надо спрашивать у ядра. у вас в машине вообще может и не быть 4х гигабайт а только 128 мегабайт, все остальное будет свапаться на ХДД. я это к тому что например у вас есть переменная, которая записана по адресу (внутри вашей программы) 0x00000001, а в реальности она записана по адресу 0x57291837 (в ОЗУ), есть вторая переменная, которая записана по адресу 0x00000002 (внутри программы), и нифига это не значит что в реальности она записана по адресу 0x57291838 (в ОЗУ). не?
Возможно, но мне [censure] не нужны реальные значения, мне конечным результатом нужно отследить переменную, если вы знаете как это сделать - прошу ответ в студию.

Добавлено через 1 час 35 минут

Не по теме:

Цитата Сообщение от Kukurudza Посмотреть сообщение
у вас в машине вообще может и не быть 4х гигабайт а только 128 мегабайт
У меня физической 4(Hunyx 2gb + Corsair 2gb)

Kukurudza
105 / 86 / 6
Регистрация: 29.08.2012
Сообщений: 539
24.07.2013, 09:51     RAM, чтение и запись в RAM, Pointer ы #6
Цитата Сообщение от Misterkat Посмотреть сообщение
мне конечным результатом нужно отследить переменную
видимо я не понял чего вы хотите.
Цитата Сообщение от Misterkat Посмотреть сообщение
У меня физической 4(Hunyx 2gb + Corsair 2gb)
да это пофиг вообще. у вас есть как минимум система, которая хавает 1+ гиг.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
24.07.2013, 10:20     RAM, чтение и запись в RAM, Pointer ы #7
Для начала уточни, о какой ОС идет речь?

В Win каждый процесс выполняется в своем собственном отдельном виртуальном адресном пространстве, никак не связанном со страницами физической памяти (точнее, таблица соответствия есть, но управляет ей исключительно ядро операционной системы). Для подавляющего большинства процессов базовый адрес загрузки есть 0x00400000. Узнать его можно очень просто:
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <windows.h>
using namespace std;
 
int main()
{
    void* p = (void*)GetModuleHandle(NULL);
    cout << p << endl;
}
Убежденный
Системный программист
 Аватар для Убежденный
14208 / 6223 / 987
Регистрация: 02.05.2013
Сообщений: 10,368
Завершенные тесты: 1
24.07.2013, 10:21     RAM, чтение и запись в RAM, Pointer ы #8
Цитата Сообщение от Misterkat Посмотреть сообщение
И так, кто еще не понял, вопрос заключается в следующем: как определить начальный адрес приложения? Имею ввиду:
0x00000 - начало озу
... - всякие программы
0x001d0 - начало выделенной озу под "какая-то хрень.exe" - То, что нужно узнать.
Про адреса в ОЗУ и "карту памяти" можете забыть.
Современные ОС давно уже работают с виртуальной памятью, где каждому процессу выделяется
свое адресное пространство размером от 4 Гигабайт и выше. "Начальный адрес приложения" -
это, грубо говоря, 0x00000000 (для 64-битных систем 0x00000000 00000000), более точно
верхнюю и нижнюю границы доступных адресов можно узнать с помощью GetSystemInfo.
Если и искать что-то, то в этой памяти, а не в физических адресах ОЗУ, куда, кстати
говоря, у пользовательских приложений вообще нет доступа.

Короче, открываете нужный процесс (OpenProcess) с правами PROCESS_QUERY_INFORMATION и
PROCESS_VM_READ, получаете информацию о доступных страницах памяти (VirtualQueryEx) и
читаете их содержимое (ReadProcessMemory). Вот и весь рецепт.
Kukurudza
105 / 86 / 6
Регистрация: 29.08.2012
Сообщений: 539
24.07.2013, 10:21     RAM, чтение и запись в RAM, Pointer ы #9
Цитата Сообщение от CheshireCat Посмотреть сообщение
В Win каждый процесс выполняется в своем собственном отдельном виртуальном адресном пространстве, никак не связанном со страницами физической памяти (точнее, таблица соответствия есть, но управляет ей исключительно ядро операционной системы).
да, вот я как раз это имел ввиду.
Misterkat
 Аватар для Misterkat
7 / 7 / 0
Регистрация: 16.11.2012
Сообщений: 83
24.07.2013, 11:13  [ТС]     RAM, чтение и запись в RAM, Pointer ы #10
Цитата Сообщение от Убежденный Посмотреть сообщение
Короче, открываете нужный процесс (OpenProcess) с правами PROCESS_QUERY_INFORMATION и
PROCESS_VM_READ, получаете информацию о доступных страницах памяти (VirtualQueryEx) и
читаете их содержимое (ReadProcessMemory). Вот и весь рецепт.
Спасибо большое за азимут поиска, но все же, можно ли ткнуть носом.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.07.2013, 11:17     RAM, чтение и запись в RAM, Pointer ы
Еще ссылки по теме:

C++ Фрагментация RAM
[Файлы] Запись-чтение-запись. Почему не прокатывает? C++
C++ Тестирование RAM (оперативной памяти)

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
24.07.2013, 11:17     RAM, чтение и запись в RAM, Pointer ы #11
Ткнуть носом можно: сюда - http://msdn.microsoft.com/en-US/

Например, вот первая функция: http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Yandex
Объявления
24.07.2013, 11:17     RAM, чтение и запись в RAM, Pointer ы
Ответ Создать тему
Опции темы

Текущее время: 23:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru