滴水逆向 switch

在这里插入图片描述
这是要求,64位还是有地方不同的在这里插入图片描述
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里呢是直接做成了一个表,把这个表里的值按照顺序拿出来然后加起来就直接了。🤷‍♂️

这个是别人做的实验x86的机子

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循环的第三个表达式是夹在第一个表达式和第二个之间。等啥时候第二次循环了就可以用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值