Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 2002.11.04;
Скачать: [xml.tar.bz2];

Вниз

Таблица импорта   Найти похожие ветки 

 
Almaz   (2002-09-01 02:42) [0]

Столкнулся с такой проблемой: получаю адрес первого элемента таблицы импорта своего приложения, при этом поле Name = 0. Согласно MSDN, если у элемента таблицы импорта Name == NULL, то это конечный элемент списка. Т.е., если верить MSDN - таблица импорта моего приложения пуста !!! Но это ерунда, т.к. приложение не может не импортировать функции ни из одной DLL !

В дополнение к сказанному, код:
var
ulSize: ULONG;
Image: PIMAGE_IMPORT_DESCRIPTOR;
Name: PChar;
Module: HMODULE;
begin
Image := ImageDirectoryEntryToData(Pointer(hInstance), TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, @ulSize);
if Image <> nil then
begin
while Image.Name <> 0 do
begin
Name := PChar(Module + Image.Name);
ListBox1.Items.Add(Name);

Image := Pointer(Integer(Image) + sizeof(IMAGE_IMPORT_DESCRIPTOR));
end;
end;
end;


 
first_aid   (2002-09-02 09:35) [1]

Приветствую.

А как у тебя проканало: Name := PChar(Module + Image.Name), по моему должно быть: Name := PChar(Module + Image^.Name);

Всего наилучшего.


 
Ketmar   (2002-09-02 10:17) [2]

2Almaz:
лично я никогда не пользовался ImageHlp, потому не знаю. при попытке проверить ваш код мне сказали, что PIMAGE_IMPORT_DESCRIPTOR - это чушь несусветная, и Дельфи с ней не знакома :-). в файлах этого тоже не обнаружилось.
если хотите, могу прислать свою древнюю (правда, рабочую :-) библиотеку для чтения всяких интересностей из PE-шников.

2first_aid:
умная Дельфи вполне может догадаться вставить циркумфлекс (словечко! :-). можете проверить.

Satanas Nobiscum! 02-Sep-XXXVII A.S.


 
paul_shmakov   (2002-09-02 15:17) [3]

2 Almaz:
что с вашим кодом - тоже не могу сказать, т.к. не знаю, что такое ImageDirectoryEntryToData.

я о другом хочу предупредить - когда у Вас все таки получится получить нормальный адрес IMAGE_IMPORT_DESCRIPTOR, то столкнетесь со следующей проблемой:
в IMAGE_IMPORT_DESCRIPTOR есть два поля - OriginalFirstThunk и FirstThunk. оба указывают на массивы IMAGE_THUNK_DATA одинакового размера.
первый массив (OriginalFirstThunk) содержит информацию об импортируемых функциях. загрузчик использует этот массив для получения адресов импортируемых функций. эти адреса он сохраняет во второй массив (FirstThunk).
такое поведение документировано в msdn.

но в borland решили оптимизировать расход памяти. если подумать, то массив OriginalFirstThunk нужен только во время загрузки. во время работы он уже не нужен.
поэтому они выкинули первый массив, а FirstThunk выполняет сразу две функции - до загрузки в нем информация об импортируемых функциях, после - адреса этих функций.
вот так, такая оптимизация. и плюют они на msdn.

когда будете перечислять список импортируемых функций, нужно сначала проверить, а не вырезан ли этот первый массив. у всех delphi программ он будет вырезан.
если не вырезан, то крутите цикл while, пока очередной OriginalFirstThunk не будет nil. если вырезан - то крутите, пока очередной FirstThunk не будет nil.

bool stripped = iid.OriginalFirstThunk == NULL;
PIMAGE_THUNK_DATA pitd = stripped ? iid.FirstThunk : iid.OriginalFirstThunk;

while(*pitd != NULL)
{
// ....
++pitd;
}

примерно так.


 
Ученик   (2002-09-02 15:32) [4]

program Project2;

uses
SysUtils, Windows;

type
TImageImportDescriptor = packed record
OriginalFirstThunk : DWORD;
TimeDateStamp : DWORD;
ForwarderChain : DWORD;
Name : DWORD;
FirstThunk : DWORD;
end;
PImageImportDescriptor = ^TImageImportDescriptor;

TImageThunkData32 = packed record
_function : PDWORD;
end;
PImageThunkData = ^TImageThunkData32;

type
PPointer = ^Pointer;

function InterceptDllCall(
hLocalModule : HMODULE;
c_szDllName : PChar;
c_szApiName : PChar;
pApiNew : Pointer;
p_pApiOrg : PPointer;
pApiToChange : Pointer) : Bool;
var
pDOSHeader : PImageDosHeader;
pNTHeader : PImageNtHeaders;
pImportDesc : PImageImportDescriptor;
dwProtect : DWORD;
bSuccess : BOOL;
pThunk : PImageThunkData;
dwNewProtect : DWORD;
dwAddressToIntercept : DWORD;
begin
Result := False;
pDOSHeader := PImageDosHeader(hLocalModule);
bSuccess := FALSE;

if (pApiToChange <> nil) then
dwAddressToIntercept := DWORD(pApiToChange)
else
dwAddressToIntercept := DWORD(GetProcAddress(GetModuleHandle(c_szDllName), c_szApiName));

if IsBadReadPtr(Pointer(hLocalModule), sizeof(TImageNtHeaders)) then
Exit;
if (pDOSHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then
Exit;
pNTHeader := PImageNtHeaders(DWORD(pDOSHeader) + DWORD(pDOSHeader^._lfanew));
if pNTHeader^.Signature <> IMAGE_NT_SIGNATURE then
Exit;

pImportDesc := PImageImportDescriptor(DWORD(hLocalModule) +
DWORD(pNTHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));

if DWORD(pImportDesc) = DWORD(pNTHeader) then
Exit;

while (pImportDesc^.Name <> 0) do begin
pThunk := PImageThunkData(DWORD(hLocalModule) + DWORD(pImportDesc^.FirstThunk));
while (pThunk^._function <> nil) do begin
if (DWORD(pThunk^._function) = dwAddressToIntercept) then begin
if not IsBadWritePtr(@pThunk^._function, sizeof(DWORD)) then begin
if (p_pApiOrg <> nil) then
p_pApiOrg^ := pThunk^._function;
pThunk^._function := pApiNew;
bSuccess := TRUE;
end else begin
if VirtualProtect(@pThunk^._function, sizeof(DWORD),
PAGE_EXECUTE_READWRITE, dwProtect) then begin
if (p_pApiOrg <> nil) then
p_pApiOrg^ := pThunk^._function;
pThunk^._function := pApiNew;
bSuccess := TRUE;
dwNewProtect := dwProtect;
VirtualProtect(@pThunk^._function, sizeof(DWORD), dwNewProtect, dwProtect)
end
end;
end;
Inc(PChar(pThunk), SizeOf(TImageThunkData32));
end;
Inc(PChar(pImportDesc), SizeOf(TImageImportDescriptor));
end;
Result := bSuccess;
end;

type
TMessageBox = function (Wnd : HWND;
lpText : PChar;
lpCaption : PChar;
uType : UINT) : Integer; stdcall;

var
p_fnMessageBoxOrg : Pointer = nil;

function MyMessageBox(Wnd : HWND;
lpText : PChar;
lpCaption : PChar;
uType : UINT) : Integer; stdcall;
begin
if (p_fnMessageBoxOrg = nil) then
Result := 0
else
Result := TMessageBox(p_fnMessageBoxOrg)(Wnd, lpCaption, lpText, uType)
end;

var
c_szTitle : PChar;
uStyle : UINT;
begin
c_szTitle := "Перехват функций API";
uStyle := MB_OK or MB_ICONHAND or MB_SYSTEMMODAL;
MessageBox(0, "Нормальный текст", c_szTitle, uStyle);
InterceptDllCall(hInstance, "user32.dll", "MessageBoxA",
@MyMessageBox, @p_fnMessageBoxOrg, nil);
MessageBox(0, "Текст и заголовок поменялись", c_szTitle, uStyle);
InterceptDllCall(hInstance, "user32.dll", "MessageBoxA",
p_fnMessageBoxOrg, nil, @MyMessageBox);
MessageBox(0, "Снова нормальный текст", c_szTitle, uStyle);
end.



 
Almaz   (2002-09-02 23:18) [5]

Благодарю всех за обсуждение, но вопрос уже разрешился - вся проблема была в том, что я просто банально ошибся в описании структуры IMAGE_IMPORT_DESCRIPTOR.

>paul_shmakov © (02.09.02 15:17)
Особая благодарность за ценный комментарий.

Удачи.



Страницы: 1 вся ветка

Форум: "Система";
Текущий архив: 2002.11.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.009 c
1-11232
AL2002
2002-10-25 11:07
2002.11.04
ListBox. Его размер, когда разворачиваем.


1-11314
irmantukas
2002-10-23 20:29
2002.11.04
Как закрыть прогу?


1-11312
Eugene_post
2002-10-23 20:15
2002.11.04
Никто не знает как посчитать контрольную сумму файла?


8-11342
Саня
2002-07-11 11:38
2002.11.04
Как перевести RGB в формат байт


14-11470
Ketmar
2002-10-16 10:55
2002.11.04
чего только не найдешь на старых компактах...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский