有关 消息 服务 进程(200分)(200分)

  • 主题发起人 heven_mingguo
  • 开始时间
H

heven_mingguo

Unregistered / Unconfirmed
GUEST, unregistred user!
1。一个进程向系统广播消息,另外一个进程如何响应。
2。如何判断一个进程是由用户启动的,还是由系统启动的。
3。我做一个程序,用来把其它程序加到win2000的服务中加是加进去了。但是
在服务里面启动的时候提示出错,1053错误码,启不了。
以上都是vc++实现,请高手赐教。解决任一问题200分。
 
大富翁的高手们,请赐教啊。
 
怎么几天没有一个人回答啊。
看来大富翁也不过如此,见面不如闻名。
 
下面的代码解决第一个问题
发送端:
procedure TForm1.Button1Click(Sender: TObject);
var uimsg:uint;
tmp:pdword;
begin
uimsg:=RegisterWindowMessage('testmsg');
caption:=inttostr(uimsg);
new(tmp);
tmp^:=BSM_APPLICATIONS;
if BroadcastSystemMessage(BSF_NOHANG or BSF_POSTMESSAGE,tmp,
uimsg,
0,0)<>-1 then
begin
caption:=caption+'ok'
end else
caption:='???'
end;
接受端
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, AppEvnts;
type
TForm1 = class(TForm)
Button1: TButton;
ApplicationEvents1: TApplicationEvents;
procedure FormCreate(Sender: TObject);
procedure ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
uimsg:uint;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
uimsg:=RegisterWindowMessage('testmsg');
caption:=inttostr(uimsg);
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if msg.message=uimsg then
begin
CaptioN:='Send message ok';
end;
end;

end.
在WindowsXP sp1 + Delphi7.0下通过
 
非常感谢,我把他转成vc++看看。
 
服务启动不了,跟具体的服务有关,检查你的程序。或者服务里占用的资源已经被其他进程占用了
 
不是很明白,能否说详细点。
 
第二个问题,没做过,查了一下API,有点线索:
OpenProcess 获取进程句炳
在OpenProcessToken获得TokenHandle
GetTokenInformation 中的Token Information Class 包含你要的信息
TokenHandle
Identifies an access token from which information is retrieved.
TokenInformationClass
Specifies a variable of the TOKEN_INFORMATION_CLASS enumerated type identifying the type of information the function retrieves.
TokenInformation
Points to a buffer the function fills with the requested information. The structure put into this buffer depends upon the type of information specified by the TokenInformationClass parameter, as shown in the following list:
Token Information Class Structure Returned
TokenUser TOKEN_USER structure. TOKEN_QUERY access is needed to retrieve this information.
TokenGroups TOKEN_GROUPS structure. TOKEN_QUERY access is needed to retrieve this information.
TokenPrivileges TOKEN_PRIVILEGES structure. TOKEN_QUERY access is needed to retrieve this information.
TokenOwner TOKEN_OWNER structure. TOKEN_QUERY access is needed to retrieve this information.
TokenPrimaryGroup TOKEN_PRIMARY_GROUP structure. TOKEN_QUERY access is needed to retrieve this information.
TokenDefaultDacl TOKEN_DEFAULT_DACL structure. TOKEN_QUERY access is needed to retrieve this information.
TokenSource TOKEN_SOURCE structure. TOKEN_QUERY_SOURCE access is needed to retrieve this information.
TokenType TOKEN_TYPE enumerated type. TOKEN_QUERY access is needed to retrieve this information.
TokenImpersonationLevel SECURITY_IMPERSONATION_LEVEL enumerated type. TOKEN_QUERY access is needed to retrieve this information about a token. If the access token is not an impersonation token, the function fails.
TokenStatistics TOKEN_STATISTICS structure. TOKEN_QUERY access is needed to retrieve this information.

怎样取得所有进程德句炳目前不会,不过觉得下面的API有点意思
EnumDesktops
EnumDesktopWindows
GetThreadDesktop
GetProcessWindowStation
EnumServicesStatus
EnumDependentServices
。。。。。。
再研究吧
 
遍历所有进程的方法,我找了篇文章,虽然是用VB写的,但用的是API,不支持nt4
2000可以:
枚举Windows载入模块
徐州 杨猛
  一个正在运行的Windows系统,内存中包含了许多模块(Module),有Windows系统模块(KERNEL32.DLL,USER32.DLL等),有正在运行的程序,有运行的程序所依赖的动态链接库。Windows的任务管理器只显示了当前运行的程序,而对于系统模块和动态链接库均不显示,不能使我们完整的掌握整个系统的状态。下面给各位介绍一种获取系统载入的所有模块的方法。
  Windows当前载入的模块属于Windows系统信息,而Toolhelp库中的函数可以得到许多关于系统运行状态的信息。在这里,我们需要以下几个函数:
  CreateToolhelp32Snapshot,Module32First,Module32Next, Process32First,Process32Next,以下是它们在WIN32API 中的原型及对它们完成的功能的简要说明:
//由于系统在动态变化之中,所以必须先使用该函数
取得当前系统状态的快照(snapshot)
HANDLE WINAPI CreateToolhelp32Snapshot
(DWORD dwFlags,DWORD th32ProcessID);

//获取快照中的第一个模块的信息
BOOL WINAPI Module32First(HANDLE
hSnapshot,LPMODULEENTRY32 lpme);

//获取快照中的下一个模块的信息
BOOL WINAPI Module32Next(HANDLE
hSnapshot,LPMODULEENTRY32 lpme);

//获取快照中的第一个进程的信息
BOOL WINAPI Process32First(HANDLE
hSnapshot,LPPROCESSENTRY32 lppe);

//获取快照中的下一个进程的信息
BOOL WINAPI Process32Next(HANDLE
hSnapshot,LPPROCESSENTRY32 lppe);

  函数调用参数lpme为指向结构MODULEENTRY32的指针,获取的模块信息将被填入到该结构中,同样参数lppe为指向结构PROCESSENTRY32的指针,获取的进程信息将被填入到该结构中。关于结构的详细信息请查阅WIN32API。
  由于模块属于各进程所有,所以为了获取系统当前的所有模块,我们需要遍历系统当前的所有进程,取出各进程中的所有模块信息,为加入到集合中去。
  VB是尝试API函数的非常好的工具,在这样的程序中算法住住不复杂,但却需要用最短的时间构造出一个满意的用户界面。下面是我使用VB实现上述功能的一个例子。
  首先创建一个EXE工程,添加一个代码模块,其中包含了对API函数及结构信息的说明:
DLLList.bas
Option Explicit
Public Const MAX_MODULE_NAME32 = 256
Public Const MAX_PATH = 260
'取得快照时指定的标志
'指定快照中包含的信息量
Public Const TH32CS_SNAPPROCESS = 2
Public Const TH32CS_SNAPMODULE = 8
Type MODULEENTRY32
dwSize As Long
th32ModuleID As Long
th32ProcessID As Long
GlblcntUsage As Long
ProccntUsage As Long
modBaseAddr As Long
modBaseSize As Long
hModule As Long
szModule As String * MAX_MODULE_NAME32
szExePath As String * MAX_PATH
End Type
Type PROCESSENTRY32
  dwSize As Long
  cntUsage As Long
  th32ProcessID As Long
  th32DefaultHeapID As Long
  th32ModuleID As Long
  cntThreads As Long
  th32ParentProcessID As Long
  pcPriClassBase As Long
  dwFlags As Long
  szExeFile As String * MAX_PATH
End Type
Declare Function CreateToolhelp
32Snapshot Lib "kernel32" _
   (ByVal dwFlags As Long, ByVal
th32ProcessID As Long) As Long
Declare Function Module32First Lib
"kernel32" (ByVal hSnapshot As Long, _
   lpme As MODULEENTRY32) As Long
Declare Function Module32Next Lib
"kernel32" (ByVal hSnapshot As Long, _
   lpme As MODULEENTRY32) As Long
Declare Function Process32First Lib
"kernel32" (ByVal hSnapshot As Long, _
   lppe As PROCESSENTRY32) As Long
Declare Function Process32Next Lib
"kernel32" (ByVal hSnapshot As Long, _
   lppe As PROCESSENTRY32) As Long
Declare Function CloseHandle Lib
"kernel32" (ByVal hObj As Long) As Long
  再创建一个窗体,其中包括两个按钮、一个列表框(ListBox)、一个标签(label),布置刷新按钮名为cmdRefresh,退出按钮名为cmdExit,列表框名为lstMod,将lstMod的Sorted属性设为True,以下是窗体各部件的事件代码:
Option Explicit
Private Sub cmdExit_Click()
Unload Me
End Sub
Private Sub cmdRefresh_Click()
Dim hSnapshotProc As Long, hSnapshotMod As Long
Dim ModEntry As MODULEENTRY32
Dim ProcEntry As PROCESSENTRY32
  
lstMod.Clear
'创建系统快照,包含进程信息
hSnapshotProc = CreateToolhelp32Snapshot
(TH32CS_SNAPPROCESS, 0)
If hSnapshotProc = -1 then

  MsgBox "Create snapshot failed!"
  Exit Sub
End If
ProcEntry.dwSize = Len(ProcEntry)
ModEntry.dwSize = Len(ModEntry)
'遍历所有进程,取得所有模块名加入列表框中
If Process32First(hSnapshotProc, ProcEntry) < > 0 then

  Do
   hSnapshotMod = CreateToolhelp32Snapshot
(TH32CS_SNAPMODULE, ProcEntry.th32ProcessID)
  
   If Module32First(hSnapshotMod, ModEntry) < > 0 then

  do

   lstMod.AddItem ModEntry.szModule
   Loop While Module32Next(hSnapshotMod, ModEntry) < > 0
   End If
   CloseHandle (hSnapshotMod)
  Loop While Process32Next(hSnapshotProc, ProcEntry) < > 0
End If
CloseHandle (hSnapshotProc)
'去除列表框中的重复项
Dim i As Long
i = 1
Do While i < lstMod.ListCount
  If lstMod.List(i - 1) = lstMod.List(i) then

   lstMod.RemoveItem i
  else

   i = i + 1
  End If
Loop
lblMsg.Caption = "模块列表" &amp;
"共" &amp;
lstMod.ListCount &amp;
"项"
End Sub
  该程序在VB6/WIN98下调试通过,在NT4中它不能运行,因为NT4中没有Toolhelp函数,NT4中获取系统信息是使用PSAPI中的函数,而在Win2000中,Microsoft又重新加入了Toolhelp函数,不过我未进行测试,各位若在实现过程中发现什么问题,欢迎与我讨论。
 
下面这篇文章可能对你的第三个问题有帮助()
http://www.9621.net/cgi-bin/printpage.cgi?forum=8&amp;topic=207
他提到了一个服务控制程序
服务控制程序
服务控制程序(SCP)则是控制服务应用程序的功能块,也是服务应用程序同服务管理器(SCM)之间的桥梁。服务控制
程序可以完成这些动作:
·如果服务启动类型为SERVICE_DEMAND_START,那么服务控制程序来启动服务
·发送控制请求给运行着的服务
·查询运行着的服务的当前状态
这些动作要求打开一个服务对象的句柄。


*************************************************************
又给你找了一篇,虽然谈的内容与你的问题关系不大,但用的技术你能用得着
杀掉本地进程其实很简单,取得进程ID后,调用OpenProcess函数打开进程句柄,然后调用
TerminateProcess函数就可以杀掉进程了。有些情况下并不能直接打开进程句柄,例如
WINLOGON等系统进程,因为权限不够。这个时候我们就得先提升自己的进程的权限了。
提升权限过程也不复杂,先调用GetCurrentProcess函数取得当前进程的句柄,然后调用
OpenProcessToken打开当前进程的访问令牌,接着调用LookupPrivilegevalue函数取得你
想提升的权限的值,最后调用AdjustTokenPrivileges函数给当前进程的访问令牌增加
权限就可以了。一般有了SeDebugPrivilege特权后,就可以杀掉除Idle外的所有进程了。
OK!那如何杀掉远程进程呢?说起来有点复杂,但其实也不难。
<1>与远程系统建立IPC连接
<2>在远程系统的系统目录admin$/system32中写入一个文件killsrv.exe
<3>调用函数OpenSCManager打开远程系统的Service Control Manager[SCM]
<4>调用函数CreateService在远程系统创建一个服务,服务指向的程序是在<2>中写入的程序killsrv.exe
<5>调用函数StartService启动刚才创建的服务,把想杀掉的进程的ID作为参数传递给它
<6>服务启动后,killsrv.exe运行,杀掉进程
<7>清场
嗯!这样看来,我们需要两个程序了。Killsrv.exe的源代码如下:
/***********************************************************************
Module:Killsrv.c
Date:2001/4/27
Author:ey4s<ey4s@21cn.com>
Http://www.ey4s.org
***********************************************************************/
#include <stdio.h>
#include <windows.h>
#include "function.c"
#define ServiceName "PSKILL"
SERVICE_STATUS_HANDLE ssh;
SERVICE_STATUS ss;
/////////////////////////////////////////////////////////////////////////
void ServiceStopped(void)
{
ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
ss.dwCurrentState=SERVICE_STOPPED;
ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
ss.dwWin32ExitCode=NO_ERROR;
ss.dwCheckPoint=0;
ss.dwWaitHint=0;
SetServiceStatus(ssh,&amp;ss);
return;
}
/////////////////////////////////////////////////////////////////////////
void ServicePaused(void)
{
ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
ss.dwCurrentState=SERVICE_PAUSED;
ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
ss.dwWin32ExitCode=NO_ERROR;
ss.dwCheckPoint=0;
ss.dwWaitHint=0;
SetServiceStatus(ssh,&amp;ss);
return;
}
void ServiceRunning(void)
{
ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
ss.dwCurrentState=SERVICE_RUNNING;
ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
ss.dwWin32ExitCode=NO_ERROR;
ss.dwCheckPoint=0;
ss.dwWaitHint=0;
SetServiceStatus(ssh,&amp;ss);
return;
}
/////////////////////////////////////////////////////////////////////////
void WINAPI servier_ctrl(DWORD Opcode)//服务控制程序
{
switch(Opcode)
{
case SERVICE_CONTROL_STOP://停止Service
ServiceStopped();
break;
case SERVICE_CONTROL_INTERROGATE:
SetServiceStatus(ssh,&amp;ss);
break;
}
return;
}
//////////////////////////////////////////////////////////////////////////////
//杀进程成功设置服务状态为SERVICE_STOPPED
//失败设置服务状态为SERVICE_PAUSED
//
void WINAPI ServiceMain(DWORD dwArgc,LPTSTR *lpszArgv)
{
ssh=RegisterServiceCtrlHandler(ServiceName,servier_ctrl);
if(!ssh)
{
ServicePaused();
return;
}
ServiceRunning();
Sleep(100);
//注意,argv[0]为此程序名,argv[1]为pskill,参数需要递增1
//argv[2]=target,argv[3]=user,argv[4]=pwd,argv[5]=pid
if(KillPS(atoi(lpszArgv[5])))
ServiceStopped();
else

ServicePaused();
return;
}
/////////////////////////////////////////////////////////////////////////////
void main(DWORD dwArgc,LPTSTR *lpszArgv)
{
SERVICE_TABLE_ENTRY ste[2];
ste[0].lpServiceName=ServiceName;
ste[0].lpServiceProc=ServiceMain;
ste[1].lpServiceName=NULL;
ste[1].lpServiceProc=NULL;
StartServiceCtrlDispatcher(ste);
return;
}
/////////////////////////////////////////////////////////////////////////////
function.c中有两个函数,一个是提升权限的,一个是提供进程ID,杀进程的。代码如
下:
/***********************************************************************
Module:function.c
Date:2001/4/28
Author:ey4s<ey4s@21cn.com>
Http://www.ey4s.org
***********************************************************************/
#include <windows.h>
////////////////////////////////////////////////////////////////////////////
BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
LUID luid;

if(!LookupPrivilegevalue(NULL,lpszPrivilege,&amp;luid))
{
printf("/nLookupPrivilegevalue error:%d", GetLastError() );
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else

tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
AdjustTokenPrivileges(
hToken,
FALSE,
&amp;tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);
// Call GetLastError to determine whether the function succeeded.
if (GetLastError() != ERROR_SUCCESS)
{
printf("AdjustTokenPrivileges failed: %u/n", GetLastError() );
return FALSE;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////
BOOL KillPS(DWORD id)
{
HANDLE hProcess=NULL,hProcessToken=NULL;
BOOL IsKilled=FALSE,bRet=FALSE;
__try
{
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&amp;hProcessToken))
{
printf("/nOpen Current Process Token failed:%d",GetLastError());
__leave;
}
//printf("/nOpen Current Process Token ok!");
if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE))
{
__leave;
}
printf("/nSetPrivilege ok!");

if((hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,id))==NULL)
{
printf("/nOpen Process %d failed:%d",id,GetLastError());
__leave;
}
//printf("/nOpen Process %d ok!",id);
if(!TerminateProcess(hProcess,1))
{
printf("/nTerminateProcess failed:%d",GetLastError());
__leave;
}
IsKilled=TRUE;
}
__finally
{
if(hProcessToken!=NULL) CloseHandle(hProcessToken);
if(hProcess!=NULL) CloseHandle(hProcess);
}
return(IsKilled);
}
//////////////////////////////////////////////////////////////////////////////////////////////
OK!服务端的程序已经好了。接下来还需要一个客户端。如果通过在客户端运行的时候,把killsrv.exe COPY到远程系统上,那么就需要提供两个exe文件给用户,这样显得不是很专业,呵呵。不如我们就把killsrv.exe的二进制码作为buff保存在客户端吧,这样在运行的时候,我们直接把buff中的内容写过去,这样提供给用户一个exe文件就可以了。Pskill.c的源代码如下:
/*********************************************************************************************
ModulesKill.c
Create:2001/4/28
Modify:2001/6/23
Author:ey4s<ey4s@21cn.com>
Http://www.ey4s.org
PsKill ==>Local and Remote process killer for windows 2k
**************************************************************************/
#include "ps.h"
#define EXE "killsrv.exe"
#define ServiceName "PSKILL"
#pragma comment(lib,"mpr.lib")
//////////////////////////////////////////////////////////////////////////
//定义全局变量
SERVICE_STATUS ssStatus;
SC_HANDLE hSCManager=NULL,hSCService=NULL;
BOOL bKilled=FALSE;
char szTarget[52]={0};
//////////////////////////////////////////////////////////////////////////
BOOL ConnIPC(char *,char *,char *);//建立IPC连接函数
BOOL InstallService(DWORD,LPTSTR *);//安装服务函数
BOOL WaitServiceStop();//等待服务停止函数
BOOL RemoveService();//删除服务函数
/////////////////////////////////////////////////////////////////////////
int main(DWORD dwArgc,LPTSTR *lpszArgv)
{
BOOL bRet=FALSE,bFile=FALSE;
char tmp[52]={0},RemoteFilePath[128]={0},
szUser[52]={0},szPass[52]={0};
HANDLE hFile=NULL;
DWORD i=0,dwIndex=0,dwWrite,dwSize=sizeof(exebuff);

//杀本地进程
if(dwArgc==2)
{
if(KillPS(atoi(lpszArgv[1])))
printf("/nLoacl Process %s have beed killed!",lpszArgv[1]);
else

printf("/nLoacl Process %s can't be killed!ErrorCode:%d",
lpszArgv[1],GetLastError());
return 0;
}
//用户输入错误
else
if(dwArgc!=5)
{
printf("/nPSKILL ==>Local and Remote Process Killer"
"/nPower by ey4s<ey4s@21cn.com>"
"/nhttp://www.ey4s.org 2001/6/23"
"/n/nUsage:%s <PID> <==Killed Local Process"
"/n %s <IP> <User> <PWD> <PID> <==Killed Remote Process/n",
lpszArgv[0],lpszArgv[0]);
return 1;
}
//杀远程机器进程
strncpy(szTarget,lpszArgv[1],sizeof(szTarget)-1);
strncpy(szUser,lpszArgv[2],sizeof(szUser)-1);
strncpy(szPass,lpszArgv[3],sizeof(szPass)-1);

//将在目标机器上创建的exe文件的路径
sprintf(RemoteFilePath,"////%s//admin$//system32//%s",szTarget,EXE);
__try
{
//与目标建立IPC连接
if(!ConnIPC(szTarget,szUser,szPass))
{
printf("/nConnect to %s failed:%d",szTarget,GetLastError());
return 1;
}
printf("/nConnect to %s success!",szTarget);
//在目标机器上创建exe文件
hFile=CreateFile(RemoteFilePath,GENERIC_ALL,FILE_SHARE_READ|FILE_SHARE_WRIT
E,
NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_value)
{
printf("/nCreate file %s failed:%d",RemoteFilePath,GetLastError());
__leave;
}
//写文件内容
while(dwSize>dwIndex)
{
if(!WriteFile(hFile,&amp;exebuff[dwIndex],dwSize-dwIndex,&amp;dwWrite,NULL))
{
printf("/nWrite file %s
failed:%d",RemoteFilePath,GetLastError());
__leave;
}
dwIndex+=dwWrite;
}
//关闭文件句柄
CloseHandle(hFile);
bFile=TRUE;
//安装服务
if(InstallService(dwArgc,lpszArgv))
{
//等待服务结束
if(WaitServiceStop())
{
//printf("/nService was stoped!");
}
else

{
//printf("/nService can't be stoped.Try to delete it.");
}
Sleep(500);
//删除服务
RemoveService();
}
}
__finally
{
//删除留下的文件
if(bFile) DeleteFile(RemoteFilePath);
//如果文件句柄没有关闭,关闭之~
if(hFile!=NULL) CloseHandle(hFile);
//Close Service handle
if(hSCService!=NULL) CloseServiceHandle(hSCService);
//Close the Service Control Manager handle
if(hSCManager!=NULL) CloseServiceHandle(hSCManager);
//断开ipc连接
wsprintf(tmp,"////%s//ipc$",szTarget);
WNetCancelConnection2(tmp,CONNECT_UPDATE_PROFILE,TRUE);
if(bKilled)
printf("/nProcess %s on %s have been
killed!/n",lpszArgv[4],lpszArgv[1]);
else

printf("/nProcess %s on %s can't be
killed!/n",lpszArgv[4],lpszArgv[1]);
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
BOOL ConnIPC(char *RemoteName,char *User,char *Pass)
{
NETRESOURCE nr;
char RN[50]="////";

strcat(RN,RemoteName);
strcat(RN,"//ipc$");

nr.dwType=RESOURCETYPE_ANY;
nr.lpLocalName=NULL;
nr.lpRemoteName=RN;
nr.lpProvider=NULL;

if(WNetAddConnection2(&amp;nr,Pass,User,FALSE)==NO_ERROR)
return TRUE;
else

return FALSE;
}
/////////////////////////////////////////////////////////////////////////
BOOL InstallService(DWORD dwArgc,LPTSTR *lpszArgv)
{
BOOL bRet=FALSE;
__try
{
//Open Service Control Manager on Local or Remote machine
hSCManager=OpenSCManager(szTarget,NULL,SC_MANAGER_ALL_ACCESS);
if(hSCManager==NULL)
{
printf("/nOpen Service Control Manage failed:%d",GetLastError());
__leave;
}
//printf("/nOpen Service Control Manage ok!");
//Create Service
hSCService=CreateService(hSCManager,// handle to SCM database
ServiceName,// name of service to start
ServiceName,// display name
SERVICE_ALL_ACCESS,// type of access to service
SERVICE_WIN32_OWN_PROCESS,// type of service
SERVICE_AUTO_START,// when to start service
SERVICE_ERROR_IGNORE,// severity of service
failure
EXE,// name of binary file
NULL,// name of load ordering group
NULL,// tag identifier
NULL,// array of dependency names
NULL,// account name
NULL);// account password
//create service failed
if(hSCService==NULL)
{
//如果服务已经存在,那么则打开
if(GetLastError()==ERROR_SERVICE_EXISTS)
{
//printf("/nService %s Already exists",ServiceName);
//open service
hSCService = OpenService(hSCManager, ServiceName,
SERVICE_ALL_ACCESS);
if(hSCService==NULL)
{
printf("/nOpen Service failed:%d",GetLastError());
__leave;
}
//printf("/nOpen Service %s ok!",ServiceName);
}
else

{
printf("/nCreateService failed:%d",GetLastError());
__leave;
}
}
//create service ok
else

{
//printf("/nCreate Service %s ok!",ServiceName);
}
// 起动服务
if ( StartService(hSCService,dwArgc,lpszArgv))
{
//printf("/nStarting %s.", ServiceName);
Sleep(20);//时间最好不要超过100ms
while( QueryServiceStatus(hSCService, &amp;ssStatus ) )
{
if ( ssStatus.dwCurrentState == SERVICE_START_PENDING)
{
printf(".");
Sleep(20);
}
else

break;
}
if ( ssStatus.dwCurrentState != SERVICE_RUNNING )
printf("/n%s failed to run:%d",ServiceName,GetLastError());
}
else
if(GetLastError()==ERROR_SERVICE_ALREADY_RUNNING)
{
//printf("/nService %s already running.",ServiceName);
}
else

{
printf("/nStart Service %s failed:%d",ServiceName,GetLastError());
__leave;
}
bRet=TRUE;
}//enf of try
__finally
{
return bRet;
}
return bRet;
}
/////////////////////////////////////////////////////////////////////////
BOOL WaitServiceStop(void)
{
BOOL bRet=FALSE;
//printf("/nWait Service stoped");
while(1)
{
Sleep(100);
if(!QueryServiceStatus(hSCService, &amp;ssStatus))
{
printf("/nQueryServiceStatus failed:%d",GetLastError());
break;
}
if(ssStatus.dwCurrentState==SERVICE_STOPPED)
{
bKilled=TRUE;
bRet=TRUE;
break;
}
if(ssStatus.dwCurrentState==SERVICE_PAUSED)
{
//停止服务
bRet=ControlService(hSCService,SERVICE_CONTROL_STOP,NULL);
break;
}
else

{
//printf(".");
continue;
}
}
return bRet;
}
/////////////////////////////////////////////////////////////////////////
BOOL RemoveService(void)
{
//Delete Service
if(!DeleteService(hSCService))
{
printf("/nDeleteService failed:%d",GetLastError());
return FALSE;
}
//printf("/nDelete Service ok!");
return TRUE;
}
/////////////////////////////////////////////////////////////////////////
其中ps.h头文件的内容如下:
/////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <windows.h>
#include "function.c"
unsigned char exebuff[]="这里存放的是killsrv.exe的二进制码";
/////////////////////////////////////////////////////////////////////////////////////////////
以上程序在Windows2000、VC++6.0环境下编译,测试还行。编译好的pskill.exe在我的主页http://www.ey4s.org有下载。其实我们变通一下,改变一下killsrv.exe的内容,例如启动一个cmd.exe什么的,呵呵,这样有了admin权限,并且可以建立IPC连接的时候,不就可以在远程运行命令了吗。象www.sysinternals.com出的psexec.exe和小榕的ntcmd.exe原理都和这差不多的。也许有人会问了,怎么得到程序的二进制码啊?呵呵,随便用一个二进制编辑器,例如UltraEdit等。但是好像不能把二进制码保存为文本,类似这样"/xAB/x77/xCD",所以我们就不能直接用了。懒的去找这样的工具了,自己写个简单的吧,代码如下[我够意思吧~_*]:
/*******************************************************************************************
Module:exe2hex.c
Author:ey4s<ey4s@21cn.com>
Http://www.ey4s.org
Date:2001/6/23
****************************************************************************/
#include <stdio.h>
#include <windows.h>
int main(int argc,char **argv)
{
HANDLE hFile;
DWORD dwSize,dwRead,dwIndex=0,i;
unsigned char *lpBuff=NULL;
__try
{
if(argc!=2)
{
printf("/nUsage: %s <File>",argv[0]);
__leave;
}
hFile=CreateFile(argv[1],GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FI
LE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_value)
{
printf("/nOpen file %s failed:%d",argv[1],GetLastError());
__leave;
}
dwSize=GetFileSize(hFile,NULL);
if(dwSize==INVALID_FILE_SIZE)
{
printf("/nGet file size failed:%d",GetLastError());
__leave;
}
lpBuff=(unsigned char *)malloc(dwSize);
if(!lpBuff)
{
printf("/nmalloc failed:%d",GetLastError());
__leave;
}
while(dwSize>dwIndex)
{
if(!ReadFile(hFile,&amp;lpBuff[dwIndex],dwSize-dwIndex,&amp;dwRead,NULL))
{
printf("/nRead file failed:%d",GetLastError());
__leave;
}
dwIndex+=dwRead;
}
for(i=0;i<dwSize;i++)
{
if((i%16)==0)
printf("/"/n/"");
printf("//x%.2X",lpBuff);
}
}//end of try
__finally
{
if(lpBuff) free(lpBuff);
CloseHandle(hFile);
}
return 0;
}
这样运行:exe2hex killsrv.exe,就把killsrv.exe的二进制码打印到屏幕上了,你可以把它重定向到一个txt文件中去,如exe2hex killsrv.exe >killsrv.txt,然后copy到ps.h中去就OK了文字
 
不是很明白,能否说的具体些。
 
上面的例子中用到了GetCurrentProcess函数取得当前进程的句柄,然后调用
OpenProcessToken打开当前进程的访问令牌
通过GetTokenInformation的参数中有一个TokenInformationClass得东东,它里面有一个TOKEN_OWNER structure
它可以返回owner的sID
通过LookupAccountSid函数返回用户信息
API是这么说的,我的E文不好,不知看得对不对,反正我是没试过
 
好久没来,请收分。
 
顶部