· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› "Восстановление" таблицы экспорта PE: ординалы->имена

Посл.отвђт Сообщен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