Форум: "WinAPI";
Текущий архив: 2004.11.21;
Скачать: [xml.tar.bz2];
ВнизVirtualProtect Найти похожие ветки
← →
Rem (2004-10-07 12:27) [0]Добрый день, мастера! Начну с главного, мне необходимо перехватить winapi"шную функцию CreateFile из одной другой проги, послать эту же функцию, но с другими параметрами из своей, получить результат и вернуть его той другой проге. Я знаю, что надо использовать функцию VirtualProtect, но я не знаю как, в MSDN практически ниче не описано по этому поводу, помогите мне плз решить эту проблему.
← →
Суслик © (2004-10-07 12:30) [1]эээ, ты куда-то не туда роешь...
это перехват api вызовов.
информации море.
дла начала см. книгу Рихтера Windows для профи - там несколько способов рассмотрено. Есть пример на rsdn - #1 с.г. или #2 с.г. (см. в статьсях)
← →
Digitman © (2004-10-07 12:55) [2]
> послать эту же функцию
"послать" - это ассоциируется с тремя веселыми буквами ... может все-таки, будешь точней ? кто, куда и по какому поводу "посылает" ? ... и оперируй понятиями не "прога", а хотя бы "трэд процесса" и "процесс" ... хоть что-то прояснится ..
← →
Rem (2004-10-07 13:06) [3]Пример на VC у меня есть, но там очень мутно, может есть у кого-нть на дельфи примерчик
← →
Rem (2004-10-07 13:17) [4]Окей, задача такая, из одного процесса (назовем его А) вызывается функция CreateFile с определенными параметрами. Мой процесс (процесс В), должен перехватить вызов этой функции, проверить параметры, и если в параметрах функции, вызванной процессом А, имя файла совпадает с моим именем фала, используемой в моем приложении, то процесс В вызывает функцию CreateFile с теми параметрами, кот. мне нужны (а именно указываю свой файл). CreateFile возвращает Handle на созданный файл, я этот Handle, должен передать порцессу А. Т.е. проблема в том, что одна программа (процесс А) используют такую затычку, что если файл создан, то она не запускается, а если не создан, то запускается. Я хочу обмануть эту прогу, перехватить вызов функции, создать свой файл и вернуть Handle процессу А. Таким образом Процесс А будет думать, что файл создан и запустится.
← →
Игорь Шевченко © (2004-10-07 14:26) [5]
> CreateFile возвращает Handle на созданный файл, я этот Handle,
> должен передать порцессу А.
Не получится.
← →
Digitman © (2004-10-07 16:32) [6]
> Rem
теперь понятно.
процесс А - это процесс GUI-приложения ?
← →
Rem (2004-10-07 16:53) [7]да, это GUI приложение
← →
Rem (2004-10-07 16:57) [8]Вообщем, я нашел один примерчик http://delphiworld.narod.ru/base/catch_dll_functions_calling.html, только вместо вызова MessageBoxA, я пишу CreateFileA, библиотеку kernel32.dll, ну и TMyProc с MyMessageBox"ом изменяю так, как нужно. Пробовал, но что-то не получается.
← →
kaZaNoVa © (2004-10-07 22:22) [9]Digitman © (07.10.04 12:55) [2]
> "послать" - это ассоциируется с тремя веселыми буквами
> ...
CAD ?
← →
kaZaNoVa © (2004-10-07 22:25) [10]http://delphimaster.net/view/4-1093466109/
там есть ВСЁ - спасибо Digitman"у !!!
← →
Digitman © (2004-10-08 08:11) [11]
> Rem (07.10.04 16:53) [7]
если GUI , то можно воспользоваться механизмом установки глоб.хука
в общем же случае (для НТ-систем) - внедрение в АП процесса своей ДЛЛ вызовом CreateRemoteThread
как только внедренная тем или иным методом библиотека получит управление (в ходе ее иниц-ции), в этот момен как раз и можно осуществить перехват, например, модификацией EAT и IAT
← →
Rem (2004-10-08 13:00) [12]Ага, спасибо, тут вообщем немного поменялась ситуация. Вообщем все сложно, есть дллка - это актив искина, в этой дллке есть класс, в нем объявлен метод, этот метод вызывает функцию CreateFile со своими параметрами, мне надо перехватить вызов этой функции, вызвать эту же функцию, но со своими параметрами. Как это можно сделать, в каком процессе загружена эта дллка? Вобщем решение такое, что я узнаю процесс, этот процесс загружает мою дллку, которая перехватывает вызов функции CreateFile. Основная проблема определить в каком процессе выполняется дллка-актив иксина. Я думал, что в explorer"e, внедрил туда свой код, кот. перехватывает вызов, но ничего не получилось. Может это так, тогда (если это так) подскажите мне где у меня ошибка.
← →
Rem (2004-10-08 13:04) [13]Ага, спасибо, тут вообщем немного поменялась ситуация. Вообщем все сложно, есть дллка - это актив искина, в этой дллке есть класс, в нем объявлен метод, этот метод вызывает функцию CreateFile со своими параметрами, мне надо перехватить вызов этой функции, вызвать эту же функцию, но со своими параметрами. Как это можно сделать, в каком процессе загружена эта дллка? Вобщем решение такое, что я узнаю процесс, этот процесс загружает мою дллку, которая перехватывает вызов функции CreateFile. Основная проблема определить в каком процессе выполняется дллка-актив иксина. Я думал, что в explorer"e, внедрил туда свой код, кот. перехватывает вызов, но ничего не получилось. Может это так, тогда (если это так) подскажите мне где у меня ошибка.
← →
Digitman © (2004-10-08 13:24) [14]
> это актив искина
"актив искина" - это по сути обычная ДЛЛ .. а ДЛЛ грузится и исполняется в АП затребовавшего ее (тем или иным образом - неважно) процесса
← →
Rem (2004-10-08 14:39) [15]Помогите плз, у меня не получается, вот код
type
PImageDosHeader = ^TImageDosHeader;
_IMAGE_DOS_HEADER = packed record
e_magic: Word;
e_cblp: Word;
e_cp: Word;
e_crlc: Word;
e_cparhdr: Word;
e_minalloc: Word;
e_maxalloc: Word;
e_ss: Word;
e_sp: Word;
e_csum: Word;
e_ip: Word;
e_cs: Word;
e_lfarlc: Word;
e_ovno: Word;
e_res: array[0..3] of Word;
e_oemid: Word;
e_oeminfo: Word;
e_res2: array[0..9] of Word;
e_lfanew: LongInt;
end;
TImageDosHeader = _IMAGE_DOS_HEADER;
IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
//***************************************
PImageDataDirectory = ^TImageDataDirectory;
_IMAGE_DATA_DIRECTORY = record
VirtualAddress: DWORD;
Size: DWORD;
end;
//
TImageDataDirectory = _IMAGE_DATA_DIRECTORY;
IMAGE_DATA_DIRECTORY = _IMAGE_DATA_DIRECTORY;
//
//*************
PImageOptionalHeader = ^TImageOptionalHeader;
_IMAGE_OPTIONAL_HEADER = packed record
Magic: Word;
MajorLinkerVersion: Byte;
MinorLinkerVersion: Byte;
SizeOfCode: DWORD;
SizeOfInitializedData: DWORD;
SizeOfUninitializedData: DWORD;
AddressOfEntryPoint: DWORD;
BaseOfCode: DWORD;
BaseOfData: DWORD;
ImageBase: DWORD;
SectionAlignment: DWORD;
FileAlignment: DWORD;
MajorOperatingSystemVersion: Word;
MinorOperatingSystemVersion: Word;
MajorImageVersion: Word;
MinorImageVersion: Word;
MajorSubsystemVersion: Word;
MinorSubsystemVersion: Word;
Win32VersionValue: DWORD;
SizeOfImage: DWORD;
SizeOfHeaders: DWORD;
CheckSum: DWORD;
Subsystem: Word;
DllCharacteristics: Word;
SizeOfStackReserve: DWORD;
SizeOfStackCommit: DWORD;
SizeOfHeapReserve: DWORD;
SizeOfHeapCommit: DWORD;
LoaderFlags: DWORD;
NumberOfRvaAndSizes: DWORD;
DataDirectory: packed array[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1] of TImageDataDirectory;
end;
TImageOptionalHeader = _IMAGE_OPTIONAL_HEADER;
IMAGE_OPTIONAL_HEADER = _IMAGE_OPTIONAL_HEADER;
PImageNtHeaders = ^TImageNtHeaders;
_IMAGE_NT_HEADERS = packed record
Signature: DWORD;
FileHeader: TImageFileHeader;
OptionalHeader: TImageOptionalHeader;
end;
TImageNtHeaders = _IMAGE_NT_HEADERS;
IMAGE_NT_HEADERS = _IMAGE_NT_HEADERS;
PImage_import_by_name = ^TImage_import_by_mame;
_IMAGE_IMPORT_BY_NAME = packed record
Hint: Word;
Name: Byte;
end;
TImage_import_by_mame = _IMAGE_IMPORT_BY_NAME;
_u1 = packed record
case Integer of
0: (ForwarderString: PByte);
1: (Functionn: PDWORD);
2: (Ordinal: DWORD);
3: (AddressOfData: PImage_import_by_name);
end;
PImageThunkData = ^TImageThunkData;
_IMAGE_THUNK_DATA = packed record
u1: _u1;
end;
TImageThunkData = _IMAGE_THUNK_DATA;
IMAGE_THUNK_DATA = _IMAGE_THUNK_DATA;
_temp_charcteristics = record
case Integer of
0: (Characteristics: DWORD);
1: (OriginalFirstThunk: PImageThunkData);
end;
PImageImportDescriptor = ^TImageImportDescriptor;
_IMAGE_IMPORT_DESCRIPTOR = packed record
t: _temp_charcteristics;
TimeDateStamp: DWord;
ForwarderChain: DWORD;
Name: DWORD;
FirstThunk: PImageThunkData;
end;
TImageImportDescriptor = _IMAGE_IMPORT_DESCRIPTOR;
IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
PPointer = ^Pointer;
function MakePtr(base: Dword; Offset: DWORD): Pointer;
begin
Result := Pointer(Base + Offset);
end;
function InterceptDllCall(hLocalModule: HModule; c_szDllName: Pchar; c_szApiName: PChar;
pApiNew: Pointer; p_pApiOrg: PPointer; pApiToChange: Pointer): Boolean;
var
pDosHeader: PImageDosHeader;
pNtHeader: PImageNtHeaders;
PImportDesc: PImageImportDescriptor;
dwProtect: DWORD;
dwNewProtect: DWORD;
dwAddressToInterCept: DWORD;
pThunk: PImageThunkData;
begin
pDosHeader := PImageDosHeader(hLocalModule);
Result := False;
if (pApiToChange <> nil) then dwAddressToIntercept := DWORD(pApiToChange)
else dwAddressToIntercept := Dword(GetProcAddress(GetModuleHandle(c_szDllName), c_szApiName));
if IsBadReadPtr(Pointer(hLocalModule), sizeof(PImageNtHeaders)) then Exit;
if pDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then exit;
pNtHeader := PImageNtHeaders(MakePtr(DWord(pDOSHeader),DWord(pDOSHeader.e_lfanew)));
if pNTHeader.signature <> IMAGE_NT_SIGNATURE then exit;
pImportDesc := PImageImportDescriptor(MakePtr(hLocalModule,pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Virtual Address));
if (PImportDesc = PImageImportDescriptor(pNtHeader)) then exit;
while (pImportDesc.Name > 0) do
begin
pThunk := PImageThunkData(MakePtr(DWord(hLocalModule), Dword(pImportDesc.FirstThunk)));
while (pThunk.u1.Functionn <> nil) do
begin
if DWord(pThunk.u1.Functionn) = dwAddressToIntercept then
begin
if not IsBadWritePtr(Pointer(@pThunk.u1.Functionn), sizeof(DWORD)) then
begin
if (p_pApiOrg <> nil) then p_pApiOrg^ := Pointer(pThunk.u1.Functionn);
pThunk.u1.Functionn := pApiNew;
Result := True;
end else
begin
if VirtualProtect(Pointer(@pThunk.u1.Functionn), sizeof(DWORD),PAGE_EXECUTE_READWRITE, @dwProtect) then
begin
if (p_pApiOrg <> nil) then p_pApiOrg^ := Pointer(pThunk.u1.Functionn);
pThunk.u1.Functionn := PDWORD(pApiNew);
Result := True;
dwNewProtect := dwProtect;
VirtualProtect(Pointer(@pThunk.u1.Functionn), sizeof(DWORD),dwNewProtect, @dwProtect);
end;
end;
end;
Inc(PThunk);
end;
Inc(pImportDEsc);
end;
end;
← →
Rem (2004-10-08 14:46) [16]Продолжение предыдущего...
var InterceptDllCall : function(hLocalModule: HModule; c_szDllName: Pchar; c_szApiName: PChar;
pApiNew: Pointer; p_pApiOrg: PPointer; pApiToChange: Pointer): Boolean;
type TMyProc= function (lpFileName: PAnsiChar; dwDesiredAccess : Cardinal; dwShareMode : Cardinal;
lpSecurityAttributes : PSecurityAttributes; dwCreationDisposition : Cardinal;
dwFlagsAndAttributes : Cardinal; hTemplateFile : Cardinal): THandle; stdcall;
PTMyProc=^TMyProc;
var OldCreateProc : PTMyProc=nil;
function MapRuleCreateFile(lpFileName: PAnsiChar; dwDesiredAccess : Cardinal; dwShareMode : Cardinal;
lpSecurityAttributes : PSecurityAttributes; dwCreationDisposition : Cardinal;
dwFlagsAndAttributes : Cardinal; hTemplateFile : Cardinal): THandle; stdcall;
begin
Result:=CreatFile(PAnsiChar("c:\TMP.tmp"),1,2,nil,2,4,0);
end;
procedure Start;
begin
CreateFile(PAnsiChar("c:\Before.TMP"),1,2,nil,2,4,0);
InterceptDllCall(hInstance,"Kernel32.dll","CreateFileA", Pointer(@MapRuleCreateFile),PPointer(@OldCreateProc),nil);
{Здесь через интерфейс вызываем функцию из дллки, в которой (дллке) должна вызываться функция CreateFile, но ничего не работает}
end;
← →
Digitman © (2004-10-08 15:17) [17]
> у меня не получается
мы догадываться должны, что у тебя там "не получается" ? у тебя языка нет детально описать проблему ?
← →
Rem (2004-10-08 15:40) [18]Вообщем, не получается перехватить функцию CreateFile, т.е. через интерфейс вызывается метод класса, он в свою очередь вызывает CreateFile, и, вот используя вышеописанный код, мне не удается перехватить вызов CreateFile. Если вы утверждаете, что дллка находится в моем процессе, то функция CreateFile должна перехватываться. Этотим кодом я пробовал перехватывать сообщение MessageBox, все замечательно перехватывался, но MessageBox вызывался из моего процесса. Так вот напрашивается вывод, что дллка загружается не в мой процесс.
← →
Digitman © (2004-10-08 15:47) [19]ты хоть определись, в каком тек.процессе происходит перехват ...
на то есть ф-ции GetCurrentThreadId и MaunThreadId
← →
Rem (2004-10-09 01:22) [20]вот я не могу определить в каком процессе загружена актив икс дллка, чтобы произвести перехват. Я перехватываю в своем процессе, ты утверждаешь, что актив икс дллка загружается в мой процесс, тогда почему не перехватывается функцию вышеописанным кодом?
← →
Rem (2004-10-09 01:31) [21]Вообщем, есть актив икс дллка, в ней описан класс, в этом классе есть метод, этот метод вызывает функцию CreateFile. Мне именно надо перехватить вызов этой функции в этом методе. Имя метода я знаю. Объект этого класса я использую у себя в программе. Явной загрузки дллки, т.е. через LoadLibrary, у меня не было, я получаю доступ к методам через интерфейс.
> ты хоть определись, в каком тек.процессе происходит перехват
> ...
И вот тут вопрос, как я могу определиться в каком тек. процессе идет перехват, если я не знаю в каком процессе загружена актив икс дллка. Если в моем, тогда почему не перехватывается функцию вышеописанным кодом?
← →
Rem (2004-10-11 11:13) [22]Господа, ну промогите мне плз, я в тупике... Может есть другой выход, мне надо сделать так, чтоб не создавался файл с указанным именем или хотя бы удалить его после создания, но удалить его просто нельзя, т.к. он создан не мной и с монопольным доступом.
← →
Erik1 © (2004-10-11 11:41) [23]А может тебе перехватить все вызовы CreateFile, во всех активных процесах? Кроме своего конечно. И если вызов происходит с именем нужного тебе файла то подменяй его. Скорее всего тебе придется перехватить еще ReadFile и WriteFile. Но все это муторно и непонятно. Может проще залезть в Dll и изменить ей имя файла?
← →
Rem (2004-10-11 12:28) [24]
> Может проще залезть в Dll и изменить ей имя файла?
Нет, это не проще т.к. это грубый хак, мне этого нельзя делать, я не для себя пишу, а по поводу всех активных процессов, я пробовал, но также не хочет отлавливать, может у меня ошибка в коде, посмотрите плз, но я пробовал на функции MessageBox - все работает нормально.
← →
Erik1 © (2004-10-11 13:49) [25]В коде у тебя точно ошибка, точнее весь код ошибка. Как я понял ты пытаешся отловить вызов API в своем процессе, а тебе нужно в чужом! Думаю, что это explorer.exe
← →
Rem (2004-10-12 08:30) [26]Я пробовал отлавливать в explorer.exe, но не отлавливается, функцию InterceptDllCall я запихивал в дллку, а в своей проге писал все остальное, плюс еще следующую функцию:
//Процедура подключения дллки к процессу
//pID - идентификатор процесса
//LibName - подключаемая библиотека
procedure AttachDllToProcess(pID: integer; LibName: string);
var ThreadID : Cardinal;
ThreadHndl : THandle;
AllocBuffer : Pointer;
BytesWritten : Cardinal;
ProcAddr : Pointer;
ExitCode : Cardinal;
hProcess : integer;
begin
hProcess:=OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE, false, pID);
if (hProcess=0) then Exit;
AllocBuffer:=VirtualAllocEx(hProcess, nil, length(LibName)+1, MEM_COMMIT, PAGE_READWRITE);
if (AllocBuffer<>nil) then WriteProcessMemory(hProcess, AllocBuffer, PChar(LibName), length(LibName)+1, BytesWritten)
else Exit;
ProcAddr:=GetProcAddress(LoadLibrary(PChar("Kernel32.dll")), PChar("LoadLibraryA"));
ThreadHndl:=CreateRemoteThread(hProcess, nil, 0, ProcAddr, AllocBuffer, 0, ThreadID);
WaitForSingleObject(ThreadHndl, INFINITE);
GetExitCodeThread(ThreadHndl, ExitCode);
CloseHandle(ThreadHndl);
VirtualFreeEx(hProcess, AllocBuffer, 0, MEM_RELEASE);
CloseHandle(hProcess);
end;
//Функция ищет процесс, к кот. надо подключиться и
//вызывает функцию подключения дллки к найденному процессу
function PrepareToAttachToDLL(PathToDll : PAnsiChar):boolean;
var
hSnapshoot: THandle;
pe32: TProcessEntry32;
PathToDLL : PAnsiChar;
hndDLLHandle : THandle;
begin
Result:=false;
//Получаем PID процесса эксплорера
hSnapshoot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshoot = -1) then Exit;
pe32.dwSize := SizeOf(TProcessEntry32);
if (Process32First(hSnapshoot, pe32)) then
repeat
//Пробовал подключать дллку ко всем порцессам,
//закомментировав строку ниже, т.е.
//if pe32.szExeFile="explorer.exe" then
if pe32.szExeFile="explorer.exe" then
begin
//Здесь именно подключаем дллку к найденному процессу
AttachDllToProcess(pe32.th32ProcessID,PathToIntrcptDll);
hndDLLHandle:=LoadLibraryA(PathToDll);
if hndDLLHandle<>0 then
begin
@InterceptDllCall:=GetProcAddress(hndDLLHandle,"InterceptDllCall");
if Addr(InterceptDllCall)<>nil then
InterceptDllCall(pe32.th32ProcessID{HInstance},"Kernel32.dll","CreateFileA", Pointer(@MapRuleCreateFile),PPointer(@OldCreateProc),nil);
end;
CloseHandle(hSnapshoot);
Result:=true;
exit;
end;
until not Process32Next(hSnapshoot, pe32);
CloseHandle (hSnapshoot);
end;
//Переписываем тогда процедуру Start
procedure Start;
var PTH : PAnsiChar;
begin
CreateFile(PAnsiChar("c:\Before.TMP"),1,2,nil,2,4,0);
GetMem(PTH,sizeof("C:\MyLib.dll"))
PTH:="C:\MyLib.dll";
PrepareToAttachToDLL(PTH);
InterceptDllCall(hInstance,"Kernel32.dll","CreateFileA", Pointer(@MapRuleCreateFile),PPointer(@OldCreateProc),nil);
{Здесь через интерфейс вызываем функцию из дллки, в которой (дллке) должна вызываться функция CreateFile, но ничего не работает}
end;
← →
Rem (2004-10-12 09:04) [27]А если попробовать другой путь, не перехват функций, а, например, можно ли удалить файл средствами winapi, если он создан другим процессом с монопольным доступом?
← →
Rem (2004-10-12 10:30) [28]Вообщем, я пробую отслеживать изменения файловой системы при создании файла, вот код, кот. это делает:
procedure ChangeFileSystem;
var ChangeHandle : THandle;
begin
ChangeHandle:= FindFirstChangeNotification(FileName,false, FILE_NOTIFY_CHANGE_FILE_NAME);
if ChangeHandle <> INVALID_HANDLE_VALUE then
while true do
begin
if WaitForSingleObject(ChangeHandle,500) = WAIT_OBJECT_0 then
begin
//Событие...
end;
FindNextChangeNotification(ChangeHandle);
end;
end;
И вот где написано событие, что должно быть? Я определил, что я вызываю функцию создания файла и вызвается эта процедура, но файл еще не создан, т.е. фактическим можно перехватить событие создания файла. А какое событие создания файла?
← →
Юра (2004-10-12 10:48) [29]Хмм. рановато ты за это дело взялся, имхо. Поучи матчасть сначала, хотя бы того же Рихтера.
← →
Erik1 © (2004-10-12 10:49) [30]Ты вобще понимаеш, что твоя функция неможет работать? Если будеш продолжать в такомже духе тебе просто перестанут отвечать. Ты посмотри как осуцествляется перехват у Digitman. Он тут давал пример как это надо делать. Пользуйся поисковиками! Вобщето есть очень простое решение, надо сделать path который будет изменять dll в памяти и менять имя создоваемого файла. Для этого есть спецальные программы по созданию таких пачей.
Или изучи перехват API функций.
← →
Rem (2004-10-12 11:43) [31]Да, я понимаю, извиняюсь если что не так, у Digitman есть функция RtlEnterCriticalSection и RtlLeaveCriticalSection, откуда он их взял, компилятор на них ругается?
← →
Суслик © (2004-10-12 11:56) [32]
> откуда он их взял
прежде чем справшивать сделай сквозной поиск по исходникам, поставляемым с дельфи.
в 99% случаев помогает.
← →
Rem (2004-10-12 13:13) [33]
> прежде чем справшивать сделай сквозной поиск по исходникам
Если б нашел, не спрашивал бы...
← →
Суслик © (2004-10-12 14:07) [34]
> [33] Rem (12.10.04 13:13)
действительно нет.
Это 1%, когда поиск не помогает :(
← →
Rem (2004-10-12 14:25) [35]но, если Rtl убрать, а оставить все остальное, то получается winайпишная функция
← →
Rem (2004-10-12 14:44) [36]У меня ошибка вываливается в процедуре LockLoader, все таки не понятно, откуда взята функция RtlEnterCriticalSection.
← →
Rem (2004-10-12 15:07) [37]Господа, большое спасибо всем за помощь, у меня все получилось!!!
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.11.21;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.06 c