Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Получение адреса функции по таблице экспорта.


Страницы:   1 2

Riply ©   (2006-12-07 20:02:00) 

Здравствуйте !
Пытаюсь "замапить" Dll и получить адрес функции по ее имени.
Функцию найти удается, но ее адрес (вот негодяй) не хочет совпадать
с адресом, полученным при помощи GetProcAddress - GetModuleHandle.
Я понимаю, что они не обязаны совпадать, но иногда ведь должны :)
Что я делаю не так ? ( Надеюсь не все :).
type
PDWordArray = ^TDWordArray;
TDWordArray = array [0..$FFFFF] of DWord;

function Get_ExportProcAddres(const pMap: Pointer; const ProcName: string; var Addr: DWord): Boolean;
var
pExportDirectory: PImageExportDirectory;
pImSectHearder: PImageSectionHeader;
pNameRVAs: PDWordArray;
ImageName: string;
cbDirSize: DWord;
i: integer;
begin
Result:= False;
pExportDirectory := ImageDirectoryEntryToData(pMap,
                     False, IMAGE_DIRECTORY_ENTRY_EXPORT, cbDirSize);
if (pExportDirectory <> nil) then
 begin
  pImSectHearder := nil;
  pNameRVAs:= ImageRvaToVa(ImageNtHeader(pMap), pMap,
              DWord(pExportDirectory^.AddressOfNames), pImSectHearder);

  for i := 0 to pExportDirectory^.NumberOfNames - 1 do
   begin
    pImSectHearder := nil;
    ImageName := PChar(ImageRvaToVa(ImageNtHeader(pMap), pMap, pNameRVAs^[i], pImSectHearder));
    if CompareText(ProcName, ImageName) = 0 then
     begin
      Result:= True;
      Addr:= pNameRVAs^[i];
      Break;
     end;
   end;
 end;
end;

function TestFunctAddress(const pModName, pProcName: PChar): Boolean;
var
HFile, HMap: THandle;
Map: Pointer;
QSysInfo: Pointer;
cbAddr: DWord;
begin
Result := false;
HFile := CreateFileA(pModName, 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
     QSysInfo := GetProcAddress(GetModuleHandle(pModName), pProcName);
      if Assigned(QSysInfo) then
       if Get_ExportProcAddres(Map, pProcName, cbAddr) then
        begin
         Result:= (cbAddr = DWord(QSysInfo) - GetModuleHandle(pModName));
         ShowMessage(IntToStr(cbAddr) + #13#10 + IntToStr(DWord(QSysInfo) - GetModuleHandle(pModName)));
        end;
    finally
      UnmapViewOfFile(Map);
    end;
  finally
    CloseHandle(HMap);
  end;
finally
  CloseHandle(HFile);
end;
end;

И вызов : TestFunctAddress('C:\Windows\system32\ntdll.dll', 'NtQuerySystemInformation');


Riply   (2006-12-08 15:48:00) [21]

> [11] Сергей М. ©   (08.12.06 08:38)
>Поясни, зачем тебе понадобилось это самое "замапить" ..
>Тебе требуется перехватить вызов некоей ф-ции ?
С точностью до наоборот :)
Есть кем-то перехваченная функция.
А это попыка получить адрес настоящей.
Ну, хотя бы, не адрес а смещение, которое, в неперехваченом варианте,
равно GetProcAddress(GetModuleHandle(NtDll), NtQuerySysInfo) - GetModuleHandle(NtDll)
Сумбурно, но что делать :)


oxffff   (2006-12-08 09:19:00) [22]


> Riply ©   (08.12.06 01:52) [10]
> >[9] oxffff © (08.12.06 00:52)
> >Тогда, что у вас не получается?
> Давай без дискриминации :)


Абсолютно без  дискриминации.
Просто это у меня вызывает уважение.


Сергей М.   (2006-12-08 08:38:00) [23]


> Riply


Поясни, зачем тебе понадобилось это самое "замапить" ..

Тебе требуется перехватить вызов некоей ф-ции ?


Riply   (2006-12-08 01:52:00) [24]

>[9] oxffff © (08.12.06 00:52)
>Тогда, что у вас не получается?
Давай без дискриминации :)
Суть вот в чем:
Игорь Шевченко приводил примерно такой код для определения перехвачена
функция или нет:
HFile := CreateFileA(DllPath, GENERIC_READ, FILE_SHARE_READ, nil,
  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE);
try
  HMap := CreateFileMappingA(HFile, nil, PAGE_READONLY, 0, 0, nil);
  try
    Map := MapViewOfFile(HMap, FILE_MAP_READ, 0, 0, 0);
    try
      Headers := RtlImageNtHeader(HMODULE(Map));
      if Assigned(Headers) then
       begin
        Result := Headers.OptionalHeader.ImageBase <> GetModuleHandle(Lib_NtDll);
        if not Result then
         begin
          QSysInfo := GetProcAddress(GetModuleHandle(Lib_NtDll), _NtQuerySysInfo);
          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;
       end;
    finally
      UnmapViewOfFile(Map);
    end;
  finally
    CloseHandle(HMap);
  end;
finally
  CloseHandle(HFile);
end;

Так вот, интересует как можно вычислить смещение
ULONG(QSysInfo) - Headers.OptionalHeader.ImageBase
если мы не прошли условие:
(Cardinal(QSysInfo) <= Headers.OptionalHeader.ImageBase)
 or (Cardinal(QSysInfo) > Headers.OptionalHeader.ImageBase + Headers.OptionalHeader.SizeOfCode);
Игорь посоветовал смотреть в сторону экспорта.


oxffff   (2006-12-08 00:52:00) [25]

А вы девушка?

Тогда, что у вас не получается?


oxffff   (2006-12-08 00:51:00) [26]

Слушай а ты не ошибся таблицами.
Почему таблица экспорта?


oxffff   (2006-12-08 00:49:00) [27]

Таблица OriginalFirstThunk во время работы программы не меняется.

Загрузчик заполняет таблицу по FirstThunk.

Поясни, что с чем ты сравниваешь и что не получается?


oxffff   (2006-12-08 00:46:00) [28]

Поясни какие у тебя проблемы.

В секции импорта 2 таблицы
одна это OriginalFirstThunk
Вторая FirstThunk

C какой ты сравниваешь?

И что ты вообще сравниваешь?


jack128   (2006-12-08 00:29:00) [29]

собственно результаты, возвращаемые твой функций об этом и говорят.. Всё таки 32К - слишком маленький адрес...


jack128   (2006-12-08 00:26:00) [30]

jack128 ©   (08.12.06 0:26) [3]
Я не спец, носудя по MSDN:


jack128   (2006-12-08 00:26:00) [31]

Хем.. Я не спец, судя по MSDN:
The ImageRvaToVa function locates a relativevirtual address (RVA)
выделенное слово переводится, как относительный...


Riply   (2006-12-07 21:23:00) [32]

>[1] jack128 ©   (07.12.06 20:56)
>Один и тот же файл замапин два раза (один раз виндой, другой - тобой) но замапин по разным адресам..
А я сравниваю не адреса "мапов", а адреса функций, найденых в этих "мапах"
Кстати, в приведенном тобой примере, они отлично совпадают .
function TestAddress: Boolean;
const
pModName = 'C:\Windows\system32\ntdll.dll';
var
hFile, hMap1, hMap2: THandle;
Addr1, Addr2: Pointer;
fs: TFileStream;
Proc1, Proc2: DWord;
begin
Result:= False;
HFile := CreateFileA(pModName, GENERIC_READ, FILE_SHARE_READ, nil,
  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE);
try
  hMap1 := CreateFileMappingA(HFile, nil, PAGE_READONLY, 0, 0, nil);
  hMap2 := CreateFileMappingA(HFile, nil, PAGE_READONLY, 0, 0, nil);
  try
    Addr1 := MapViewOfFile(HMap1, FILE_MAP_READ, 0, 0, 0);
    Addr2 := MapViewOfFile(HMap2, FILE_MAP_READ, 0, 0, 0);
    try
     Get_ExportProcAddres(Addr1, 'NtQuerySystemInformation', Proc1);
     Get_ExportProcAddres(Addr2, 'NtQuerySystemInformation', Proc2);
     Result:= Proc1 = Proc2;
    finally
     UnmapViewOfFile(Addr1); UnmapViewOfFile(Addr2);
    end;
  finally
    CloseHandle(hMap1); CloseHandle(hMap2)
  end;
finally
 CloseHandle(HFile);
end;
end;

P.S. Функцию Get_ExportProcAddres см. выше


jack128   (2006-12-07 20:56:00) [33]

Riply ©   (07.12.06 20:02)
Я понимаю, что они не обязаны совпадать, но иногда ведь должны :)

Хм. А почему должны?  Один и тот же файл замапин два раза (один раз виндой, другой - тобой) но замапин по разным адресам..

const
 FileName = 'F:\p2p на E\download\Setup.exe';
var
 hMap1, hMap2: THandle;
 Addr1, Addr2: Pointer;
 fs: TFileStream;
begin
 fs := TFileStream.Create(FileName, fmOpenRead);
 try
   hMap1 := CreateFileMappingA(fs.Handle, nil, PAGE_READONLY, 0, 0, nil);
   hMap2 := CreateFileMappingA(fs.Handle, nil, PAGE_READONLY, 0, 0, nil);
   try
     Addr1 := MapViewOfFile(HMap1, FILE_MAP_READ, 0, 0, 0);
     Addr2 := MapViewOfFile(HMap2, FILE_MAP_READ, 0, 0, 0);
     try
       Assert(Addr1 = Addr2);
     finally
       UnmapViewOfFile(Addr1); UnmapViewOfFile(Addr2);
     end;
   finally
     CloseHandle(hMap1); CloseHandle(hMap2)
   end;
 finally
   fs.Free;
 end;
end;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо