Сейчас на форуме: zds (+4 невидимых)

 eXeL@B —› Программирование —› Выделение памяти в х64 процессе из х86
Посл.ответ Сообщение


Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 29 декабря 2013 19:00
· Личное сообщение · #1

Здравствуйте, товарищи. Возникла у меня проблема такого рода. Нужно мне выделить память (обычным вызовом VirtualAllocEx) в другом процессе. Но проблема в том, что VirtualAllocEx вызывается из 32-разрядного процесса, а выделить память нужно в 64-разрядном. Память-то выделяется, т.е. VirtualAllocEx отрабатывает, но вот проблема в том, что размерности указателей разные. Поясню детальнее.

в х64 все указатели восьмибайтовые, и, соответственно, память выделить можно и выше 4 гигов. А в процессе, где разрядность 32 бита, указатели все четырёхбайтовые. Поэтому происходит усечение указателя, и истинное значение адреса теряется (VirtualAllocEx возвращает адрес, который помещается в 32-разрядный регистр). И получается, что память где-то выделилась, а где - непонятно. Как решить такую проблему, не пересобирая приложение под х64?

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 301.4 (мудрец), 194thx
Активность: 0.170.01
Статус: Участник

Создано: 29 декабря 2013 19:11
· Личное сообщение · #2

пробежать VirtualQueryEx и запросить у VirtualAllocEx заведомо пустую область в нижних 4гб

| Сообщение посчитали полезным: ARCHANGEL

Ранг: 53.9 (постоянный), 33thx
Активность: 0.050
Статус: Участник

Создано: 29 декабря 2013 19:13
· Личное сообщение · #3

Использовать апи х64 версии, через X86SwitchTo64BitMode.




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 29 декабря 2013 22:28
· Личное сообщение · #4

Решил последовать совету Veliant'а, но появилась проблема - VirtualQueryEx правильно определяет свободную область, т.е. ту, у которой State == MEM_FREE, но вот я вызываю VirtualAllocEx, в качестве второго параметра передаю ей BaseAddress из MEMORY_BASIC_INFORMATION, и вызов завершается с ошибкой об INVALID_ADDRESS. Но в ходе опытов я, бывает, передавал какие-то значения в середине региона, и, о чудо, оно позволяло выделить память. Причём, как и заявлено в документации, происходило округление вниз согласно гранулярности страниц.

Code:
  1.          virtual PVOID __stdcall AllocateMemory(DWORD Size,DWORD flProtect)
  2.          {
  3.                  MEMORY_BASIC_INFORMATION MemBasic = {0};
  4.                  PVOID result = NULL;
  5.  
  6.                  for (DWORD i = 0x1000, Step = 0x1000;i < 0x7FFFFFFF;i += Step)
  7.                  {
  8.                         if (VirtualQueryEx(ProcessHandle,(LPCVOID) i,&MemBasic,sizeof(MemBasic)))
  9.                         {
  10.                               Step = MemBasic.RegionSize;
  11.                               if (MemBasic.State == MEM_FREE)
  12.                               {
  13.                                    result = VirtualAllocEx(ProcessHandle,(LPVOID) MemBasic.BaseAddress,Size,MEM_COMMIT,flProtect);
  14.                                    if (result)
  15.                                        break;
  16.                               }
  17.                         }
  18.                         else
  19.                               Step = 0x1000;
  20.                  }
  21.  
  22.                  return result;
  23.          }


Выше приведен код метода, что я делаю не так?

-----
Stuck to the plan, always think that we would stand up, never ran.





Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 30 декабря 2013 00:38
· Личное сообщение · #5

Смотри на AllocationType:

MSDN: Attempting to commit a specific address range by specifying MEM_COMMIT without MEM_RESERVE and a non-NULL lpAddress fails unless the entire range has already been reserved. The resulting error code is ERROR_INVALID_ADDRESS.

-----
the Power of Reversing team


| Сообщение посчитали полезным: ARCHANGEL


Ранг: 622.6 (!), 521thx
Активность: 0.330.89
Статус: Участник
_Вечный_Студент_

Создано: 30 декабря 2013 00:52 · Поправил: plutos
· Личное сообщение · #6

Может попробовать вставить

Code:
  1. if(!VirtualFreeEx(Process, Module, NULL, MEM_DECOMMIT))   
  2.  {
  3.         printf("VirtualFreeEx(%d)", GetLastError()); return false;
  4. }


-----
Give me a HANDLE and I will move the Earth.





Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 30 декабря 2013 01:28
· Личное сообщение · #7

DillerInc

Да, именно в этом и были грабли, добавил MEM_RESERVE и заработало. Теперь буду тестить на х64.

plutos

Я не понял, зачем освобождать память, заранее ведь неизвестно, что за данные в чужом процессе расположены по каким-то адресам.

-----
Stuck to the plan, always think that we would stand up, never ran.



 eXeL@B —› Программирование —› Выделение памяти в х64 процессе из х86
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати