继续前一篇提到的问题。仍然是根据天杀的建议更专业一点的方法是通过判断当前进程的父进程来得知是如何运行的。比如,双击运行父进程就是Explore.exe,命令行运行,父进程就是 cmd.exe 。
代码如下:
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils,
windows,
Tlhelp32,
PsApi;
//检查自己的进程的父进程
procedure CheckParentProc;
var //检查自己的进程的父进程
Pn: TProcesseNtry32;
sHandle:THandle;
H,hMod:Hwnd;
Found:Boolean;
Buffer:array[0..1023]of Char;
cbNeeded:DWORD;
begin
//得到所有进程的列表快照
sHandle:= CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
Found:= Process32First(sHandle,Pn);//查找进程
while Found do //遍历所有进程
begin
//比较枚举出来的ID是否是当前的ID
if Pn.th32ProcessID = GetCurrentProcessId then
begin
//父进程的句柄
H:= OpenProcess(PROCESS_ALL_ACCESS,True,Pn.th32ParentProcessID);
if EnumProcessModules( H,@hMod,sizeof(hMod),cbNeeded) then
begin
ZeroMemory(@Buffer,MAX_PATH+1);
GetModuleFileNameEx(H, hMod,Buffer,MAX_PATH+1); //枚举进程文件所在路径
//只是简单把它打印出来而已
writeln(strpas(Buffer));
end;
CloseHandle(H);
end;
Found:= Process32Next(sHandle,Pn);//查找下一个
end;
CloseHandle(sHandle);
end;
begin
CheckParentProc;
readln;
end.
下图是这个程序分别在cmd窗口,直接双击和Delphi IDE环境中的运行结果。
完整代码下载
=============================================================
2022年01月24日补充 VC 下的实现方法
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <Psapi.h>
int getProcessName(DWORD pid, LPWSTR fname, DWORD sz)
{
HANDLE h = NULL;
int e = 0;
h = OpenProcess
(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
pid
);
if (h)
{
if (GetModuleFileNameEx(h, NULL, fname, sz) == 0)
e = GetLastError();
CloseHandle(h);
}
else
{
e = GetLastError();
}
return (e);
}
DWORD getParentPID(DWORD pid)
{
HANDLE h = NULL;
PROCESSENTRY32 pe = { 0 };
DWORD ppid = 0;
pe.dwSize = sizeof(PROCESSENTRY32);
h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (Process32First(h, &pe))
{
do
{
if (pe.th32ProcessID == pid)
{
ppid = pe.th32ParentProcessID;
break;
}
} while (Process32Next(h, &pe));
}
CloseHandle(h);
return (ppid);
}
boolean IsRuninCMD() {
DWORD pid, ppid;
int e;
wchar_t fname[256];
pid = GetCurrentProcessId();
ppid = getParentPID(pid);
e = getProcessName(ppid, fname, MAX_PATH);
wprintf(L"PPID=%d\nErr=%d\nEXE={%s}\n", ppid, e, fname);
if ((wcsstr(fname, L"cmd.exe") != NULL) ||
(wcsstr(fname, L"powershell.exe") != NULL)) {
return true;
} else return false;
}
void main(int argc, char* argv[])
{
if (IsRuninCMD()) {
printf("in cmd\n");
}
else {
printf("NOT in cmd\n");
getchar();
}
}