секции СИСТЕМНЫХ dll
Проблема состоит в том что в системных DLL
(ntdll,kernel32 итп)
данные касающиеся имён и адресов экспортируемых
и импортируемых функций находятся не в секциях
.idata и .edata а в секции .text
И если пытаться ПРОГРАММНО! искать в .text секции так же как
и для .idata и .edata то будет выводится мусор
то есть непонятные значения.Помогите!
ответ на мой вопрос, в отчаянии решил все-таки еще раз попробовать
поломать голову и таки мне это удалось после нескольких часов!
Я помещаю часть кода который позволяет динамически в 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);
Отвечаю на свой же вопрос.Не дождавшись пока кто-нибудь пришлет мне
ответ на мой вопрос, в отчаянии решил все-таки еще раз попробовать
поломать голову и таки мне это удалось после нескольких часов!
Я помещаю часть кода который позволяет динамически в 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.
Если не сложно вышли исходник на [email]icecoder@ukr.net[/email]
Проблема состоит в том что в системных DLL
(ntdll,kernel32 итп)
данные касающиеся имён и адресов экспортируемых
и импортируемых функций находятся не в секциях
.idata и .edata а в секции .text
Кто тебе такую глупость сказал?
Таблицы импорта и экспорта у этих DLL находятся там же, где и у других DLL.
Вот так я обхожу таблицу экспорта. Весь код не привожу, только метод обхода таблицы экспорта.
Код несколько староват, есть неучтенный нюанс, но для общего представления подойдет.
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.
Ты где таблицы ищешь? В памяти или в файле?
#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;
}
Во-первых, в ntdll нет импорта.
Во-вторых, загруженный как исполняемый образ имеет уже разрезолвленную таблицу импорта. Поэтому информация об именах импортируемых функций в таблице импорта уже загруженного модуля потеряна. Но в принципе её можно восстановить по косвенным данным.
Ты должен был бы знать это, раз занимаешься в этой области.
P.S. Мне тренироваться не надо, я сам писал загрузчик (см. тему про PE-упаковщик http://forum.codenet.ru/showthread.php?t=34753), а вот тебе тренировка (в т.ч. в пользовании google) не помешает. :)
Во-вторых, загруженный как исполняемый образ имеет уже разрезолвленную таблицу импорта. Поэтому информация об именах импортируемых функций в таблице импорта уже загруженного модуля потеряна. Но в принципе её можно восстановить по косвенным данным.
Ты должен был бы знать это, раз занимаешься в этой области.
P.S. Мне тренироваться не надо, я сам писал загрузчик (см. тему про PE-упаковщик http://forum.codenet.ru/showthread.php?t=34753), а вот тебе тренировка (в т.ч. в пользовании google) не помешает. :)
Да знал я эти фичи.... с чувством юмора - напряг...Чего ты обижаешься сразу, я про ntdll поэтому и сказал, что нету импорта...А тренироваться нам нужно всем и постоянно, хотя может ты не человек и тренировка мозга тебе не нужна...
Славянский Брат наверно весь такой, только стоит над ним немного пошутить как он сразу начинает злиться и защищаться, люди будьте проще по жизни и умейте смеяться над собой и другими...