I made a little test program that uses the Toolhelp api to get all the processes and SHGetFileInfo to get the icon for the process. On a lot of processes it gets an access denied error and doesnt return the full path to the file, just the filename. BUT, if I load my test program in OllyDebug and run it from there, it gets all the processes with full path names just fine.

Is there something I can change in my program to get it to work right without being in Olly? :)


example of my failure:
Posted on 2003-07-07 13:47:15 by jcsn
After several false starts I have gotten no further. I'm not sure why some processes return access denied or how OllyDbg manages to avoid it. I used the following test code
SearchForProcess proc

LOCAL pe32 :PROCESSENTRY32
LOCAL me32 :MODULEENTRY32
LOCAL hProcessSnap :HANDLE
LOCAL hModuleSnap :HANDLE

mov pe32.dwSize,SIZEOF PROCESSENTRY32
mov me32.dwSize,SIZEOF MODULEENTRY32

invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
.IF eax == -1
ret
.ENDIF
mov hProcessSnap,eax
invoke Process32First, hProcessSnap, ADDR pe32
.IF eax==0
ret
.ENDIF

.WHILE eax
invoke SetLastError,0
invoke CreateToolhelp32Snapshot, TH32CS_SNAPMODULE, pe32.th32ProcessID
.IF eax != INVALID_HANDLE_VALUE
mov hModuleSnap,eax
invoke Module32First,hModuleSnap,ADDR me32
invoke CloseHandle,hModuleSnap
; Using a listbox ID=1002 to display the results
invoke SendDlgItemMessage, hDlg, 1002, LB_ADDSTRING,0, ADDR me32.szExePath
invoke SendDlgItemMessage, hDlg, 1002, LB_SETITEMDATA, eax, pe32.th32ProcessID
.ELSE
; VKim's debug
PrintError
.ENDIF
invoke Process32Next, hProcessSnap, ADDR pe32
.ENDW
invoke CloseHandle, hProcessSnap

ret
SearchForProcess endp
Posted on 2003-07-07 21:30:53 by donkey
Wow, somebody actually responded. :) My last thread was a complete failure.

I looked at LordPE in Olly to see how it enumerated the processes, since it works fine, and it uses the psapi stuff (EnumProcesses,etc). I tried those and it only lists the processes that had full path names using Toolhelp. :(

Madness!

Again, thanks for the reply. At least I'm not the only one. 8u)


Oh, my code's pretty much exactly the same as yours, but here it is in case there's any obvious failures:
invoke GetDlgItem, hWin, 1001

mov treeview, eax

mov tvs.hParent, NULL
mov tvs.hInsertAfter, TVI_LAST
mov tvs.item._mask, TVIF_IMAGE or TVIF_TEXT or TVIF_SELECTEDIMAGE

invoke GetModuleFileName, NULL, addr FilePath, 255
invoke SHGetFileInfo, addr FilePath, 0, addr sfi, sizeof sfi, SHGFI_SYSICONINDEX or \
SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES
invoke SendMessage, listview, TVM_SETIMAGELIST, 0, eax

invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
mov snap, eax
mov pe.dwSize, sizeof PROCESSENTRY32
invoke Process32First, snap, addr pe

.while eax
invoke CreateToolhelp32Snapshot, TH32CS_SNAPMODULE, pe.th32ProcessID
mov msnap, eax
mov me.dwSize, sizeof me
invoke Module32First, msnap, addr me

invoke SHGetFileInfo, offset me.szExePath, 0, addr sfi, sizeof sfi, SHGFI_SYSICONINDEX or \
SHGFI_USEFILEATTRIBUTES
push offset me.szExePath
pop tvs.item.pszText
mov tvs.item.cchTextMax, 512
push sfi.iIcon
push sfi.iIcon
pop tvs.item.iImage
pop tvs.item.iSelectedImage
invoke SendMessage, listview, TVM_INSERTITEM, 0, addr tvs

invoke CloseHandle, msnap
;mov pe.dwSize, sizeof pe - not needed?
invoke Process32Next, snap, addr pe
.endw

invoke CloseHandle, snap


Adds to a treeview using the icon of the process. I took out the checks to see if the module handle, etc were valid just to make sure I was getting the full list of everything running.

edit: made it..less wide. 8-)
Posted on 2003-07-07 21:43:38 by jcsn
Yeah, I was looking at psapi as well but that would limit the OS versions it could be run on to NT systems. I looked at GetModuleFileNameEx, but that one is Win2KPro and XP only. Obviously there is a way to do this but I can't figure it out :confused:
Posted on 2003-07-07 22:10:08 by donkey
Well, I looked around a bit and I think I have a solution. There was this article in the KB :

http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q228/4/69.ASP&NoWebContent=1

It seems to give a way to get a module name and path from a given PID. I don't have the time to look into right away but I can take a look later in the week. In my Win 98 test the full path was shown so I think you just have to verify the windows version and if it is NT then use the psapi functions (GetModuleFilenameEx) to extract the actual file name from the module.

Nah, just tried it and it doesn't do much better
SearchForProcess proc

LOCAL pe32 :PROCESSENTRY32
LOCAL me32 :MODULEENTRY32
LOCAL hProcessSnap :HANDLE
LOCAL hModuleSnap :HANDLE
LOCAL hProcess :HANDLE
LOCAL fNT :DWORD
LOCAL pGetModuleFileNameEx :DWORD
LOCAL pGetModuleBaseName :DWORD
LOCAL hPSAPI :HANDLE
LOCAL buffer[MAX_PATH] :BYTE

.data
szPSAPI BYTE "psapi.dll",0
szGetModuleFileNameEx BYTE "GetModuleFileNameExA",0
szGetModuleBaseName BYTE "GetModuleBaseNameA",0
.code

mov pe32.dwSize,SIZEOF PROCESSENTRY32
mov me32.dwSize,SIZEOF MODULEENTRY32

mov fNT,FALSE

invoke GetVersion
and eax,080000000h
.IF !eax
mov fNT,TRUE
invoke LoadLibrary,OFFSET szPSAPI
mov hPSAPI,eax
invoke GetProcAddress,hPSAPI,OFFSET szGetModuleFileNameEx
mov pGetModuleFileNameEx,eax
invoke GetProcAddress,hPSAPI,OFFSET szGetModuleBaseName
mov pGetModuleBaseName,eax
.ENDIF

invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,0
.IF eax == -1
ret
.ENDIF
mov hProcessSnap,eax
invoke Process32First,hProcessSnap,ADDR pe32
.IF eax==0
ret
.ENDIF

.WHILE eax
invoke SetLastError,0
invoke CreateToolhelp32Snapshot,TH32CS_SNAPMODULE,pe32.th32ProcessID
mov hModuleSnap,eax
invoke Module32First,hModuleSnap,ADDR me32
invoke CloseHandle,hModuleSnap
; Using a listbox ID=1002 to display the results
.if fNT == TRUE
invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,pe32.th32ProcessID
mov hProcess,eax
push MAX_PATH
lea eax,buffer
push eax
push me32.hModule
push hProcess
call pGetModuleFileNameEx
invoke CloseHandle,hProcess
invoke SendDlgItemMessage, hDlg, 1002, LB_ADDSTRING,0, ADDR buffer
invoke SendDlgItemMessage, hDlg, 1002, LB_SETITEMDATA, eax, pe32.th32ProcessID
.else
invoke SendDlgItemMessage, hDlg, 1002, LB_ADDSTRING,0, ADDR me32.szExePath
invoke SendDlgItemMessage, hDlg, 1002, LB_SETITEMDATA, eax, pe32.th32ProcessID
.endif

invoke Process32Next,hProcessSnap,ADDR pe32
.ENDW
invoke CloseHandle,hProcessSnap

ret
SearchForProcess endp
You have to load the psapi dll and call the functions becasue the program will not run on 9x if you use the lib file. Well, a little further along and still no results :rolleyes:
Posted on 2003-07-07 23:34:45 by donkey
I think I read in the Toolhelp stuff that the module # couldn't be used with any api other than the Toolhelp stuff. Maybe you have to use all psapi stuff to enumerate the processes, modules, etc? I'll look into it, thanks. 8-)

edit: yeah:
th32ModuleID
Module identifier in the context of the owning process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by functions other than the ToolHelp functions.


edit2: oh, you're using hModule, nevermind :)
Posted on 2003-07-08 00:12:15 by jcsn
I don't know if this will help? But it's something I was messing about with a few months ago and never
really got around to finishing. It's mostly psapi.dll based with a bit of Toolhelp stuff to backup
where psapi fails.

arz
Posted on 2003-07-08 10:56:39 by arz
Wow, works great, arz. :alright:

Thanks :)
Posted on 2003-07-08 12:28:11 by jcsn



Is there something I can change in my program to get it to work right without being in Olly? :)




Enable the SE_DEBUG_NAME priviledge in your process.

I assume Olly is doing this for you automagically, since it is a debugger.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/enabling_and_disabling_privileges.asp
Posted on 2003-07-08 18:22:57 by Mecurius
Ahhh, thanks! :alright:
Posted on 2003-07-08 18:25:13 by jcsn