1.在获取字符串输入时尽量不要用gets(),因为gets()不检查长度,如果数据过长可能会覆盖内存其他位置,造成程序错误。
2.内存拷贝时高地址向低地址拷贝时正向拷贝就可以,如果是低地址向高地址拷贝要考虑内存重叠问题,如果有重叠则从低地址的最高位向高地址最高位反向拷贝
例:高往低拷
1 2 3 4 5 6 7 8 9 0
a b
如果要从b将数据拷贝到a 因为b为高地址则第一次拷贝b[0] 2到a[0] 1第一次拷贝后a[0]为2,第二次拷贝则从b[1] 3拷贝到a[1] 2则第二次拷贝后a[1]为3按以上顺序重复进行,拷贝完毕后则a为 2,3,4,5,6,7,8,9,0,0 b为3,4,5,,6,7,8,9,0,0.
例2 低往高拷
1 2 3 4 5 6 7 8 9 0 ?
a b a[9] b[9]
如果要从a拷贝到b,则先从a[9]拷贝到b[9],第一次拷贝a[9] 0到b[9] ?
1 2 3 4 5 6 7 8 9 0 0
a b a[9] b[9]
第二次拷贝a[8] 9到b[8] 0
1 2 3 4 5 6 7 8 9 9 0
a b a[8] b[8]
第二次拷贝a[7] 8到b[7] 9
1 2 3 4 5 6 7 8 8 9 0
a b a[7] b[7]
..............
程序的四个区
栈 |
Rw读、写属性 |
堆 |
Rw读、写属性 |
代码 |
Re读、执行 |
数据 |
R读属性 |
Rw读写属性 |
栈和堆地址大概从00120000处开始
代码段地址大概从00401000处开始
数据段地址大概从00420000处开始
栈和堆的地址受操作系统影响
Virtualprotect(起始地址(地址),要改属性的范围(字节),改为什么属性(读、写、执行),旧属性存放哪里(dword))
头文件为windows.h
简单防止爆破的方法,将代码与密码做绑定,将主要代码加密后的值放在原地址处,执行代码时输入正确密码进行还原。
利用数组寻址公式
定义数组array[n]:n大小无所谓只是为了用来寻址用。
array[( 要访问地址( 0x00?? ) - array(首地址)) / sizeof(array元素类型长度)]
绿色下划线处最后其实转换成了下标地址,利用下标进行访问。
可以用以上的公式和函数进行简单的代码加密防爆破.
void encptry(int asm,int lengh)//
{
int n;
unsigned long oldBuff;
char array[2]={0};
//修改要加密代码处长度lengh字节的的属性为读写,旧属性放在oldbuff中
VirtualProtect((void *)asm,lengh,PAGE_EXECUTE_READWRITE,&oldBuff);
for (n=0;n<lengh;n++)//循环lengh-1次
{
array[((int)asm-(int)array)+n]-=1; 每次将array[?+n]处的数值减1
}
}