本文作者:念真(二进制逆向星球学员)
01
—
进制
进制也就是进位计数制,是人为定义的带进位的计数方法(有不带进位的计数方法,比如原始的结绳计数法,唱票时常用的“正”字计数法,以及类似的tally mark计数)。对于任何一种进制---X进制,就表示每一位置上的数运算时都是逢X进一位。十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。
比如:10进制,1,2...9,10,11。逢10进一
2进制,10001。逢2进一。
16进制,1,2,3...9,a,b,c,d,e,f,10。逢16进一。
进制之间的一个换算,这里主要讲2进制与10进制的换算,如:100001,可以通过算法:1*2^0+0*2^1+0*2^2+...+1*2^5=33。(注:从右往左,可以分成0到5总共6位的排序,这些排序的位数对应与之相对应的2^n次方的指数。)
对于16进制换算为10进制,其实跟2进制的结构是类似的,比如:2f8,转换为10进制,可以写出算法为:8*16^0+f*16^1+2*16^2。
那么如何讲10进制的数转换为16进制或者2进制呢,其实也很简单(百度一下,你就知道23333)算法为:将10进制的数除以x(x为x进制),余数为x进制数的第1位,然后再将商除以x,余数为第2位,然后再将商除以x,以此类推。(故视频中的数字的转换就可以以此来进行换算,当然这里就不给答案啦,大家也可以利用计算器来进行转换)
02
—
进制的运算
进制的运算与我们平时所了解的运算方法基本上是一致的,唯一注意的就是进制的进位与借位,比如一个X进制的数,在进行运算的时候,他的进位和借位就为X,不能按照平时我们所学的10的惯性思维去以为进位和借位为10。
03
—
逻辑运算
逻辑运算主要有我们熟知的与或非,异或,同或等等。
与门(C语言中为&,汇编中为and)即:同真为真,不同为假。
或门(C语言中为|,汇编中为or)即:有真则真,同假为假。
非门(C语言中为!,汇编中为not)即:按位取反。
异或(C语言中为^,汇编中为xor)即:不同则真,相同则假。
同或(在C语言中和汇编中好像没有定义的符号)即:相同则真,不同则假。
左移与右移运算(C语言中为<<,>>)并且如果左移右移高位溢出的话,则弃之,空缺位补0。注:在没有发生高位溢出的情况下(高位溢出,即指最左边的一位不为1),左移x位相当该数乘以2^x次方,同理,右移呢?则是除以2^x次方。
在汇编语言当中,左移的逻辑算术符号为,左移指令包含sal和shl,这两条指令的作用是相同的。右移指令sar和shr,其中右移sar的指令用法,sar右移会用符号位填充,如果符号位是1,就填充1,如果是0就填充0。(符号位,表示的是eflags寄存器里面的符号位,规定当中,负数的高位均采用补码的形式,也就是高位为0的话补1)(这里提一个问:所有的移位操作,最终的结果是不是都会为0呢?左移的最终结果是不是全为0呢?)
注:xor运算可以用于加解密,因为它本身的特性,可以进行一种还原操作。
对于作业中的题,前面几道只需将16进制数转换为2进制数,然后进行逻辑运算即可。至于最后一题00001101,取出第5位(这里老师应该讲错了,应该是第4位,在我们的计算逻辑中,这应该是第四位),其实很简单,将(00001101)&(00001000)即可,也可以用异或运算(实际中我估计应该不会这么用,太傻了)(00001101)xor(00000101)
第一章(汇编基础)(环境搭建略过)
前面的三节视频基本上要总结的不多,就用几张图来概括了
注意:寄存器是我中有你,你中有我的兼容关系,跟指令集一样,是有向下兼容的。
这里再讲一下一些重要的寄存器:
EAX:(针对操作数和结果数据的)累加器,一些指令的会将结果返回给EAX中。
EBX:(DS段中的数据指针)基址寄存器。
ECX:(字符串和循环操作的)计数器,一些指令会用该寄存器来进行计数。
EDX:(I/O指针)数据寄存器。
EBP:(SS段中栈内数据指针)扩展基址指针寄存器。
ESI:(字符串操作源指针)源变址寄存器。
EDI:(字符串操作目标指针)目的变址寄存器
ESP:(SS段中栈指针)栈指针寄存器。
EBP到ESP的这四个寄存器主要用作保存内存地址的指针。
ESP指示栈区域的栈顶地址,某些指令(PUSH,POP,CALL,RET)可以直接用来操作ESP(注:栈区域管理是程序中相当重要的部分,请不要把ESP用作其他用途)
EBP表示栈区域的基地址,函数被调用时保存EBP的值,函数返回时再把值返回给ESP,保证栈不会崩溃(这称为栈帧技术,这是逆向中的一个重要概念)。ESI和EDI与特定指令(LODS,STOS,REP,MOVS等)一起使用,主要用于内存复制。
段寄存器:段,这一术语来自IA-32的内存管理模型,在IA-32中,段是一种保护内存的技术,它把内存分为多个区段,并为每个区段赋予了起始地址,范围,访问权限等,以保护内存。此外,它还同分页技术一起用于将虚拟内存变更为实际物理内存。段内存记录在SDT(段描述符表中,这里有兴趣的可以去看滴水中级的视频,里面有对段描述符和段描述符表的介绍),而段寄存器就持有这些SDT的索引。
各段寄存器的名称如下:
CS:code segment 代码段寄存器
SS:stack segment 栈段寄存器
DS:data segment 数据段寄存器
ES:extra segment 附加(数据)寄存器
FS:data segment (附加)数据段寄存器
GS:data segmet (附加