009-注册算法分析
一、工具和调试环境
PE
信息查看工具:Die
- 动态调试工具:
x64dbg
- 系统环境:
win10 1909
二、分析用户名/注册码的算法
2.1运行程序
输入Name
和Key
后,直接点击ok
按钮会报错
2.2查壳
用Die
查壳,无壳,vb
程序
2.3详细分析
既然有提示字符串,直接上x64dbg
搜索字符串。和008
一样,基本都是关键字符串
直接选中失败提示字符串双击跟过去看看,和008
基本类型,向上很快就能找到关键跳转
向上继续找,可以发现vbaVarTstEq
函数的返回值来确定是否跳转。该函数是比较两个Variant
变量值是否相等。我们在该函数下个断点,然后随便输入name
和key
,点击ok
。成功断在该断点
分析该函数参数,可以看到一个是我们输入的key
,另一个就是计算后的真码(也就是我们需要输入的正确的key
)。
vbaVarTstEq
函数的两个参数是两个指向Variant
类型的指针,Variant
类型的结构如下
struct Variant
{
short varType;
short res1;
short res2;
short res3;
long long data;
}
类型如下,来自VBA) (VarType 常量 | Microsoft Learn
其中注意为vbEmpty
类型时表示尚未被初始化的 Variant
变量(已分配初始值)。 包含 vbEmpty
的 Variant
用于数值上下文时为 0;用于字符串上下文时为零长度字符串 ("")。
长整型是占4个字节,如下
搞清楚了Variant
类型结构下面的分析就好分析了。
通过不断的回溯找到算法位置如下,由于大部分使用Variant
变量进行运算,所以单步调试的时候无法直接看到变量数据,每次还需要自己在内存中查看
key
的算法:name
的每个字符的ascii
码值相加之和的结果乘以1234567890
(0x499602D2
)获得的新结果转换为字符串,然后将其中的第4个字符和第9个字符替换为'-'。
三、算法核心代码模拟
char* GetKey8(char* szName)
{
static char szKey[60] = {};
int nSum = 0;
for (int i = 0; i < strlen(szName); i++)
{
nSum += szName[i];
}
long long llKey = ((long long)1234567890 * nSum);
sprintf(szKey, "%lld", llKey);
szKey[3] = '-';
szKey[8] = '-';
return szKey;
}
四、API
总结
vbaVarMove
Variant* vbaVarMove(Variant* pVariant1, Variant* pVariant2);
vbaLenVar
Variant* vbaLenVar(Variant* pVariant1, Variant* pVariant2);
vbaVarForInit
int vbaVarForInit(Variant* pForI, Variant* pForEnd, Variant* pForStep,
Variant* pStart, Variant* pEnd, Variant* pStep);
vbaVarForNext
int vbaVarForNext(Variant* pForI, Variant* pForEnd, Variant* pForStep);
vbaI4Var
int vbaI4Var(Variant* pVariant1);
rtcMidCharVar
Variant* rtcMidCharVar(Variant* pSubStr, Variant* pSrcStr, int nIdx, Variant* pCnt);
vbaStrVarVal
wchar* vbaStrVarVal(wchar** pStr, Variant* pVariant1);
rtcAnsiValueBstr
short rtcAnsiValueBstr(wchar* pStr);
vbaVarAdd
Variant* vbaVarAdd(Variant* pVariant1, Variant* pVariant2, Variant* pVariant3);
vbaVarMul
Variant* vbaVarMul(Variant* pVariant1, Variant* pVariant2, Variant* pVariant3);
vbaMidStmtVar
void vbaMidStmtVar(Variant* pReplaceStr, int nCnt, int nIdx, Variant* pSrcStr);
vbaVarTstEq
int vbaVarTstEq(Variant* pVariant1, Variant* pVariant2);