部分C库函数重写以及反汇编分析之memmov()

本文探讨了C库中的memmov()函数,详细分析了其处理内存区域重叠的逻辑,并通过反汇编进行了深入理解。在release模式下,使用OD加载进行反汇编分析,揭示了函数内部的工作机制。
摘要由CSDN通过智能技术生成
/*/

功能:由src所指内存区域复制count个字节到dest所指内存区域。   
说明:src和dest所指内存区域可以重叠,但复制后dest内容会被更改。函数返回指向dest的指针。
 
/*/
#include "stdafx.h"

void *pmemmove(void *dest , void *src , int count);

int main(int argc, char* argv[])
{
	//printf("Hello World!\n");
	char a1[]="abcdefg";
	char a2[10]={0};

	printf("%s\n",a2);

	pmemmove(a2,a1,5);

	printf("%s\n",a2);
	return 0;
}

void *pmemmove(void *dest , void *src , int count)
{
	char *temp_dest=(char *)dest;
	char *temp_src=(char *)src;

	if (temp_dest<temp_src || temp_src+count<temp_dest)
	{
		// 没有重叠区域
		//从高地址拷贝到低地址
		while (count--)
		{
			*temp_dest=*temp_src;
			temp_src++;
			temp_dest++;
		}
		
	}
	else
	{
		//有重叠区域
		temp_src=temp_src+count-1;
		temp_dest=temp_dest+count-1;

		while(count--)
		{
			*temp_dest=*temp_src;
			temp_src--;
			temp_dest--;
		}
	}
	
	return dest;
}

这个函数主要考虑到2段内存区域是否重叠。

判断是否重叠的逻辑分析如下图:


release模式编译,OD载入反汇编分析如下:

00401000  /$  83EC 14       sub esp,14
00401003  |.  A1 34704000   mov eax,dword ptr ds:[407034]
00401008  |.  8B0D 38704000 mov ecx,dword ptr ds:[407038]            ;  abcdefg赋值,存在eax/ecx中
0040100E  |.  33D2          xor edx,edx                              ;  edx=0
00401010  |.  894424 00     mov dword ptr ss:[esp],eax               ;  a1=abcdefg
00401014  |.  895424 09     mov dword ptr ss:[esp+9],edx             ;  a2[]={0};
00401018  |.  8D4424 08     lea eax,dword ptr ss:[esp+8]             ;  eac存放a2首地址
0040101C  |.  895424 0D     mov dword ptr ss:[esp+D],edx
00401020  |.  50            push eax
00401021  |.  68 30704000   push memmove.00407030                    ;  ASCII "%s
"
00401026  |.  894C24 0C     mov dword ptr ss:[esp+C],ecx
0040102A  |.  C64424 10 00  mov byte ptr ss:[esp+10],0
0040102F  |.  885424 19     mov byte ptr ss:[esp+19],dl
00401033  |.  E8 78000000   call memmove.004010B0
00401038  |.  8D4C24 08     lea ecx,dword ptr ss:[esp+8]             ;  abcdefg存入ecx
0040103C  |.  6A 05         push 5
0040103E  |.  8D5424 14     lea edx,dword ptr ss:[esp+14]            ;  将数组a2首地址存入edx
00401042  |.  51            push ecx
00401043 >|.  52            push edx                                 ;  三个参数依次入栈
00401044  |.  E8 17000000   call memmove.00401060                    ;  调用函数(memmove)
00401049  |.  8D4424 1C     lea eax,dword ptr ss:[esp+1C]
0040104D  |.  50            push eax
0040104E  |.  68 30704000   push memmove.00407030                    ;  ASCII "%s
"
00401053  |.  E8 58000000   call memmove.004010B0
00401058  |.  33C0          xor eax,eax
0040105A  |.  83C4 30       add esp,30
0040105D  \.  C3            retn
0040105E      90            nop
0040105F      90            nop
00401060  /$  8B4424 04     mov eax,dword ptr ss:[esp+4]             ;  将第一个参数(从左往右)存入eax(memmove函数的入口处)
00401064  |.  8B4C24 0C     mov ecx,dword ptr ss:[esp+C]             ;  将第三个参数存入ecx  (5)
00401068  |.  56            push esi
00401069  |.  8B7424 0C     mov esi,dword ptr ss:[esp+C]             ;  esi=abcdefg;
0040106D  |.  3BC6          cmp eax,esi                              ;  参数1和参数2进行比较  这里esi存的是abcd首地址
0040106F  |.  57            push edi
00401070  |.  8BD0          mov edx,eax
00401072  |.  72 24         jb short memmove.00401098                ;  参数1<=参数2,则跳
00401074  |.  8D3C0E        lea edi,dword ptr ds:[esi+ecx]
00401077  |.  3BF8          cmp edi,eax                              ;  这里edi存的是“fg”字符串首地址
00401079  |.  72 1D         jb short memmove.00401098                ;  dest<src,跳
0040107B  |.  8D57 FF       lea edx,dword ptr ds:[edi-1]
0040107E  |.  8D7408 FF     lea esi,dword ptr ds:[eax+ecx-1]
00401082  |.  8BF9          mov edi,ecx
00401084  |.  49            dec ecx
00401085  |.  85FF          test edi,edi
00401087  |.  74 24         je short memmove.004010AD
00401089  |.  8D79 01       lea edi,dword ptr ds:[ecx+1]
0040108C  |>  8A0A          /mov cl,byte ptr ds:[edx]
0040108E  |.  4A            |dec edx
0040108F  |.  880E          |mov byte ptr ds:[esi],cl
00401091  |.  4E            |dec esi
00401092  |.  4F            |dec edi
00401093  |.^ 75 F7         \jnz short memmove.0040108C
00401095  |.  5F            pop edi
00401096  |.  5E            pop esi
00401097  |.  C3            retn
00401098  |>  8BF9          mov edi,ecx                              ;  进入while(n--)循环,开始拷贝内存数据
0040109A  |.  49            dec ecx
0040109B  |.  85FF          test edi,edi
0040109D  |.  74 0E         je short memmove.004010AD
0040109F  |.  2BF0          sub esi,eax
004010A1  |.  8D79 01       lea edi,dword ptr ds:[ecx+1]
004010A4  |>  8A0C16        /mov cl,byte ptr ds:[esi+edx]
004010A7  |.  880A          |mov byte ptr ds:[edx],cl
004010A9  |.  42            |inc edx
004010AA  |.  4F            |dec edi
004010AB  |.^ 75 F7         \jnz short memmove.004010A4
004010AD  |>  5F            pop edi
004010AE  |.  5E            pop esi
004010AF  \.  C3            retn

表示反汇编功底太差,看得我要死。。。。。。。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值