uses TlHelp32;procedure TForm1.Button1Click(Sender: TObject); var hSnapshot: Cardinal; me: TModuleEntry32; begin hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId); FillChar(me, SizeOf(me), 0); me.dwSize := SizeOf(me); if not Module32First(hSnapshot, me) then Exit; repeat Memo1.Lines.Add(me.szExePath); until not Module32Next(hSnapshot, me); end;
如果是动态调用dll怎么知道?
var
hSnapshot: Cardinal;
me: TModuleEntry32;
begin
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId);
FillChar(me, SizeOf(me), 0);
me.dwSize := SizeOf(me);
if not Module32First(hSnapshot, me) then Exit;
repeat
Memo1.Lines.Add(me.szExePath);
until not Module32Next(hSnapshot, me);
end;
查了一下资料,好像GetCurrentProcessId这句,换成其它进程的句柄就行了,不知,用哪个api?
var
hProcessSnapshot, hModuleSnapshot: Cardinal;
pe: TProcessEntry32;
me: TModuleEntry32;
ProcessNode: TTreeNode;
procedure AdjustPrivileges;
var
hToken: Cardinal;
tp: TTokenPrivileges;
nSize: Cardinal;
begin
if not OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, hToken) then Exit;
tp.PrivilegeCount := 1;
LookupPrivilegeValue(nil, 'SeDebugPrivilege', tp.Privileges[0].Luid);
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, False, tp, SizeOf(tp), tp, nSize);
CloseHandle(hToken);
end;
begin
AdjustPrivileges;
ATreeView.Items.BeginUpdate;
try
hProcessSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
pe.dwSize := SizeOf(pe);
me.dwSize := SizeOf(me);
Process32First(hProcessSnapshot, pe);
repeat
ProcessNode := ATreeView.Items.AddChild(nil, pe.szExeFile);
hModuleSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPALL, pe.th32ProcessID);
Module32First(hModuleSnapshot, me);
repeat
ATreeView.Items.AddChild(ProcessNode, me.szModule);
until not Module32Next(hModuleSnapshot, me);
CloseHandle(hModuleSnapshot);
until not Process32Next(hProcessSnapshot, pe);
CloseHandle(hProcessSnapshot);
finally
ATreeView.Items.EndUpdate;
end;
end;
没太明白,这个过程怎么赋值?我在窗体上加入了TreeView控件,感觉好像没有什么用,在代码中体现不了?
不知,能否对进程进行操作,在treeview1k中.
如果能做到结束进程,结束dll的话,我愿意给6楼50分.结束进程或dll的方式不一定仿系统的进程管理器哪样,只要能结束就行.如双击,或单击鼠标结束.经常遇到一些dll文件不能删除,非要用冰刃去系统的每个进程中查找指定的模块卸载后方能删除.
var
hProcessSnapshot, hModuleSnapshot: Cardinal;
pe: TProcessEntry32;
me: TModuleEntry32;
ProcessNode: TTreeNode;
procedure AdjustPrivileges;
var
hToken: Cardinal;
tp: TTokenPrivileges;
nSize: Cardinal;
begin
if not OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, hToken) then Exit;
tp.PrivilegeCount := 1;
LookupPrivilegeValue(nil, 'SeDebugPrivilege', tp.Privileges[0].Luid);
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, False, tp, SizeOf(tp), tp, nSize);
CloseHandle(hToken);
end;
begin
AdjustPrivileges;
ATreeView.Items.BeginUpdate;
try
hProcessSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
pe.dwSize := SizeOf(pe);
me.dwSize := SizeOf(me);
Process32First(hProcessSnapshot, pe);
repeat
ProcessNode := ATreeView.Items.AddChild(nil, pe.szExeFile);
hModuleSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPALL, pe.th32ProcessID);
Module32First(hModuleSnapshot, me);
repeat
ATreeView.Items.AddChild(ProcessNode, me.szExePath).Data := Pointer(pe.th32ProcessID);
until not Module32Next(hModuleSnapshot, me);
CloseHandle(hModuleSnapshot);
until not Process32Next(hProcessSnapshot, pe);
CloseHandle(hProcessSnapshot);
finally
ATreeView.Items.EndUpdate;
end;
end;procedure UnloadDll(ProcessId: Cardinal; DllName: string);
const
MAX_TRY = 10;
var
hProcess: Cardinal;
pBuf, pFreeLibrary, pGetModuleHandle: Pointer;
hThread, ThreadId, hDll, FreeCount: Cardinal;
DllPath: array[0..MAX_PATH] of Char;
begin
pBuf := nil;
FreeCount := 0;
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
if hProcess = 0 then Exit;
try
FillChar(DllPath, SizeOf(DllPath), 0);
StrCopy(DllPath, PChar(DllName));
pBuf := VirtualAllocEx(hProcess, nil, SizeOf(DllPath), MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, pBuf, @DllPath, SizeOf(DllPath), hDll);
pFreeLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'), 'FreeLibrary');
pGetModuleHandle := GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetModuleHandleA');
while FreeCount < MAX_TRY do
begin
hThread := CreateRemoteThread(hProcess, nil, 0, pGetModuleHandle, pBuf, 0, ThreadId);
GetExitCodeThread(hThread, hDll);
CloseHandle(hThread);
if hDll = 0 then Break;
hThread := CreateRemoteThread(hProcess, nil, 0, pFreeLibrary, Pointer(hDll), 0, ThreadId);
CloseHandle(hThread);
Inc(FreeCount);
end;
finally
if pBuf <> nil then VirtualFree(pBuf, Length(DllName) + 1, MEM_FREE);
if hProcess <> 0 then CloseHandle(hProcess);
end;
end;procedure TForm1.TreeView1DblClick(Sender: TObject);
begin
if (TreeView1.Selected = nil) or (TreeView1.Selected.Data = nil) then Exit;
UnloadDll(Cardinal(TreeView1.Selected.Data), TreeView1.Selected.Text);
end;procedure TForm1.Button1Click(Sender: TObject);
begin
TreeView1.Items.Clear;
FillProcessTree(TreeView1);
end;
有些能卸载,有些卸载不了,你自己试
?
WriteProcessMemory(hProcess, pBuf, @DllPath, SizeOf(DllPath), hDll);
pFreeLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'), 'FreeLibrary');
这些代码,在dll注入系统进程中看到过,难道也可以在要被结束的dll中创建空间吗?