Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.01.2012, 05:08   #1
bizkitlimp
Пользователь
 
Регистрация: 17.03.2011
Сообщений: 12
По умолчанию Изменить неизменяемое(защищенное?) значение в памяти процесса(DLL Hook)

С новым старым новым годом!

Написал небольшой плагин к игрушке, который берет скорость аппарата (зашитую намертво в exe ввиде 2500) и... он как-то не срабатывает.
Код рабочий 100%. Он банально должен менять 4 байта в памяти и он меняет их, например, по адресу 0x010000 так запросто, а вот там где находится скорость аппарата наотрез отказывается.

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

Собственно, идея была сделать бесконечный цикл,чтобы постоянно держал мое значение, типа так:
Код:
   
Application.ProcessMessages();
sleep(1000);
Но ваще без понятия как это делается даже в случае форм и таймеров накинутых, не то что в DLL. Лишь реально ступора добился от процесса и се.

Как пропатчить это защищенные байты? Request Help.

Код:
library Project2;

uses
  System.SysUtils,
  System.Classes,
  windows,
  PsAPI,
  tlhelp32;

var
  Written: SIZE_T;
PidHandle: integer;
PidID: integer;
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
Temp: Integer;
ProcessId: DWORD;
HandleWindow: THandle;
ThreadID: Cardinal;
ChangeValues: dword;
WndHandle : THandle;

const
ExeFileName = 'Freelancer';

{$R *.res}


Function GetProcessID(Const ExeFileName: string; var ProcessId: integer;Const ProcessNo :Integer = 1): boolean;
begin
result := false;
temp:=1;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
 while integer(ContinueLoop) <> 0 do
  begin
   if (StrIComp(PChar(ExtractFileName(FProcessEntry32.szExeFile)), PChar(ExeFileName)) = 0)
     or (StrIComp(FProcessEntry32.szExeFile, PChar(ExeFileName)) = 0)  then
      begin
       If Temp = ProcessNo then
        begin
        ProcessId:= FProcessEntry32.th32ProcessID;
        result := true;
        break;
       end else inc(Temp);
      end;
     ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    end;
  CloseHandle(FSnapshotHandle);
end;

Function WriteByte(Address: Cardinal; ChangeValues: dword) : boolean;
Begin
Result := false;
 if GetProcessID('Freelancer.exe', PidID, 1) = true then
  Begin
    PidHandle:= OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ or PROCESS_VM_OPERATION 
or PROCESS_VM_WRITE{PROCESS_ALL_ACCESS},False,PidId);
    Result := WriteProcessMemory(PidHandle, Pointer(Address), @ChangeValues, SizeOf(ChangeValues), Written);
    Closehandle(PidHandle);
  End;
End;

procedure DllEntry(dwReason: DWORD);
label again;
begin
  case dwReason of
    DLL_PROCESS_ATTACH:
      begin
          WriteByte($010000,$43160000);    //Читаем адрес 010000, записываем байты $43$16$00$00. Этот код работает.
          //WriteByte($0639F3CC,$43160000); //А вот этот нет. Не патчит.

      end;
    DLL_PROCESS_DETACH:
     begin
      end;
    DLL_THREAD_ATTACH:
     begin
      end;
    DLL_THREAD_DETACH:
  {   begin
      end; }
  end;

end;


begin
  @DllProc := @DllEntry;
  DllEntry(DLL_PROCESS_ATTACH);
end.
bizkitlimp вне форума Ответить с цитированием
Старый 15.01.2012, 09:31   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

если это зашитое значение, то оно зашито значит в код.
а значит лишь дизасм и затем патч.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 15.01.2012, 20:36   #3
bizkitlimp
Пользователь
 
Регистрация: 17.03.2011
Сообщений: 12
По умолчанию

Всмысле сам экзешник патчить? Да не, быть не может
Вот сорсы на c++, правда тут плаг более продвинутый, работает как часы. Может из-за virtualprotect?
Я в cpp ни капли, поэтому на делфи пишу.


Код:
#include "Common.h"
#include <map>

#define NAKED	__declspec( naked )
#define STDCALL __stdcall


#define ADDR_SPEED   ((PDWORD)(0x62b19b8+1))	// within CShip::go_tradelane
#define ADDR_READ    ((PBYTE)0x6399858) 	// Archetype::Solar::read

#define pLaneSpeed   ((float*)0x639f3cc)


DWORD dummy;
#define ProtectX( addr, size ) \
  VirtualProtect( addr, size, PAGE_EXECUTE_READWRITE, &dummy )
#define ProtectW( addr, size ) \
  VirtualProtect( addr, size, PAGE_READWRITE, &dummy )

#define RELOFS( from, to ) \
  *(PDWORD)(from) = (DWORD)(to) - (DWORD)(from) - 4

#define NEWOFS( from, to ) \
  to##_Old = (DWORD)(from) + *(PDWORD)(from) + 4; \
  RELOFS( from, to##_Hook )

#define NEWABS( from, to ) \
  to##_Old = *(PDWORD)(from); \
  *(PDWORD)(from) = (DWORD)to##_Hook


typedef std::map<UINT, float> SpeedMap;
typedef SpeedMap::const_iterator SpeedMapCIter;

SpeedMap speeds;
float default_speed;


bool STDCALL ReadSpeed( INI_Reader& ini, PDWORD solar )
{
  if (ini.is_value( "lane_speed" ))
  {
    speeds[solar[2]] = ini.get_value_float( 0 );
    return true;
  }
  return false;
}


void STDCALL SetSpeed( IObjInspectImpl* ship, IObjInspectImpl* ring )
{
  if (ship->is_player())
  {
    SpeedMapCIter iter = speeds.find( ring->solar->archetype->id );
    *pLaneSpeed = (iter == speeds.end()) ? default_speed : iter->second;
  }
}


DWORD Read_Old, Read_New;
DWORD Speed_Old;

NAKED
void Speed_Hook()
{
  __asm {
	push	ecx
	push	dword ptr [esp+4+4]
	push	dword ptr [esp+12+8]
	call	SetSpeed
	pop	ecx
	jmp	Speed_Old
  }
}


NAKED
void Read_Hook()
{
  __asm {
	push	ecx
	push	ecx
	push	dword ptr [esp+4+8]
	call	ReadSpeed
	pop	ecx
	test	al, al
	jnz	done
	jmp	Read_Old
  done:
	ret	4
  }
}


void Patch()
{
  ProtectX( ADDR_SPEED, 4 );
  ProtectW( ADDR_READ,	4 );
  ProtectW( pLaneSpeed, 4 );

  NEWOFS( ADDR_SPEED, Speed );
  NEWABS( ADDR_READ,  Read );

  default_speed = *pLaneSpeed;
}


BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
  if (fdwReason == DLL_PROCESS_ATTACH)
    Patch();

  return TRUE;
}

Последний раз редактировалось bizkitlimp; 15.01.2012 в 21:20.
bizkitlimp вне форума Ответить с цитированием
Старый 15.01.2012, 21:47   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Может из-за virtualprotect?
ну тот плагин вполне может и патчить память процесса(код тоже в памяти). соответственно изменяет аттрибут страницы чтоб разрешить запись.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 15.01.2012, 22:07   #5
bizkitlimp
Пользователь
 
Регистрация: 17.03.2011
Сообщений: 12
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
соответственно изменяет аттрибут страницы чтоб разрешить запись.
Спасибо, то что нужно. Сразу нашел в нете на делфях. Патчит как миленький
Код:
const
AddressReload = $0639F3CC;
PatchReload : Array[0..3] of byte = ($AA,$AA,$AA,$AA);

Function WriteBytes(pAddress: Pointer; Bytes: Array of Byte): Boolean;
var
  OldProtect, DummyProtect: DWord;
begin
  if VirtualProtect(pAddress, SizeOf(Bytes), PAGE_EXECUTE_READWRITE, @OldProtect) then
   begin
    Move(Bytes, pAddress^, Length(Bytes));
    VirtualProtect(pAddress, SizeOf(Bytes), OldProtect, @DummyProtect);
    Result := True
   end
   else
    Result := False;
end;

procedure DllEntry(dwReason: DWORD);
label again;
begin
  case dwReason of
    DLL_PROCESS_ATTACH:
      begin
          WriteBytes(ptr(AddressReload),PatchReload);
      end;
  end;
bizkitlimp вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Определить SIZEMEM у DLL(Размер dll в памяти процесса) Человек_Борща Общие вопросы Delphi 6 22.07.2011 20:54
hook в dll legendary Общие вопросы C/C++ 5 19.10.2010 21:13
[DLL] Загрузка и выгрузка dll в/из чужого процесса Человек_Борща Win Api 4 28.02.2010 17:47
Считать значение из памяти чужого процесса EvgenyZ Win Api 2 27.11.2009 09:29
hook в dll? Altera Win Api 3 09.03.2008 09:54