Function CreateKernelFile(SaveFile:String):Boolean;
begin
//详细代码参见源码
end;
2、修改系统可访问权限
为了让把动态库登录为有效进程,首先必须修改到系统为可访问的权限,步骤如下:
★获取当前进程伪句柄
通过API函数GetCurrentProcess获取当前进程的一个伪句柄,该函数没有参数;
★获取当前进程的令牌句柄
要对一个任意进程(包括系统安全进程和服务进程)进行指定写相关的访问权的OpenProcess操作,只要当前进程具有SeDeDebug权限就可以了,但是,在默认的情况下,进程的一些访问权限是没有被使用的,所以我们要做的首先是使用这些权限。这就需要获得进程访问令牌的句柄,可以通过API函数OpenProcessToken(ProcessHandle,DesiredAccess,TokenHandle)得到,其中:
ProcessHandle:要修改访问权限的进程句柄
DesiredAccess:要进行的操作类型
TokenHandle:返回的访问令牌指针
★获取权限的LUID值
在对令牌进行修改前,我们需要知道一个权限对应的LUID值是多少呢?这就要用API函数LookupPrivilegevalue(lpSystemName,lpName,lpLuid)来实现,其中:
lpSystemName:系统的名称,本地系统指明为NULL就可以了
lpName:权限的名称,如:SeDebugPrivilege
lpLuid:返回LUID的指针
★修改要访问的令牌
在得到令牌句柄和权限的LUID值后,接着可以对这个访问令牌进行修改,取得系统可访问权限,通过以下API函数实现,AdjustTokenPrivileges(TokenHandle,DisableAllPrivileges,NewState,BufferLength,PreviousState,ReturnLength),其中:
TokenHandle:访问令牌的句柄
DisableAllPrivileges:决定是进行权限修改还是除能所有权限
NewState:要修改的权限,是一个指向TokenPrivileges结构的指针
BufferLength:是PreviousState结构的长度
PreviousState:修改前的访问权限信息,一个指向TokenPrivileges结构的指针
ReturnLength:返回PreviousState结构实际大小
获取系统可访问权限的核心代码如下:
Procedure GetDebugPrivs;
begin
If (OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hToken)) then
begin
LookupPrivilegeValue(nil,'SeDebugPrivilege',tkp.Privileges[0].Luid);
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,False,tkp,0,nil,retval);
end;
end;
3、把DLL登录到系统进程
在获取系统可访问权限后,接着用OpenProcess函数打开进程、用VirtualAllocEx函数分配一个进程的空间、用WriteProcessMemory函数把文件嵌入内存、用CreateRemoteThread函数把钩子代码注入系统进程,这样,刚注入的进程起到了消息拦截的作用,从而实现了组合键的屏蔽。编程方法和核心代码如下:
procedure InjectKernelModule(ProcessName,DllName:Pchar);
begin
GetDebugPrivs;//取得系统可访问权限
//取得经常的PID,NameToPID过程参见源码
Pid:=NameToPID(ProcessName);
Myhandle:=OpenProcess(PROCESS_ALL_ACCESS, False, Pid);
Mysize:=strlen(MyKernel)+1;
Parameter:=VirtualAllocEx(Myhandle,nil,Mysize,MEM_COMMIT,PAGE_READWRITE);
WriteProcessMemory(Myhandle,Parameter,Pointer(DllName),MySize,tmp);
hThread:=CreateRemoteThread(Myhandle,nil,0,GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'LoadLibraryA'),Parameter,0,tmp);
……
end;