Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

секции СИСТЕМНЫХ dll

8.9K
17 января 2005 года
semskmax
8 / / 17.01.2005
секции СИСТЕМНЫХ dll
Проблема состоит в том что в системных DLL
(ntdll,kernel32 итп)
данные касающиеся имён и адресов экспортируемых
и импортируемых функций находятся не в секциях
.idata и .edata а в секции .text
И если пытаться ПРОГРАММНО! искать в .text секции так же как
и для .idata и .edata то будет выводится мусор
то есть непонятные значения.Помогите!
8.9K
20 января 2005 года
semskmax
8 / / 17.01.2005
Отвечаю на свой же вопрос.Не дождавшись пока кто-нибудь пришлет мне
ответ на мой вопрос, в отчаянии решил все-таки еще раз попробовать
поломать голову и таки мне это удалось после нескольких часов!
Я помещаю часть кода который позволяет динамически в runtime узнать
адреса и имена функций системных DLL,и делать перехват вызовов этих
функций не из приложений а в самих системных DLL.
Если кому интересно могу выслать продолжение.

PIMAGE_NT_HEADERS pNTHeader;
pNTHeader=(PIMAGE_NT_HEADERS)(base+dosHeader->e_lfanew);
PIMAGE_SECTION_HEADER section;
section = (PIMAGE_SECTION_HEADER)(pNTHeader+1);

for ( int i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
{
if ( strnicmp((const char*)section->Name, ".text", 8) == 0 )
break;
}
PIMAGE_EXPORT_DIRECTORY exportDir;
DWORD virtRVA=(DWORD)pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress;
DWORD offsraw = virtRVA-section->VirtualAddress;
exportDir=(PIMAGE_EXPORT_DIRECTORY)(base + section->PointerToRawData + offsraw);
487
29 января 2005 года
ddnh_bc
301 / / 16.09.2003
Цитата:
Originally posted by semskmax
Отвечаю на свой же вопрос.Не дождавшись пока кто-нибудь пришлет мне
ответ на мой вопрос, в отчаянии решил все-таки еще раз попробовать
поломать голову и таки мне это удалось после нескольких часов!
Я помещаю часть кода который позволяет динамически в runtime узнать
адреса и имена функций системных DLL,и делать перехват вызовов этих
функций не из приложений а в самих системных DLL.
Если кому интересно могу выслать продолжение.

PIMAGE_NT_HEADERS pNTHeader;
pNTHeader=(PIMAGE_NT_HEADERS)(base+dosHeader->e_lfanew);
PIMAGE_SECTION_HEADER section;
section = (PIMAGE_SECTION_HEADER)(pNTHeader+1);

for ( int i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
{
if ( strnicmp((const char*)section->Name, ".text", 8) == 0 )
break;
}
PIMAGE_EXPORT_DIRECTORY exportDir;
DWORD virtRVA=(DWORD)pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress;
DWORD offsraw = virtRVA-section->VirtualAddress;
exportDir=(PIMAGE_EXPORT_DIRECTORY)(base + section->PointerToRawData + offsraw);



Таблица импортов и их данные могут лежать в разных секциях.

Вобщем - вот нормальный хелп по формату PE на русском.

P.S. Есть в нем одна ошибка - заголовок секции имеет размер 0x28 а не 0x2C.

31K
29 августа 2007 года
Ice-coder
3 / / 29.08.2007
Таблица импорта лежит восновном в секции .text поэтому под конкретную задачу вполне подходит...
Если не сложно вышли исходник на [email]icecoder@ukr.net[/email]
3
29 августа 2007 года
Green
4.8K / / 20.01.2000
Цитата: semskmax
секции СИСТЕМНЫХ dll
Проблема состоит в том что в системных DLL
(ntdll,kernel32 итп)
данные касающиеся имён и адресов экспортируемых
и импортируемых функций находятся не в секциях
.idata и .edata а в секции .text


Кто тебе такую глупость сказал?
Таблицы импорта и экспорта у этих DLL находятся там же, где и у других DLL.

Вот так я обхожу таблицу экспорта. Весь код не привожу, только метод обхода таблицы экспорта.
Код несколько староват, есть неучтенный нюанс, но для общего представления подойдет.

Код:
#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))

template<class Visitor>
void PE::walkExportTable(Visitor visitor)
{
    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)RVA(imageBase, PIMAGE_DOS_HEADER(imageBase)->e_lfanew);
    IMAGE_DATA_DIRECTORY& dataDirItem = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
    if(dataDirItem.Size == 0)
        return;

    PIMAGE_EXPORT_DIRECTORY expDir = (PIMAGE_EXPORT_DIRECTORY)RVA(imageBase, dataDirItem.VirtualAddress);

    PCSTR* expNames = (PCSTR*)RVA(imageBase, expDir->AddressOfNames);
    PWORD hint = (PWORD)RVA(imageBase, expDir->AddressOfNameOrdinals);
    PDWORD addrs = (PDWORD)RVA(imageBase, expDir->AddressOfFunctions);

    std::vector<PCSTR> names(expDir->NumberOfFunctions, NULL);
    for(DWORD i=0; i<expDir->NumberOfNames; i++) {
        names[hint] = (PCSTR)RVA(imageBase, expNames);
    }

    for(DWORD i=0; i<expDir->NumberOfFunctions; i++) {
        visitor(i+1, names, (DWORD)RVA(imageBase, addrs));
    }
}

Как видно из кода, нужную секцию надо искать не по имени, а по нужному вхождению в DataDirectory,
а RVA высчитываются относительно imageBase.

Ты где таблицы ищешь? В памяти или в файле?
3
29 августа 2007 года
Green
4.8K / / 20.01.2000
Решил привести полный работоспособный пример:
Код:
#include <windows.h>
#include <iostream>
#include <vector>

#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))

template<class Visitor>
void walkExportTable(PVOID imageBase, Visitor& visitor)
{
    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)RVA(imageBase, PIMAGE_DOS_HEADER(imageBase)->e_lfanew);
    IMAGE_DATA_DIRECTORY& dataDirItem = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
    if(dataDirItem.Size == 0) {
        return;
    }

    PIMAGE_EXPORT_DIRECTORY expDir = (PIMAGE_EXPORT_DIRECTORY)RVA(imageBase, dataDirItem.VirtualAddress);

    PCSTR* expNames = (PCSTR*)RVA(imageBase, expDir->AddressOfNames);
    PWORD hint = (PWORD)RVA(imageBase, expDir->AddressOfNameOrdinals);
    PDWORD addrs = (PDWORD)RVA(imageBase, expDir->AddressOfFunctions);

    std::vector<PCSTR> names(expDir->NumberOfFunctions, NULL);
    for(DWORD i=0; i<expDir->NumberOfNames; i++) {
        names[hint] = (PCSTR)RVA(imageBase, expNames);
    }

    for(DWORD i=0; i<expDir->NumberOfFunctions; i++) {
        visitor(i+1, names, (DWORD)RVA(imageBase, addrs));
    }
}

void functionViewer(DWORD ord, PCSTR name, DWORD addr) {
    std::cout << std::dec << ord << ' ' << (name ? name : (PCSTR)"NONAME") << ' ' << std::hex << addr << std::endl;
}

int main()
{
    HMODULE hDll = GetModuleHandle("ntdll");
    walkExportTable(hDll, functionViewer);

    return 0;
}
31K
30 августа 2007 года
Ice-coder
3 / / 29.08.2007
За код спасибо...а ты попробуй взять... и имена и адреса ...из таблицы импорта в runtime(можешь потренироваться на ntdll.dll:)
3
30 августа 2007 года
Green
4.8K / / 20.01.2000
Цитата: Ice-coder
За код спасибо...а ты попробуй взять... и имена и адреса ...из таблицы импорта в runtime(можешь потренироваться на ntdll.dll:)


Во-первых, в ntdll нет импорта.
Во-вторых, загруженный как исполняемый образ имеет уже разрезолвленную таблицу импорта. Поэтому информация об именах импортируемых функций в таблице импорта уже загруженного модуля потеряна. Но в принципе её можно восстановить по косвенным данным.

Ты должен был бы знать это, раз занимаешься в этой области.

P.S. Мне тренироваться не надо, я сам писал загрузчик (см. тему про PE-упаковщик http://forum.codenet.ru/showthread.php?t=34753), а вот тебе тренировка (в т.ч. в пользовании google) не помешает. :)

31K
31 августа 2007 года
Ice-coder
3 / / 29.08.2007
Цитата: Green
Во-первых, в ntdll нет импорта.
Во-вторых, загруженный как исполняемый образ имеет уже разрезолвленную таблицу импорта. Поэтому информация об именах импортируемых функций в таблице импорта уже загруженного модуля потеряна. Но в принципе её можно восстановить по косвенным данным.

Ты должен был бы знать это, раз занимаешься в этой области.

P.S. Мне тренироваться не надо, я сам писал загрузчик (см. тему про PE-упаковщик http://forum.codenet.ru/showthread.php?t=34753), а вот тебе тренировка (в т.ч. в пользовании google) не помешает. :)



Да знал я эти фичи.... с чувством юмора - напряг...Чего ты обижаешься сразу, я про ntdll поэтому и сказал, что нету импорта...А тренироваться нам нужно всем и постоянно, хотя может ты не человек и тренировка мозга тебе не нужна...
Славянский Брат наверно весь такой, только стоит над ним немного пошутить как он сразу начинает злиться и защищаться, люди будьте проще по жизни и умейте смеяться над собой и другими...

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог