Jump to content
Tuts 4 You

Get Process List without using any APIs


Kabamaru

Recommended Posts

#include <windows.h>

#include <tlhelp32.h>

#include <stdio.h>

int usage() ;

void EnumProcesses() ;

BOOL KillProcess(int pid) ;

void EnumModule(int pid) ;

void EnumThread(int pid) ;

int main(int argc, char *argv[])

{

BOOL isKilled ;

if (argc == 1)

{

usage() ;

}

else if (!strncmp(argv[1], "/l", 2))

{

EnumProcesses() ;

}

else if (!strncmp(argv[1], "/k",2) && argv[2] != NULL)

{

isKilled = KillProcess(atoi(argv[2])) ;

if (isKilled)

{

printf("Clear Process List!:-)\n") ;

}

else

{

printf("Fail!:-(\n") ;

}

}

else if (!strncmp(argv[1], "/m",2) && argv[2] != NULL)

{

EnumModule(atoi(argv[2])) ;

}

else if (!strncmp(argv[1], "/?", 2))

{

usage() ;

}

else

{

printf("Wrong Arguments!\n") ;

usage() ;

}

}

int usage()

{

printf("\n") ;

printf("-----------------------------\n") ;

printf("[Process List v1.0]\n\n") ;

printf("-----------------------------\n") ;

printf("usage:pi /l /k [PID] /m[PID]\n") ;

printf("/l:List all the process\n") ;

printf("/k [PID]:Clear the process\n") ;

printf("/m [PID]:Process List") ;

printf("\n-----------------------------\n") ;

printf("\n") ;

return 0 ;

}

void EnumProcesses()

{

HANDLE hSnapshot ;

BOOL ret ;

TCHAR *szPid = TEXT("PID") ;

TCHAR *iCntThreads = TEXT("Threads") ;

TCHAR *szExeFile = TEXT("Executable") ;

PROCESSENTRY32 pe32 ;

pe32.dwSize = sizeof(PROCESSENTRY32) ;

hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ;

if (INVALID_HANDLE_VALUE == hSnapshot)

{

printf("Error Number: %d", GetLastError()) ;

ExitProcess(1) ;

}

ret = Process32First(hSnapshot, &pe32) ;

printf("%5s%15s%25s\n", szPid, iCntThreads, szExeFile) ;

printf("==============================================\n") ;

while(ret)

{

printf("%5d%15d%25s\n",pe32.th32ProcessID, pe32.cntThreads, pe32.szExeFile) ;

ret = Process32Next(hSnapshot, &pe32) ;

}

CloseHandle(hSnapshot) ;

}

BOOL KillProcess(int pid)

{

BOOL ret ;

HANDLE hToken ;

HANDLE hProcess ;

TOKEN_PRIVILEGES tp ;

ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ;

if (ret == 0)

{

printf("Error Number:%d\n", GetLastError()) ;

ExitProcess(1) ;

}

LookupPrivilegeValue(NULL, "SeDebugPrivilege", &tp.Privileges[0].Luid) ;

tp.PrivilegeCount = 1 ;

tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED ;

ret = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL) ;

if (ret != 0)

{

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid) ;

if (hProcess == NULL)

{

printf("Error Number:%d\n", GetLastError()) ;

ExitProcess(1) ;

}

ret = TerminateProcess(hProcess, 1) ;

if (ret == 0)

{

return FALSE ;

}

WaitForSingleObject(hProcess, 5000) ;

}

CloseHandle(hToken) ;

return TRUE ;

}

void EnumModule(int pid)

{

HANDLE hSnapshot ;

MODULEENTRY32 me32 ;

BOOL ret ;

hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid) ;

me32.dwSize = sizeof(MODULEENTRY32) ;

ret = Module32First(hSnapshot, &me32) ;

printf("Process ID:%d[Module Infomation]\n", pid) ;

printf("==============================================\n") ;

while(ret)

{

printf("Mudule Name = %s\n",me32.szModule) ;

printf("Usage Count(Global) = %d\n", me32.GlblcntUsage) ;

printf("Usage Count(Process) = %d\n", me32.GlblcntUsage) ;

printf("Base Address = 0x%x\n", me32.modBaseAddr) ;

printf("Base Size = %d??\n", me32.modBaseSize) ;

printf("Executable = %s\n", me32.szExePath) ;

printf("\n\n") ;

ret = Module32Next(hSnapshot, &me32) ;

}

}

Link to comment

I guess it's possible inside ring0, but no way you could achieve that in a normal ring3 process.

You can resort to official APIs like the code NikolayD provided (alternatively you can use psapi), or use the more or less documented NT APIs.

Link to comment

Thank you both for your time and help.

But I found a code that suppose to bring back all the processes without using any APIs at all. (Ring3)

No EnumProcesses, no CreateToolhelp32Snapshot.

But i can't port it successfully to Delphi asm.

Edited by Kabamaru
Link to comment

Well here's a startling new way to look at this situation:

1. You are already in possession of code which claims to achieve what you desire, but can't port to Delphi.

2. You're asking members of this forum for help on how to achieve the same end result.

3. You have been given an example but unfortunately it uses API which is one of your requirements: No API.

Just from these three things i can see something which may improve your chances of gaining the help you so bady want, post your example source code and see if someone can help port it over to Delphi. If it is private source which isn't to be shared, then it places you in a dilly of a pickle, because then it raises the question of:

'Why does this person have access to private source they can't use and how stupid do they think everybody else is, to come asking for help with their situation but not being prepared to disclose any information themselves?'

The nature of your request also makes me ask myself:

'What possible reason could a person have for wanting to list all active processes on a PC without using API?'

Try as i might, i can only think that something shady or questionable is intended, correct me if i'm wrong though.

HR,

Ghandi

Link to comment

I agree with ghandi.

As a reverser of assembler to Delphi, I assure you everything can be reversed without much problem, so don't hesitate to ask for the doubts you keep on reversing certain instructions... ;)

Anyway, the best you can do always is trying of reproduce the behaviour of those instructions into Delphi sentences and going testing with the Delphi's debugger. And Delphi's asm is much nearly the same than asm...

Best regards

Nacho_dj

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...