我还是在研究那个游戏,因为是联网游戏,他肯定是加密的,然后我就看见了代码里面写死的2个长字符串
通过hookEncrypt函数,发现确实是des加密用到的密钥
查看了加密解密函数,参数结构基本上一致。
现在猜测加密发包和解密收包应该是通过不同的密钥来实现的。
客户端只能:解密收到的数据,加密发送的数据。(因为密钥是不同的)
但是我不死心啊,我想hook到加密函数以后。利用加密时传入的数据,执行解密函数,打印出来看看。是否可以通过利用加密的密钥,调用解密的函数(des对称加密的,应该是用同一个密钥的)实现解密,进一步确定,加密和解密的算法是一致的,只是密钥区别。
然后,就有以下代码。
#include <substrate.h>
#import <sys/socket.h>
#import <UIKit/UIKit.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h> // 包含inet_ntoa函数的头文件
#import <Foundation/Foundation.h>
void* (*orig_ChangeState)(char *a1,int a2);
void* new_ChangeState(char *a1,int a2)
{
// 默认情况下调用原始函数
if (a2 != 21 && a2 != 16 ){//只有16和21流程可以执行 其他的全部作为14
a2=14;
}
void* ret = orig_ChangeState(a1, a2);
return ret;
}
int (*orig_MakeEncryptCode)( int *a2);
int new_MakeEncryptCode( int *a2)
{
int ret = orig_MakeEncryptCode(a2);
return ret;
}
int (*orig_encrypt)(char *a1, char *a2, int a3, char *a4, int *a5, int a6);
int new_encrypt(char *a1, char *a2, int a3, char *a4, int *a5, int a6)
{
StrNSlog(@"执行加密之前A1",a1);
StrNSlog(@"执行加密之前A2",a2);
StrNSlog(@"执行加密之前A4",a4);
int ret= orig_encrypt(a1,a2,a3,a4,a5,a6);//先执行原流程。保证正常进行流程
StrNSlog(@"执行加密之后A1",a1);
StrNSlog(@"执行加密之后A2",a2);
StrNSlog(@"执行加密之后A4",a4);
char* olda1=a1;
char* olda2=a2;
int olda3=a3;
char* olda4=a4;
int* olda5=a5;
int olda6=a6;
int(*decryptFunction)(char*, char*, int, char*, int*, int) = (int (*)(char*, char*, int, char*, int*, int))MSFindSymbol(NULL, "__ZN8CEncrypt7decryptEPKciPcRii");
if (*decryptFunction){
NSLog(@"地址获取成功");
NSLog(@"解密函数地址:%p", decryptFunction);
NSLog(@"解密之前");
StrNSlog(@"执行解密之前A1",olda1);
StrNSlog(@"执行解密之前A2",olda2);
StrNSlog(@"执行解密之前A4",olda4);
// 调用函数
NSLog(@"解密完成");
int ret1=decryptFunction(olda1, olda2,olda3, olda4, olda5,olda6);
StrNSlog(@"执行解密之后A1",olda1);
StrNSlog(@"执行解密之后A2",olda2);
StrNSlog(@"执行解密之后A4",olda4);
NSLog(@"有没有执行:%d", ret1);
}
return ret;
}
%ctor {
void *lpFun = ((void*)MSFindSymbol(NULL, "__ZN11CGameUpdate11ChangeStateEi"));//跳过更新
if (lpFun) {
MSHookFunction(lpFun, (void*)new_ChangeState, (void**)&orig_ChangeState);
}
void *lpFun4 = ((void*)MSFindSymbol(NULL, "__ZN8CEncrypt7encryptEPKciPcRii"));
if (lpFun4) {
MSHookFunction(lpFun4, (void*)new_encrypt, (void**)&orig_encrypt);
}
}
代码大概是这样的 。
经过大佬的帮助,把代码修改了一下。应该可以基本上证明,加密解密是同一个des算法,没有区别
加密之前是
58 02
加密之后是1A C8 4A 2D F0 CF 7D BF C5 73 6C A4 2A FF 15 28 02 0F 76 3F AC D9 99 74 59 74 AF B5 B9 EE E5 05
解密之前是
1A C8 4A 2D F0 CF 7D BF C5 73 6C A4 2A FF 15 28 02 0F 76 3F AC D9 99 74 59 74 AF B5 B9 EE E5 05
解密以后还是 58 02