![在这里插入图片描述](https://img-blog.csdnimg.cn/52d8a8fd30844ac9a0d66cda8470c7b4.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAdl8zNDgzNjA4NzYy,size_19,color_FFFFFF,t_70,g_se,x_16)
这是要求,64位还是有地方不同的![在这里插入图片描述](https://img-blog.csdnimg.cn/c46fb2545128460f97ff225e9f01acd8.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAdl8zNDgzNjA4NzYy,size_20,color_FFFFFF,t_70,g_se,x_16)
1.这个rcx像是基地址后面的找表和跳转都要用到。在倒数第四行就是把这个00007FF623180000 给rcx给它存着先。
2.然后找表,表里面存的数给eax。
3.然后这个rcx和rax相加就得到了,应该跳转的地方 。
这个是我做的普通的表。
下面是作业
1、写一个switch语句,不生产大表也不生产小表,贴出对应的反汇编.
#include <iostream>
using namespace std;
int main()
{
int a = 3;
switch (a)
{case 1:
printf("a");
break;
case 2:
printf("b");
break;
case 3:
printf("c");
break;
default:
printf("error");
break;
}
return 0;
}
mov eax,dword ptr [a]
mov dword ptr [rbp+0D4h],eax
cmp dword ptr [rbp+0D4h],1
je main+48h (07FF620B92148h)
cmp dword ptr [rbp+0D4h],2
je main+56h (07FF620B92156h)
cmp dword ptr [rbp+0D4h],3
je main+64h (07FF620B92164h)
jmp main+72h (07FF620B92172h)
就是相等就跳,不相等就跳default。
2、写一个switch语句,只生成大表,贴出对应的反汇编.
#include <iostream>
using namespace std;
int main()
{
int a = 3;
switch (a)
{case 1:
printf("a");
break;
case 2:
printf("b");
break;
case 3:
printf("c");
break;
case 4:
printf("d");
break;
case 5:
printf("e");
break;
case 6:
printf("f");
break;
default:
printf("error");
break;
}
return 0;
}
lea rcx,[__ImageBase (07FF7D5EE0000h)]
mov eax,dword ptr [rcx+rax*4+121C8h]
add rax,rcx
jmp rax
这个是找表的过程
下面的是表,表都是八个字节的然后再加上rcx就可以找到应该跳的地方。
emm,找不到小表。或者可以这么说在x86里,大表里的地址就直接跳转了,当中间不连续很多的时候采用小表,小表里面里的值就是大表的排序,然后根据小表的序号找大表,这样可以节省空间。👀
而x64里呢是直接做成了一个表,把这个表里的值按照顺序拿出来然后加起来就直接了。🤷♂️
do ——while
printf("d",&i)
lea rdx,[i]
lea rcx,[string "%d" (07FF6F48BAD24h)]
call printf (07FF6F48B11EAh)
i++;
mov eax,dword ptr [i]
inc eax
mov dword ptr [i],eax
} while (i<3);
cmp dword ptr [i],3
jl __$EncStackInitStart+35h (07FF6F48B2144h)
先是输出然后i++,最后cmp比较,如果i小于 3就在跳回去。
while
while(i < 3)
cmp dword ptr [i],3
jge main+41h (07FF6F26D2141h)
{
printf("%d", i);
mov edx,dword ptr [i]
lea rcx,[string "%d" (07FF6F26DAD24h)]
call printf (07FF6F26D11EAh)
i++;
mov eax,dword ptr [i]
inc eax
mov dword ptr [i],eax
}
jmp main+22h (07FF6F26D2122h)
从一开始比较如果符合条件就直接跳到while循环外,如果不符合就进入while最后再跳到比较。
for
for (int i = 0; i < 3; i++)
mov dword ptr [rbp+4],0
jmp main+2Ch (07FF7C4CD181Ch)
mov eax,dword ptr [rbp+4]
inc eax
mov dword ptr [rbp+4],eax
cmp dword ptr [rbp+4],3
jge main+44h (07FF7C4CD1834h)
{
cout << i;
mov edx,dword ptr [rbp+4]
mov rcx,qword ptr [__imp_std::cout (07FF7C4CE0150h)]
call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7C4CE0158h)]
}
jmp main+24h (07FF7C4CD1814h)
第一次循环的时候没有使用
mov eax,dword ptr [rbp+4]
inc eax
而是 jmp main+2Ch (07FF7C4CD181Ch) 跳到了比较,其实就是for语句的第三个表达式。然后就进行比较比较没成功就进行 for循环里的,比较好就跳走了。
for循环的第三个表达式是夹在第一个表达式和第二个之间。等啥时候第二次循环了就可以用了。