Форум: "Прочее";
Текущий архив: 2008.04.20;
Скачать: [xml.tar.bz2];
ВнизСи в delphi Найти похожие ветки
← →
xVlad (2008-03-10 07:55) [0]Есть код на Си, я его перевел на delphi. Но работоспособность не сохранилась.
bool RemoveFWHook(char* szDllPath, char* szFuncName) // в szDllPath полный путь к DLL !
{
// получаем указатель на функцию
HMODULE lpBase = LoadLibrary(szDllPath);
LPVOID lpFunc = GetProcAddress(lpBase, szFuncName);
if(!lpFunc)
return false;
// получаем RVA
DWORD dwRVA = (DWORD)lpFunc-(DWORD)lpBase;
// проецируем файл в память
HANDLE hFile = CreateFile(szDllPath,GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
if(INVALID_HANDLE_VALUE == hFile)
return false;
DWORD dwSize = GetFileSize(hFile, NULL);
HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY|SEC_IMAGE, 0, dwSize, NULL);
LPVOID lpBaseMap = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, dwSize);
// указатель на настоящую функцию
LPVOID lpRealFunc = (LPVOID)((DWORD)lpBaseMap+dwRVA);
// изменяем права на доступ и копируем
DWORD dwOldProtect;
BOOL bRes=true;
if(VirtualProtect(lpFunc, 10, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
memcpy(lpFunc, lpRealFunc, 10);
}else{
bRes=false;
}
UnmapViewOfFile(lpBaseMap);
CloseHandle(hMapFile);
CloseHandle(hFile);
return bRes;
}
Мой вариант, он изменен, сразу указана библиотека и функция в остальном вроде все так же.procedure RemoveFWHook;
type
TConnect = function (s: TSocket; var name: TSockAddr; namelen: Integer): Integer; stdcall;
const
szDllPath = "C:\WINNT\system32\wsock32.dll";
szFuncName = "connect";
var
lpBase, hFile, hMapFile: THandle;
lpFunc, lpRealFunc, lpBaseMap: Pointer;
dwRVA, dwSize, dwOldProtect: DWord;
ConnectFunc: TConnect;
Socket: TSocket;
SockAddr: TSockAddr;
WsaData: TWsaData;
begin
lpBase := LoadLibrary(PAnsiChar(szDllPath));
lpFunc := GetProcAddress(lpBase, PAnsiChar(szFuncName));
if lpFunc = nil then
begin
ShowMessage("lpFunc = nil");
Exit;
end;
dwRVA := DWord(lpFunc) - DWord(lpBase);
hFile := CreateFile(PAnsiChar(szDllPath), GENERIC_READ, FILE_SHARE_READ,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if INVALID_HANDLE_VALUE = hFile then
begin
ShowMessage("INVALID_HANDLE_VALUE = hFile");
Exit;
end;
dwSize := GetFileSize(hFile, nil);
hMapFile := CreateFileMapping(hFile, nil, PAGE_READONLY or SEC_IMAGE, 0, dwSize, nil);
lpBaseMap := MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, dwSize);
lpRealFunc := Pointer(DWord(lpBaseMap) + dwRVA);
// if VirtualProtect(lpFunc, 10, PAGE_EXECUTE_READWRITE, dwOldProtect) then
// Move(lpRealFunc, lpFunc, 10);
UnmapViewOfFile(lpBaseMap);
CloseHandle(hMapFile);
CloseHandle(hFile);
WSAStartup(1, WsaData);
@ConnectFunc := lpRealFunc;
ConnectFunc(Socket, SockAddr, 0);
end;
В итоге - в моем случае получаю при вызове lpRealFunc (->ConnectFunc) AV. Что тут не так?
← →
Сергей М. © (2008-03-10 10:17) [1]Ты чего добиться-то хочешь в результате ? Какова цель всех этих приседаний ?
← →
xVlad (2008-03-10 10:31) [2]Я хочу получить-прочитать функцию непосредственно из dll библиотеки файла.
Я так пнял RVA вычисляется коряво, но что не так по сравнению с сишным кодом.
← →
Сергей М. © (2008-03-10 10:41) [3]
> получить-прочитать функцию непосредственно из dll библиотеки
> файла
В смысле ее машкод что ли ?
А нафих он нужен в "сыром" виде, если он позиционно-зависимый ?
← →
Сергей М. © (2008-03-10 11:04) [4]
> если он позиционно-зависимый
И даже если при SEC_IMAGE ты получил образ модуля, настроенного по всем правилам загрузки PE-модулей, обращение к подпрограммам в этом модуле лишено смысла, потому что модуль не инициализирован.
← →
xVlad (2008-03-10 11:21) [5]Бррр.. ничего не понимаю. Тут даже на форуме была ветка с кодом Игоря Шевченко, она не сохранилась правда.
Там был его исходник в котором он заменял функцию на функцию из файла. Правда там он не указывал SEC_IMAGE и расчитывал RVA исходя из заголовков как-то.
Сам код: (жирным я выделил метсто считывания из файла)unit CheckNtDll;
interface
uses
Windows, HsNtDef;
function RealQueryListInformation (InfoClass: Integer; var rc: NTSTATUS;
var ReturnLength: DWORD): Pointer;
function IsNtDllHooked: Boolean;
implementation
uses
SysUtils, NtDll, PeImage, NtStatusDefs;
{$IFDEF VER140}
{$WARN SYMBOL_PLATFORM OFF}
{$ENDIF}
type
TSysCallData = array[0..13] of Byte;
TNtQuerySystemInformation = function (SystemInformationClass: LongInt;
SystemInformation: Pointer; SystemInformationLength: ULONG;
ReturnLength: PDWORD): NTSTATUS; stdcall;
var
FRealQuerySystemInformation: TNtQuerySystemInformation;
function RealQueryListInformation (InfoClass: Integer; var rc: NTSTATUS;
var ReturnLength: DWORD): Pointer;
var
ListSize: Integer;
begin
ListSize := $400; { Начальный размер буфера }
GetMem(Result, ListSize);
rc := FRealQuerySystemInformation(InfoClass, Result, ListSize, @ReturnLength);
while rc = STATUS_INFO_LENGTH_MISMATCH do begin
FreeMem(Result);
ListSize := ListSize * 2;
GetMem(Result, ListSize);
rc := FRealQuerySystemInformation(InfoClass, Result, ListSize,
@ReturnLength);
end;
if rc <> STATUS_SUCCESS then begin
FreeMem(Result);
Result := nil;
end;
end;
procedure MakeRealQS (const SysCallData: TSysCallData);
var
OldProtection: DWORD;
FuncPtr: Pointer;
begin
FuncPtr := VirtualAlloc(nil, $1000, MEM_COMMIT, PAGE_READWRITE);
Win32Check(Assigned(FuncPtr));
Move(SysCallData, FuncPtr^, SizeOf(SysCallData));
Win32Check(VirtualProtect(FuncPtr, SizeOf(SysCallData), PAGE_EXECUTE,
OldProtection));
@FRealQuerySystemInformation := FuncPtr;
end;
function IsNtDllCodeHooked (const FileName: string; ProcOffset: ULONG): Boolean;
var
Image: THSPeImage;
SysCall: TSysCallData;
SysCall2: TSysCallData;
QSPtr: Pointer;
begin
Image := THSPEImage.Create (FileName);
try
Move(Image.RVAData[ProcOffset]^, SysCall, SizeOf(SysCall));
finally
Image.Free;
end;
QSPtr := GetProcAddress(GetModuleHandle("ntdll.dll"),
" NtQuerySystemInformation ");
Move(QSPtr^, SysCall2, SizeOf(SysCall2));
Result := not CompareMem(@SysCall, @SysCall2, SizeOf(SysCall));
if Result then
MakeRealQS (SysCall);
end;
function IsNtDllHooked: Boolean;
const
SDllPath = "%SystemRoot%\system32\ntdll.dll";
var
DllPath: ZString;
HFile, HMap: THandle;
Map: Pointer;
Headers: PImageNtHeaders;
QSysInfo: Pointer;
begin
Result := false;
Win32Check(
ExpandEnvironmentStringsA(SDllPath, DllPath, SizeOf(DllPath)) <> 0);
HFile := CreateFileA(DllPath, GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE);
Win32Check(HFile <> INVALID_HANDLE_VALUE);
try
HMap := CreateFileMappingA(HFile, nil, PAGE_READONLY, 0, 0, nil);
Win32Check(HMap <> 0);
try
Map := MapViewOfFile(HMap, FILE_MAP_READ, 0, 0, 0);
Win32Check(Assigned(Map));
try
Headers := RtlImageNtHeader(HMODULE(Map));
if Assigned(Headers) then
Result :=
Headers.OptionalHeader.ImageBase <> GetModuleHandle("ntdll.dll");
if not Result then begin
QSysInfo := GetProcAddress(GetModuleHandle("ntdll.dll"),
" NtQuerySystemInformation ");
if Assigned(QSysInfo) then begin
Result := (Cardinal(QSysInfo) <=
Headers.OptionalHeader.ImageBase) or (Cardinal(QSysInfo) >
Headers.OptionalHeader.ImageBase +
Headers.OptionalHeader.SizeOfCode);
if not Result then
Result := IsNtDllCodeHooked(DllPath, ULONG(QSysInfo) -
Headers.OptionalHeader.ImageBase);
end else
Result := true;
end;
finally
UnmapViewOfFile(Map);
end;
finally
CloseHandle(HMap);
end;
finally
CloseHandle(HFile);
end;
end;
initialization
finalization
if Assigned(FRealQuerySystemInformation) then
VirtualFree(@FRealQuerySystemInformation, $1000, MEM_DECOMMIT);
end.
← →
Сергей М. © (2008-03-10 11:33) [6]Код ИШ основан на индивидуальных особенностях модуля ntdll, а ты этот код хочешь присобачить к произвольному модулю, не понимая в чем заключаются эти индивидуальные особенности
← →
xVlad (2008-03-10 12:12) [7]Эмм.. а какие индивидуальные особенности?
Я же взял другой код (сишный), который не привязан к ntdll. Но схожесть работы прослеживается. Код Игоря Шевченок был - в пример подмены кода из файла.
← →
Игорь Шевченко © (2008-03-10 12:25) [8]
> Есть код на Си
Выкинь. Код, копирующий первые 10 байт в тело произвольной функции, кроме корзины никуда не годен.
← →
Riply © (2008-03-10 12:26) [9]> [6] Сергей М. © (10.03.08 11:33)
> Код ИШ основан на индивидуальных особенностях модуля ntdll, а ты этот код хочешь присобачить к произвольному модулю,
> не понимая в чем заключаются эти индивидуальные особенности
Когда этот код только появился,
мне (как казалось) удалось его "подогнать" для работы с другими модулями и функциями.
Я ошибалась, пометив эту задачу как решенную, ибо в общем случае это невозможно ?
← →
Сергей М. © (2008-03-10 12:43) [10]
> какие индивидуальные особенности?
Модуль NTDLL загружается сист.загрузчиком в ВАП любого процесса всегда по одному и тому же базовому адресу, при этом условии нет нужды в релокации.
Модуль wsock32 не обладает этой особенностью, поэтому после работы сист.загрузчика машкод модуля будет настроен отн-но фактического базового адреса.
← →
Сергей М. © (2008-03-10 12:44) [11]
> Riply © (10.03.08 12:26) [9]
Конечно ошибалась)
← →
Игорь Шевченко © (2008-03-10 12:47) [12]Riply © (10.03.08 12:26) [9]
допустим, произвольная функция начинается сpush ebp
mov ebp,esp
mov [some_address],some_constant
call [some_imported_reference]
....
В процессе загрузки все адресные ссылки разрешаются загрузчиком. А если просто скопировать код с неразрешенными ссылками, то что произойдет ?
← →
xVlad (2008-03-10 12:48) [13]
> Сергей М. © (10.03.08 12:43) [10]
Спасибо. А вообще реально добиться аналогичной работы с wsock32?
← →
Игорь Шевченко © (2008-03-10 12:49) [14]Сергей М. © (10.03.08 12:43) [10]
> Модуль NTDLL загружается сист.загрузчиком в ВАП любого процесса
> всегда по одному и тому же базовому адресу, при этом условии
> нет нужды в релокации.
Немножко не в этом дело, хотя этот факт тоже имеет место быть.
Мой код основан на том, что в системных вызовах, экспортируемых NTDLL нет ни одной неперещаемой машинной команды. Ну ни единой.
← →
xVlad (2008-03-10 13:03) [15]Игорь Шевченко, я думаю вы подскажете: а каким обазом можно отловить/обойти хук при использовании wsock32?
Если функцию перехватывают через патч IAT или сплайсинг самого кода. У меня единственное пердположение - это искать в начале функции инструкции вида jmp... Но это конечно плохое решение мне так кажется.
← →
Сергей М. © (2008-03-10 13:05) [16]
> Игорь Шевченко © (10.03.08 12:49) [14]
А даже если бы и были оные, то это не меняло бы дело, поскольку и в этом случае копировался бы позиционно-зависимый код, уже настроенный для применения "по месту", что никоим образом не относится к произвольно выбранному модулю, как в случае автора.
> xVlad (10.03.08 12:48) [13]
> реально добиться аналогичной работы с wsock32?
А зачем ?
← →
boriskb © (2008-03-10 13:15) [17]
> А зачем ?
> Игорь Шевченко ©
Игорь, а что тебя подвигло на эти "кренделя" с NTDLL ?
← →
Игорь Шевченко © (2008-03-10 13:24) [18]boriskb © (10.03.08 13:15) [17]
> Игорь, а что тебя подвигло на эти "кренделя" с NTDLL ?
Какой-то вопрос на мастаках в WinAPI сколько-то лет назад
← →
Riply © (2008-03-10 13:28) [19]> [10] Сергей М. © (10.03.08 12:43)
> Модуль NTDLL загружается сист.загрузчиком в ВАП любого процесса всегда по одному и тому же базовому адресу,
> при этом условии нет нужды в релокации.
> Конечно ошибалась)
> [12] Игорь Шевченко © (10.03.08 12:47)
> допустим, произвольная функция начинается с
> push ebp
> mov ebp,esp
> mov [some_address],some_constant
> call [some_imported_reference]
....
> В процессе загрузки все адресные ссылки разрешаются загрузчиком.
> А если просто скопировать код с неразрешенными ссылками, то что произойдет ?
Мне сейчас трудно вспомнить, как я делала.
(открывать проект, вспоминать и разбираться нет возможности,
т.к. у меня файл неправильно записывается ! Какие тут еще могут быть "релокации" :))
Так что могу и что-то путать.
Действовала так:
Подгружала подопытный модуль. Мапила его.
Затем сравнивала и высчитывала смещения не только для базового адреса загрузки модуля,
но и для экспортируемых функций.
(Игорь, кстати, мне в этом очень помог. В том числе дал и "расширенный" PeImage для этого :)
Тестировалось (перехватывалось и ловился перехват) на ntdll, kernel32, user32,
и еще каких - то библиотеках (не помню, но "основных").
Все работало.
Неужели, когда я научусь записывать в файл, мне надо будет срова возвращаться к этому ?
Не пугайте :)
← →
Сергей М. © (2008-03-10 13:52) [20]
> Riply © (10.03.08 13:28) [19]
> у меня файл неправильно записывается ! Какие тут еще могут
> быть "релокации"
И верно - какое отношение огородная бузина может иметь к киевскому дядьке ?)
← →
xVlad (2008-03-10 15:11) [21]
> Сергей М. © (10.03.08 13:05) [16]
</I
> А зачем ?
>
Ну мне теперь стало интересно. Да и например хочу обойти (не поймать и узнать) перехватчик установленный на функцию из wsock32.
← →
Сергей М. © (2008-03-10 15:33) [22]Вряд ли какой идиот будет ставить такой хук, да еще на упомянутую тобой ф-цию)
← →
Сергей М. © (2008-03-10 15:35) [23]Вряд ли какой идиот будет ставить такой хук, да еще на упомянутую тобой ф-цию)
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2008.04.20;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.038 c