Сейчас на форуме: UniSoft, bartolomeo (+6 невидимых)

 eXeL@B —› Программирование —› Таблица экспорта NTDLL
Посл.ответ Сообщение

Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 13 января 2011 10:44
· Личное сообщение · #1

Вместо GetProcAddress, вручную разбираю таблицу экспорта NTDLL на предмент нужных Native API. Алгоритм рабочий: гружу EXPORT ADDRESS TABLE и EXPORT NAME POINTER'S, в цикле перебираю имена по EXPORT NAME POINTER'S, если пасьянс сходится, из EXPORT ADDRESS TABLE достаю сырое смещение, накидываю module handle ну и получаю нужный адрес. Однако, одно НО: реальное текущее смещение в EXPORT ADDRESS TABLE съезжает вверх от текущего EXPORT NAME POINTER'S на 0xC (для XP-Vista) и 0x2C(для Win7). Одним словом если это не учитывать, получаем RVA другой функции. С чем связана такая несостыковка? (винда сортирует по имени?)




Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 13 января 2011 10:55
· Личное сообщение · #2

алгоритм точно верный? перебираете AddressOfNames по именам и если совпало, то из AddressOfFunctions дёргаете элемент AddressOfNameOrdinals.

Code:
  1. adr := dwImageBase + AddressOfFunctions[AddressOfNameOrdinals[i]])

ничего не должно съезжать.

-----
[nice coder and reverser]




Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 13 января 2011 11:26
· Личное сообщение · #3

Hellspawn пишет:
ничего не должно съезжать.

Ну если корректно все дергается значит верный. (Хотя я два раза срезал: по Rtl префикса, затем до Zw. Однако срезал корректно)
1. adr := dwImageBase + AddressOfFunctions[AddressOfNameOrdinals[i]])
Но съезжает все таки! Причем едет с самой первого экспорта.
Я просто подумал: когда в Ольке смотриш, сортировка по имени - первыми идут функции с нижней чертой. Может таблица строится отправляя их в самый вниз.



Ранг: 35.1 (посетитель), 1thx
Активность: 0.010
Статус: Участник

Создано: 13 января 2011 11:50
· Личное сообщение · #4

Хм, а вот так:

program Project1;

{$APPTYPE CONSOLE}

uses
Windows,
SysUtils;

var
FuncName: AnsiString;
pNtHeaders: PImageNtHeaders;
ExportAddr: TImageDataDirectory = (VirtualAddress: 0; Size: 0);
ImageBase: DWORD;
IED: PImageExportDirectory;
I: Integer;
FuntionAddr: DWORD;
NamesCursor: PDWORD;
OrdinalCursor: PWORD;
Ordinal: DWORD;
begin
ImageBase := GetModuleHandle('NTDLL.DLL');

if PWord(ImageBase)^ = IMAGE_DOS_SIGNATURE then
begin
// проверка заголовков
pNtHeaders := Pointer(ImageBase +
DWORD(PImageDosHeader(ImageBase)^._lfanew));
ExportAddr.VirtualAddress := 0;
ExportAddr.Size := 0;
if (pNtHeaders^.Signature = IMAGE_NT_SIGNATURE) and
(pNtHeaders^.FileHeader.Machine = IMAGE_FILE_MACHINE_I386) then
begin
// получаем указатель на таблицу экспорта
ExportAddr := pNtHeaders.OptionalHeader.DataDirectory[
IMAGE_DIRECTORY_ENTRY_EXPORT];
if ExportAddr.VirtualAddress <> 0 then
Inc(ExportAddr.VirtualAddress, ImageBase)
else
ExportAddr.Size := 0;
end;
end;

if (ImageBase = 0) or (ExportAddr.VirtualAddress = 0) then Exit;
IED := PImageExportDirectory(ExportAddr.VirtualAddress);
I := 1;
NamesCursor := Pointer(ImageBase + DWORD(IED^.AddressOfNames));
OrdinalCursor := Pointer(ImageBase + DWORD(IED^.AddressOfNameOrdinals));
while I < Integer(IED^.NumberOfNames) do
begin
// получаем имя функции
FuncName := PAnsiChar(ImageBase + PDWORD(NamesCursor)^);
// Смотрим номер функции в таблице ординалов
Ordinal := OrdinalCursor^ + IED^.Base;
// Через ординал вычисляем реальный адрес функции
FuntionAddr := ImageBase + DWORD(IED^.AddressOfFunctions);
FuntionAddr := ImageBase + PDWORD(FuntionAddr + (Ordinal - 1) * 4)^;
Writeln(FuncName, ' addr: 0x', IntToHex(FuntionAddr, 8));
Inc(I);
Inc(NamesCursor);
Inc(OrdinalCursor);
end;
Readln;
end.



Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 13 января 2011 14:16
· Личное сообщение · #5

Rouse_
не delphi) асм вставка
вот так:
Code:
  1.          ADD EDI, 0xC // <- если не писать, на выходе RtlOpenCurrentUser не получиться! до этого  EXPORT ADDRESS TABLE ==EXPORT NAME POINTER'S
  2.          MOV ECX, DWORD PTR DS:[EDI-4] //сырой оффсет
  3.          ADD ECX, EAX //до RVA
  4.          MOV Rtl_OpenCurrUser_Spec,ECX //сохраняем
  5. //срез до Zw префикса
  6.          ADD EDI, 0x1D4 //выравнивание по EXPORT ADDRESS TABLE
  7.            ADD ESI, 0x1E0 //выравнивание по EXPORT NAME POINTER'S (с учетом 0xC выше снова EXPORT ADDRESS TABLE ==EXPORT NAME POINTER'S)
  8.            ADD EBX, 0x78 //выравнивание по количеству оставшихся объектов в таблице
  9.            MOV CH, 0x5A // буква Z
  10. NEXT_ITERATION_when_Zw: //цикл с перечислителем Zw префикса

УТОЧНЕНИЕ: - СЪЕЗЖАТЬ НАЧИНАЕТ С НАЧАЛА ЭКСПОРТА И ДО... НАЧИНАЯ С Zw ВСЕ ПРАВИЛЬНО(во всяком случае на XP-Vista, на 7ке все равно уходит на 0xC вперед)




Ранг: 116.6 (ветеран), 8thx
Активность: 0.050
Статус: Участник

Создано: 13 января 2011 14:36
· Личное сообщение · #6

Rouse_ пишет:
FuntionAddr := ImageBase + PDWORD(FuntionAddr + (Ordinal - 1) * 4)^;

Вместо "1" должно быть IED.Base



Ранг: 35.1 (посетитель), 1thx
Активность: 0.010
Статус: Участник

Создано: 13 января 2011 14:51
· Личное сообщение · #7

Угу, пасиб, учту на будующее...




Ранг: 116.6 (ветеран), 8thx
Активность: 0.050
Статус: Участник

Создано: 13 января 2011 15:41
· Личное сообщение · #8

Rouse_
Не - у тебя все правильно, это я уже гоню )



Ранг: 39.6 (посетитель), 21thx
Активность: 0.020
Статус: Участник

Создано: 14 января 2011 06:22
· Личное сообщение · #9

ELF_7719116
ничего никуда не съезжает и никаких магических цифирек добавлять не надо, ищи ошибку у себя.



Ранг: 65.4 (постоянный), 10thx
Активность: 0.020
Статус: Участник

Создано: 14 января 2011 08:54
· Личное сообщение · #10

Не может быть это проблема с выравниваем структур или настройками компиляции? И в СЯХ и в МАСМе парсование уже давным давно писал никаких проблем нету ...


 eXeL@B —› Программирование —› Таблица экспорта NTDLL
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати