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

/*///////////////////////////////////////////////////////////////////////////////////////

函数解释:将s中前n个字节替换为ch并返回s;   
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。

///////////////////////////////////////////////////////////////////////////////////////*/

#include "stdafx.h"

void *pmemset(void *s , char ch , int n);

int main(int argc, char* argv[])
{
	char a[20];
	printf("%s\n",a);
	pmemset(a,'a',10);
	printf("%s\n",a);
	return 0;
}

void *pmemset(void *s , char ch , int n)
{
	char *temp_s=(char *)s;
	while (n--)
	{
		*temp_s=ch;
		temp_s++;
	}

	return s;
}

代码很简单,每天坚持,确实可以感受到明显的进步,特备是反汇编分析能力。加油!!

release编译,OD载入分析如下:

在release编译模式下,rep stos 配合填充,可以使dword 、byte快速初始化。

00401000  /$  83EC 14       sub esp,14                               ;  开辟14h(20)字节大小的内存空间留个变量(数组a[20])
00401003  |.  8D4424 00     lea eax,dword ptr ss:[esp]               ;  eax存放地址a
00401007  |.  50            push eax                                 ;  地址a入栈
00401008  |.  68 30704000   push memset.00407030                     ;  ASCII "%s
"
0040100D  |.  E8 6E000000   call memset.00401080                     ;  printf
00401012  |.  6A 0A         push 0A                                  ;  参数3:10 入栈
00401014  |.  8D4C24 0C     lea ecx,dword ptr ss:[esp+C]             ;  ecx存放地址a
00401018  |.  6A 61         push 61                                  ;  ‘a’入栈
0040101A  |.  51            push ecx                                 ;  地址a入栈
0040101B  |.  E8 20000000   call memset.00401040                     ;  memset()
00401020  |.  8D5424 14     lea edx,dword ptr ss:[esp+14]
00401024  |.  52            push edx
00401025  |.  68 30704000   push memset.00407030                     ;  ASCII "%s
"
0040102A  |.  E8 51000000   call memset.00401080
0040102F  |.  33C0          xor eax,eax
00401031  |.  83C4 30       add esp,30
00401034  \.  C3            retn
00401035      90            nop
00401036      90            nop
00401037      90            nop
00401038      90            nop
00401039      90            nop
0040103A      90            nop
0040103B      90            nop
0040103C      90            nop
0040103D      90            nop
0040103E      90            nop
0040103F      90            nop
00401040  /$  8B4424 0C     mov eax,dword ptr ss:[esp+C]             ;  memset入口地址  eax存int n=0ah
00401044  |.  8BC8          mov ecx,eax                              ;  while(n--)
00401046  |.  48            dec eax
00401047  |.  85C9          test ecx,ecx
00401049  |.  74 30         je short memset.0040107B
0040104B  |.  8D48 01       lea ecx,dword ptr ds:[eax+1]             ;  ecx=n-1
0040104E  |.  8A4424 08     mov al,byte ptr ss:[esp+8]               ;  al存‘a’
00401052  |.  53            push ebx
00401053  |.  8AD8          mov bl,al
00401055  |.  8AFB          mov bh,bl                                ;  bh='a'
00401057  |.  56            push esi
00401058  |.  8B7424 0C     mov esi,dword ptr ss:[esp+C]             ;  esi存放地址a
0040105C  |.  8BC3          mov eax,ebx                              ;  'a'存入eax
0040105E  |.  8BD1          mov edx,ecx                              ;  edx=n-1
00401060  |.  57            push edi
00401061  |.  C1E0 10       shl eax,10                               ;  eax逻辑左移10h位
00401064  |.  8BFE          mov edi,esi                              ;  edi存放地址a
00401066  |.  66:8BC3       mov ax,bx
00401069  |.  C1E9 02       shr ecx,2                                ;  ecx右移2位 ecx为后面重复次数 ecx=10b
0040106C  |.  F3:AB         rep stos dword ptr es:[edi]              ;  将ax值重复存放到目的串符号地址(地址a),即填充,一次填充8个a
0040106E  |.  8BCA          mov ecx,edx
00401070  |.  83E1 03       and ecx,3                                ;  ecx=2
00401073  |.  F3:AA         rep stos byte ptr es:[edi]               ;  填充了2个a  此处是以byte填充的
00401075  |.  8BC6          mov eax,esi
00401077  |.  5F            pop edi
00401078  |.  5E            pop esi
00401079  |.  5B            pop ebx
0040107A  |.  C3            retn
0040107B  |>  8B4424 04     mov eax,dword ptr ss:[esp+4]
0040107F  \.  C3            retn


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章