Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
15-1204805445
webSQLNeederr
2008-03-06 15:10
2008.04.20
Функция транслита


2-1206197229
hprx
2008-03-22 17:47
2008.04.20
Скорость набора


15-1204691569
Skyle
2008-03-05 07:32
2008.04.20
Вывод "Hello Hello" с помощью esc-последовательностей


2-1206598873
zdm
2008-03-27 09:21
2008.04.20
Отслеживание исполнения


11-1188223121
Ned
2007-08-27 17:58
2008.04.20
Консольные приложения





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский