function GetNameByPid(Pid: dword): string;
var
hProcess, Bytes: dword;
Info: PROCESS_BASIC_INFORMATION;
ProcessParametres: pointer;
ImagePath: TUnicodeString;
ImgPath: array[0..MAX_PATH] of WideChar;
begin
Result := '';
ZeroMemory(@ImgPath, MAX_PATH * SizeOf(WideChar));
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, Pid);
if ZwQueryInformationProcess(hProcess, ProcessBasicInformation, @Info,
SizeOf(PROCESS_BASIC_INFORMATION), nil) = STATUS_SUCCESS then
begin
if ReadProcessMemory(hProcess, pointer(dword(Info.PebBaseAddress) + $10),
@ProcessParametres, SizeOf(pointer), Bytes) and
ReadProcessMemory(hProcess, pointer(dword(ProcessParametres) + $38),
@ImagePath, SizeOf(TUnicodeString), Bytes) and
ReadProcessMemory(hProcess, ImagePath.Buffer, @ImgPath,
ImagePath.Length, Bytes) then
begin
Result := ExtractFileName(WideCharToString(ImgPath));
end;
end;
CloseHandle(hProcess);
end;
Получение дескрипторы приложения через DLLMain
Вопрос такой:при вызове DLLMain ей передаются 3 параметра,один из которых является дескриптором модуля.Так вот,это дескриптор самой DLL'ки или приложения,к которому она была подключена?И как,во втором случае,узнать имя приложения(а лучше дескриптор)?
(Реализация-на Ассемблере)
получение имени через ID найдешь на форуме (поиск рулит :))
есть более навороченный код который получает полный путь, но он требует Native API
Код:
а дескриптор через OpenProcess
А разве нет апишки для получения имени процесса по Id?Вроде бы была.В крайнем случае-EnumProcess:rolleyes:
не нравится предыдущая , тогда вот стандартная
Код:
Function GetProcessName(ProcessID:DWORD):string;
var Snapshot:THandle;
Process: TPROCESSENTRY32;
begin
result:='';
Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Snapshot = INVALID_HANDLE_VALUE then exit;
Process.dwSize := SizeOf(TPROCESSENTRY32);
if Process32First(SnapShot, Process) then
repeat
if ProcessID=Process.th32ProcessID then
begin
Result := Process.szExeFile;
CloseHandle(Snapshot);
Exit;
end;
until not Process32Next(Snapshot, Process);
CloseHandle(Snapshot);
end;
var Snapshot:THandle;
Process: TPROCESSENTRY32;
begin
result:='';
Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Snapshot = INVALID_HANDLE_VALUE then exit;
Process.dwSize := SizeOf(TPROCESSENTRY32);
if Process32First(SnapShot, Process) then
repeat
if ProcessID=Process.th32ProcessID then
begin
Result := Process.szExeFile;
CloseHandle(Snapshot);
Exit;
end;
until not Process32Next(Snapshot, Process);
CloseHandle(Snapshot);
end;
чем тебя вышеприведённая не устранивает? она получает полный путь к экзешнику, а если надо только имя, то используй ExtractFileName
Цитата: @pixo $oft
Я хочу написать DLL'ку,которая будет внедряться в каждое запускаемое приложение и писать в лог,какое приложение было запущено.
Цитирую MSDN.
If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
Т. е. можно вызвать GetModuleFileName и первым параметром передать NULL, тебе вернется полный путь к exe.
Я в общем-то сам догадался,когда вспомнил.Дооолго не мог придумать,что бы впихнуть в hModule,но потом вспомнил Visual Basic:) и то,что следовало тыкнуть 0
Код:
.386
.Model Flat,StdCall
Include ..\Include\Kernel32.inc
IncludeLib ..\Lib\Kernel32
.Data?
szBuf DB 266 Dup(?)
.Code
hFile DD ?
dwLen DD ?
dwBytes DD ?
;SystemTime
wYear DW ?
wMonth DW ?
wDayOfWeek DW ?
wDay DW ?
wHour DW ?
wMinute DW ?
wSecond DW ?
wMillisecond DW ?
;End
szFile DB 'Data.log',0
DLLMain:Mov EAX,[ESP+8]
Test EAX,EAX
JNZ MaybeAttach
Push Word Ptr 2
Call WriteInfo
Jmp StdExit
MaybeAttach:Dec EAX
Test EAX,EAX
JNZ StdExit
Push Word Ptr 0
Call WriteInfo
StdExit:XOr EAX,EAX
Inc EAX
Ret 12
WriteInfo:Mov EDI,Offset szBuf
Mov DWord Ptr[EDI],976236587
Mov DWord Ptr[EDI+4],809119792
Mov Word Ptr[EDI+8],11568 ;Обнуление полей "+00:00:00-"(<загрузка/выгрузка>чч:мм:сс-)
Mov AL,[ESP+4]
Add [EDI],AL ;Формирование знака +/-(модуль загружен/выгружен)
Inc EDI
Invoke GetLocalTime,Offset wYear
Mov CL,10
Mov AX,wHour
Div CL
Add [EDI+1],AH
Add [EDI],AL ;Час
Mov AX,wMinute
Div CL
Add [EDI+4],AH
Add [EDI+3],AL ;Минута
Mov AX,wSecond
Div CL
Add [EDI+7],AH
Add [EDI+6],AL ;Секунда
Add EDI,9
Invoke GetModuleFileName,0,EDI,254
Test EAX,EAX
JZ Exit
Mov Word Ptr[EAX+EDI],2573
Inc EAX
Inc EAX
Mov dwLen,EAX
Invoke CreateFile,Offset szFile,1073741824,3,0,4,0,0
Test EAX,EAX
JS Exit
Mov hFile,EAX
Invoke SetFilePointer,EAX,0,0,2
Invoke WriteFile,hFile,EDI,dwLen,Offset dwBytes,0
Invoke CloseHandle,hFile
Exit:Ret 2
End DLLMain
.Model Flat,StdCall
Include ..\Include\Kernel32.inc
IncludeLib ..\Lib\Kernel32
.Data?
szBuf DB 266 Dup(?)
.Code
hFile DD ?
dwLen DD ?
dwBytes DD ?
;SystemTime
wYear DW ?
wMonth DW ?
wDayOfWeek DW ?
wDay DW ?
wHour DW ?
wMinute DW ?
wSecond DW ?
wMillisecond DW ?
;End
szFile DB 'Data.log',0
DLLMain:Mov EAX,[ESP+8]
Test EAX,EAX
JNZ MaybeAttach
Push Word Ptr 2
Call WriteInfo
Jmp StdExit
MaybeAttach:Dec EAX
Test EAX,EAX
JNZ StdExit
Push Word Ptr 0
Call WriteInfo
StdExit:XOr EAX,EAX
Inc EAX
Ret 12
WriteInfo:Mov EDI,Offset szBuf
Mov DWord Ptr[EDI],976236587
Mov DWord Ptr[EDI+4],809119792
Mov Word Ptr[EDI+8],11568 ;Обнуление полей "+00:00:00-"(<загрузка/выгрузка>чч:мм:сс-)
Mov AL,[ESP+4]
Add [EDI],AL ;Формирование знака +/-(модуль загружен/выгружен)
Inc EDI
Invoke GetLocalTime,Offset wYear
Mov CL,10
Mov AX,wHour
Div CL
Add [EDI+1],AH
Add [EDI],AL ;Час
Mov AX,wMinute
Div CL
Add [EDI+4],AH
Add [EDI+3],AL ;Минута
Mov AX,wSecond
Div CL
Add [EDI+7],AH
Add [EDI+6],AL ;Секунда
Add EDI,9
Invoke GetModuleFileName,0,EDI,254
Test EAX,EAX
JZ Exit
Mov Word Ptr[EAX+EDI],2573
Inc EAX
Inc EAX
Mov dwLen,EAX
Invoke CreateFile,Offset szFile,1073741824,3,0,4,0,0
Test EAX,EAX
JS Exit
Mov hFile,EAX
Invoke SetFilePointer,EAX,0,0,2
Invoke WriteFile,hFile,EDI,dwLen,Offset dwBytes,0
Invoke CloseHandle,hFile
Exit:Ret 2
End DLLMain
Если кто не понял,DLL'ка подгружается к каждому процессу и при DLLProcessAttach и DLLProcessDetach пишет в лог статус приложения(запущено "+",завершено "-"),время и имя приложения,используя процедуру WriteInfo.Может,не следовало писать Push Word Ptr 2?Или у константы OpenAlways есть свои заморочки?
Helplz!!!
Вот и справился с проблемой!Всего-то заменил передачу параметров через стек на регистровую(через EAX) и кое-что подправил,и никаких Error_NoAxeAss:).Правда,кое-какие ошибки проскакивают,но на работоспособность DLL'ки они не влияют-все процессы записываются в лог(правда,без командной строки,но это мелочи-легко исправить).Всем спасибо(только 2 человека пытались мне помочь:rolleyes:...Ай-яй-яй).Теме можно сделать Alt+F4:D