Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Delphi | Работа с памятью чужого процесса, перехват API (http://forum.oszone.net/showthread.php?t=52078)

Savant 21-07-2005 20:15 342754

Delphi | Работа с памятью чужого процесса, перехват API
 
Вопрос в PM пришел:
Цитата:

Цитата DillerInc
Привет!
Как не трудно догадаться,данная функция возвращает False,и я не уверен,всё ли правильно я делаю.
Итак:

var
eax : Pointer;
OldProtect : DWORD;
begin
VirtualProtectEx(processInfo.hProcess, eax, 2, PAGE_EXECUTE_READWRITE, @OldProtect);
end;

Указатель eax получен от GetProcAddress и имеет значение 7C5901D5 (адрес загрузки функции LoadLibraryA).
В общем,в отладчике можно наблюдать следующие ошибки :
C0000018 - STATUS_CONFLICTING_ADDRESSES
ERROR_INVALID_ADDRESS (GetLastError)
Что делать ?!

Вторым парметром должен идти адрес в памяти, зарезервированной функциями VirtualAlloc(Ex) c параметром MEM_RESERVE, а не указатель, полученный "от GetProcAddress и имеющий значение 7C5901D5 (адрес загрузки функции LoadLibraryA)".
Цитата:

lpAddress
[in] Pointer to the base address of the region of pages whose access protection attributes are to be changed.
All pages in the specified region must be within the same reserved region allocated when calling the VirtualAlloc or VirtualAllocEx function using MEM_RESERVE. The pages cannot span adjacent reserved regions that were allocated by separate calls to VirtualAlloc or VirtualAllocEx using MEM_RESERVE.

DillerInc 21-07-2005 21:10 342768

Savant
Ну,тогда я сдаюсь :( .
Дело в том,что мне необходимо изменить защитные атрибуты определённой страницы чужого процесса,к примеру: поменять на PAGE_EXECUTE_READWRITE ,но теперь я совсем запутался...

Savant 21-07-2005 22:18 342779

DillerInc
Не могу не спросить - каковы причины?
Может есть другое решение?

Кстати, нужные адреса можно и через VirtualQueryEx() получить. Ща попробуем.... =)

DillerInc 21-07-2005 23:08 342783

Savant
Цитата:

Не могу не спросить - каковы причины?
...т.е. всей моей затеи что-ли ?
Мне необходимо поймать на крючок вызов функции LoadLibraryA из библиотеки Kernel32.dll в чужом процессе, иными словами,иметь возможность поместить в нужное место в нужное время два байта ( EB FE ), если я вообще правильно понял всю эту катавасию.
Цитата:

нужные адреса можно и через VirtualQueryEx() получить
...типа так:
Код:

var
 memInfo : _MEMORY_BASIC_INFORMATION
 address : Pointer;
begin
 VirtualQueryEx(processInfo.hProcess, address, memInfo, SizeOf(memInfo));
end;

...только что мы поставим в качестве переменной address - ведь там тоже "Pointer to the base address..." ?

Savant 21-07-2005 23:20 342785

Когда мне надо посмотреть или проверить как работает та или иная функция, то обычно я пишу небольшую программку, которая эту самую функцию активно использует
Итак, представленная ниже программа (если я все правильно сделал) должна:
1) найти все запущенные процессы
2) в области виртуальной памяти каждого процесса найти используемые им части (регионы/блоки) и вывести по ним информацию
Если выводить в файл, то он получается размером в 2,37 мб :)))
Код:

program vpe;

{$APPTYPE CONSOLE}

uses
  Windows, PsAPI;

var
  hProcess: Cardinal;
  Buf: Memory_Basic_Information;
  tmp: array[0..200] of Cardinal; // буыер под 201 процесс =))
  i, k, j: Cardinal;
//  si: System_Info;

label
  l;

function Int2Hex( Value : DWord; Digits : Integer ): ShortString;
{ this function is copyrighted by KSer}
asm
        MOV      [ECX], DL
        XADD      EDX, ECX
@@loop1:
        PUSH      EAX
        db  $24, $0F    // and  al,$0F
        AAM
        //AAD
        DB $D5, $11
        db  $04, $30    // add  al,$30
        MOV      [EDX], AL
        POP      EAX
        SHR      EAX, 4
        DEC      EDX
        LOOP      @@loop1
end;

function GetAProtect(const i: Cardinal): String;
var
  temp: Cardinal;
const
  PAGE_WRITECOMBINE = $400;
begin
  Result := '';

  if i = 0 then begin
    Result := 'unknown (0)'; Exit; end;
   
  temp := i and $000000FF;
  case temp of
    PAGE_NOACCESS:          Result := 'PAGE_NOACCESS';
    PAGE_READONLY:          Result := 'PAGE_READONLY';
    PAGE_READWRITE:        Result := 'PAGE_READWRITE';
    PAGE_WRITECOPY:        Result := 'PAGE_WRITECOPY';
    PAGE_EXECUTE:          Result := 'PAGE_EXECUTE';
    PAGE_EXECUTE_READ:      Result := 'PAGE_EXECUTE_READ';
    PAGE_EXECUTE_READWRITE: Result := 'PAGE_EXECUTE_READWRITE';
    PAGE_EXECUTE_WRITECOPY: Result := 'PAGE_EXECUTE_WRITECOPY';
  end;

  if i and PAGE_GUARD <> 0 then
    Result := Result + ' && PAGE_GUARD';
  if i and PAGE_NOCACHE <> 0 then
    Result := Result + ' && PAGE_NOCACHE';
  if i and PAGE_WRITECOMBINE <> 0 then
    Result := Result + ' && PAGE_WRITECOMBINE';
   
  if Result = '' then Result := '!!! Error';
end;

function GetState(const i: Cardinal): String;
begin
  case i of
    MEM_COMMIT:  Result := 'MEM_COMMIT';
    MEM_FREE:    Result := 'MEM_FREE';
    MEM_RESERVE: Result := 'MEM_RESERVE';
    else        Result := '!!! Error';
  end;
end;

function GetType(const i: Integer): String;
begin
  case i of
    0:          Result := 'unknown (0)';
    MEM_IMAGE:  Result := 'MEM_IMAGE';
    MEM_MAPPED:  Result := 'MEM_MAPPED';
    MEM_PRIVATE: Result := 'MEM_PRIVATE';
    else        Result := '!!! Error';
  end;
end;

begin
// Через GetSystemInfo можно узнать размер страницы в памяти и так как
// Вам нужно добраться до определенной страницы, то ее адрес вычисляется
// просто: Base_Address + si.dwPageSize * PageNumber_In_Allocation_Region
//  GetSystemInfo(si);
  if not EnumProcesses(@tmp, sizeof(tmp), i) then Exit;
  for k := 0 to (i div 4) - 1 do begin
    WriteLn(#10#13'* * * * * // PID = ', tmp[k]);
    hProcess := OpenProcess(PROCESS_QUERY_INFORMATION, True, tmp[k]);
    j := 0;
l:  if VirtualQueryEx(hProcess, Ptr(j), Buf, sizeof(Buf)) > 0 then begin
      WriteLn('Base Address: 0x' + Int2Hex(Cardinal(Buf.BaseAddress), 8) + ' (', Cardinal(Buf.BaseAddress), ')');
      WriteLn('Allocation Base: 0x' + Int2Hex(Cardinal(Buf.AllocationBase), 8) + ' (', Cardinal(Buf.AllocationBase), ')');
      WriteLn('Allocation Protect: ', GetAProtect(Buf.AllocationProtect));
      WriteLn('Region Size: 0x' + Int2Hex(Buf.RegionSize, 8) + ' (', Buf.RegionSize, ')');
      WriteLn('State: ', GetState(Buf.State));
      WriteLn('Protect: ', Buf.Protect);
      WriteLn('Type: ', GetType(Buf.Type_9));
      if (Cardinal(Buf.BaseAddress) + Buf.RegionSize < $FFFFFFFF) and (Buf.RegionSize > 0) then begin
        WriteLn;
        j := Cardinal(Buf.BaseAddress) + Buf.RegionSize;
        goto l; // loop
      end;
    end;                         
  end;

  ReadLn;
end.

Эх, млин чуть-чуть не успел, вот и пост DillerInc'a появился... :(

Цитата:

Мне необходимо поймать на крючок вызов функции LoadLibrary
Это уже хуки. Если не ошибаюсь, то подробности в гугле по Hooking Windows API .

Цитата:

EB FE
хех. цикл. бесконечный. очень любимый всякими патчами/кряками ("замораживание" процесса). н-да...

Savant 21-07-2005 23:24 342787

Вот на Делфи - http://forum.sources.ru/index.php?sh...=43286&hl=hook

Добавлено:
В этой статье (ближе к концу) тоже есть полезности (на асме).

Перехват APi функций в WinNT+

Добавлено:
Статьи о перехвате вызовов API, используя Delphi:
Перехват API функций в Windows NT (часть 1). Основы перехвата.
Перехват API функций в Windows NT (часть 2). Методы внедрения кода.
Перехват API функций в Windows NT (часть 3). Нулевое кольцо.

DillerInc 22-07-2005 00:14 342797

Savant
Спасибо за ссылки - будем разбираться.
Если что, буду тогда сюда постить,если ты не против.
Цитата:

очень любимый всякими патчами/кряками
...а кто ж его не любит - экспериментируем,экспериментируем... ;) .

DillerInc 23-07-2005 21:31 343192

Вообще,как то странно это...к примеру:
Код:

var
 EntryPoint : LPDWORD;
 Temp_Protect : Cardinal;
begin
 VirtualProtectEx(pInfo.hProcess, PPointer(EntryPoint), 2, PAGE_EXECUTE_READWRITE, Temp_Protect);
end;

...работает на ура,а этот вариант:
Код:

var
 ProcAddress : LPDWORD;
 Temp_Protect : Cardinal;
begin
 ProcAddress := LPDWORD(GetProcAddress(GetModuleHandle('Kernel32.dll'), 'LoadLibraryA'));
 VirtualProtectEx(pInfo.hProcess, PPointer(ProcAddress), 2, PAGE_EXECUTE_READWRITE, Temp_Protect);
end;

...продолжает упорно возвращать STATUS_CONFLICTING_ADDRESSES, хотя если взять последнюю предоставленную ссылку,то там описывается как раз аналогичный вариант с внедрением своего кода в начало системной функции (только там сразу применяется функция ReadProcessMemory,что кстати странно, т.к. кто гарантирует,что у нас есть право записи в эту страницу памяти ).
Вопрос: почему первый вариант работает,а второй нет ?
Как можно поправить ситуацию ?

DillerInc 25-07-2005 00:12 343343

Нет,ну это просто проказа какая-то :angry: :
беру любое смещение из адресного простанства чужого процесса,вставляю его как второй параметр в функцию VirtualProtectEx - всё работает без каких-либо проблем!
Как только использую адрес начала системной функции - всё идёт крахом, из-за чего рушится и вся остальная конструкция.
Может быть проблема заключается именно в попытке обращения к импортируемой библиотеке,но в указанных примерах (по ссылкам) предлагали же непосредственное внедрение своих команд в начало системной функции :blink: ...

DillerInc 26-07-2005 22:32 343759

Ну,неужели ни у кого нету никаких соображений по этому поводу,никаких советов ?
Может причина "недосягаемости" адресного пространтсва импортируемых библиотек заключается где-то в атрибутах,свойствах открытия файла или создания процесса из последнего...
:help:

Savant 27-07-2005 11:58 343883

hasherfrog
Темы разбил...

DillerInc
Цитата:

Ну,неужели ни у кого нету никаких соображений по этому поводу,никаких советов ?
Конкретно я могу посоветовать прочитать еще три статьи, добавленные чуть выше. Там на Delphi, но довольно муторно расписано (по крайней мере я первую статью съел только со второго прочтения, вторая статья получше ушла, до третьей еще не дошел).
Цитата:

беру любое смещение из адресного простанства чужого процесса,вставляю его как второй параметр в функцию VirtualProtectEx - всё работает без каких-либо проблем!
Этого не может быть. Могу представить программу, которая это подтвердит.
Цитата:

... применяется функция ReadProcessMemory,что кстати странно, т.к. кто гарантирует,что у нас есть право записи в эту страницу памяти?
права задаются в OpenProcess()

Кстати говоря, а Вы не из под 9x/Me случайно работаете?! Там область применения VirtualProtectEx() ограничена 2 Гб, а область загрузки системных DLL как раз идет дальше (т.н. shared virtual address space).

p.s.: получать адрес из числа (Integer->Pointer) в Delphi лучше функцией ptr(), например ptr($4FFF).

DillerInc 27-07-2005 15:53 343940

Savant
Цитата:

Кстати говоря, а Вы не из под 9x/Me случайно работаете?!
...нет,Win2k SP4 .
Цитата:

Этого не может быть
...да,походу я действительно погорячился.Я имел в виду смещения в секции кода - та же точка входа позволяет проводить данную экзекуцию,пробовал ещё над несколькими смещениями - без проблем :huh: .
Цитата:

права задаются в OpenProcess()
...а если чужой процесс создан следующим образом:
Код:

var
 sInfo : TStartupInfo;
 pInfo : TProcessInformation;
begin
 sInfo.cb := SizeOf(sInfo.cb); // Обрубок структуры класса TStartupInfo

 CreateProcess(OpenFileName.lpstrfile, NIL, NIL, NIL, False, CREATE_SUSPENDED, NIL, NIL, sInfo, pInfo);

...возможна ли тут какая-то заковырка ?

DillerInc 01-08-2005 23:56 345275

В общем,почитав всякого и наковырявшись с кодом "по полной программе",я к сожалению так конкретно и не понял почему возникает вышеописанная ошибка - ну,да бог с ним...
Во большинстве материалов,которые я читал,преподавалась следующая техника т.н. "сплайсинга" системных функций:
в адресном пространстве чужого процесса создаётся удалённый поток с помощью CreateRemoteThread,в который потом подгружается библиотека,ответственная за перехват системных функций (размещение своих команд в начале таких функций,перенаправление управления на свой код-перехватчик)...
Причём такой вариант трактуется именно как наиболее предпочтительный и эффективный.

Но теперь я здесь по иному вопросу.
Функция GetModuleHandle возвращает дескриптор указанного модуля,который,как я понял,является ни чем иным как базовым адрестом загрузки этого самого модуля.Проблема заключается походу в следующем:
Цитата:

Цитата MSDN
The GetModuleHandle function retrieves a module handle for the specified module if the file has been mapped into the address space of the calling process.

...если опять-таки правильно понял,функция способна возвратить хэндлы только тех модулей,которые являются загруженными в адресное простанство вызывающего процесса.
А как можно получить такой дескриптор какого-нибудь модуля в чужом процессе ?

DillerInc 04-08-2005 00:19 345800

Я почти достиг того,чего я хотел,а именно:
Код:

var
 sInfo : TStartupInfo;
 pInfo : TProcessInformation;
 dEvent : _DEBUG_EVENT;
 Base : Cardinal;
 dll_Name : array [0..MAX_PATH - 1] of Char;
begin
 if CreateProcess(OpenFileName.lpstrFile, NIL, NIL, NIL, False,
                  DEBUG_ONLY_THIS_PROCESS, NIL, NIL, sInfo, pInfo) then
begin
repeat // начинаем бесконечный цикл ожидания отладочного события
 WaitForDebugEvent(dEvent, INFINITE);
if dEvent.dwDebugEventCode = LOAD_DLL_DEBUG_EVENT then // если отладочное событие - загрузка библиотеки,то...
begin
 PPointer(Base) := dEvent.LoadDll.lpBaseOfDll; // ...получаем базовый адрес загруженной библиотеки
if GetModuleFileNameEx(pInfo.hProcess, Base,
                        @dll_Name, SizeOf(dll_Name)) <> 0 then // Пытаемся получить имя библиотеки по её модулю...
begin
 Break; // Если предыдущая функция удалась,то выходим из бесконечного цикла
end else MessageBox(Handle, 'Function failed', NIL, MB_OK);
            DoExit; // Типа убиваем всё наповал :]
end;
 ContinueDebugEvent(dEvent.dwProcessId, dEvent.dwThreadId, DBG_CONTINUE);
until False;

...недочёт в том,что функция GetModuleFileNameEx постоянно проваливается,возвращая нуль.
Соответственно,кто-нибудь может сказать в чём могут быть причины ?

Можно,конечно,пытаться использовать поле dEvent.LoadDll.lpImageName структуры _DEBUG_EVENT, которое,как я понял,должно содержать указатель на имя загруженной библиотеки,но там какие-то трудности,о которых как-то размыто пишут на MSDN...и сколько я не пробЫвал использовать эту возможность - ничего путного не выходило.Хотя это был бы наверное самый идеальный вариант получения имени загруженной библиотеки.

DillerInc 09-08-2005 01:30 346774

хм...неужели я задаю такие сложные вопросы,что никто не хочет на них отвечать... :huh:
Иными словами,либо я чего-то не допонимаю,либо библиотека psapi.dll, в которой объявлены такие функции как GetModuleFileNameEx, GetModuleBaseName, криво написана...
Тем не менее мне удалось создать работающий код(точнее взять его основу на MSDN),который будет динамически получать имя загружаемой в чужом процессе библиотеки,хотя,по-моему,всё это скорее напоминает какие-то танцы с бубном.
Код:

function GetFileNameFromHandle(hFile : Cardinal) : Boolean;
 { Параметр hFile мы получаем из dEvent.LoadDll.hFile (см. выше) - кстати,одно из значений,которое в отличии от остальных значений реально возвращается отладочным событием LOAD_DLL_DEBUG_EVENT }
const
 wantedLibName = 'XXX.dll';
var
 hFileMap : Cardinal;
 pMem : Pointer;
 FilePath : array [0..MAX_PATH - 1] of Char;
 sFilePath : String;
 sFileName : String;
begin
 Result := False;

try
 hFileMap := CreateFileMapping(hFile, NIL, PAGE_READONLY, 0, 0, NIL);
if hFileMap <> 0 then
begin
 pMem := MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
if pMem <> NIL then
begin
if GetMappedFileName(GetCurrentProcess(), pMem,
                    @FilePath, SizeOf(FilePath)) <> 0 then // тут мы наконец-то получаем полный путь к нашему файлу
begin
 sFilePath := StrPas(FilePath);
 sFileName := ExtractFileName(sFilePath); // здесь мы убираем путь,оставляя только само имя файла...
if AnsiSameText(wantedLibName, sFileName) then // и сравниваем его с именем искомого файла
begin
 Result := True;
end;
end else MessageBox(Handle, 'GetMappedFileName failed', NIL, MB_OK);
end else MessageBox(Handle, 'pMem = NIL', NIL, MB_OK);
end else MessageBox(Handle, 'hFileMap = 0', NIL, MB_OK);

finally
 UnMapViewOfFile(pMem);
 CloseHandle(hFileMap);
end; // try...finally

end; // GetFileNameFromHandle

...вот так вот :) .

DillerInc 21-04-2006 16:53 430436

В общем,подумал,что может кому-то будет интересно,каким образом можно всё-таки поймать вызов какой-нибудь API-функции,заменив первые команды последней банальным EB FE,то есть попросту зациклив эту функцию.
Случай относится к тому варианту,когда вы запускаете подопытный процесс в режиме CREATE_SUSPENDED.
Причина,из-за которой у меня в своё время не получалось поймать функцию,заключалась в следующем.
При подобной технике необходимо,чтобы процесс был разморожен и как бы начал физически выполняться,если так можно выразиться.
Достигается это с помощью предварительного зацикливания процесса на точке входа,а именно:
Код:

var
 OpenDlgBox : TOpenFileName;
 sInfo : TStartupInfo;
 pInfo : TProcessInformation;
 EntryPoint : Cardinal;
 RestoreEP : WORD;

// Функция для зацикливания адреса,которая возвращает два оригинальных байта,заменённых нашим опкодом
function EndlessLoopRVA(RVA : DWORD) : WORD;
const
 Code : WORD = $FEEB; // наш магический опкод
 error : LPCTSTR = 'Произошла ошибка во время зацикливания RVA';
var
 OriginalData : WORD;
 Temp_Protect : Cardinal;
 nBytesRead, nBytesWritten : Cardinal;
begin
try
 VirtualProtectEx(pInfo.hProcess, PPointer(RVA), 2,
                  PAGE_EXECUTE_READWRITE, Temp_Protect);
 ReadProcessMemory(pInfo.hProcess, PPointer(RVA),
                  @OriginalData, 2, nBytesRead);
 WriteProcessMemory(pInfo.hProcess, PPointer(RVA), @Code,
                    SizeOf(WORD), nBytesWritten);
 VirtualProtectEx(pInfo.hProcess, PPointer(RVA), 2,
                  Temp_Protect, Temp_Protect);

 Result := OriginalData;

except MessageBox(Handle, error, NIL, MB_OK);
end; // try...except

end; // EndlessLoopRVA

// Процедура,которая восстанавливает оригинальные байты
procedure RestoreData(RVAs : DWORD; RestoreCode : WORD);
var
 Trash : WORD; // это просто для размещения мусора
 Temp_Protect : Cardinal;
 nBytesRead, nBytesWritten : Cardinal;
begin
try
 VirtualProtectEx(pInfo.hProcess, PPointer(RVAs), 2,
                  PAGE_EXECUTE_READWRITE, Temp_Protect);
 ReadProcessMemory(pInfo.hProcess, PPointer(RVAs), @Trash,
                    2, nBytesRead);
 WriteProcessMemory(pInfo.hProcess, PPointer(RVAs),
                    @RestoreCode, SizeOf(WORD), nBytesWritten);
 VirtualProtectEx(pInfo.hProcess, PPointer(RVAs), 2,
                  Temp_Protect, Temp_Protect);

except MessageBox(Handle, 'Произошла ошибка при восстановлении кода',
                                                      NIL, MB_OK);
end; // try...except

end; // RestoreData

begin

if CreateProcess(OpenDlgBox.lpstrFile, nil, nil, nil, False, CREATE_SUSPENDED,
              nil, nil, sInfo, pInfo) then
begin
 RestoreEP := EndlessLoopRVA(EntryPoint);  // Помещаем наш опкод на точку входа
 ResumeThread(pInfo.hThread);                    // Размораживаем процесс
 Sleep(300);                                                  // Даём ему немножко времени очухаться
 SuspendThread(pInfo.hThread);                  // Снова замораживаем его
 RestoreData(EntryPoint, RestoreEP);            // И восстанавливаем оригинальные байты
 end;
end;

После того как процесс,только набрав обороты,упрётся в наш опкод на точке входа мы будем в состоянии работать с API-функциями,отображёнными в адресное пространство подопытного процесса.

Под конец стоит заметить,что зацикливание библиотечных функций не будет работать на 9х-ой линейке Windows,т.к. если я не ошибаюсь,библиотеки там отображаются в некую общую область памяти,а не в каждый процесс отдельно.

QWERYTY 08-04-2012 16:08 1895722

Вижу тема давнишняя, но наверняка сюда заходят.
Была аналогичная проблема с получением хендла длл в чужом процессе.
Честно говоря был удивлен не найдя простой функции для этого.
Пришлось делать через тулхелп32.
В юзес подключаем Tlhelp32 и перечисляем модули в конкретном процессе(или если не ошибаюсь во всех когда вместо PId передаётся 0):
{Code}
// HLibrary := GetModuleHandle(PWideChar('ИмяМодуля.Dll')); Вот так разумеется не проканывает
// HLibrary разумеется глобальная переменная

procedure TForm1.Button2Click(Sender: TObject);
var
SnapModule: CARDINAL;
ModuleEntry: ModuleEntry32;
NextModule: BOOL;
begin
HLibrary := 0;
SnapModule := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PId); // Не забываем предварительно получить пид
ModuleEntry.dwSize := SizeOf(ModuleEntry);
NextModule := Module32First(SnapModule, ModuleEntry);
while NextModule do
begin
if ModuleEntry.szModule = 'ИмяМодуля.Dll' then
begin
HLibrary := ModuleEntry.hModule;
Exit;
end;
NextModule := Module32Next(SnapModule, ModuleEntry);
end;
CloseHandle(SnapModule);
end;
{/Code}

Ну там можно поиграть структурой ModuleEntry под свои потребности. Там много интересных полей.

QWERYTY 11-04-2012 13:06 1897589

DillerInc
"var
ProcAddress : LPDWORD;
Temp_Protect : Cardinal;
begin
ProcAddress := LPDWORD(GetProcAddress(GetModuleHandle('Kernel32.dll'), 'LoadLibraryA'));"

Зачем ProcAddress какого то непонятного типа?
var
ProcAddress: POINTER;
begin
ProcAddress := GetProcAddress(GetModuleHandle('Kernel32.dll'), 'LoadLibraryA');"
Функция VirtualProtectEx судя из описания в моей студии требует lpAddress (System.Pointer), так надо понимать lp перед переменной означает что нам нужен LONG POINTER, т.е. указатель на функцию, а не указатель на параметр DWORD. Зачем там все эти выкрутасы?

Поймать то вызов легко. Создаётся удалённый поток в процессе "жертве", и поток загружает нашу длл в адресное пространство. А в длл разумеется код который выполняет перехват(затирает первые 5 байт перехватываемой функции и записывает адрес нашей функции), и в зависимости от задачи можно восстановить искомую функцию, вызвать её, и опять переписать 5 байт до следующего вызова.

А вот самому вызвать свою функцию из своей же длл(закинутой в сторонний процесс) не понятно пока как.
Я понимаю что моя длл теперь в виртуальном пространстве стороннего процесса.
Непонятно почему .modBaseAddr(как я понимаю адрес загрузки) совпадает с хендлом модуля.
Допустим можно вычислить адрес функции, но ведь это виртуальный адрес в том процессе, и как вызвать функцию по виртуальному адресу?


Время: 16:08.

Время: 16:08.
© OSzone.net 2001-