Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Dll inject в 64-битный процесс 
:(
    Опции темы
xteam777
Дата 3.10.2016, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 11.10.2015

Репутация: нет
Всего: нет



Мне необходимо заинжектить свою Dll (64 бита) в 64-битный процесс. Следующий код прекрасно отрабатывает если Dll и процесс 32-битные.
Но если перекомпилировать все в 64 бита, то при отсоединении Dll, в процессе, к тоторому присоединяем вываливается Access Violation $C0000005. Подскажите в чем может быть дело.

Код инжектора:
Код

function SetDebugPriv: Boolean;
var
  Token: THandle;
  tkp: TTokenPrivileges;
  ReturnLength: DWORD;
begin
  Result := false;
  // Получаем токен текущего процесса
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then
  try
    // Получаем Luid привилегии
    if LookupPrivilegeValue(nil, PChar('SeDebugPrivilege'), tkp.Privileges[0].Luid) then
    begin
      // Заполняем необходимые параметры
      tkp.PrivilegeCount := 1;
      tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
      // Включаем привилегию
      Result := AdjustTokenPrivileges(Token, false, tkp, 0, nil, ReturnLength);
    end;
  finally
    CloseHandle(Token);
  end;
end;

function TForm22.InjectLib(ProcessID: Integer): Boolean;
var
  Process: HWND;
  ThreadRtn: FARPROC;
  DllPath: AnsiString;
  RemoteDll: Pointer;
  BytesWriten: SIZE_T;
  Thread: DWORD;
  ThreadId: DWORD;
begin
  // Устанавливаем отладочные привилегии для нашего процесса
  Result := SetDebugPriv;
  if not Result then Exit;

  // Открываем процесс
  Process := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or
    PROCESS_VM_WRITE, True, ProcessID);
  if Process = 0 then Exit;
  try
    // Выделяем в нем память под строку
    DllPath := AnsiString({ExtractFilePath(ParamStr(0)) +} DLLName) + #0;
    RemoteDll := VirtualAllocEx(Process, nil, Length(DllPath),
      MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
    if RemoteDll = nil then Exit;
    try
      // Пишем путь к длл в его адресное пространство
      if not WriteProcessMemory(Process, RemoteDll, @DllPath[1],
        Length(DllPath), BytesWriten) then Exit;
      if BytesWriten <> DWORD(Length(DllPath)) then Exit;
      // Получаем адрес функции из Kernel32.dll
      ThreadRtn := GetProcAddress(GetModuleHandle('Kernel32.dll'), 'LoadLibraryA');
      if ThreadRtn = nil then Exit;
      // Запускаем удаленный поток
      Thread := CreateRemoteThread(Process, nil, 0, ThreadRtn, RemoteDll, 0, ThreadId);
      if Thread = 0 then Exit;
      try
        // Ждем пока удаленный поток отработает...
        Result := WaitForSingleObject(Thread, INFINITE) = WAIT_OBJECT_0;
      finally
        CloseHandle(Thread);
      end;
    finally
      VirtualFreeEx(Process, RemoteDll, 0, MEM_RELEASE);
    end;
  finally
    CloseHandle(Process);
  end;
end;

//  Данная функция запускает в удаленном процессе поток
//  который стартует с инструкции JMP [EBX]
//  В EBX будет лежать адрес функции SelfUnload,
//  который будет выгружать библиотеку.
//  Адрес функции рассчитывается отдельно и равен
//  адресу загрузки библиотеки + смещение на саму функцию
// =============================================================================
function TForm22.EjectLib(ProcessID: Integer): Boolean;
var
  hLibHandle: THandle;
  hModuleSnap: THandle;
  ModuleEntry: TModuleEntry32;
  OpCodeData: Word;
  Process: HWND;
  BytesWriten: SIZE_T;
  Thread: DWORD;
  ThreadId: DWORD;
  ExitCode: DWORD;
  PLibHandle: PDWORD;
  OpCode: PWORD;
  CurrUnloadAddrOffset: DWORD;
  UnloadAddrOffset: DWORD;
begin
  // Устанавливаем отладочные привилегии для нашего процесса
  Result := SetDebugPriv;
  if not Result then Exit;

  // рассчитываем оффсет адреса выгрузки библиотеки относительно адреса ее загрузки
  hLibHandle := LoadLibrary(PChar(DLLName));
  try
    UnloadAddrOffset :=
      DWORD(GetProcAddress(hLibHandle, 'SelfUnload')) - hLibHandle;
    if UnloadAddrOffset = -hLibHandle then Exit;
  finally
    FreeLibrary(hLibHandle);
  end;

  // Находим адрес библиотеки в чужом адресном пространстве
  hModuleSnap := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID);
  if hModuleSnap <> INVALID_HANDLE_VALUE then
  try
    FillChar(ModuleEntry, SizeOf(TModuleEntry32), #0);
    ModuleEntry.dwSize := SizeOf(TModuleEntry32);
    if not Module32First(hModuleSnap, ModuleEntry) then Exit;
    repeat
      if AnsiUpperCase(ModuleEntry.szModule) =
        AnsiUpperCase(ExtractFileName(DLLName)) then
      begin
        // Получаем адрес функции выгрузки
        CurrUnloadAddrOffset := ModuleEntry.hModule + UnloadAddrOffset;
        Break;
      end;
    until not Module32Next(hModuleSnap, ModuleEntry);
  finally
    CloseHandle(hModuleSnap);
  end;

  if CurrUnloadAddrOffset = 0 then
  begin
    lbStatus.Items.Add('Library has not injected.');
    Exit;
  end;

  // Открываем процесс
  Process := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or
    PROCESS_VM_WRITE, True, ProcessID);
  if Process = 0 then Exit;
  try
    // Пишем опкод jmp [ebx]
    OpCode := VirtualAllocEx(Process, nil, 2,
      MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
    if OpCode = nil then Exit;
    try
      OpCodeData := $23FF;
      if not WriteProcessMemory(Process, OpCode, @OpCodeData,
        2, BytesWriten) then Exit;

      // Пишем адрес функции выгрузки (он будет лежать в EBX при старте потока)
      PLibHandle := VirtualAllocEx(Process, nil, 4,
        MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
      if PLibHandle = nil then Exit;
      try
        if not WriteProcessMemory(Process, PLibHandle, @CurrUnloadAddrOffset,
          4, BytesWriten) then Exit;

        // запускаем поток
        Thread := CreateRemoteThread(Process, nil, 0, OpCode,
          PLibHandle, 0, ThreadId);
        if Thread = 0 then Exit;
        try
          // Ждем пока удаленный поток отработает...
          if (WaitForSingleObject(Thread, INFINITE) = WAIT_OBJECT_0) then
            if GetExitCodeThread(Thread, ExitCode) then
              Result := ExitCode = 0;
        finally
          CloseHandle(Thread);
        end;
      finally
        VirtualFreeEx(Process, PLibHandle, 0, MEM_RELEASE);
      end;
    finally
      VirtualFreeEx(Process, OpCode, 0, MEM_RELEASE);
    end;
  finally
    CloseHandle(Process);
  end;
end;



Код Dll:
Код

procedure DLLEntryPoint(dwReason: DWORD);
begin
  case dwReason of
    DLL_PROCESS_ATTACH:
    begin
      MessageBoxA(0, 'Injected', 'Injected', MB_OK);
    end;
    DLL_PROCESS_DETACH:
    begin
      MessageBoxA(0, 'Rejected', 'Rejected', MB_OK);
    end;
  end;
end;

procedure SelfUnload(lpParametr: Pointer); stdcall;
begin
  FreeLibraryAndExitThread(HInstance, 0);
end;

exports
  SelfUnload;

begin
  DLLProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.


Это сообщение отредактировал(а) xteam777 - 3.10.2016, 15:27
PM MAIL   Вверх
xteam777
Дата 4.10.2016, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 11.10.2015

Репутация: нет
Всего: нет



UP
PM MAIL   Вверх
Angel666
Дата 4.10.2016, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 8.9.2011

Репутация: нет
Всего: 1



http://forum.codecall.net/topic/60111-how-...th-delphi-code/

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
Angel666
Дата 4.10.2016, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 8.9.2011

Репутация: нет
Всего: 1



http://forum.codecall.net/topic/60111-how-...th-delphi-code/

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
Angel666
Дата 4.10.2016, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 8.9.2011

Репутация: нет
Всего: 1



http://forum.codecall.net/topic/60111-how-...th-delphi-code/

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
Angel666
Дата 4.10.2016, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 8.9.2011

Репутация: нет
Всего: 1



http://forum.codecall.net/topic/60111-how-...th-delphi-code/

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
Angel666
Дата 4.10.2016, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 8.9.2011

Репутация: нет
Всего: 1



http://forum.codecall.net/topic/60111-how-...th-delphi-code/

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
xteam777
Дата 5.10.2016, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 11.10.2015

Репутация: нет
Всего: нет



Спасибо. Но у меня проблема не в определении разрядности Windows. Проблема в том, что выложенный код отлично работает в связке 32bit Injector + 32bit Dll + 32bit Targer processs, а при перекомпиляции всех участников в 64bit Injector + 64bit Dll + 64bit Targer processs, при выгрузке Dll в Target process AV $C0000005. Все тесты выполняются в Win 10 x64.
PM MAIL   Вверх
_zorn_
Дата 6.10.2016, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 21.8.2007

Репутация: -1
Всего: 12



А у вас прав то хоть хватает в системе на такие варварские операции ? Под админом пробовали запускать ?
Хотя скорей всего и это не поможет. Вам наверное невдомек что помимо разрядности ОЧЕНЬ СИЛЬНО влияет и версия операционной системы.
Вы УВЕРЕНЫ, что ваш код будет работать на х32 win10 ?
PM MAIL   Вверх
kami
Дата 14.10.2016, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Код

OpCodeData := $23FF;

Думаю, что 32-битные машинные коды как минимум не должны отработать на 64 битах. ASM-то отличается. И разрядности регистров тоже.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1630 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.