开一篇讲下学C/C++以来的感触与一些心得。以帮助初学者提升以及帮助自己整理思路。文中若有不对的地方,望指正,提出讨论,谢谢。
总而言之,虽然在学习过程中都会含糊不清,到后面慢慢习惯以为就是这样的,不过仔细纠下还是有些东西。
文主要关于内存的,我认为学习C/C++最重要的是弄懂内存。基本上都是较直观的方式表达。这里仅仅从一些实例中来说明,可能有些观点以及操作有悖于常规板书,但是如果这些操作从内存角度来看的话,都是没问题的。往往从学习时候就奉书本,编程习惯为最上,反正忽视了很多东西,其实C++规则一直在变动,唯一不变的就是内存规则这个根基。
黑鸡生的都是白蛋。语言语法再变化,也是只有一个目的操作内存。
“不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。”
首先,内存是什么?
从有计算机开始就有内存了。编写程序,几乎无时无刻不在使用内存,我们使用变量,调用函数,申请空间存放我们的数据,都是在对内存进行操作。
我自己观念里给内存下了一些定义,意在便于理解新情况,自我总结。
在纵观整个内存的情况下,内存最重要的一个属性基本上就是权限,简单说就是是否有权限可读可写可执行。各种漏洞都是在突破这一点。
举个例子之所以需要注入就是为了获得那段内存的一个读写权限,由于用户内存进程内存保护的问题,假如均可以读写修改,那么也用不到注入、上驱动等等操作了。管理员权限用户权限就是需要改动的内存需要权限,这样的操作“允许程序以管理员运行”就是授权给进程这个权限去操作相关内存。
好了~太大的话题不说了,这个话题再说下去可能装13就要失败了~从编程需要的开始吧。仅仅看单个程序的内存。
研究程序代码与内存的关系还是要从实际来~深入浅出。一点点开始掰吧。
类型与空间占用
第一段
我们先百度
包括书上也有说,int和long,或者说DOWRD是区别的,实际上呢?
我们验证下,
上例子,
然后在32位下看内存,
可以看到都是四字节~所以这个百度的回答错误(这条回答后面有人评论了不过也不直观)。long也就是DWORD的空间不比int大,都是一样的,我的环境是WIN10-64位,但是这里无论WIN7还是WIN10,64位32位都是这样结果。上图还显示了地址,这个是32位程序。
然后再百度,又有人说64位下long是8字节,比int大,那么要不要信呢?我们还是实践出真知。
这里是编译成64位的程序,均为四字节,所以关于这个问题,百度一大堆模糊的答案。自己实践才是真的。
不过这东西大小是由编译器喜好决定的。编译出文件这里放在EXE中的,所以不会环境影响,但是当你做new的时候,才会受到系统环境的影响。
第二段
很多初学者在看代码的时候会遇到很多没见过的数据类型,不过其实他们本质一般都是一个int的4字节而已。类型名字不同仅仅是为了方便阅读,EXE运行时候不会受到类型名字不同的影响。
void*还是万能啊~
这里我在实践中,总结了一个自己的看法,一切都是指针,无论是函数,或者常量,变量,堆区栈区数据。从内存角度来说,刻意定义一个指针或者不是刻意的,都是在做指针操作的工作,而指针对我而言就是一个四字节的存储单位。
这里把int_num看作int*,对char*进行操作,然后又把
int_num看作字符串去打印。
int_num
你认为他是什么他就是什么。
通过这个例子要说明的是不要拘泥于规则,但是假如学二进制或者写马啊逆向破解等等,要学会从内存角度看,
char*是一个四字节,句柄类型是四字节,int也是四字节,从内存角度他们没有任何区别,只要是四字节用什么类型名字随意决定。然后(xxxx)强转给编译器看,倒是不是说实际写码都这么写,只是要明白原理。
再来个更直观实用的例子,
这是网上copy的获取当前进程实用内存的情况。
看下pmc的类型结构改成shellcode,
改写为shellcode来演示。
typedef BOOL(WINAPI *g_GetProcessMemoryInfo)(DWORD, DWORD*, DWORD);
//依照刚才看法,定义就这么就好了~不必全按照他的,后面写着还麻烦,这样也就不需要去重载他的特殊的类型
//PROCESS_MEMORY_COUNTERS结构体就当做一个指针好了,DWORD*就OK
g_GetProcessMemoryInfo fGetProcessMemoryInfo;
……(这里去k32寻址什么的不放代码了)
DWORD pmc[10];//之前看了就是10个int,所以这么定了
fGetProcessMemoryInfo(-1, pmc,sizeof(pmc));
//最后结果是正确的
规矩固然重要,不过明白原理才知道规矩的意义~盲目死背规矩不明白规矩的意义那就是死读书了。
篇幅有点长了~暂告一段落以后再写~
多说个小插曲,最后一个例子有一个小用处…不过这个方法还是挺多的。这里仅仅是类似360沙盒这种。
if ((int)((float)pmc[3] / (float) pmc [8] - 3))//测试下来市面上几款软件,Sandboxie等等的都OK
{
MessageBoxA(0, 0, "正常环境", 0);
}
else
{
MessageBoxA(0, 0, "沙____箱中", 0);
exit(0);
}
感兴趣小伙伴可以群里183746493交流交流~~
[课程]Android-CTF解题方法汇总!
最后于 2018-7-9 10:38
被ISSACASSI编辑
,原因: