Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> узнать имя файла DOS-приложения по окну, для Win 98/2k/XP (32-bit APP - не нужно) 
:(
    Опции темы
wadim
Дата 10.3.2009, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 19.10.2006
Где: г.Тамбов

Репутация: нет
Всего: нет



Народ, помогите узнать путь/имя файла чужого DOS-приложения по его окну.
Моё 32-разрядное приложение должно работать в Windows 98/2k/XP/Vista

Поиск дал ответ на тот же вопрос но только для 32-разрядного чужого приложения.

Перечислить окна, процессы, модули, потоки - могу.

Попытка использования под XP функции VDMEnumTaskWOWEx из VDMDBG.DLL мне не помогла:
1) перечислены не все DOS-задачи, хотя вызывалась для всех PID, у которых имя модуля ntvdm.exe или класс окна ConsoleWindowClass
2) неизвестно, как ассоциировать даже и найденные 16-разрядные модули с каким-то конкретным окном.

Спасибо.
PM MAIL   Вверх
dumb
Дата 11.3.2009, 02:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



Цитата(http://support.microsoft.com/kb/182559)
Note Regarding 16-bit DOS Applications
None of the VDMDBG functions work with 16-bit DOS applications. To enumerate DOS VDMs, you need to use another method. First, you could use VDMEnumProcessWOW() to make a list of all Win16 VDMs, and then enumerate all instances of NTVDM.exe using some other scheme (such as PSAPI). Any NTVDM.exe from the full enumeration that was not in the Win16 list is a DOS VDM.

так что простого способа нет.

при беглом осмотре в экспортах ntvdm.exe была обнаружена недокументированная функция GetDOSAppName, которая, возможно и "скажет правду". но чтобы ее вызывать, надо находиться в адресном пространстве целевого ntvdm.exe. т.е. нужно создать поток через CreateRemoteThread(ну или вгружаться через AppInit и там локально создавать) и в контексте этого потока вызывать эту функцию.

возникает вопрос: а оно тебе надо? smile
PM MAIL   Вверх
wadim
Дата 11.3.2009, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 19.10.2006
Где: г.Тамбов

Репутация: нет
Всего: нет



Цитата
возникает вопрос: а оно тебе надо?

ДА, НАДО И ОЧЕНЬ.
(заголовок окна может быть изменён после запуска DOS-приложения или с помощью pif-файлов, поэтому мне нужно привязываться к имени файла)

По первой части. Попробую перечислить копии VDM и их исследовать.

По второй части:
Я готов использовать CreateRemoteThread для создания потока в ntvdm.exe - проблемы не вижу, передать полученную в этом потоке информацию в своё приложение смогу.
Но не понял, как мне это поможет. Ведь:
1) параметры GetDOSAppName неизвестны
2) как насчёт ассоциации с окном ?
3) а как это в Win98 ?

Ответ на вопрос пока не получен.
Может быть необходимо породить 16-разрядное приложение и из него получить требуемое ?
Если так - подскажите как в 16-разрядном приложении можно получить по окну имя файла программы - его владельца.
PM MAIL   Вверх
dumb
Дата 11.3.2009, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



Цитата(wadim @  11.3.2009,  10:25 Найти цитируемый пост)
1) параметры GetDOSAppName неизвестны
там один параметр - буфер для получения имени

Цитата(wadim @  11.3.2009,  10:25 Найти цитируемый пост)
2) как насчёт ассоциации с окном ?
из того же созданного потока вызови GetConsoleWindow

Цитата(wadim @  11.3.2009,  10:25 Найти цитируемый пост)
3) а как это в Win98 ?
именно это - никак. там, возможно, есть альтернативное решение(возможно даже более простое).

Цитата(wadim @  11.3.2009,  10:25 Найти цитируемый пост)
Может быть необходимо породить 16-разрядное приложение и из него получить требуемое ?
можно "породить" dos'овый резидент с перехватом 21h/4bh, который будет тупо записывать имя запускаемого приложения в какой-либо файл.

Цитата(wadim @  11.3.2009,  10:25 Найти цитируемый пост)
Ответ на вопрос пока не получен.
такие фразы лучше приберечь для какой-либо платной поддержки, ага.
PM MAIL   Вверх
wadim
Дата 11.3.2009, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 19.10.2006
Где: г.Тамбов

Репутация: нет
Всего: нет



Извини, dumb, обидеть не хотел smile . Спасибо.
Ожидал, честно говоря, что ответов будет больше и инвариантнее.

PM MAIL   Вверх
dumb
Дата 12.3.2009, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



немного покопал GetDOSAppName - она берет путь к программе из блока окружения(environment block - сегментный адрес оного находится в PSP(program segment prefix) по смещению 0x2C). соответственно, если дос-программа освободит этот блок окружения(так делают, например, резиденты и экстендеры), то функция вернет пустую строку. но случай этот нечастый. чаще пустая строка получается, если активным является command.com(не cmd.exe, а именно command.com).

попутно набросал болванку(правда на асме, готовая .dll в аттаче):
Код

.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

;DEBUG_LOG   equ "s:\dosapp.log"
FIRST_DELAY equ 3000 ;ms
INTERVAL    equ 500 ;ms
MAPBUF_SIZE equ 16384 ;bytes

.data

IFDEF DEBUG_LOG
crlf        db 0dh, 0ah
logname     db DEBUG_LOG,0
someerror   db "error!",0
ENDIF

szNtvdm     db "ntvdm.exe",0
szGetDOSAppName db "GetDOSAppName",0
szSetMSW    db "setMSW",0
szGetMSW    db "getMSW",0
szMutexName db "GetDosAppNames_Mutex",0
szMapName   db "GetDosAppNames_MMF",0

.code

; ,d:\Projects\home\asm\inj_dll\injdll.dll

Thread proto :DWORD

;===============================================
IFDEF DEBUG_LOG

LOG proc buf:PCHAR
  LOCAL rw:DWORD
  
  push      ebx
  invoke    CreateFileA, addr logname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
  inc       eax
  jz        @@ret
  dec       eax
  mov       ebx, eax
  invoke    SetFilePointer, ebx, 0, NULL, FILE_END
  
  xor       ecx, ecx
  xor       eax, eax
  mov       edx, buf
@@nextc:
  mov       al, [edx]
  or        eax, eax
  jz        @@endstr
  inc       edx
  inc       ecx
  jmp       @@nextc
@@endstr:  
  invoke    WriteFile, ebx, buf, ecx, addr rw, NULL
  invoke    WriteFile, ebx, addr crlf, 2, addr rw, NULL
  invoke    CloseHandle, ebx
@@ret:
  pop       ebx
  ret
LOG endp
ENDIF

;===============================================
DllMain proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD
  cmp       reason, DLL_PROCESS_ATTACH
  jnz       @@exit
  invoke    GetModuleHandleA, addr szNtvdm
  or        eax, eax
  jz        @@exit
  invoke    CreateThread, 0, 0, offset Thread, INTERVAL, 0, 0
@@exit:
  mov       eax, 1
  ret
DllMain Endp

;===============================================
Thread proc prm:DWORD

LOCAL hMutex  :HANDLE
LOCAL hMap    :HANDLE
LOCAL hWnd    :HWND
LOCAL pSetMSW :DWORD
LOCAL pGetMSW :DWORD
LOCAL pGetApp :DWORD
LOCAL buffer[200h]:BYTE

  push      esi
  push      edi
  push      ebx
  xor       ebx, ebx
  xor       edi, edi
  mov       hMutex, ebx
  mov       hMap, ebx

  invoke    Sleep, FIRST_DELAY

  invoke    GetModuleHandleA, addr szNtvdm
  or        eax, eax
  jz        @@exit
  mov       esi, eax

  invoke    GetProcAddress, esi, offset szGetDOSAppName
  or        eax, eax
  jz        @@erra
  mov       pGetApp, eax

  invoke    GetProcAddress, esi, offset szSetMSW
  or        eax, eax
  jz        @@erra
  mov       pSetMSW, eax
  
  invoke    GetProcAddress, esi, offset szGetMSW
  or        eax, eax
  jz        @@erra
  mov       pGetMSW, eax

  invoke    CreateMutex, 0, FALSE, addr szMutexName
  or        eax, eax
  jz        @@exit
  mov       hMutex, eax

  invoke    CreateFileMapping, INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAPBUF_SIZE, addr szMapName
  or        eax, eax
  jz        @@exit
  mov       hMap, eax
  
  invoke    MapViewOfFile, hMap, FILE_MAP_ALL_ACCESS, 0, 0, MAPBUF_SIZE
  or        eax, eax
  jz        @@exit
  mov       edi, eax
  
@@again:
  invoke    Sleep, prm

  invoke    GetConsoleWindow
  or        eax, eax
  jz        @@exit
  mov       hWnd, eax
; do some street magic
  call      pGetMSW
  push      eax
  and       eax, not 1
  push      eax
  call      pSetMSW
  lea       eax, buffer
  push      eax
  call      pGetApp ; get app name from env.block (PSP[0x2C]:0)
  call      pSetMSW ; arg already on stack
  
  invoke    WaitForSingleObject, hMutex, 1000
  cmp       eax, WAIT_OBJECT_0
  jnz       @@exit ; oO

  ; find old rec and refresh, or add new rec
  mov       eax, hWnd
  mov       edx, edi
  mov       ecx, [edx] ; count
  add       edx, 4
  jecxz     @@addnew
  cmp       ecx, (MAPBUF_SIZE-4) / (4 + 256) - 2 ; hWnd(4) + filename(256)
  jae       @@free ; log full, skip write
@@find:
  cmp       [edx], eax
  je        @@fill
  add       edx, 260
  dec       ecx
  jnz       @@find
@@addnew:
  inc       dword ptr [edi]
@@fill:
  mov       [edx], eax
  add       edx, 4
  invoke    lstrcpyn, edx, addr buffer, 255
@@free:
  invoke    ReleaseMutex, hMutex

IFDEF DEBUG_LOG2FILE  
  cmp       buffer[0], bl
  jz        @@again ; don't write empty strings in log
  invoke    LOG, addr buffer
ENDIF

  jmp       @@again
@@erra:
;  invoke    log, addr someerror
@@exit:
  or        edi, edi
  jz        @F
  invoke    UnmapViewOfFile, edi
@@:
  cmp       hMap, eax
  jz        @F
  invoke    CloseHandle, hMap
@@:
  cmp       hMutex, eax
  jz        @F
  invoke    CloseHandle, hMutex
@@:
  pop       ebx
  pop       edi
  pop       esi
  ret
Thread endp

  end       DllMain


эта .dll, будучи вгруженной в процесс(посредством CreateRemoteThread или AppInit_DLLs), создает поток, в котором периодически "дергает" GetDOSAppName и записывает результаты в MMF(TMappedLog):
Код

// структура одного элемента
TDosName = packed struct
  hwnd: Dword; // хэндл консольного окна
  name: array[0..255] of byte; // имя запущенной дос-программы
end;

// структура всего memory mapped file лога
PMappedLog = ^TMappedLog;
TMappedLog = packed struct
  count: Dword; // кол-во эл-тов
  names: array[0..count-1] of TDosName; // не компилируемо, но суть ясна
end;    


как использовать(схематично smile):
Код

  //предполагается, что все уже инжектировано - тут просто чтение
  hMutex = CreateMutex(0, false, 'GetDosAppNames_Mutex');
  if hMutex = 0 exit;
  hMap = CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, 16384, 'GetDosAppNames_MMF');
  if hMap = 0 exit; // здесь и далее вместо exit должны быть предварительно закрыты уже открытые хэндлы
  PMappedLog pLog = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 16384);
  if pLog = nil exit;
  if WaitForSingleObject(hMutex, 1000) = WAIT_OBJECT_0 then begin
    for i = 0 to pLog^.count do begin
      // вычитываем все имена
    end
    FillChar(pLog, 16384, 0); // очищаем
    ReleaseMutex(hMutex);
  end
  UnmapViewOfFile(pLog);
  CloseHandle(hMap);
  CloseHandle(hMutex);


Добавлено через 1 минуту и 40 секунд
ps. кстати, в win98, по идее, дос-процессы должны перечисляться(обычными методами) наравне с win-процессами.

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  injdll.rar 2,43 Kb
PM MAIL   Вверх
wadim
Дата 12.3.2009, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 19.10.2006
Где: г.Тамбов

Репутация: нет
Всего: нет



спасибо. бум испытать...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1267 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.