- 博客(14)
- 收藏
- 关注
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.18)
1.18. 浮点数单元CPU中的FPU1.18.1. IEEE 754sign+significand+exponent1.18.2. x86一开始FPU和CPU是分开的,FWAIT用来转换CPU状态,等待FPU完成工作。FPU有一个栈,用来保存8个80比特的寄存器ST(0)……ST(7)。1.18.3. ARM, MIPS, x86/x64 SIMDARM和MIPS不是栈,而是一些寄存器,在x86
2016-12-30 10:38:19
728
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.15-1.17)
1.15. 循环1.15.1. 简单例子x86x86中的LOOP指令,检查ECX中的值,如果不为0就不断跳到标签重复执行代码。LOOP并不是很方便,一般的编译器也不会用它,所以如果在代码中出现就一定是手写的。 对于for循环中的i值,在x86中,代码的逻辑就是,每次检查EAX的值是否是i的最大值,如果是,就跳出循环,否则不断跳回代码初始位置。GCC的实现也差不多。上述都是未优化版本。如果我们把/0
2016-12-29 12:01:14
408
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.14)
1.14. switch()/case/default1.14.1. case数量较少x86未优化MSVCcase数量较少时,相当于数个if/else语句结合。光看汇编代码很难判断源代码是什么。优化后的MSVC一些优化很有趣:把a的值放在EAX中,用它减去0,用来检查a是否为0。如果ZF设置了(减法结果为0),则JE触发。接下来会分别减1、减2,即分别与1,2比较。另一点是,调用printf()不是
2016-12-19 08:55:07
521
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.13)
1.13. 条件跳转1.13.1. 简单例子两个函数,由一些if条件语句组成。没有then。x86x86+MSVCf_signed()函数,接收int类型作为参数。先后用了eax、ecx、edx来完成三次条件的比较。第一个JLE表示如果小于等于就跳转。第二个JNE表示如果不等于就跳转。第三个JGE表示如果大于等于就跳转。f_unsigned()函数,接收unsigned int作为参数。程序流程差不
2016-12-19 08:51:34
688
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.10-1.12)
1.10. 关于返回结果x86中通常用EAX保存返回结果。如果是byte或char类型,用EAX的低位AL。如果是float,用FPU寄存器ST(0)。在ARM中,结果用R0寄存器返回。1.10.1. 使用返回void函数的结果因为所有函数都有push eax call exit。所以如果返回值是void,就不会返回任何值。EAX中就会有随机值。在一个例子中,源代码中没有返回指令。汇编代码中没有pu
2016-12-19 08:45:37
319
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.8-1.9)
1.8 scanf()1.8.1. 简单例子用scanf()从屏幕上的输入读入一个整数。关于指针:在32位系统中是一个4byte的地址,在64位中则是8byte。指针仅仅是一个源代码里的概念。汇编代码里找不到这个概念。x86MSVC用于接收输入值的x变量是局部变量,所以储存在栈上。函数前言里有一个PUSH ECX,并不是要存下来ECX的值,而是在栈上为保存x变量开辟4字节的空间。要访问x,通过EBP
2016-12-08 14:34:17
486
原创 C程序的内存层次
一个C程序的内存分布可以分为五大部分:代码段、初始化的数据段、未初始化的数据段、栈、堆。注意这里我们讨论的是,在运行一个C编写的二进制程序时,内存是如何分布的。有一些前提知识需要强调。我们都知道,二进制程序原本存在硬盘上,要执行时,会加载进入内存。因为操作系统的作用,虽然一个计算机的内存可能只有4GB,但是操作系统会让每一个程序都以为自己独占了这所有的空间,那么这个时候每一个程序处理的内存地址就是一
2016-12-05 14:44:40
411
原创 C语言编程中常见的漏洞原因
1. getsgets()函数不检查缓冲长度,可能导致漏洞。调用函数gets(buffer),会把用户输入的内容放在buffer中,但是对这个内容没有检查长度。如果用户输入内容过长,就会覆盖在buffer之后定义的变量,也就是说用户可以随意更改一些程序中的变量。那么应该怎么用才安全呢?使用fgets()函数更好一些。首先你要用malloc为buffer分配一部分固定的空间,然后调用fgets的时候传
2016-12-05 11:22:48
5680
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.7)
1.7. 带有参数的printf()示例代码:#include <stdio.h>int main(){ printf(“a=%d; b=%d; c=%d”, 1, 2, 3); return 0;}1.7.1. x86x86: 3个参数MSVC参数是以3,2,1的顺序入栈的。因为参数类型是int,是32bits大小,所以一个参数占4byte。除了参数,还要入栈字符串的地址,
2016-12-05 10:41:23
526
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.5-1.6)
1.5. 函数序言和结尾函数开头的一些指令序列。通常是这样的:push ebpmov ebp, espsub esp, X首先保存EBP中的值,把EBP的值设置为ESP的值,然后在栈上为局部变量分配一些空间。EBP中的值在整个函数执行的时候都会原封不动地保存在栈中。然后EBP会用作访问局部变量。函数结尾的指令通常释放栈中之前分配的空间,恢复EBP寄存器中的值,并将
2016-12-04 09:24:19
486
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.4)
1.4.Hello World1.4.1.x86MSVC用这个编译器编译的二进制。其汇编代码大致过程是保存EBP,压栈字符串参数,调用printf,然后恢复ESP和EBP。注意恢复ESP用的是ADD ESP, 4,其实也可以用POP ECX。用前者可以不使用任何额外寄存器,也就不会改变ECX的值。用后者,汇编代码指令的长度会短一点。对于return 0的处理,因为EAX放置返回
2016-12-03 08:53:32
390
原创 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.1-1.3)
第一章 代码模式 1.1.方法 作者学习C/C++的时候曾经花了大量时间写出代码然后查看反汇编后的汇编语言代码,以此来搞清楚这些C/C++代码究竟有什么作用。这是一个非常好的学习方法。 作者学习汇编的时候,尝试把一些简单的C函数用汇编语言写出来,而且是越简短越好。这对于理解汇编语言非常有帮助。 编译器的优化选项。三种选项:①没有优化。
2016-12-03 08:50:12
457
原创 《老码识途:从机器码到框架的系统观逆向修炼之路》- 第1章 - 总结
本章学到了什么调试技巧:在VS中断点调试,查看反汇编代码,step into进行步进调试,运行过程中查看寄存器、内存地址、变量值变化等。机器码构造能力:使用C/C++中的直接在C代码里写汇编语言的功能(_asm)。学会了常见的汇编指令,接触了几个带有循环、跳转的汇编语言代码。指针机制:对C/C++中的指针机制有了更深的了解。函数调用机制:函数调用过程中栈的变化。函数调用约定的大致了解。数组
2016-11-17 14:51:25
2391
原创 Linux vimtutor笔记
Linux vimtutor笔记 本文是学习Linux系统自带vimtutor文档的笔记,主要记录了Vim常用命令,用以自己随时查漏补缺。如果有想学习的同学,建议自己在终端输入vimtutor,即可进入教程。该教程的每个命令介绍都提供了例子,一边读一边做,很快就能够记下来,并在使用中逐渐熟练。
2016-11-08 16:19:17
956
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人