Старый 19.01.2009, 20:16   #1   
Форумец
 
Сообщений: 58
Регистрация: 12.03.2007

Dream Worker вне форума Не в сети
перехват WinApi GetLocalTime

Пытался повторить по примеру, взятому у MS_REM
http://www.wasm.ru/article.php?article=apihook_1
пример AdwareBox

Но во первых в Делфи GetLocalTime объявлена как процедура а не функция, во вторых мне не особо понятно смысл значений


Цитата:
кусок кода

Procedure SetHook();
var
Khernel32: dword;
Bytes: dword;
begin
Khernel32 := GetModuleHandle('Kernel32.dll');
GltAdr := GetProcAddress(Khernel32, 'GetLocalTime');
ReadProcessMemory(INVALID_HANDLE_VALUE, GltAdr, @OldGlt, SizeOf(OldCode), Bytes);
JmpGlt.PuhsOp := $68;
JmpGlt.PushArg := @NewGetLocalTime;
JmpGlt.RetOp := $C3;
WriteProcessMemory(INVALID_HANDLE_VALUE, GltAdr, @JmpGlt, SizeOf(far_jmp), Bytes);
end;
Цитата:
JmpGlt.PuhsOp := $68;
JmpGlt.RetOp := $C3;
Я видел множество примеров на C++ или на ASM, но в них, я к сожалению, не силен.
Если кому не тяжело, посоветуйте как нужно исправить код. спс.
  Ответить с цитированием
Старый 19.01.2009, 21:17   #2   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
Цитата:
Сообщение от Dream Worker Посмотреть сообщение
объявлена как процедура а не функция
А в чем, собсно, разница?
Цитата:
Сообщение от Dream Worker Посмотреть сообщение
во вторых мне не особо понятно смысл значений
Это машкоды. Зачем тебе такие извращения? В нете масса примеров, написанных без подобных извратов.
Цитата:
Сообщение от Dream Worker Посмотреть сообщение
множество примеров на C++
Они гораздо понятнее, чем эти мегакульхацкерные выпендрёжи. Напиши, что тебе не понятно в них.

Кстати, ты случаем, не вирус пишешь? ) Если нет, то тебе, скорее всего, вовсе не нужны такие изощренные методы внедрения.
  Ответить с цитированием
Старый 20.01.2009, 09:08   #3   
Пессимист
 
Аватар для dn2k4
 
Сообщений: 618
Регистрация: 22.07.2004

dn2k4 вне форума Не в сети
Цитата:
Сообщение от Part!zan Посмотреть сообщение
В нете масса примеров, написанных без подобных извратов.
+1
Этот кусок кода не надо править - его надо выкинуть. Здесь в начала кода перехватываемой функции создается конструкция:
Код:
push <новый адрес обработчика>
ret
выполнение которой приводит к передаче управления на твою функцию.

Такой подход был хорош под DOS и под Win16. В современных системах с вытесняющей многозадачностью в момент между установкой первого и второго байта "патча" функция может понадобится другому процессу, который в лучшем случае благополучно рухнет, а в худшем - вынесет тебе половину системы.

Единственно вменяемое решение - править таблицу импорта модуля. Ищи, например, книгу: Джеффри РИХТЕР. "Создание эффективных WIN32-приложений" (по моему оно так называется, под рукой сейчас нет).
  Ответить с цитированием
Старый 20.01.2009, 11:30   #4   
Форумец
 
Аватар для MadFish
 
Сообщений: 340
Регистрация: 25.07.2002

MadFish вне форума Не в сети
Гыы повеселило!!! Не пробовал (дельфи нет под рукой) а GPF не прилетит в момент записи в системный процесс?
  Ответить с цитированием
Старый 20.01.2009, 17:17   #5   
Пессимист
 
Аватар для dn2k4
 
Сообщений: 618
Регистрация: 22.07.2004

dn2k4 вне форума Не в сети
MadFish, хехе, а ну ка, где там системный процесс? =)
  Ответить с цитированием
Старый 20.01.2009, 17:23   #6   
Форумец
 
Аватар для MadFish
 
Сообщений: 340
Регистрация: 25.07.2002

MadFish вне форума Не в сети
а чё кернел32 не на 0 кольце разве работает???
  Ответить с цитированием
Старый 20.01.2009, 22:26   #7   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
Цитата:
Сообщение от dn2k4 Посмотреть сообщение
в момент между установкой первого и второго байта "патча" функция может понадобится другому процессу
А в коде, который этот кусок использует, автор предусмотрительно останавливает треды... Но метод все равно изуверский и чисто вирусовый, называется сплайсинг. Делается с целью скрытия перехвата.
Цитата:
Сообщение от MadFish Посмотреть сообщение
чё кернел32 не на 0 кольце разве работает
С какого перепугу? Этак каждое приложение юзермоды, подключившее kernel32.dll (а это практически любое виндовое приложение), получит реальную возможность завалить систему.
  Ответить с цитированием
Старый 21.01.2009, 10:02   #8   
Форумец
 
Аватар для MadFish
 
Сообщений: 340
Регистрация: 25.07.2002

MadFish вне форума Не в сети
Цитата:
Сообщение от Part!zan Посмотреть сообщение
С какого перепугу? Этак каждое приложение юзермоды, подключившее kernel32.dll (а это практически любое виндовое приложение), получит реальную возможность завалить систему.
Сори, я конечно может быть и нуб в этом вопросе но всегда считал что Kernel32.dll это свалка винапишных вызовов и менеджер памяти. Грузится и юзается ядром в том числе. И предполагается что с GDT и TSS можно работать только из 0 кольца. Киньте в меня ссылкой где можно почитать в инете или скачать микрософтовский DDK.
  Ответить с цитированием
Старый 21.01.2009, 21:33   #9   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
Цитата:
Сообщение от MadFish Посмотреть сообщение
всегда считал что Kernel32.dll это свалка винапишных вызовов и менеджер памяти. Грузится и юзается ядром в том числе
Ты путаешь с ntdll.dll. Ее функциями действительно пользуются драйверы ядра и, в том числе, kernel32.dll. Но даже если программа юзермоды напрямую подключит ntdll.dll, это вовсе не значит, что она автоматически начнет работать в ring0. Длл сама по себе нигде не выполняется и лишь содержит код, который выполняется в других процессах. И только от самого процесса зависит, на каком уровне он будет работать, а вовсе не от используемых длл.

Цитата:
Сообщение от MadFish Посмотреть сообщение
скачать микрософтовский DDK
microsoft.com, а еще на торрентах есть.
  Ответить с цитированием
Старый 21.01.2009, 22:47   #10   
Форумец
 
Аватар для MadFish
 
Сообщений: 340
Регистрация: 25.07.2002

MadFish вне форума Не в сети
Цитата:
Сообщение от Part!zan Посмотреть сообщение
Ты путаешь с ntdll.dll.
Погодте... Например список экспортируемых функций kernel32.dll ... бла-бла-бла... HeapAlloc... бла-бла-бла...

Цитата:
Сообщение от Part!zan Посмотреть сообщение
о даже если программа юзермоды напрямую подключит ntdll.dll, это вовсе не значит, что она автоматически начнет работать в ring0.
А я и не утверждал этого! Вызов произойдет понятное дело ЧЕРЕЗ вентель. А вот попытка записать в сегмент кода пошлет далеко и надолго вместе с GPF-ом...

Цитата:
Сообщение от Part!zan Посмотреть сообщение
Длл сама по себе нигде не выполняется и лишь содержит код, который выполняется в других процессах
А вот это неверное утверждение!!! Никто мне не помешает при инициализации dll запустить поток и будет он у меня шарашить как проклятый!!!

Цитата:
Сообщение от Part!zan Посмотреть сообщение
microsoft.com
Там он за деньги... пошел искать в торентах...
  Ответить с цитированием
Старый 21.01.2009, 23:08   #11   
Пессимист
 
Аватар для dn2k4
 
Сообщений: 618
Регистрация: 22.07.2004

dn2k4 вне форума Не в сети
Цитата:
Сообщение от Part!zan Посмотреть сообщение
автор предусмотрительно останавливает треды
Угу. Но если мне не изменяет память, то WriteProcessMemory пишет в область памяти, которая общая отмаппированая, там только seDebugPrivilege (которое по умолчанию у администраторов есть) и нужно. Так что треды других процессов, использующих dll, тоже придется тормозить. Что, в общем-то нетривиально и делает эту затею еще более извратной.

UPD: Память таки изменяет. Посморел таки в msdn - там хендл процесса нужен, правится его память. Значит надо возится с ToolHelpAPI, что тоже довольно через одно место.

Цитата:
Сообщение от MadFish Посмотреть сообщение
А вот это неверное утверждение!!! Никто мне не помешает при инициализации dll запустить поток и будет он у меня шарашить как проклятый!!!
Вот только инициализация dll сама по себе, без процесса, который ее загружает, не происходит. В результате "шарашить как проклятый" будет код, находящийся в адресном пространстве и с правами твоего процесса.

И ты тоже Рихтера почитай - "Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows"
  Ответить с цитированием
Старый 21.01.2009, 23:57   #12   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
Цитата:
Сообщение от MadFish Посмотреть сообщение
HeapAlloc
Эээ. Ну и чо? Это что-то доказывает?

Цитата:
Сообщение от MadFish Посмотреть сообщение
попытка записать в сегмент кода пошлет далеко и надолго вместе с GPF-ом
С какой стати?

Цитата:
Сообщение от MadFish Посмотреть сообщение
при инициализации dll запустить поток
Пардон, а какое этот поток будет отношение к длл? Он сам по себе, длл - сама по себе.

Цитата:
Сообщение от dn2k4 Посмотреть сообщение
треды других процессов, использующих dll, тоже придется тормозить
Он так и делает, насколько я понял.
  Ответить с цитированием
Старый 22.01.2009, 09:19   #13   
Форумец
 
Аватар для MadFish
 
Сообщений: 340
Регистрация: 25.07.2002

MadFish вне форума Не в сети
Цитата:
Сообщение от dn2k4 Посмотреть сообщение
Вот только инициализация dll сама по себе, без процесса, который ее загружает, не происходит.
Ага, только например есть такая милая штучка как DCOM dll грузится и инициализируется не только не в адресном пространстве процесса а и вообще на физически другой машине

Цитата:
В результате "шарашить как проклятый" будет код, находящийся в адресном пространстве и с правами твоего процесса.
Угу, а если dll загрузило ядро? Вопрос у меня в том и был какой DPL у сегмента кода kernel32.dll.
Ладно пошел курить DDK и Рихтера на закуску, вернусь расскажу

Цитата:
Сообщение от Part!zan Посмотреть сообщение
С какой стати?
Если DPL сегмента кода kernel32 будет ниже CPL процесса прилетит GPF


Цитата:
Сообщение от Part!zan Посмотреть сообщение
Пардон, а какое этот поток будет отношение к длл? Он сам по себе, длл - сама по себе.
эээ не понял как это сам по себе? кусок кода dll шарашит и он сам по себе?
  Ответить с цитированием
Старый 22.01.2009, 19:49   #14   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
MadFish, короче, длл работает в контексте потока, ее подключившего. Независимо от "вероисповедания и цвета кожи" длл. Если у потока есть нужные привилегии - все будет пучком, не будет - прога обломается. Длл - всего лишь абстрактный код.
  Ответить с цитированием
Старый 23.01.2009, 02:00   #15   
Форумец
 
Сообщений: 58
Регистрация: 12.03.2007

Dream Worker вне форума Не в сети
Цитата:
Сообщение от Part!zan Посмотреть сообщение
Кстати, ты случаем, не вирус пишешь? ) .
Да нет, просто некоторые программы не просто имеют триальный период а просто не работают помле определенной даты, тут даже не сторлько халява - к примеру на работе - работа с клиентом БД на редактирование возможно только в 2008 году, а теперь его можно только просматривать (проверяется системное время). Можно конешно время в виндову переводить - но это неудобно.
Вот и хотлось получить возможность "утанавливать" время отдельно для выбранного приложения.
  Ответить с цитированием
Старый 25.01.2009, 05:19   #16   
Форумец
 
Сообщений: 58
Регистрация: 12.03.2007

Dream Worker вне форума Не в сети
Цитата:
library TimeShift;
uses
Windows,TLHelp32;

type
OldCode = packed record
One: dword;
two: word;
end;


far_jmp = packed record
PuhsOp: byte;
PushArg: pointer;
RetOp: byte;
end;

var
JmpGlt : far_jmp;
OldGlt : OldCode;
GltAdr : pointer;

JmpGst : far_jmp;
OldGst : OldCode;
GstAdr : pointer;

Function OpenThread(dwDesiredAccess: dword;
bInheritHandle: bool;
dwThreadId: dword): dword; stdcall;
external 'kernel32.dll';


Procedure StopThreads;
var
h, CurrTh, ThrHandle, CurrPr: dword;
Thread: TThreadEntry32;
begin
CurrTh := GetCurrentThreadId;
CurrPr := GetCurrentProcessId;
h := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if h <> INVALID_HANDLE_VALUE then
begin
Thread.dwSize := SizeOf(TThreadEntry32);
if Thread32First(h, Thread) then
repeat
if (Thread.th32ThreadID <> CurrTh) and (Thread.th32OwnerProcessID = CurrPr) then
begin
ThrHandle := OpenThread(0002, false, Thread.th32ThreadID);
if ThrHandle>0 then
begin
SuspendThread(ThrHandle);
CloseHandle(ThrHandle);
end;
end;
until not Thread32Next(h, Thread);
CloseHandle(h);
end;
end;

Procedure RunThreads;
var
h, CurrTh, ThrHandle, CurrPr: dword;
Thread: TThreadEntry32;
begin
CurrTh := GetCurrentThreadId;
CurrPr := GetCurrentProcessId;
h := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if h <> INVALID_HANDLE_VALUE then
begin
Thread.dwSize := SizeOf(TThreadEntry32);
if Thread32First(h, Thread) then
repeat
if (Thread.th32ThreadID <> CurrTh) and (Thread.th32OwnerProcessID = CurrPr) then
begin
ThrHandle := OpenThread(2, false, Thread.th32ThreadID);
if ThrHandle>0 then
begin
ResumeThread(ThrHandle);
CloseHandle(ThrHandle);
end;
end;
until not Thread32Next(h, Thread);
CloseHandle(h);
end;
end;

procedure TrueGetLocalTime(var lpSystemTime: TSystemTime); stdcall;
var
Written: dword;
begin
WriteProcessMemory(INVALID_HANDLE_VALUE, GltAdr, @OldGlt, SizeOf(OldCode), Written);
GetLocalTime(lpSystemTime) ;
WriteProcessMemory(INVALID_HANDLE_VALUE, GltAdr,@JmpGlt, SizeOf(far_jmp), Written);
end;

procedure NewGetLocalTime(var lpSystemTime: TSystemTime); stdcall;
begin
TrueGetLocalTime(lpSystemTime) ;
lpSystemTime.wYear:=2008;
lpSystemTime.wDayOfWeek:=2;
end;

procedure TrueGetSystemTime(var lpSystemTime: TSystemTime); stdcall;
var
Written: dword;
begin
WriteProcessMemory(INVALID_HANDLE_VALUE, GstAdr,@OldGst, SizeOf(OldCode), Written);
GetSystemTime(lpSystemTime) ;
WriteProcessMemory(INVALID_HANDLE_VALUE, GstAdr,@JmpGst, SizeOf(far_jmp), Written);
end;

procedure NewGetSystemTime(var lpSystemTime: TSystemTime); stdcall;
begin
TrueGetSystemTime(lpSystemTime) ;
lpSystemTime.wYear:=2008;
end;

Procedure SetHook();
var
Khernel32: dword;
Bytes: dword;
begin
Khernel32 := GetModuleHandle('Kernel32.dll');

GltAdr := GetProcAddress(Khernel32, 'GetLocalTime');
ReadProcessMemory(INVALID_HANDLE_VALUE, GltAdr, @OldGlt, SizeOf(OldCode), Bytes);
JmpGlt.PuhsOp := $68;
JmpGlt.PushArg := @NewGetLocalTime;
JmpGlt.RetOp := $C3;
WriteProcessMemory(INVALID_HANDLE_VALUE, GltAdr, @JmpGlt, SizeOf(far_jmp), Bytes);

GstAdr := GetProcAddress(Khernel32, 'GetSystemTime');
ReadProcessMemory(INVALID_HANDLE_VALUE, GstAdr, @OldGst, SizeOf(OldCode), Bytes);
JmpGst.PuhsOp := $68;
JmpGst.PushArg := @NewGetSystemTime;
JmpGst.RetOp := $C3;
WriteProcessMemory(INVALID_HANDLE_VALUE, GstAdr, @JmpGst, SizeOf(far_jmp), Bytes);


end;

Procedure Unhook();
var
Bytes: dword;
begin
WriteProcessMemory(INVALID_HANDLE_VALUE, GltAdr, @OldGlt, SizeOf(OldCode), Bytes);
WriteProcessMemory(INVALID_HANDLE_VALUE, GstAdr, @OldGst, SizeOf(OldCode), Bytes);
end;


// залепа
Function MessageProc(code : integer; wParam : word;
lParam : longint) : longint; stdcall;
begin
CallNextHookEx(0, Code, wParam, lparam);
Result := 0;
end;

Procedure SetGlobalHookProc();
begin
SetWindowsHookEx(WH_GETMESSAGE, @MessageProc, HInstance, 0);
Sleep(INFINITE);
end;
//

Procedure SetGlobalHook();
var
hMutex: dword;
TrId: dword;
begin
hMutex := CreateMutex(nil, false, 'AdvareHook');
if GetLastError = 0 then
CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else
CloseHandle(hMutex);
end;


procedure DLLEntryPoint(dwReason: DWord);
begin
case dwReason of
DLL_PROCESS_ATTACH: begin
SetGlobalHook();
Randomize();
StopThreads;
SetHook();
RunThreads;
end;
DLL_PROCESS_DETACH: UnHook();
end;
end;


begin
DllProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
ну вот при мерно так как-то... (жалко что при добалении форматирование кода калечитсмя )
  Ответить с цитированием
Старый 25.01.2009, 11:07   #17   
Out There
 
Аватар для Part!zan
 
Сообщений: 5,910
Регистрация: 13.12.2004
Возраст: 47

Part!zan вне форума Не в сети
Цитата:
Сообщение от Dream Worker Посмотреть сообщение
добалении форматирование кода калечитсмя
Используй тэг code:
Код:
#include <stdio.h>

int nod(int a, int b){

   if (a<2 || b<2) return 1;
   while(a!=b)
      if (a>b) a-=b; else b-=a;
   return a;
}

void main(int argc, char* argv[]){

   printf("%d",nod(atoi(argv[1]),atoi(argv[2])));
}
  Ответить с цитированием
Старый 25.01.2009, 12:41   #18   
Пессимист
 
Аватар для dn2k4
 
Сообщений: 618
Регистрация: 22.07.2004

dn2k4 вне форума Не в сети
Dream Worker, мракобесие это все...

Никто не мешает процессу запустить новый тред, пока ты будешь колупаться между CreateToolhelp32Snapshot и установкой джампа. Проще тогда совсем забить на проверки и сразу писать в память, результат будет тот же.

Ну и хакерские танцы с хуками, рандомайзами, мутексами ради внедрения длл... Послушай умных дядек - почитай Рихтера про модификацию секции импорта - там даже рабочие исходники класса для перехвата API есть =)
  Ответить с цитированием
Старый 25.01.2009, 17:42   #19   
Форумец
 
Сообщений: 58
Регистрация: 12.03.2007

Dream Worker вне форума Не в сети
Угу, спасибо. Надо и Си потихонечку начинать изучать...
  Ответить с цитированием
Поиск в теме: 


Опции темы

Быстрый переход:

  Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Support by DrIQ & Netwind