逆向随笔 - strcmp函数的实现和分析

一、函数的实现

 

   这个函数还是比较简单的,就不做多余的解释了,上代码:

   

int _myStrcmp( char * str1, char * str2 )
{
	while ( *str1 != 0 && *str2 != 0 && *str1 == *str2 )
	{
		str1++;
		str2++;
	}
	return ( *str1 == 0 && *str2 == 0 );
}

 

 

二、逆向分析

    

       用IDA打开看看函数结构:

   

.text:004113C0 ; int __cdecl _myStrcmp(char *str1, char *str2)
.text:004113C0 ?_myStrcmp@@YAHPAD0@Z proc near         ; CODE XREF: _myStrcmp(char *,char *)j
.text:004113C0
.text:004113C0 var_C4          = dword ptr -0C4h
.text:004113C0 str1            = dword ptr  8
.text:004113C0 str2            = dword ptr  0Ch
.text:004113C0
.text:004113C0                 push    ebp
.text:004113C1                 mov     ebp, esp
.text:004113C3                 sub     esp, 0C4h
.text:004113C9                 push    ebx
.text:004113CA                 push    esi
.text:004113CB                 push    edi
.text:004113CC                 lea     edi, [ebp+var_C4]
.text:004113D2                 mov     ecx, 31h
.text:004113D7                 mov     eax, 0CCCCCCCCh
.text:004113DC                 rep stosd               ; 上面是填充栈空间
.text:004113DE
.text:004113DE loc_4113DE:                             ; CODE XREF: _myStrcmp(char *,char *)+54j
.text:004113DE                 mov     eax, [ebp+str1]
.text:004113E1                 movsx   ecx, byte ptr [eax] ; ecx = *str1
.text:004113E4                 test    ecx, ecx
.text:004113E6                 jz      short loc_411416 ; ecx == 0 ? 判断str1是否到结束符
.text:004113E8                 mov     eax, [ebp+str2]
.text:004113EB                 movsx   ecx, byte ptr [eax]
.text:004113EE                 test    ecx, ecx
.text:004113F0                 jz      short loc_411416 ; ecx = *str2     ecx == 0 ? 同上判断str2是否到达结束符
.text:004113F2                 mov     eax, [ebp+str1]
.text:004113F5                 movsx   ecx, byte ptr [eax]
.text:004113F8                 mov     edx, [ebp+str2]
.text:004113FB                 movsx   eax, byte ptr [edx]
.text:004113FE                 cmp     ecx, eax
.text:00411400                 jnz     short loc_411416 ; 取一字节带符号位扩展到4字节,*str1 == *str2 ?
.text:00411402                 mov     eax, [ebp+str1]
.text:00411405                 add     eax, 1
.text:00411408                 mov     [ebp+str1], eax ; str1++ 指针向前移动1字节
.text:0041140B                 mov     eax, [ebp+str2]
.text:0041140E                 add     eax, 1
.text:00411411                 mov     [ebp+str2], eax ; str2++ 指针向前移动1字节
.text:00411414                 jmp     short loc_4113DE ; 继续判断比较
.text:00411416 ; ---------------------------------------------------------------------------
.text:00411416
.text:00411416 loc_411416:                             ; CODE XREF: _myStrcmp(char *,char *)+26j
.text:00411416                                         ; _myStrcmp(char *,char *)+30j ...
.text:00411416                 mov     eax, [ebp+str1]
.text:00411419                 movsx   ecx, byte ptr [eax]
.text:0041141C                 test    ecx, ecx
.text:0041141E                 jnz     short loc_411436 ; *str1 == 0 ? 判断字符串str1是否到达末尾
.text:00411420                 mov     edx, [ebp+str2]
.text:00411423                 movsx   eax, byte ptr [edx]
.text:00411426                 test    eax, eax
.text:00411428                 jnz     short loc_411436 ; *str2 == 0 ? 判断字符串str2是否到达末
.text:0041142A                 mov     [ebp+var_C4], 1 ; *str1 == 0 && *str2 == 0, 局部变量赋值为1
.text:00411434                 jmp     short loc_411440 ; 结果赋值到eax返回
.text:00411436 ; ---------------------------------------------------------------------------
.text:00411436
.text:00411436 loc_411436:                             ; CODE XREF: _myStrcmp(char *,char *)+5Ej
.text:00411436                                         ; _myStrcmp(char *,char *)+68j
.text:00411436                 mov     [ebp+var_C4], 0 ; *str1 != 0 或者 *str2 != 0, 局部变量赋值成0
.text:00411440
.text:00411440 loc_411440:                             ; CODE XREF: _myStrcmp(char *,char *)+74j
.text:00411440                 mov     eax, [ebp+var_C4] ; 结果赋值到eax返回
.text:00411446                 pop     edi
.text:00411447                 pop     esi
.text:00411448                 pop     ebx
.text:00411449                 mov     esp, ebp
.text:0041144B                 pop     ebp
.text:0041144C                 retn
.text:0041144C ?_myStrcmp@@YAHPAD0@Z endp


 

      看下结构图 ,结构很清晰

           

 

 

三、我们自己用汇编写一个

      

int _myStrcmp( char * str1, char * str2 )
{
	__asm
	{
	____CMP:
		mov ecx, [str1]
		mov ah, byte ptr [ecx]
		cmp ah, 0x0
		je ___ENDLAB
		mov ecx, [str2]
		mov al, byte ptr [ecx]
		cmp al, 0x0
		je ___ENDLAB
		cmp ah, al
		jne ___ENDLAB
		mov eax, [str1]
		add eax, 0x1
		mov [str1], eax
		mov eax, [str2]
		add eax, 0x1
		mov [str2], eax
		jmp ____CMP
	
	___ENDLAB:
		xor eax, eax
		mov ecx, [str1]
		movsx eax, byte ptr [ecx]
		mov ecx, [str2]
		movsx ecx, byte ptr[ecx]
		sub  eax, ecx
	};
}


 


 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值