Как получить полный путь к файлу по хэндлу процесса (FASM)

Тема в разделе "WASM.BEGINNERS", создана пользователем NAGRIS, 6 апр 2007.

  1. NAGRIS

    NAGRIS New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    17
    Почему не удается получить полный путь к файлу по хэндлу процесса (FASM)

    Необходимо получить полные пути к файлам работающих процессов и занести их в ListView

    Код (Text):
    1. ...
    2.  
    3. invoke   OpenProcess, STANDARD_RIGHTS_REQUIRED+SYNCHRONIZE+0FFFh, 0, [ProcessEntry.th32ProcessID]  
    4. mov       [HandleOpenProcess], eax                                                                                                                              
    5. invoke   CloseHandle, eax
    6. invoke   GetModuleFileName, [HandleOpenProcess], ExePath, 260
    7. mov       [ListViewItem.pszText], ExePath
    8. stdcall   [SendMessage], [hListViewProcesses], LVM_SETITEM, 0, ListViewItem
    9.  
    10. ...
    Данный код выводит в ListView путь к моей программе в каждой строке ListView.
    Если поставить в первую строку вместо [ProcessEntry.th32ProcessID] конкретное число (PID взятый из Process Explorer),
    то вообще ничего не выводится - OpenProcess в EAX всегда помещает 80h.
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    GetModuleFileName надо передавать HMODULE.
    Код (Text):
    1. PWSTR GetNameByPID(DWORD PID){
    2.     ULONG pInfo[6], dwReaded, pProcParams, pName;
    3.     USHORT wNameLen;
    4.     PWSTR ret = NULL;
    5.     HANDLE hProc = 0;
    6.  
    7.     hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, PID);
    8.     if (!hProc)
    9.         goto exit;
    10.     if (NtQueryInformationProcess(hProc, 0, pInfo, 0x18, 0))
    11.         goto exit;
    12.     if ((!ReadProcessMemory(hProc, (PVOID)((__int64)pInfo[1] + 0x10), &pProcParams, 4, &dwReaded))
    13.         || (dwReaded != 4))
    14.             goto exit;
    15.     if ((!ReadProcessMemory(hProc, (PVOID)((__int64)pProcParams + 0x38), &wNameLen, 2, &dwReaded))
    16.         || (dwReaded != 2))
    17.             goto exit;
    18.     if ((!ReadProcessMemory(hProc, (PVOID)((__int64)pProcParams + 0x3C), &pName, 4, &dwReaded))
    19.         || (dwReaded != 4))
    20.             goto exit;
    21.     if (!pName)
    22.         goto exit;
    23.     ret = malloc(wNameLen + 2);
    24.     if (!ret)
    25.         goto exit;
    26.     if ((!ReadProcessMemory(hProc, (PVOID)((__int64)pName), ret, wNameLen, &dwReaded))
    27.         || (dwReaded != wNameLen)){
    28.             free(ret);
    29.             ret = NULL;
    30.         }
    31. exit:
    32.     if (hProc)
    33.         CloseHandle(hProc);
    34.     return ret;
    35. }
     
  3. NAGRIS

    NAGRIS New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    17
    А я что передаю в этой строке
    Код (Text):
    1. invoke   GetModuleFileName, [HandleOpenProcess], ExePath, 260
    Все как написано в помощи

    hModule
    [in] Handle to the module whose path is being requested. If this parameter is NULL, GetModuleFileName retrieves the path for the current module.


    я передаю хэндл полученный OpenProcess, но даже когда я указываю конкретные разные Process ID в OpenProcess, то возвращается все время одно и тоже число. Почему?

    Попробую переписать ваш код на FASM, надеюсь заработает.
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    HMODULE - это на самом деле никакой не хендл. Это базовый адрес загрузки МОДУЛЯ. А у тебя есть только hProcess, это ХЕНДЛ ПРОЦЕССА. Вещи совершенно разные.

    Чтобы узнать имя главного модуля процесса можно пошарить в списке загруженных модулей, который можно прочитать в PEB процесса.
    Или можно пошаманить с CreateToolhelp32Snapshot.

    Пример кода (получение HMODULE но имени модуля и PID):
    Код (Text):
    1. DWORD RemoteGetModuleHandle(char *name, DWORD dwPid)
    2. {
    3.     MODULEENTRY32 m = {sizeof(m)};
    4.          DWORD dwRet = 0;
    5.  
    6.     HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPid);
    7.     if (hSnap == INVALID_HANDLE_VALUE)
    8.         return NULL;
    9.  
    10.     if (!Module32First(hSnap, &m))
    11.         return NULL;
    12.     do {
    13.         if (!lstrcmpi(m.szModule, name))
    14.                   {
    15.             dwRet = m.modBaseAddr;
    16.                            break;
    17.                   }
    18.     } while (Module32Next(hSnap, &m));
    19.  
    20.     CloseHandle(hSnap);
    21.    
    22.     return dwRet;
    23. }
    Пример с PEB:
    Код (Text):
    1.     const DWORD FS = 0x3B;
    2.     DWORD ownerProcessId = 38056;
    3.  
    4.     // Open process
    5.     HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, ownerProcessId);
    6.     if(!hProcess)
    7.         return printf("Cannot open process\n");
    8.  
    9.     // Find thread
    10.     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    11.     THREADENTRY32 te = {sizeof(te)};
    12.     Thread32First(hSnapshot, &te);
    13.     DWORD threadId = 0;
    14.     do
    15.     {
    16.         if(te.th32OwnerProcessID == ownerProcessId)
    17.             threadId = te.th32ThreadID;
    18.     }
    19.     while(Thread32Next(hSnapshot, &te));
    20.     if(!threadId)
    21.         return printf("No threads for specified process id\n");
    22.  
    23.     // Get FS base
    24.     HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, threadId);
    25.     if(!hThread)
    26.         return printf("Cannot open thread\n");
    27.  
    28.     LDT_ENTRY fs_entry;
    29.     GetThreadSelectorEntry(hThread, FS, &fs_entry);
    30.  
    31.     DWORD fs_base = fs_entry.BaseLow | (fs_entry.HighWord.Bytes.BaseMid<<16) | (fs_entry.HighWord.Bytes.BaseHi<<24);
    32.  
    33.     // Read modules list
    34.     TEB teb;
    35.     DWORD read;
    36.     if(!ReadProcessMemory(hProcess, (LPCVOID) fs_base, &teb, sizeof(teb), &read))
    37.         return printf("Can't read process memory for TEB, %d bytes read\n", read);
    38.  
    39.     PEB peb;
    40.     if(!ReadProcessMemory(hProcess, (LPCVOID) teb.Peb, &peb, sizeof(peb), &read))
    41.         return printf("Can't read process memory for PEB, %d bytes read\n", read);
    42.  
    43.     PEB_LDR_DATA pld;
    44.     if(!ReadProcessMemory(hProcess, (LPCVOID) peb.LoaderData, &pld, sizeof(pld), &read))
    45.         return printf("Can't read process memory for PEB_LDR_DATA, %d bytes read\n", read);
    46.  
    47.     LDR_MODULE entry;
    48.     if(!ReadProcessMemory(hProcess, (LPCVOID) pld.InInitializationOrderModuleList.Flink, &entry, sizeof(entry), &read))
    49.         return printf("Can't read process memory for LDR_MODULE, %d bytes read\n", read);
    50.  
    51.     WORD wbuffer[20];
    52.     char buffer[1024];
    53.  
    54.     // Walk the list
    55.     do
    56.     {
    57.         // Print the name
    58.         if(!ReadProcessMemory(hProcess, (LPCVOID) entry.BaseDllName.Buffer, &wbuffer, sizeof(wbuffer), &read))
    59.             return printf("Can't read process memory for wbuffer in loop, %d bytes read\n", read);
    60.        
    61.         WideCharToMultiByte(CP_ACP, 0, wbuffer, -1, buffer, sizeof(buffer), 0, 0);
    62.         printf("%s\t[0x%08x]\n", buffer, entry.BaseAddress);
    63.  
    64.         // Next
    65.         if(!ReadProcessMemory(hProcess, (LPCVOID) entry.ModuleList.Flink, &entry, sizeof(entry), &read))
    66.             return printf("Can't read process memory for LDR_MODULE in loop, %d bytes read\n", read);
    67.     }
    68.     while(entry.ModuleList.Flink != pld.InInitializationOrderModuleList.Flink);
    69.  
    70.     CloseHandle(hThread);
    71.     CloseHandle(hProcess);
    72.     CloseHandle(hSnapshot);
     
  5. GMax

    GMax Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    218
    Вот код из такой программы:
    Код (Text):
    1. GetProcessPath proc  dwPID:DWORD,  p_szBuff:DWORD, dwBuffSize:DWORD
    2. LOCAL   hProcess    :DWORD
    3. LOCAL   hModule :DWORD
    4. LOCAL   cbNeeded    :DWORD
    5.    
    6.     invoke  EnablePrivilege,TRUE
    7.    
    8.     invoke  OpenProcess,PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,0,dwPID
    9.     .if eax==0
    10.         xor eax,eax
    11.         ret
    12.     .endif
    13.     mov hProcess,eax
    14.    
    15.     invoke  EnumProcessModules,hProcess,addr hModule,4,addr cbNeeded
    16.     .if eax==0
    17.         xor eax,eax
    18.         ret
    19.     .endif
    20.    
    21.     invoke  GetModuleFileNameEx,hProcess,hModule,p_szBuff,dwBuffSize
    22.     .if eax == 0
    23.         xor eax,eax
    24.         ret
    25.     .endif
    26.     invoke  CloseHandle,hProcess
    27.    
    28.     invoke  EnablePrivilege,FALSE
    29.    
    30.     xor eax,eax
    31.     inc eax
    32. Ret
    33. GetProcessPath EndP
    Код рабочий! (Из моей программы с похожим функционалом)

    P.S. экзэшник в атаче

    файл не прицепился
    Ссылка на рапиду: http://rapidshare.com/files/24729880/ProcessList.rar.html
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    с аттачами тут проблемы ;)
    да и я думаю, что екзешник ему не нужен.
     
  7. NAGRIS

    NAGRIS New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    17
    Всем спасибо буду разбираться
     
  8. NAGRIS

    NAGRIS New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    17
    Для Gmax

    1)
    Твой код переделал так:

    Код (Text):
    1. ...
    2. invoke  OpenProcess,STANDARD_RIGHTS_REQUIRED+SYNCHRONIZE+0FFFh,0,[ProcessEntry.th32ProcessID]
    3. mov     [hProcess],eax
    4. invoke  EnumProcessModules,[hProcess],hModule,4,cbNeeded
    5. invoke  GetModuleFileNameEx,[hProcess], [hModule],ExePath,260
    6. mov     [ListViewItem.pszText], ExePath
    7.  
    8. stdcall [SendMessage],[hListViewProcesses],LVM_SETITEM,0, ListViewItem ;
    9. ...
    Программа при запуске пишет "Точка входа в процедуру GetModuleFileNameEx не найдена в библиотеке DLL PSAPI.dll" -
    если GetModuleFileNameEx заменить на GetModuleFileName, то все по старому в ListView заносится только путь к моей программе.

    ( Все эти действия я произвожу в отдельном потоке который после заполнения ListView списком процессов закрывается.
    Может проблема в этом.
    И еще - OllyDbg при отладке делает два прохода в цикле, а потом выпадает в ntdll и пишет Process terminated, exit code C0000008)

    2)
    Возможно это из-за того, что я не использую EnablePrivilege ( как я понимаю ты устанавливаешь необходимые привилегии своему процессу).
    Я использую такой код:

    Код (Text):
    1. ...
    2. push    ebp
    3.   mov     ebp, esp
    4.   sub     esp, 24h
    5.   push    esp
    6.   push    28h
    7.   push    -1
    8.   call    [OpenProcessToken]
    9.   test    eax, eax
    10.   jz      @F
    11.   lea     eax, [esp + 8]
    12.   push    eax
    13.   push    PrivName
    14.   push    0
    15.   call    [LookupPrivilegeValue]
    16.   test    eax, eax
    17.   jz      @F
    18.   mov     dword [esp + 14h], 1
    19.   mov     eax, [esp + 8]
    20.   mov     [esp + 18h], eax
    21.   mov     eax, [esp + 0Ch]
    22.   mov     [esp + 1Ch], eax
    23.   mov     dword [esp + 20h], 2
    24.   lea     eax, [esp + 10h]
    25.   push    eax
    26.   lea     eax, [esp + 18h]
    27.   push    eax
    28.   push    10h
    29.   lea     eax, [esp + 20h]
    30.   push    eax
    31.   push    0
    32.   mov     eax, [esp + 14h]
    33.   push    eax
    34.   call    [AdjustTokenPrivileges]
    35. @@:
    36.   leave
    37.   ...
    38. ( здесь получаю полный путь)  
    39.  ...
    3)
    Твой экзэшник скачал и посмотрел - да вот это я и хочу сделать

    4)
    Возможно посмотреть твои исходники ?
     
  9. GMax

    GMax Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    218
    NAGRIS
    1)
    А что у тебя за ось?
    Библиотека PSAPI.dll есть в наличие?
    Посмотри есть ли там такая функция.

    Про олю: на расстоянии определить ошибку не берусь.

    Привилегии (debug) нужны что бы получить доступ к некоторым системным процессам.
    3)
    :)

    4)
    Лучше давай я твои посмотрю.
     
  10. NAGRIS

    NAGRIS New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    17
    Gmax

    Windows XP SP2

    Библиотека PSAPI.dll есть.
    Такая функция там есть.

    В FASM не было psapi.inc переписал сам из MASM

    Посылаю исходник:
    http://www.rapidshare.ru/240622
     
  11. GMax

    GMax Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    218
    NAGRIS

    В библиотеке PSAPI.dll есть функция GetModuleFileNameExA (для обычных строк)
    и функция GetModuleFileNameExW(для юникода), а вот функции GetModuleFileNameEx -- нет.

    В psapi.inc у тебя надо написать вместо
    GetModuleFileNameEx, 'GetModuleFileNameEx',\
    так
    GetModuleFileNameEx, 'GetModuleFileNameExA',\

    И еще у тебя там есть ошибки с PropertySheet, у меня прога вылетала с ошибкой, пока не закоментил.

    Если все это поправить и раскоментить вариант с GetModuleFileNameEx то работает.

    А вообще присмотрись к библиотеке PSAPI.dll там есть хорошие функции для замены CreateToolhelp32Snapshot.
    В NT лучше использовать PSAPI.dll.
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    В NT лучше всего использовать собственные реализации :derisive:
     
  13. NAGRIS

    NAGRIS New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    17
    Спасибо буду разбираться
     
  14. NAGRIS

    NAGRIS New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    17
    GMax
    Спасибо, получилось