Сейчас на форуме: UniSoft, bartolomeo (+6 невидимых) |
eXeL@B —› Программирование —› Таблица экспорта NTDLL |
Посл.ответ | Сообщение |
Ранг: 419.0 (мудрец), 647thx Активность: 0.46↗0.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 другой функции. С чем связана такая несостыковка? (винда сортирует по имени?) |
|
Создано: 13 января 2011 10:55 · Личное сообщение · #2 |
Ранг: 419.0 (мудрец), 647thx Активность: 0.46↗0.51 Статус: Участник "Тибериумный реверсинг" |
Создано: 13 января 2011 11:26 · Личное сообщение · #3 Hellspawn пишет: ничего не должно съезжать. Ну если корректно все дергается значит верный. (Хотя я два раза срезал: по Rtl префикса, затем до Zw. Однако срезал корректно) 1. adr := dwImageBase + AddressOfFunctions[AddressOfNameOrdinals[i]]) Но съезжает все таки! Причем едет с самой первого экспорта. Я просто подумал: когда в Ольке смотриш, сортировка по имени - первыми идут функции с нижней чертой. Может таблица строится отправляя их в самый вниз. |
|
Создано: 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.46↗0.51 Статус: Участник "Тибериумный реверсинг" |
Создано: 13 января 2011 14:16 · Личное сообщение · #5 Rouse_ не delphi) асм вставка вот так: Code:
УТОЧНЕНИЕ: - СЪЕЗЖАТЬ НАЧИНАЕТ С НАЧАЛА ЭКСПОРТА И ДО... НАЧИНАЯ С Zw ВСЕ ПРАВИЛЬНО(во всяком случае на XP-Vista, на 7ке все равно уходит на 0xC вперед) |
|
Создано: 13 января 2011 14:36 · Личное сообщение · #6 |
|
Создано: 13 января 2011 14:51 · Личное сообщение · #7 |
|
Создано: 13 января 2011 15:41 · Личное сообщение · #8 |
|
Создано: 14 января 2011 06:22 · Личное сообщение · #9 |
|
Создано: 14 января 2011 08:54 · Личное сообщение · #10 |
eXeL@B —› Программирование —› Таблица экспорта NTDLL |