1) IceStudent >>запускаем, скажем, ProcExp - и видим там переименованное >Это который? ProcessXP? Не показывает он. Имелся в виду Process Explorer by Russinovich. Показывает. Если соблюдать указанные условия. Показывает и штатный таскменеджер, да и мой простейший WinTreeSnap ( http://www.wasm.ru/forum/attachment.php?item=154 ) . (А ProcExp был выбран специально в честь EP_X0FF: по-моему, на форуме по ProcExp нет ветки без его участия ) 2) Ну, а если так - в директории, полученной через GetModuleFileName, перебор всех файлов + тест на ... (критерий за вами, файл-то ваш).
Под NT-based Код (Text): TCHAR tszPath[MAX_PATH]; GetMappedFileName(GetCurrentProcess(), GetModuleHandle(NULL), tszPath, sizeof(tszPath)); если нужно перевести путь в классический, можно воспользоваться RtlNtPathNameToDosPathName под 9x не знаю...
Ну, я тоже о нём. Не показывает. Прога, выводящая MessageBox. Запускаем. Переименовываем исполняемый файл. Запускаем ProcessXP, смотрим всеми доступными способами имя файла - везде старое (свойства процесса, список его длл, в хэндлах его вообще нет, поиском по всем процессам). То же самое, если переименовывать программно после запуска. О чём я и говорил. А толку - файл можно перемещать куда угодно в пределах раздела. Nouzui Вот, именно это и показывает реальное имя файла.
Ну да. Собственно, Native API - ответ на большинство вопросов. Не догадался заглянуть раньше: Код (Text): struct { OBJECT_NAME_INFORMATION ObjectNameInfo; WCHAR FileName[MAX_PATH]; } s; Status = NtQueryVirtualMemory(hProcess, lpv, MemoryMappedFilenameInformation, &s.ObjectNameInfo, sizeof(s), &ReturnLength );
Nouzui Точно, самое оно. IceStudent >>Имелся в виду Process Explorer by Russinovich.Показывает. Если соблюдать указанные условия. >Ну, я тоже о нём. Не показывает. Однако странно вы его обозвали - ProcessXP. Показывает. >Прога, выводящая MessageBox. Запускаем. Переименовываем исполняемый файл. Стоп, а как именно переименовываете ? (И кстати - на каких виндах ? У меня XP). Переименовывать нужно нежно. >Запускаем ProcessXP, смотрим всеми доступными способами имя файла - везде старое (свойства процесса, список его длл, в хэндлах его вообще нет, поиском по всем процессам). не надо всеми способами, смотрите только способом глазения на дерево процессов в главном окне, вот там - не старое, а новое. Еще раз: запускаем прогу mb.exe, видим MessageBox, перетаскиваем файл mb.exe в другую директорию, там переименовываем этот файл в 123.4567, запускаем ProcExp, и - зуб даю - видим в дереве процессов 123.4567. >>в директории, полученной через GetModuleFileName, перебор всех файлов >А толку - файл можно перемещать куда угодно в пределах раздела. Это да.
Код (Text): static DWORD InternalGetMappedFileName(BOOLEAN bUnicode, HANDLE hProcess, LPVOID lpv, LPVOID lpName, DWORD nSize) { PMEMORY_SECTION_NAME pmsnName; ULONG nBufSize; NTSTATUS Status; if(nSize == 0 || lpName == NULL) { return 0; } if(nSize > (0xFFFF / sizeof(WCHAR))) { /* if the user buffer contains more characters than would fit in an UNICODE_STRING, limit the buffer size. RATIONALE: we don't limit buffer size elsewhere because here superfluous buffer size will mean a larger temporary buffer */ nBufSize = 0xFFFF / sizeof(WCHAR); } else { nBufSize = nSize * sizeof(WCHAR); } /* allocate the memory */ pmsnName = PsaiMalloc(nBufSize + sizeof(MEMORY_SECTION_NAME)); if(pmsnName == NULL) { SetLastError(ERROR_OUTOFMEMORY); return 0; } /* initialize the destination buffer */ pmsnName->SectionFileName.Length = 0; pmsnName->SectionFileName.Length = nBufSize; #if 0 __try { #endif /* query the name */ Status = NtQueryVirtualMemory(hProcess, lpv, MemorySectionName, pmsnName, nBufSize, NULL); if(!NT_SUCCESS(Status)) { PsaiFree(pmsnName); SetLastErrorByStatus(Status); return 0; } if(bUnicode) { /* destination is an Unicode string: direct copy */ memcpy((LPWSTR)lpName, pmsnName + 1, pmsnName->SectionFileName.Length); PsaiFree(pmsnName); if(pmsnName->SectionFileName.Length < nSize) { /* null-terminate the string */ ((LPWSTR)lpName)[pmsnName->SectionFileName.Length] = 0; return pmsnName->SectionFileName.Length + 1; } return pmsnName->SectionFileName.Length; } else { ANSI_STRING AnsiString; AnsiString.Length = 0; AnsiString.MaximumLength = nSize; AnsiString.Buffer = (LPSTR)lpName; if(AreFileApisANSI()) RtlUnicodeStringToAnsiString(&AnsiString, &pmsnName->SectionFileName, FALSE); else RtlUnicodeStringToOemString(&AnsiString, &pmsnName->SectionFileName, FALSE); PsaiFree(pmsnName); if(AnsiString.Length < nSize) { /* null-terminate the string */ ((LPSTR)lpName)[AnsiString.Length] = 0; return AnsiString.Length + 1; } return AnsiString.Length; } #if 0 } __finally { PsaiFree(pmsnName); } #endif }
Ну-ну.. Код (Text): xor ebx,ebx invoke GetModuleFileName,ebx,buf,256 invoke MoveFile,buf,szSystem invoke GetModuleFileName,ebx,self,256 invoke MessageBox,ebx,self,_getpath,MB_ICONINFORMATION invoke GetModuleHandle,ebx invoke GetMappedFileName,-1,eax,self,256 invoke MessageBox,ebx,self,_getpath,MB_ICONINFORMATION invoke MoveFile,szSystem,buf ... szSystem db 'test.dll',0 buf rb 256 self rb 256 Не показывает. Имя файла у него такое
>>Переименовывать нужно нежно. >Ну-ну.. >invoke MoveFile,buf,szSystem Это-то и грубо. Нежно - это, например, смена текста временного Edit-а в Explorer-е (иконка файла). Вот тогда ProcExp и покажет новое имя. (Но только раз, - дальнейшие переименования того же файла не воспримет ни этот, ни другие экземпляры ProcExp). >>Однако странно вы его обозвали - ProcessXP. >Имя файла у него такое Руссинович в курсе ?
Имею следующий код: Код (Text): if (hModule <> 0) then begin hProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if hProcess <> 0 then begin Bytes := GetMappedFileName(hProcess, Pointer(hModule), @sbuf, SizeOf(sbuf)-1); if Bytes <> 0 then Result := AnsiUpperCase(sbuf); CloseHandle(hProcess); end; end; Ф-ия GetMappedFileName из PsAPI. Интересно, что с PROCESS_VM_READ ф-ия GetMappedFileName возвращает 0. Через ToolHelp32 узнаю hModule первого модуля из процесса pid (т.е. базовый адрес главного модуля). Как попроще узнать hModule ? И как преобразовать путь "\DEVICE\HARDDISCVOLUME5\" в стандартный вид ?
Перенёс на паскаль ф-ию InternalGetMappedFileName (через NtQueryVirtualMemory). Для определения hModule использую ZwQueryInformationProcess: по адресу (PROCESS_BASIC_INFORMATION.PebBaseAddress + 08) как раз и находится hModule. Осталось только преобразовать "\DEVICE\HARDDISCVOLUME5\" в стандартный вид. Интересная особенность: иногда GetMappedFileName и NtQueryVirtualMemory возвращают путь в формате 8.3. Не могу понять от чего это зависит.
По поводу KAV.EXE скажу следующее: через OpenProcess прожка моя не может открыть процесс KAV, но если KAV.EXE запустить из под ArtMoney, то ArtMoney определяет пути ко всем модулям процесса KAV.EXE. Как нито можно получить hProcess для уже работающего KAV.EXE ?
Большой спасибо. Нашёл. Теперь и пусть к касперу определяется. А можно каким то макаром принудительно заставить NtQueryVirtualMemory возвратить путь в формате 8.3 ?