CSharp 一般数据加密后解密使用 CryptoStream::Read 解密, 在程序启动时Hook 该函数, 然后可以截获到解密的数据
步骤:
- Hook引擎mono的函数 mono_runtime_invoke
AsmHook::HOOK_INFO _mono_runtime_invoke;
BOOL __cdecl hook_mono_runtime_invoke(VOID *pUserParam, AsmHook::PUSHAD_DAT *pReg)
{
CUnityMono *pThis;
pThis = (CUnityMono *)pUserParam;
pThis->On_mono_runtime_invoke();
return TRUE;
}
bRetVal &= AsmHook::Hook(mo._mono_runtime_invoke, &hook_mono_runtime_invoke, this, &_mono_runtime_invoke);
- 在mono_runtime_invoke的调用时, 编译 CryptoStream::Read
在其他时候编译会有问题, 在这个未知为了保证安全
BOOL CryptoHook::OnMonoStart()
{
BOOL bRetVal;
bRetVal = MethodBuild("mscorlib", "System.Security.Cryptography", "CryptoStream", "Read", 3, funCryptoStream_Read);
MethodHook(funCryptoStream_Read, &CryptoStream_Read_Hook, "CryptoStream_Read", &CryptoStream_Read_Info);
return TRUE;
}
- 对编译后的X64函数地址Hook
int WINAPIV CryptoStream_Read(void *CryptoStream, void *buffer, int offset, int count);
AsmHook::HOOK_INFO CryptoStream_Read_Info;
BOOL WINAPIV CryptoStream_Read_Hook(VOID *pUserParam, AsmHook::PUSHAD_DAT *pReg)
{
CryptoHook *pThis = (CryptoHook *)pUserParam;
#ifdef _WIN64
decltype(&CryptoStream_Read) fun;
void *param64[8];
void *backaddr;
void *buffer, *CryptoStream;
int offset, count;
int nReturn;
AsmHook::GetCallParam64(pReg, backaddr, param64);
CryptoStream = param64[0];
buffer = param64[1];
offset = (int)(size_t)param64[2];
count = (int)(size_t)param64[3];
AsmHook::GetClassOrgFun(pReg, &CryptoStream_Read_Info, &fun);
nReturn = fun(CryptoStream, buffer, offset, count);
pThis->SaveCryptoDat(buffer, count);
return AsmHook::SetReturn64(pReg, nReturn);
#endif
return TRUE;
}
- 在Hook中拦截数据并保存
BOOL CryptoHook::SaveCryptoDat(void *ByteAry, int nSize)
{
static int snSaveId = 0;
void *pData;
int nMaxSize;
CHAR szFilePath[1024];
snSaveId ++;
GetObjProp(ByteAry, nMaxSize, ByteAry_Size);
ObjAddOffset(ByteAry, pData, ByteAry_Data);
if(nSize > nMaxSize)
{
assert(0);
return FALSE;
}
sprintf(szFilePath, "V:\\Temp\\CryptoHook_%04d.dat", snSaveId);
NFile::DumpToFile(szFilePath, pData, nSize);
return TRUE;
}
- 附相关函数
BOOL CUnityMono::MonoGetImage(void *&img, CHAR *name)
{
list<PVOID> tAsmList;
list<PVOID>::iterator Iter;
void *asmb;
void *img_item;
CHAR *img_name;
img = NULL;
tAsmList.clear();
mo._mono_assembly_foreach(foreach_list_push, &tAsmList);
for(Iter = tAsmList.begin();
Iter != tAsmList.end();
Iter ++)
{
asmb = *Iter;
img_item = mo._mono_assembly_get_image(asmb);
img_name = mo._mono_image_get_name(img_item);
if(stricmp(img_name, name) == 0)
{
img = img_item;
return TRUE;
}
}
return FALSE;
}
BOOL CUnityMono::MonoGetClass(void *&cls, void *img, CHAR *name_space, CHAR *name)
{
cls = mo._mono_class_from_name(img, name_space, name);
return FALSE;
}
BOOL CUnityMono::MonoGetMethod(void *&method, void *cls, CHAR *name, int nParamCount)
{
method = mo._mono_class_get_method_from_name(cls, name, nParamCount);
if(method)
return TRUE;
return FALSE;
}
BOOL CUnityMono::MethodGet(void *&method, CHAR *pImg, CHAR *pSpace, CHAR *pClass, CHAR *pName, int nParamCount)
{
void *img, *cls;
method = NULL;
MonoGetImage(img, pImg);
if(img == NULL)
return FALSE;
MonoGetClass(cls, img, pSpace, pClass);
if(cls == NULL)
return FALSE;
MonoGetMethod(method, cls, pName, nParamCount);
if(method == NULL)
return FALSE;
return TRUE;
}
BOOL CUnityMono::MethodBuild(CHAR *pImg, CHAR *pSpace, CHAR *pClass, CHAR *pName, int nParamCount, void *&code)
{
void *method;
code = NULL;
MethodGet(method, pImg, pSpace, pClass, pName, nParamCount);
if(method == NULL)
return FALSE;
code = mo._mono_compile_method(method);
if(code == NULL)
return FALSE;
return TRUE;
}
标签:return,name,img,mono,void,Unity,CSharp,加密,CryptoStream
From: https://www.cnblogs.com/zzz3265/p/18474661