install (server端)工程
1 程序的主线
1. 当程序被加载时,去掉加载时那个小漏斗的动画过程
2. 查找服务器端的配置,主要创建了一个FindConfigString方法来查找插入在服务端的配置信息,比如控制端IP、端口等必要信息,这里定义了4个字符指针,lpEncodeString、lpServiceConfig、lpServiceDisplayName、lpServiceDescription,从代码上理解可以认为是编码、服务配置、服务端显示名称、服务端的描述(lpEncodeString应该是那个加密的唯一字符串)
3. 查看程序是否需要更新,利用GetCommandLine()函数,这个函数是获取当前命令行的内存指针,返回一个LONG型的指针,然后用lpUpdateArgs字符指针判断是不是"Gh0st Update"命令,也就是判断是否是需要更新服务端的命令
4. 如果不是更新服务端,就用函数CreateMutex()去判断lpEncodeString内存中是否已经定义了一个一样的唯一标识,然后用GetLastError()来判断是否有互斥的两个值,如果有就返回相应的错误标识,这里gh0st用的是ERROR_ALREADY_EXISTS与ERROR_ACCESS_DENIED常量,然后只要有一个是真的那么就返回不安装了,如果没有,那么先释放掉刚刚对lpEncodeString互斥字符串的判断时所用的资源,因为如果不释放掉系统会自动把这个资源设置为不可用,但是系统仍然可以去调用它,所以我们要利用。如果程序是要更新服务端,那么,我们就直接睡眠5秒。
5. 设置异常处理函数,如果程序出现异常,利用SetUnhandledExceptionFilter()函数设置处理异常的函数句柄。
6. 调用SetAccessRights()函数,来设置当前用户对系统目录的最高权限,并且让该用户所在的所有组都有对系统目录已经系统驱动目录的ACL的最高权限
7. 调用InstallService来初始化我们要安装的服务端
2 函数解析
2.1 SetAccessRights
2.1.1 申明
void SetAccessRights()
2.1.2 变量
参数 类型 缺省值 描述
lpUserName char[] 50 记录当前用户名
lpGroupName char[] 100 记录当前用户组
lpDriverDirectory char[] MAX_PATH 系统驱动目录
lpSysDirectory char[] MAX_PATH 系统目录
nSize DWORD sizeof(lpUserName) 当前用户用户名的大小
pBuf LPLOCALGROUP_USERS_INFO_0 NULL 当前本地用户的用户信息指针
dwEntriesRead DWORD 0 用来遍历用户组的变量
dwTotalEntries DWORD 0 用来遍历用户组的变量
nStatus NET_API_STATUS 获取用户组信息的返回状态
wUserName WCHAR 宽字符的用户名
2.1.3 详细描述
1.函数首先把三个变量在内存中的地址用变量的sizeof大小一块一块的填充,使用到的方法是ZeroMemory()、清理了三个变量lpUserName、lpDriverDirectory、lpSysDirectory,
2.然后调用GetSystemDirectory()方法获得系统目录,调用了两次,把相同的信息存在了两个不同的变量里:lpSysDirectory、lpDriverDirectory,
3.然后调用lstrcat把"\\Drivers" 字符串添加到lpDriverDirectory字符串后面,
4然后调用GetUserName()获取本地当前用户的用户名,
5然后调用AddAccessRights 为当前用户添加一个当前用户组对lpSysDirectory与lpDriverDirectory的权限,
6.然后把获得的用户名转化成UNICODE字符集,存入的对象就是wUserName
7.然后调用 NetUserGetLocalGroups()这个函数允许我们判断一个用户属于哪些组,并且显示这些组,
8 判断获取用户组是否成功,如果成功了,就建立一个LPLOCALGROUP_USERS_INFO_0用户类型的缓存,然后利用这个变量遍历整个列表,每遍历到一个用户组就把改用户的用户组名转化为ASCII码然后再用AddAccessRights()函数给其添加当前所遍历的用户组的权限
9.释放刚刚为了遍历数组而建立的变量。
2.2 InstallService
2.2.1 申明
char *InstallService(LPCTSTR lpServiceDisplayName,
LPCTSTR lpServiceDescription,
LPCTSTR lpConfigString)
参数说明:
lpServiceDisplayName:服务端的名称
lpServiceDescription:服务端描述
lpEncodeString:服务端唯一字符串
2.2.2 主要参数表
参数 类型 缺省值 描述
lpServiceName char* NULL
rc int 0
hkRoot HKEY HKEY_LOCAL_MACHINE 注册表KEY的结构
hkParam HKEY 0
hscm SC_HANDLE NULL
schService SC_HANDLE NULL
strModulePath char[] MAX_PATH
strSysDir char[] MAX_PATH
dwStartType DWORD 0
2.2.3 详细描述
1. 用一个try把下面的代码保护起来了,如果有异常,后面将捕获
2. 定义了几个变量一个是大小为1024的char数组,和两个字符指针,缺省值为"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost",这个是windows的注册表的一个KEY
3. 调用RegOpenKeyEx函数打开刚刚定义的注册表段,把这个KEY的句柄交给hkRoot,然后返回一个是否成功的标志
4. 判断打开注册表是否成功,如果不成功则抛出异常,异常被标识为“”,
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课