• 逆向分析练习三(最长公共前缀)


    逆向分析练习三(最长公共前缀

    这次选择的这个代码中存在for和while的嵌套,适合提升逆向中对循环的感知。

    题目描述

    编写一个函数来查找字符串数组中的最长公共前缀。

    如果不存在公共前缀,返回空字符串 ""

    示例 1:

    输入:strs = ["flower","flow","flight"]
    输出:"fl"
    
    • 1
    • 2

    debug版本汇编代码

    009F3580  push        ebp  
    009F3581  mov         ebp,esp 
    009F3583  sub         esp,0F0h 
    009F3589  push        ebx  
    009F358A  push        esi  
    009F358B  push        edi  
    009F358C  lea         edi,[ebp-0F0h] 
    009F3592  mov         ecx,3Ch 
    009F3597  mov         eax,0CCCCCCCCh 						
    009F359C  rep stos    dword ptr es:[edi] 				//rep 和 stos 在下面分析节点的[1]中有描述
    009F359E  mov         eax,dword ptr [strs] 			这下面开始是业务逻辑的代码了
    009F35A1  mov         ecx,dword ptr [eax] 
    009F35A3  push        ecx  										//上面应该是从一个指针的指针对象中取出地址
    009F35A4  call        @ILT+495(_strlen) (9F11F4h) //调用strlen
    009F35A9  add         esp,4 
    009F35AC  mov         dword ptr [a],eax 			//a = strlen的返回值
    009F35AF  mov         eax,dword ptr [strs] 	//
    009F35B2  mov         ecx,dword ptr [eax] 
    009F35B4  mov         dword ptr [ss],ecx 	//ss = strs[0]
    009F35B7  mov         dword ptr [j],1 				//这下面这一块应该是个for(;j=strSize
    009F35D1  mov         dword ptr [i],0 				//i=0
    009F35D8  mov         eax,dword ptr [i] 			//进入循环判断
    009F35DB  cmp         eax,dword ptr [a] 
    009F35DE  jge         longestCommonPrefix+88h (9F3608h) //if(a
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    分析

    1. stos:作用是把eax里面的数据,赋值给后面的地址,然后edi + 4,或者是-4,加或减主要看方向标志位DF,DF=0 就是+地址 DF=1就是减地址

      1. 例如:stos dword ptr es:[edi]这条stos指令可以分解后变成下面汇编代码

        mov dword ptr es:[edi],eax
        add edi , 4
        
        • 1
        • 2
    2. rep指令作用是:重复后面的指令,是个前缀,例如这里 rep stos,就是重复执行stos指令
      rep指令每次执行的时候都从ecx寄存器里面读取值,当ecx大于0,就执行后面语句,执行完以后,会让ecx - 1,然后再执行rep后面的指令。

    DOWRD func(char** strs,int strSize){
    	int  a = strlen(strs[0]);
    	char* ss = strs[0]
    	for(int j=0;j<strSize;j++){
    	int i = 0;
    		while(i<a){
    			if(ss[i] == strs[j][i]){
    				i++;
    			}else{
    				a = i;
    				break;
    			}
    		}
    	}
    	ss[a] = 0;
    	return ss;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    源代码

    
    char * longestCommonPrefix(char ** strs, int strsSize){
    int a=strlen(strs[0]);
    char*ss=strs[0];
    for(int j=1;j<strsSize;j++)
    {
    int i=0;
    while(i<a&&strs[j][i]==ss[i])
    {
        i++;
    }
    a=i;
    }
    ss[a]='\0';
    return ss;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    Unity技术手册 - 粒子发射和生命周期内速度子模块
    [单片机框架][bsp层][N32G4FR][bsp_flash] flash配置和使用
    【C++】记录一次代码优化,28490行代码优化到1401行代码
    PHP多功能投票微信小程序系统源码
    Java基本数据类型和变量
    每日学习笔记:C++ STL 的队列Deque
    选择图像区域矩形框控件【原创】
    (一)NIO 基础
    大学毕业一年 - 北漂生活
    [paddle]paddleseg中eiseg加载模型参数的模型下载地址
  • 原文地址:https://blog.csdn.net/qq_43147121/article/details/128039886