Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.04.20;
Скачать: CL | DM;

Вниз

Си в 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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.025 c
2-1206480203
VR
2008-03-26 00:23
2008.04.20
степень


3-1196068794
Paradise
2007-11-26 12:19
2008.04.20
Перекрытие временных периодов


15-1204899711
Kolan
2008-03-07 17:21
2008.04.20
Чем же все таки работать с базами SQLite?


15-1204617442
Kolan
2008-03-04 10:57
2008.04.20
А можно ли на двух мониторах в паре поставить разное разрешение?


15-1205082091
who
2008-03-09 20:01
2008.04.20
Игорь Шевченко