C语言-植物大战僵尸-刷僵尸call;fps游戏CS-方框透视(矩阵+传统)前言:大家好,我是向上先生,嘿嘿~最近在学习逆向、反汇编等等,首先我在非常感谢52pojie这个平台,差不多很多学习资源都是在这个平台得到的,也学到了非常多的知识;才申请会员通过,这是第一篇帖子。
一、植物大战僵尸辅助(远程线程注入)
主要讲解一个刷僵尸call,其他的功能自行学习,不懂的联评论后解答,首先通过CE和OD分析,通过搜索场上僵尸数量,作为突破口
我们来到OD通过CTRL+G来到41de07这里,首先我们分析一下,刷僵尸这个call应该需要哪些参数,应该会有刷在哪里,刷什么僵尸,也许不会有参数,直接在call里通过代码随机生成等等情况;然后下断点,找到上一层调用的地方,观察堆栈变化根据返回地址找到调用的call;
由于栈是先进后出,调用关系就是由上到下,我们找的时候就应该由上往下跟随
将原来的eax==1 esi == 0 改为 eax == 2 esi == 1,后面又来了两次改为eax == 2 esi == 3,得出eax为行数,esi为类型
接下来就简单了,我们需要edi的值,去CE中直接直接搜索edi的值,下访问断点是要保证od必须脱钩,否则不可以。结果edi的值为 [[6a9ec0 ]+ 0x768]。
代码讲解:
1、dll代码:
DWORD WINAPI readCount(LPVOIDlParam)是自己dll里创建线程的回调函数
BOOL APIENTRY DllMain(HANDLE hModule,,DWORD ul_reason_for_call,,LPVOID lpReserved) 是Dll的入口
功能代码讲解:
getProcessHandleByName(char* name);根据进程名获取PID
injectDll(HANDDLE handle,char* key,int address);通过远程线程注入Dll
种植无CD线程函数
刷僵尸功能
主函数,入口
Dll完整代码:dll.txt(编译后会得到一个TestDll.dll)
功能控制完整代码:功能.txt
测试代码结果如图:
二、fps游戏 CS方框透视原理(矩阵+传统坐标转换)
我采用的是GDI窗口绘制,需要干的事就是创建一个窗口,这个窗口透明并且具有穿透效果和置于顶层等特点。然后就是根据敌人和自己坐标点绘制方框。
第一种方式:传统型转换坐标原理:
CE搜索自己和敌人坐标标的基址,我喜欢找z坐标,然后x、y坐标就是z坐标地址 -8、-4;x、y、z坐标不会东一个西一个,因为在3d游戏中坐标都是通过向量Vector3存储,我们找的很多都是游戏引擎规定好了的东西。就不带着大家去找了,给大家说一下方法就行了,掌握方法;
自己坐标:
CE搜索方法:通过搜索z坐标,CE选择未知的初始值,改变Z坐标,然后改变了或者增加了或者减少了,不动时未改变不断过滤;说的迷迷糊糊~~哈哈
自己坐标基址:0x223d24d4
Z坐标:+ 0x350
X坐标:+ 0x348
Y坐标:+ 0x34c
敌人坐标:
CE搜索方法:通过自己坐标位置,然后搜索值大于,值小于,改变,未改变,不断过滤。
第一个敌人基址:0x223d24e4
Z坐标:+ 0x350
X坐标:+ 0x348
Y坐标:+ 0x34c
鼠标:
CE搜索方法:通过移动鼠标,搜索改变了,未改变,不断过滤。
鼠标X: 0x20326ec0
鼠标Y: 0x20326ebc
传统坐标换算关键代码:
[C] 纯文本查看 复制代码// 线程函数 透视DWORD WINAPI ThreadProc(LPVOID lpParam){ DWORD addr; while(F1_Statue) { // 读取自己信息 ReadProcessMemory(handle,(void*)(0x223d24d4),&addr,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x348),&selfBody.x,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x34c),&selfBody.y,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x350),&selfBody.z,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x22c),&selfBody.ct,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x9C),&selfBody.hp,sizeof(DWORD),NULL); for(int i = 1;i 0) { // 一四象限 if((emBox[i-1].y - selfBody.y) > 0) { // 一 坐标转换代码 float tanA = tan((mousePoint.x*3.1415/180.0)); float tanB = (emBox[i-1].y - selfBody.y)/(emBox[i-1].x - selfBody.x); emBox[i-1].cx = (box.width/2) + (box.width/2)*((tanA - tanB)/(1+tanA*tanB)) -10; float sqrtX = sqrt((emBox[i-1].x - selfBody.x)*(emBox[i-1].x - selfBody.x) + (emBox[i-1].y - selfBody.y)*(emBox[i-1].y - selfBody.y)); tanA = tan((-mousePoint.y*3.1415/180.0)); tanB = (emBox[i-1].z - 68 - selfBody.z)/sqrtX; emBox[i-1].cy = (box.height/2) + (box.height/2)*((tanA - tanB)/(1+tanA*tanB)) + 50*tanA; tanB = (emBox[i-1].z - selfBody.z)/sqrtX; emBox[i-1].ch = (box.height/2) + (box.height/2)*((tanA - tanB)/(1+tanA*tanB)) + 50*tanA; } } } InvalidateRect(hwnd,NULL,true); Sleep(150); } return 0;}
传统方式效果图:
第二种方式:矩阵转换坐标
原理:
所谓矩阵就是关于游戏摄像机的一组数据,一般都是4*4和4*3,这是游戏引擎决定的;然后根据这组数据套用公式直接可以得到屏幕坐标,至于公式怎么来的,这里一下子也说不清,感兴趣的可以自己去学习一下,有点复杂,就是一些列的矩阵计算。
公式:
Temp = 矩阵[2][0] * 敌人X坐标 + 矩阵[2][1] * 敌人Y坐标 + 矩阵[2][2] * 敌人Z坐标 + 矩阵[2][3];
计算比例 = 1 / Temp;
屏幕X坐标 = 屏幕/2 + (屏幕/2 )* 计算比例 * (矩阵[0][0] * 敌人X坐标 + 矩阵[0][1] * 敌人Y坐标 + 矩阵[0][2] * 敌人Z坐标 + 矩阵[0][3]);
屏幕Y坐标 = 屏幕/2 + (屏幕/2 )* 计算比例 * (矩阵[1][0] * 敌人X坐标 + 矩阵[1][1] * 敌人Y坐标 + 矩阵[1][2] * 敌人Z坐标 + 矩阵[1][3]);
CE搜索方法:
通过一把狙,不要也行~~,未知初始值,移动鼠标改变,不动未改变,开镜改变,收镜改变,不断过滤~~哈哈也是迷迷糊糊。主要我描述不清楚,还是要通过视频,自己在网上找一些
CS矩阵图:
红色的就是矩阵,矩阵特点:第一个值在不开镜的情况下,一般不会超过2不会小于-2且开局不动都是0;第一行第三个值不会变;有一行或列是比较大的数值。满足这几个条件一般都是矩阵~~
[C] 纯文本查看 复制代码// 线程函数 透视DWORD WINAPI ThreadProc(LPVOID lpParam){ float matrixData[4][4] = {0}; DWORD addr; while(F1_Statue) { int temp = 0; for(int k = 0;k < 4;k++) { for(int j = 0; j < 4;j++) { ReadProcessMemory(handle,(void*)(0x2048BC9C + temp * 0x4),&matrixData[k][j],sizeof(DWORD),NULL); temp++; } } // 读取自己信息 ReadProcessMemory(handle,(void*)(0x223d24d4),&addr,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x348),&selfBody.x,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x34c),&selfBody.y,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x350),&selfBody.z,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x22c),&selfBody.ct,sizeof(DWORD),NULL); ReadProcessMemory(handle,(void*)(addr+0x9C),&selfBody.hp,sizeof(DWORD),NULL); for(int i = 1;i |