首页 > 代码库 > 学习的感想
学习的感想
在15PB学习已经有
8、9、10、11 4个月了,头两个月学了C,C++,数据结构,两遍,然后阶段项目是两遍的坦克大战
10月学了python, java,数据库,然后阶段项目就是一个c++的聊天服务器,Python的客户端
11月学了汇编,写一个32位电话簿,SDK界面编程,MFC界面编程,windows原理前段
12月接下来学PE格式,window原理高级,病毒高级行为,然后写一个任务管理器,然后再学个“安全编程”,就开始这阶段的项目调试器了。
一共7个月
2 1 2 2
现在是第三个阶段的一半。
学习速度很快,但这个快只是从内容进度上来看,学习的内容其实不算多得无法承受,但这也是对我来说
好几次想写感想,但都觉得浪费时间,也就不了了之,至于经验分享,因为觉得写出来似乎还得加上说明,很麻烦,也就没写
不过偶尔写写似乎可以梳理一下,不过以前看到过一句话"如果一个体系极力追求自身的完整性,那么叙述他的本身就充满了重复与陈词滥调",
所以我在写某些东西时不会考虑连续,可能会跳跃。
我"原本的思考过程",而且是我当时思考的时候写下来的话,那么字数应该蛮多,有时感觉
文字太啰嗦,在脑中的一个想法要表达出来竟然就写了一大段话,所以我似乎为自己以前字写得丑找到了理由,因为文字太慢了,没耐性一笔一划地画了半天写那么"一个"字。
有关感想,分几个阶段,而且时间太久了,有些当时很深刻的感想,,现在也可能忘了,不过有一些最让我记忆深刻的我忘不了。
第一个阶段:
当时在学C和C++,因为我以前学过C语言而且按二级标准来说学的还不错,半小时交卷拿了个二级优秀,当然了,我写感想肯定会吹吹牛逼。
学完C之后,老师就发了本项目指导手册,让我们去写个C语言版的坦克大战, 在这里,我第一次见识到了无限循环的威力
while(1) { ...; }
这个结构有多么强, 这个结构在我眼中就等于创造了一个"世界", 通过在一次循环中,每个东西行动一步(坦克,子弹),然后让这个无限循环运行起来,就是一个坦克大战! 不过当时我没意识到这个层次, 直到后来再学到数据结构的树,有关递归,递归如果只按逻辑去理解,那好理解,但如果要一层层地想下去,那会感觉有点累,而且会感觉这东西太巧妙,似乎不好设计.
网上有关递归和迭代都说可以相互转化,而且教材里说起来一套一套的,但这两个词总感觉对他没什么感觉,所以当时理解不深.
但后来某一天,我突然想到 无限循环 和 递归 和迭代,比如
int a = 3; while(1) { a = a + 1; } //这算迭代吧,反正我理解的最简单迭代就这样了 递归,比如: int fuck(int a) { if(a==0) return 0; return a+fuck(a-1); } 这个也算最简单递归了,就求和 然后用无限循环的观点来看 迭代就是无限循环每一次循环进行一次迭代 (无限循环和迭代没什么好说的,因为迭代一般都是在一个for里) 递归就是每一次循环代码是一样的,产出的功能是根据某个变量来确定的,而且还多了个变量来控制出口,所以只要控制了进入下一层 会改变的变量(在这里就是a),也就相当于"递归了" int a = 5,sum=0; while(1) { if(a==0) //递归的出口条件 break; sum+=a; --a; } 至于如何设计递归呢? 我目前的感觉就是,可递归这是个属性,不是什么问题都能有这属性的, 可递归的东西应该也不多,而且遇到了肯定会有感觉,或者直接去搜哪些问题可递归,应该不会很多。 无限循环是可以创造世界的 特别是学了对象,比如对象A,对象B while(1) { if(白天) { A.去死; B.上班 } else { A.轮回; B.睡觉; } } 然后一跑,就是一个两人世界。 数据结构时,有个排队模拟什么的, 也就是主要是while循环,全都是while循环 在这个世界里设定一些变量,让对象根据变量做不同的事情,变量越多, 对象行为越多,这世界也就越真实。
有关递归和无限循环和对象 当时就感觉到了这些,脑中的一个念头,写出来却这么多字。。。。
另外写坦克大战的A星寻路,其实也就是这么个无限循环,然后设定变量,让他慢慢找。。
还有学习方法方面的感觉就是,初学语法,应该直接找到主干道,然后码一遍代码,无视不重要的细节,
重要的细节在码代码的时候都会碰到,以后随着接触面广了,那么更多的细节就会接触到,到时在学,否则
一开始就会迷失在细节中,白浪费时间且无效果。
另外这阶段最后的C++的坦克大战,我就用了三个类互相friend一下,感觉完全感觉不到面对对象的那种感觉,
虽然是把数据和函数写在一起了。
第二阶段
python,java这两种新语言,python老师就讲了一个小时,感觉老师有点太搞噱头了,什么三十分钟讲完python,就只把最简单的讲了而且还不全,
尼玛让我看我十分钟都不用。 然后就让我们自己百度了。不过这是叫信息安全兴趣课,讲了很多操作系统的功能,,以及另一种看待C语言的方式,最后还给我们弄了一个SVM机器学习,验证码识别,学的时候还是很兴奋的。
然后就是java,java这一个星期,6天,每天上午,就这么6天,就讲完了java基础语法,IDEA工具使用,高级特性,然后逆向,和界面编程,仅仅6天,
我们当时连C++都还没学界面,结果JAVA就把界面上完了,还搞上了逆向,哈哈哈哈。 不过JAVA和C基础语法基本一样,就是数组变成了对象,还有那个bool变成了boolean. 全是对象全是类
不过JAVA的逆向可以看到源码,所以。。。不过这六天收获巨大
当时学C++走了弯路,我他妈竟然去看了C++PrimerPlus,从8月4号一直看到9月4号,一个月看完,但结果是,就是我前面说的迷失在了细节之中,
虽然也得到了,但总的说,不值得。 然后我深刻地体会到了,老师发下来的教材,是多么的精炼,而且仔细去想,越想越多,通过不断的试验,就越读越厚,可以说老师的教材就帮我们找到了主干道,然后我后来就不花时间看大本书了,就只看发下来的教材,然后思考各种可能,一一试验。
学PYTHON和JAVA,我也发现了,很多东西都是一样的,什么异常处理之类的,后面的高级特性,就是换了个形式。
而且学习这些语言的方式,似乎应该是到语言的官网下载help 文档,先tutorial,然后最严格的就是language reference,
接下来就学怎么查库文档,这就算基础入门了。 然后我发现似乎找不到C, C++的官网,但最终在MSDN里找到了language reference, 以及
各种VS自带的工具的使用、说明,什么链接器,编译器,VS的使用,HELPVIEWER等等,MSDN里都有,我意识到,这些帮助文档都是个好东西。
不过这些东西其中某些看起来有点吃力,所以一般先看看其他来源的资料,然后对这东西有大概概念了,再看最准确的,这样就多知道了很多东西,比如
int a = 10000000; 可以写成 int a = 1‘0‘0000‘00; 单引号可以用来给这样直接写出来的数字作分隔。
另外第二阶段,在JAVA破解时,老师发了一道题目,那道题我竟然灵光一闪看出来了,也得到了解决,当然了也只有我一个人解决了,就是如下几行代码
int[] k = new int[]{19088743, -1985229329, -19088744, 1985229328};
//v也是个int数组,两个元素,作为输入 encrypt(v, var15); public static void encrypt(int[] v, int[] k) { int y = v[0]; int z = v[1]; int sum = 0; int delta = -1640531527; for(int n = 32; n-- > 0; z += (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3]) { sum += delta; y += (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1]; } v[0] = y; v[1] = z; } 主要的就是这个for循环,等价于 for(int n = 32; n-- > 0; ) { sum += delta; y += (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1]; z += (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3]; }
一看到+= 后面那么复杂,就感觉有点吓人,但机智如我,一下子就看出了这只是个纸老虎,
这个循环是可逆的,但必须看出了结构才知道怎么逆,难道把+=改成-=,左移改成右移,然后循环体里代码倒个个就可以了吗?
我确定当时老师也没有看清这个结构,然而我却看出来了,我太牛逼了,哈哈哈哈哈哈哈哈
这个循环其实就相当于
int a = 1, b = 1; a += b + 15; b += a - 6; a += b + 15; b += a - 6; 结果为a‘, b‘ 那么只需要 b‘ -= a‘-6 a‘ -=b‘+15; b‘ -= a‘-6 a‘ -=b‘+15; 就可以得到a, b 至于等号右边的,都不需要改变。 把for扩展出来,就知道这是个什么情况了, 至于k,因为都是常量,所以不需要注意, 唯一需要注意的,就是sum, 因为sum参与了等号右边的运算, 只需要求出 每次循环中用到的sum,放进去就可以了, 相当于一个路径,所以只需要求出sum最后一次参与循环的值,作为起始,然后往前减,就可以反着来了!破解代码如下 public class crackme06 { public static void main(String[] args) { int sum = 0; int delta = -1640531527; int i=0; for(int n=32;n-->0;) { sum+= delta; } System.out.println(sum); //得到sum的最终参与值 int[] vv = new int[]{0x691e666c,0x294bbb32}; decrypt(vv); System.out.println(vv[0]); System.out.println(vv[1]); } public static void decrypt(int[] v) { int[] k = new int[]{19088743, -1985229329, -19088744, 1985229328}; int y = v[0]; int z = v[1]; int sum = -957401312; //上面求得的最终参与值 int delta = -1640531527; for(int n = 32; n-- > 0; ) { z -= (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3]; y -= (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1]; sum -= delta; } System.out.println(sum); v[0] = y; v[1] = z; } }
这个办法是我当时灵光一闪就想到了,真的,我觉得能像我这样的一下看出这个的没多少个,我还记得以前灵光一闪看出了一个蛮复杂的一个数学式子,
老师在上面分类讨论了半天,而我当时一眼就觉得这东西可以因式分解,而且还真给我分解出来了,然后一个不等式,就解出了所有,答案跟老师讨论了半节课然后综上可得得出的结果一样,不过这种灵光一闪还真是可遇不可求。
还有一件比较玄学的,就是梦中想到解决方案,那是在初中了,一道数学题,当时真是比较容易投入,后来晚上睡觉做梦梦到了解法,第二天早上一起来就到桌上验证了,结果真写出来了。
第三阶段,也就是我这阶段了,过了一半,感想就是MSDN真是个好东西,学完老师精炼的教材,
然后去看看MSDN对应的About XXX, 就可以多知道很多,比如学了list view,
就可以去MSDN里的List View, 然后里面有About List-View Controls ; Using List-View Controls
About里面有有关这控件的详细说明,Using有使用这个控件的最简单的例子
其他的东西也一样。
就写到这了。
学习的感想