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

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

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 06.12.2015, 11:39   #1
JPCool
Пользователь
 
Регистрация: 06.09.2015
Сообщений: 31
По умолчанию Расчет адреса. Вставка инструкции.

Доброго дня, подскажите как правильно реализовать код:

Код:
var
 PtrMessageBoxA:Pointer;

function NewMessageBoxA(hWnd: HWND; lpText, lpCaption: LPCSTR; uType: UINT): Integer; stdcall;
begin
   Result:=MessageBoxW(0,'GOOD HOOKING','',0);
end;


type
 far_jmp = packed record
   PuhsOp: byte;
   PushArg: Pointer;
  end;


Procedure HookMessageBoxA;

var
 HKernel32, HUser32: Int64;
 JmpCrProcA: far_jmp;
 bw,Writen:SIZE_T;
begin

 JmpCrProcA.PuhsOp  := $E8;
 JmpCrProcA.PushArg := @NewMessageBoxA;

{
  Вот тут я так понимаю надо правильно расчитать адрес 
   потому как инструкция JMP = E8 не может прыгнуть на адрес pointer(8 байт) 
   нужно сделать что то вроде 
  
  

   mov rax,@NewMessageBoxA  (Опять же адрес не верный) так как подозреваю что нужно высчитать смешение и т.д. то есть полный адрес. 

   jmp rax
}


 PtrMessageBoxA := GetProcAddress(GetModuleHandle('user32.dll'), 'MessageBoxA');

 WriteProcessMemory(GetCurrentProcess, PtrMessageBoxA, @JmpCrProcA, SizeOf(far_jmp), Writen);
end;
Можете подсказать мне про вычисление адреса, и как встроить ассмеблерный код Delphi XE5 не позволяет создать ассмеблерный код внутри процедуры (64 бит) только отдельную процедуру в виде ассмеблерного кода.

Можно пример перехвата в 64 битной системе на делфи.
JPCool вне форума Ответить с цитированием
Старый 06.12.2015, 12:25   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Рекомендую следующую статью: http://ms-rem.narod.ru/hook/ApiHook1/apihook.htm
Только сильно не увлекайся )
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.12.2015, 21:09   #3
JPCool
Пользователь
 
Регистрация: 06.09.2015
Сообщений: 31
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Рекомендую следующую статью: http://ms-rem.narod.ru/hook/ApiHook1/apihook.htm
Только сильно не увлекайся )
Спасибо, я прочитал давайте поговорим про опкоды...

Размер прыжка для 32 бит расчитал.

Код:
JmpCrProcA.PushArg:=DWord(@NewMessageBoxA) - (DWord(PtrMessageBoxA)+ SizeOf(SpliceRec));
но хочу сделать опкод такой вставки...

Код:
asm
 mov eax,JmpCrProcA.PushArg 
 jmp eax
end
в 64 бит я так понимаю будет так

Код:
type
 JmpCrProcA.PushArg:UInt64;

 JmpCrProcA.PushArg:=UInt64 (@NewMessageBoxA) - (UInt64 (PtrMessageBoxA)+ SizeOf(SpliceRec));
asm
 mov rax,JmpCrProcA.PushArg
 jmp rax
end;



потому что я так понимаю в 64 битной системе не получиться прыгнуть по адресу через jmp? только через подобную конструкцию.

http://www.programmersforum.ru/showthread.php?t=110979


Вопрос как получить OpCode команды самой втсавки, я хочу понять не просто данный пример, а именно где и как брать эти коды для 64 битных процессоров и 32 битных как их получать. Пробовал просто писать код на ассемблере (вставки в делфи) и смотреть в отладчике что получилось, но не догоняю как написать свой опкод с правильным адресом хотя бы для такой просто конструкции что описал выше.

Последний раз редактировалось JPCool; 06.12.2015 в 21:16.
JPCool вне форума Ответить с цитированием
Старый 06.12.2015, 21:16   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
как получить OpCode
http://ref.x86asm.net/coder64.html
А еще лучше скачать МАСМ для 64, с хорошим хелпом.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.12.2015, 21:34   #5
JPCool
Пользователь
 
Регистрация: 06.09.2015
Сообщений: 31
По умолчанию

Ок гугл! я понял надо выучить ассемблер ))

А кроме гугл кто не буть понимает может объяснить, сложно говорить с машиной если ты не знаешь ее язык ))...

Последний раз редактировалось JPCool; 06.12.2015 в 22:09.
JPCool вне форума Ответить с цитированием
Старый 07.12.2015, 03:08   #6
JPCool
Пользователь
 
Регистрация: 06.09.2015
Сообщений: 31
По умолчанию

Итак немного подучив ассемблер получилось реализовать что описывал выше, появился ряд вопросов.

В Fasm собрал код:
Код:
use32
mov eax, 11111111h
jmp eax


use64
mov rax, 1111111111111111h
jmp rax
получил байт коды 64x код для делфи выглядит так:

Код:
type
 SpliceRec = packed record
    Mov1:byte;
    Mov2:byte;
    Offset: Pointer;
    Jmp1: byte;
    Jmp2:byte;
  end;

var
 Rec:SpliceRec;


Procedure HookMessageBoxA;

var
  Writen:SIZE_T;
begin
 PtrMessageBoxA := GetProcAddress(GetModuleHandle('user32.dll'), 'MessageBoxA');
 Rec.Mov1:=$48;
 Rec.Mov2:=$B8;  //mov rax, Rec.Offset

 Rec.Offset:=@NewMessageBoxA;

 Rec.Jmp1 := $FF;  
 Rec.Jmp2:=$E0; //jmp rax 

 if WriteProcessMemory(GetCurrentProcess, PtrMessageBoxA, @Rec, SizeOf(Rec), Writen) then
    MessageBoxA(0,'Test','',0);
end;
Прыжок прошел успешно, хотелось задать вопрос про выделение памяти и расчет адреса прыжка.

Про расчет прыжка, в прошлом примере кода я рассчитывал размер прыжка таким методом (Функция Перехватчика)-(Функция Оригинал)-(Размер Вставки) по итогу я получал отрицательное смешение и вызывал jmp по нему. опкодом $E8 я так понимаю прыжок происходил по значению смешения, а сейчас когда я делаю FF E0 этот прыжок происходит именно по адресу лежащему в rax так как JMP может работать в разных режимах? (Не догоняю этот момент).

И второй момент, хотелось бы перехватывать функции методом хотпачь, вставкой короткого и длинного прыжка так как функции от (микрософт) имеют nop перед их началом туда можно записать прыжок с адресом DWORD а в начало короткий прыжок с адресом на длинный прыжок.

Собственно вопрос про память, как мне выделить память рядом с перехватываемой функции что бы можно было разместить большой прыжок в виде

mov rax, qword_jump
jmp rax

и сделать перехват в 3 прыжка. что даст возможность работы с много поточностью так как не будет необходимости перезаписи jmp... Или есть более простые варианты работы с 64 бит? (IDA 64 разобрала c:\windows\system32\user32.dll в win 8 64 bit и количество nop не изменилось) работа через RAX тоже не есть хорошо я верно понимаю?

Какой функцией выделить, и как правильно посчитать самый ближайший и свободный адрес?

Последний раз редактировалось JPCool; 07.12.2015 в 03:10.
JPCool вне форума Ответить с цитированием
Старый 07.12.2015, 03:08   #7
JPCool
Пользователь
 
Регистрация: 06.09.2015
Сообщений: 31
По умолчанию

Код для работы с 32 битным перехватом методом хотпачь.
Код:

const
  LOCK_JMP_OPKODE: Word = $F9EB;
  JMP_OPKODE: Word = $E9;

type
  // структура для обычного сплайса через JMP NEAR OFFSET
  TNearJmpSpliceRec = packed record
    JmpOpcode: Byte;
    Offset: DWORD;
  end;

  THotPachSpliceData = packed record
    FuncAddr: FARPROC;
    SpliceRec: TNearJmpSpliceRec;
    LockJmp: Word;
  end;

const
  NearJmpSpliceRecSize = SizeOf(TNearJmpSpliceRec);
  LockJmpOpcodeSize = SizeOf(Word);


var
 PtrMessageBoxA:Pointer;
 HotPathSpliceRec: THotPachSpliceData;


function NewMessageBoxA(hWnd: HWND; lpText, lpCaption: LPCSTR; uType: UINT): Integer; stdcall;
var
 MyMessageBoxA:TMessageBoxA;
begin
 @MyMessageBoxA := PAnsiChar(HotPathSpliceRec.FuncAddr) + LockJmpOpcodeSize;
 Result:=MyMessageBoxA(hWnd,'GOOD HOOKING',lpCaption,uType);
end;


// процедура пищет новый блок данных по адресу функции
procedure SpliceNearJmp(FuncAddr: Pointer; NewData: TNearJmpSpliceRec);
var
  OldProtect: DWORD;
begin
  VirtualProtect(FuncAddr, NearJmpSpliceRecSize,
    PAGE_EXECUTE_READWRITE, OldProtect);
  try
    Move(NewData, FuncAddr^, NearJmpSpliceRecSize);
  finally
    VirtualProtect(FuncAddr, NearJmpSpliceRecSize,
      OldProtect, OldProtect);
  end;
end;

 


// процедура атомарно изменяет два байта по переданному адресу
procedure SpliceLockJmp(FuncAddr: Pointer; NewData: Word);
var
  OldProtect: DWORD;
begin
  VirtualProtect(FuncAddr, LockJmpOpcodeSize, PAGE_EXECUTE_READWRITE, OldProtect);
 // try
    asm
      mov  ax, NewData
      mov  ecx, FuncAddr
      lock xchg word ptr [ecx], ax
    end;
    //MyInterLock(NewData,FuncAddr);
    //InterlockedExchange
  //finally
    VirtualProtect(FuncAddr, LockJmpOpcodeSize, OldProtect, OldProtect);
  //end;
end;

// процедура инициализирует структуру для установки перехвата
procedure InitHotPatchSpliceRec(const LibraryName, FunctionName: string;
  InterceptHandler: Pointer; out HotPathSpliceRec: THotPachSpliceData);
begin
  // запоминаем оригинальный адрес перехватываемой функции
  HotPathSpliceRec.FuncAddr :=
    GetProcAddress(GetModuleHandle(PChar(LibraryName)), PChar(FunctionName));
  // читаем два байта с ее начала, их мы будем перезатирать
  Move(HotPathSpliceRec.FuncAddr^, HotPathSpliceRec.LockJmp, LockJmpOpcodeSize);
  // инициализируем опкод JMP NEAR
  HotPathSpliceRec.SpliceRec.JmpOpcode := JMP_OPKODE;
  // рассчитываем адрес прыжка (поправка на NearJmpSpliceRecSize не нужна,
  // т.к. адрес находится уже со смещением)
  HotPathSpliceRec.SpliceRec.Offset :=
    DWord(InterceptHandler) - DWord(HotPathSpliceRec.FuncAddr);
end;

Последний раз редактировалось JPCool; 07.12.2015 в 03:19.
JPCool вне форума Ответить с цитированием
Старый 07.12.2015, 05:26   #8
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 272
По умолчанию

https://github.com/mahdisafsafi/delphi-detours-library
Filka вне форума Ответить с цитированием
Старый 07.12.2015, 09:51   #9
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
так как JMP может работать в разных режимах?
Ну есть абсолютная и относительная адресация, а так же дальний и ближний прыжки.
Почитай про команду JMP подробнее.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 07.12.2015, 18:04   #10
JPCool
Пользователь
 
Регистрация: 06.09.2015
Сообщений: 31
По умолчанию

Цитата:
Сообщение от Filka Посмотреть сообщение
Хороший пример спасибо. Но все же хотелось понять про память? возможно как то выделить ее максимально близко в функции? я так понимаю VirtualAlloc ? но как посчитать где не занемаемое место и т.д. Раскажите про выделение памяти на моем примере, как мне выделить кусок кода рядом в диапазоне user32.dll скажем и т.д. вообще смогу я это делать? я так понимаю что VurtualProtect устанавливает возможность работы со страницами их атрибуты. Покажите пример как правильно выделить память в нужной мне области. (максимально приближенной для функции).
JPCool вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
расшифровка инструкции alinash HTML и CSS 4 22.06.2015 20:31
Си инструкции Praud Помощь студентам 7 01.03.2013 16:13
Инструкции IL stenl1 C# (си шарп) 6 05.12.2011 22:39
Известны фамилии,адреса и телефоны 25-ти человек,Найти фамилии и адреса людей,чей телефон начинается с цифры 3. Расмотреть два слу salomon93 Паскаль, Turbo Pascal, PascalABC.NET 11 01.12.2011 23:36