*1)switch语句,找CALL的时候经常碰到switch,如果有效的识别出switch语句,只要找到其中一个CALL,其他的CALL变址搞定。
2)if 和 if else 语句中的表达式没有要求,只要成立执行代码,后面不执行了。
3)另外的一种 if else = switch,如果表达式中有大量的类似 (x ==1),就可以用switch
4)游戏中,switch语句经常用在角色的技能上,比如:打坐、技能、加血、加蓝、等等;例如加红,先从明文发包下手,加红后会向服务器发数据,拦截发的数据逐层反到加红的方法,对switch反汇编结构熟悉,就能一次性找到很多技能,case上下结构环境。
以下测试用visual studio2019,会因为编译器版本算法不同,生成不同的测试结果;
5)当case分支条件小于4个的时候,与if else 没有区别(效率和反汇编);
3个case分支6)当case分支条件大于3个的时候(不同编译器会有差异),在编译时算好生成switch大表地址,并且case后面的常量可以无序,不影响大表;
原理:switch(x){case 1: case 2: case 3: }
1.当传入变量的x,不合法(即,x 不等于case列表的某一常量)直接进入default,此块不做研究
2.当传入变量的x,合法(即,x等于case列表的某一常量),
或者 说x减去case 最小常量的值,在(常量偏移系数 k = case 最大常量值 - case 最小常量值)范围内:
下图中是5个case分支:
5个case分支(switch大表,case常量可无序排列)virual studio 2019下图例中是4个case分支,即4 -1 = 3(case 4 - case 1),如果x-1的值比还3大直接进入default:
4个case分支(switch大表,case常量可无序排列)7)当case 分支常量不连续,且有一个case常量相差很大 switch(x){case 301: case 302: case 303: case 304: case 7 : default: }
无章法了,和if else一样8)当case 分支常量不连续,且有一个case常量相差非常小之【大表】 switch(x){case 301: case 302: case 303: case 304: case 8:default: }
只生成case分支大表注意:case 5:case 6:分支虽然没有,但编译器还是生成case表用defaul填充了(上图中64 5C 44 00 即:0x445C64),浪费了两个地址空间;
9)当case 分支常量不连续,且有一个case常量相差非常小之小表和大表switch(x){case 301: case 308: case 309: case 310: default: }
生成case分支小表和大表注意:case 2:case 3:case4:case5:case6:case7分支虽然没有,这次编译器再生成大表的同时,紧挨着大表小面有个小表(用来计算eax*4的查表偏移),movzx eax,byte ptr [edx+205C94h] 指令中的 edx 是在小表中查表后得到的偏移量,在类型扩展给eax送给大表做最后的计算,并不浪费查表所产生的填充空间;
总结:switch语句使用时,case常量的连续性,无任何间断。是效率最高的!减少cpu执行指令的周期。
注:什么时候用小表,就是case常量不连续,间隔小于256个case分支.
小表范围是0xFF(即256个,movzx eax, byte ptr [edx+0x205c94 ] )
如果小表也超出了。大表和小表不生成,用收索二叉数判断。
网友评论