附 1:
测试碰撞率带接口源码
在之前的Shellcode代码中,
对于必要的一些字符串常量采用的方法是:
将字符串以16进制形式保存在代码中。
而大多数常用的调试工具能够对其进行转译,明眼人一看,诶,这有猫腻啊。
很容易导致我们的“计划”流产。
那顺水推舟的,就接着分享一下鄙人的字符串加密的算法以及需要留意之处。
在Shellcode内加密字符串除了增加保密性以外,很重要的一点是能够缩小体积,
而体积(即字节数)对于Shellcode是至关生死的一项。
在设计加密算法时需要注意碰撞率,即在统一语境下不同源数据生成的密码的雷同率。
为测试本算法碰撞率,分别将Kernal32、user32、ntdll中所有导出函数名加密,
下面是测试结果:
综合考虑体积和碰撞率后,这里尝试写一个简单的字符串加密使用2字节长的密码,
翠花,上代码:
C源代码
WORD Encode(CHAR* pFuncName)
{
WORD Code = 0;
BOOL isOdd = FALSE;// 是否为奇数下标
WORD times = 1;
// 循环遍历Kernal32函数名并加密
while (*pFuncName)
{
/*
思路:
*********************************************
将字符串数组奇数下标取出来的字节放在高字节,(<<8)
将偶数下标取出来的字节放在低字节,
这是一层加密,
由于结果有大于百分之一的碰撞,
逐增加一层加密,
每次乘以一个从0每次递增1的数,
后检查带0特例,
将此些特例进行相应的位移。
*********************************************
*/
// 奇数下标pFuncName[奇数]
if (isOdd)
{
Code += (*pFuncName << 8) * times;
isOdd = FALSE;// 设置下次进入偶数下标
}
// 偶数下标pFuncName[偶数]
else
{
Code += *pFuncName * times;
isOdd = TRUE;// 设置下次进入奇数下标
}
++pFuncName;// 字符串后移一个字节
++times;
}
// 对于特殊情况的处理
if (Code >> 8 == 0)
{
Code <<= 3;// 左边有0 则填充左边
}
else if (Code << 8 == 0)
{
Code >>= 3;// 右边有0 则填充右边
}
return Code;
}
汇编源代码
WORD Enco