Перейти к содержанию

Возвращение настоящих название модулей


Рекомендуемые сообщения

Xipho, помнишь ты мне дал твою функцию определения настоящего имени модуля dll в удалённом процессе.

Тут что используем?!

CreateFile, CreateFileMapping, MapViewOfFile, затем через череду путей добираемся до pImportDesc (это PIMAGE_EXPORT_DIRECTORY)

Затем так получаем реальное имя (char*)(DWORD(mFile)+ (DWORD)(pImportDesc->Name)),

где mFile был получен из MapViewOfFile(hMapFile....)

hMapFile - из CreateFileMapping(hFile,...)

hFile - из CreateFile(Path,...)

Path - полный путь с названием файла модуля

// Дефайны
#define MakePtr(Type, Base, Offset) ((Type)(DWORD(Base) + (DWORD)(Offset)))
#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew))

// char *Output - возврат реального имени модуля
// char *Path - передача пути модуля по указателю в GetModuleRealName
void GetModuleRealName(char *Output,char *Path) {
HANDLE hFile = CreateFile(Path,GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if (hFile!=INVALID_HANDLE_VALUE) {
HANDLE hMapFile = CreateFileMapping(hFile,NULL,PAGE_READONLY | SEC_IMAGE,0,0,NULL);
if (hMapFile) {
PBYTE mFile = (PBYTE)MapViewOfFile(hMapFile,FILE_MAP_READ,0,0,0);
PIMAGE_DOS_HEADER pDOSHead;
pDOSHead = (PIMAGE_DOS_HEADER)mFile;
if (pDOSHead->e_magic != IMAGE_DOS_SIGNATURE) {
MessageBox(NULL,"Error Dos Header signature MZ","Error",MB_OK);
}
PIMAGE_NT_HEADERS pPEHeader;
pPEHeader=(PIMAGE_NT_HEADERS) NTSIGNATURE(pDOSHead);

if (pPEHeader->Signature != IMAGE_NT_SIGNATURE) {
MessageBox(NULL,"Error PE Header signature PE","Error",MB_OK);
}
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
OptionalHeader = (IMAGE_OPTIONAL_HEADER32) pPEHeader->OptionalHeader;

PIMAGE_EXPORT_DIRECTORY pImportDesc=NULL;
pImportDesc = MakePtr(PIMAGE_EXPORT_DIRECTORY,mFile,pPEHeader->OptionalHeader.DataDirectory[0].VirtualAddress);
char *p = MakePtr(char*,mFile,pImportDesc->Name);
strcpy_s(Output,strlen(p)+1,p);
UnmapViewOfFile(mFile);
}
CloseHandle(hMapFile);
} else {
int er = GetLastError();
char p[30];
wsprintf(p,"Last Error: %d",er);
MessageBox(NULL,p,"ERROR",MB_OK);
}
CloseHandle(hFile);
}

1) Так вот у меня вопросы как называется твой метод если имеет какое название?

2) Какое отношение он имеет к именованным каналам и другим видам межпроцессорного взаимодействия?

3) Теоритически можно ли было твою функцию переписать как поиск сигнатуры?

4) Теоритически можно ли было твою функцию переписать используя метод разделяемой памяти?

Т.е. делаем например так.

Ищем все модули процесса (как ты делал)

У каждого модуля ищем реальное имя и возвращаем его, а делаем это так.

Своим главным потоком процесса1 позаимствуем секцию(ии) чужого процесса2 по методу разделяемой памяти, остановив перед этим процесс2. И работаем с этими секциями как со своими внутри процесса1 - читаем данные этих секций как свои для процесса1 на предмет поиска настоящего имени dll. Выводим на консоль, отменяем семафоры (их два и их ещё надо было создать до этого), закрываем ненужные дескрипторы, размораживаем процесс2...

Ссылка на комментарий
Поделиться на другие сайты

1. Это не мой метод, это стандартный метод работы с PE-файлами, да и вообще один из оптимальных методов считывания файлов, как отображения файла в собственное адресное пространство читающего файл процесса. Я лишь приспособил этот метод для получения реального имени модуля в тех случаях, когда модуль меняет свое имя (как в пресловутой F.E.A.R.).

2. Именно этот метод, по сути, не имеет отношения ни к именованным каналам, ни к межпроцессорному взаимодействию, ибо в память отображается файл с жесткого диска. Но, теоритически, его можно приспособить для нахождения сигнатур. Для этого необходимо сначала отобразить в свою память необходимый модуль игры, найти в нем сигнатуру, а затем конвертнуть ее в RVA адрес.

3. Ответил в предыдущем пункте.

4. Алгоритм заинтересовал. Поразмыслю. Пока точно ничего не скажу, кроме одного: для того, чтобы остановить процесс2 (предположительно, игра) нужно остановить все потоки этого процесса, что может вызвать вылет, если потоки будут остановлены в неправильном порядке. Далее, я не уверен, что можно "захватить" сегмент памяти процесса2 для использования его как разделяемого сегмента. Поэкспериментирую.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.