|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 14, 2004 23:53:49 Ищется программа, которая, получив на вход PE файл, и, скажем, def файл, выдаст на выход PE файл с таблицей экспорта по именам. Также, для полноты, хотелось бы иметь аналогичную утилиту для таблицы импорта. Буду признателен за любую конкретную информацию, особенно если будут еще и исходники. PS: Afaik, DLL forwarders не работают по ординалам, так что в данном случае, входной def файл может быть любым, например состоящим из имен типа f0, f1, .... PS/2: Прииенение DLL forwarders единственно приемлемо в данной ситуации, так что обсуждению не подлежит. |
|
|
Дата: Авг 16, 2004 12:26:17 > PS: Afaik, DLL forwarders не работают по ординалам, так что в данном случае Почему не работают? kernel.#10 |
|
|
Дата: Авг 17, 2004 16:37:54 2 Dr. Golova: Спасибо огромнейшее! Такого синтаксиса я нигде не встречал. Также большой THANX 2 Red Plait за его прекрасный DLL Wrapper Wizard на Perl. 2 Volodya: Как поведет себя NT-подобный loader? Однако, я, тем временем, почти уже написал свой tool. Т.к. Вы, уважаемый Volodya, судя по замечательному циклу статей "Об упаковщиках в последний раз", являетесь специалистом по NT-подобному loaderу, хотелось бы кое-что уточнить и подтвердить некоторые догадки. (Реально они работают, во всяком случае у меня на NT4 Workstation SP/2, но хотелось бы подтвердить теоритически и узнать насчет кросс-платформенности) Рассмотрим ситуацию: секция экспорта находится где-то в середине файла. Как поведет себя loader, если AddressOfFunctions, AddressOfNames, AddressOfNameOrdinals в IMAGE_EXPORT_DIRECTORY сылаются на другую секцию, скажем, в конце файла? Или правильнее будет поправить DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] в IMAGE_OPTIONAL_HEADER32, так, чтоб он целиком ссылался на модифицированную копию IMAGE_EXPORT_DIRECTORY где-нибудь в последней секции файла? И еще вопрос, какие размеры нужно править при увеличении объема файла (IMAGE_OPTIONAL_HEADER32.SizeOfImage, кратно IMAGE_OPTIONAL_HEADER32.SectionAlignment IMAGE_SECTION_HEADER.Misc.VirtualSize, кратно IMAGE_OPTIONAL_HEADER32.SectionAlignment IMAGE_SECTION_HEADER.PhysicalSize кратно IMAGE_OPTIONAL_HEADER32.FileAlignment), или что-то еще? И последнее: какая правильная формула пересчета RVA в File Offset? |
|
|
Дата: Авг 17, 2004 18:23:41 Приятно, когда тебя считают спецом :) Но с того момента уже год прошел :) Я многое забыл и сосредоточен на другом. Кроме того, экспортом я вообще не занимался. Поэтому особо помочь не могу. Разве что, ответы на некоторые вопросы ты найдешь внутри LdrpSnapThunk. Вот так:
NTSTATUS
LdrpSnapThunk (
IN PVOID DllBase,
IN PVOID ImageBase,
IN PIMAGE_THUNK_DATA OriginalThunk,
IN OUT PIMAGE_THUNK_DATA Thunk,
IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
IN ULONG ExportSize,
IN BOOLEAN StaticSnap,
IN PSZ DllName
)
/*++
Routine Description:
This function snaps a thunk using the specified Export Section data.
If the section data does not support the thunk, then the thunk is
partially snapped (Dll field is still non-null, but snap address is
set).
Arguments:
DllBase - Base of Dll.
ImageBase - Base of image that contains the thunks to snap.
Thunk - On input, supplies the thunk to snap. When successfully
snapped, the function field is set to point to the address in
the DLL, and the DLL field is set to NULL.
ExportDirectory - Supplies the Export Section data from a DLL.
StaticSnap - If TRUE, then loader is attempting a static snap,
and any ordinal/name lookup failure will be reported.
Return Value:
STATUS_SUCCESS or STATUS_PROCEDURE_NOT_FOUND
--*/
{
BOOLEAN Ordinal;
USHORT OrdinalNumber;
ULONG OriginalOrdinalNumber;
PIMAGE_IMPORT_BY_NAME AddressOfData;
PULONG NameTableBase;
PUSHORT NameOrdinalTableBase;
PULONG Addr;
USHORT HintIndex;
NTSTATUS st;
PSZ ImportString;
//
// Determine if snap is by name, or by ordinal
//
Ordinal = (BOOLEAN)IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal);
if (Ordinal) {
OriginalOrdinalNumber = (ULONG)IMAGE_ORDINAL(OriginalThunk->u1.Ordinal);
OrdinalNumber = (USHORT)(OriginalOrdinalNumber - ExportDirectory->Base);
} else {
//
// Change AddressOfData from an RVA to a VA.
//
AddressOfData = (PIMAGE_IMPORT_BY_NAME)((ULONG_PTR)ImageBase + ((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff));
ImportString = (PSZ)AddressOfData->Name;
//
// Lookup Name in NameTable
//
NameTableBase = (PULONG)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
NameOrdinalTableBase = (PUSHORT)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
//
// Before dropping into binary search, see if
// the hint index results in a successful
// match. If the hint index is zero, then
// drop into binary search.
//
HintIndex = AddressOfData->Hint;
if ((ULONG)HintIndex < ExportDirectory->NumberOfNames &&
!strcmp(ImportString, (PSZ)((ULONG_PTR)DllBase + NameTableBase[HintIndex]))) {
OrdinalNumber = NameOrdinalTableBase[HintIndex];
#if LDRDBG
if (ShowSnaps) {
DbgPrint("LDR: Snapping %s\n", ImportString);
}
#endif
} else {
#if LDRDBG
if (HintIndex) {
DbgPrint("LDR: Warning HintIndex Failure. Name %s (%lx) Hint 0x%lx\n",
ImportString,
(ULONG)ImportString,
(ULONG)HintIndex
);
}
#endif
OrdinalNumber = LdrpNameToOrdinal(
ImportString,
ExportDirectory->NumberOfNames,
DllBase,
NameTableBase,
NameOrdinalTableBase
);
}
}
//
// If OrdinalNumber is not within the Export Address Table,
// then DLL does not implement function. Snap to LDRP_BAD_DLL.
//
if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
baddllref:
#if DBG
if (StaticSnap) {
if (Ordinal) {
DbgPrint("LDR: Can't locate ordinal 0x%lx\n", OriginalOrdinalNumber);
}
else {
DbgPrint("LDR: Can't locate %s\n", ImportString);
}
}
#endif
if ( StaticSnap ) {
//
// Hard Error Time
//
ULONG_PTR ErrorParameters[3];
UNICODE_STRING ErrorDllName, ErrorEntryPointName;
ANSI_STRING AnsiScratch;
ULONG ParameterStringMask;
ULONG ErrorResponse;
RtlInitAnsiString(&AnsiScratch,DllName ? DllName : "Unknown");
RtlAnsiStringToUnicodeString(&ErrorDllName,&AnsiScratch,TRUE);
ErrorParameters[1] = (ULONG_PTR)&ErrorDllName;
ParameterStringMask = 2;
if ( Ordinal ) {
ErrorParameters[0] = OriginalOrdinalNumber;
}
else {
RtlInitAnsiString(&AnsiScratch,ImportString);
RtlAnsiStringToUnicodeString(&ErrorEntryPointName,&AnsiScratch,TRUE);
ErrorParameters[0] = (ULONG_PTR)&ErrorEntryPointName;
ParameterStringMask = 3;
}
NtRaiseHardError(
Ordinal ? STATUS_ORDINAL_NOT_FOUND : STATUS_ENTRYPOINT_NOT_FOUND,
2,
ParameterStringMask,
ErrorParameters,
OptionOk,
&ErrorResponse
);
if ( LdrpInLdrInit ) {
LdrpFatalHardErrorCount++;
}
RtlFreeUnicodeString(&ErrorDllName);
if ( !Ordinal ) {
RtlFreeUnicodeString(&ErrorEntryPointName);
RtlRaiseStatus(STATUS_ENTRYPOINT_NOT_FOUND);
}
RtlRaiseStatus(STATUS_ORDINAL_NOT_FOUND);
}
Thunk->u1.Function = (ULONG_PTR)LDRP_BAD_DLL;
st = Ordinal ? STATUS_ORDINAL_NOT_FOUND : STATUS_ENTRYPOINT_NOT_FOUND;
} else {
Addr = (PULONG)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
Thunk->u1.Function = ((ULONG_PTR)DllBase + Addr[OrdinalNumber]);
if (Thunk->u1.Function > (ULONG_PTR)ExportDirectory &&
Thunk->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)
) {
UNICODE_STRING UnicodeString;
ANSI_STRING ForwardDllName;
PVOID ForwardDllHandle;
PUNICODE_STRING ForwardProcName;
ULONG ForwardProcOrdinal;
ImportString = (PSZ)Thunk->u1.Function;
ForwardDllName.Buffer = ImportString,
ForwardDllName.Length = (USHORT)(strchr(ImportString, '.') - ImportString);
ForwardDllName.MaximumLength = ForwardDllName.Length;
st = RtlAnsiStringToUnicodeString(&UnicodeString, &ForwardDllName, TRUE);
if (NT_SUCCESS(st)) {
#if defined (WX86)
if (Wx86ProcessInit) {
NtCurrentTeb()->Wx86Thread.UseKnownWx86Dll = RtlImageNtHeader(DllBase)->FileHeader.Machine
== IMAGE_FILE_MACHINE_I386;
}
#endif
st = LdrpLoadDll(NULL, NULL, &UnicodeString, &ForwardDllHandle,FALSE);
RtlFreeUnicodeString(&UnicodeString);
}
if (!NT_SUCCESS(st)) {
goto baddllref;
}
RtlInitAnsiString( &ForwardDllName,
ImportString + ForwardDllName.Length + 1
);
if (ForwardDllName.Length > 1 &&
*ForwardDllName.Buffer == '#'
) {
ForwardProcName = NULL;
st = RtlCharToInteger( ForwardDllName.Buffer+1,
0,
&ForwardProcOrdinal
);
if (!NT_SUCCESS(st)) {
goto baddllref;
}
}
else {
ForwardProcName = (PUNICODE_STRING)&ForwardDllName;
//
// Following line is not needed since this is a by name lookup
//
//
//ForwardProcOrdinal = (ULONG)&ForwardDllName;
//
}
st = LdrpGetProcedureAddress( ForwardDllHandle,
(PANSI_STRING )ForwardProcName,
ForwardProcOrdinal,
&(PVOID)Thunk->u1.Function,
FALSE
);
if (!NT_SUCCESS(st)) {
goto baddllref;
}
}
else {
if ( !Addr[OrdinalNumber] ) {
goto baddllref;
}
#if defined (_ALPHA_) && defined (WX86)
else {
PIMAGE_NT_HEADERS ExportNtHeaders = RtlImageNtHeader(DllBase);
if ((ExportNtHeaders->OptionalHeader.SectionAlignment < PAGE_SIZE) &&
(ExportNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)) {
Thunk->u1.Function += LdrpWx86RelocatedFixupDiff(DllBase, Addr[OrdinalNumber]);
}
}
#endif // defined (_ALPHA_) && defined (WX86)
}
st = STATUS_SUCCESS;
}
return st;
}
|
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.056 |