asm source code note 1.9 结构和数组的访问
发布日期:2021-06-30 22:06:03 浏览次数:2 分类:技术文章

本文共 10482 字,大约阅读时间需要 34 分钟。

数组的访问

源程序

// test1020.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#define ARRAY_SIZE 10 ///< 数组的元素个数/// @fn ArrayInit/// @brief 给定一个数组的首地址, 对数组初始化. 数组size = ARRAY_SIZEvoid ArrayInit(char * pcArray);/// @fn ArrayShow/// @brief 给定一个数组的首地址, 显示数组内容void ArrayShow(char * pcArray);int _tmain(int argc, _TCHAR* argv[]){ char cBuf[ARRAY_SIZE]; ArrayInit(cBuf); ArrayShow(cBuf); getwchar(); return 0;}void ArrayInit(char * pcArray){ size_t nIndex = 0; for (nIndex = 0; nIndex < ARRAY_SIZE; nIndex++) *(pcArray + nIndex) = nIndex + 1;}void ArrayShow(char * pcArray){ size_t nIndex = 0; for (nIndex = 0; nIndex < ARRAY_SIZE; nIndex++) _tprintf(L"*(pcArray + %d) = %d\r\n", nIndex, *(pcArray + nIndex));}
OD反汇编

00821000 >/$  83EC 10       sub     esp, 10                                  ;  开辟16个字节的栈空间, 小地址前10个为数据, 大地址最后是一个栈溢出检查值00821003  |.  A1 00308200   mov     eax, dword ptr [__security_cookie]       ;  dword ptr [__security_cookie]每次的栈溢出检查初始值值都不同00821008  |.  33C4          xor     eax, esp0082100A  |.  894424 0C     mov     dword ptr [esp+C], eax                   ;  压入栈溢出检查的参数0082100E  |.  33C0          xor     eax, eax00821010  |>  8AC8          /mov     cl, al                                  ;  对数组进行初始化00821012  |.  FEC1          |inc     cl                                      ;  每个元素初始值 = 当前位置索引 + 100821014  |.  880C04        |mov     byte ptr [esp+eax], cl                  ;  基址 + 变址, 可以看成是对数组的操作.00821017  |.  40            |inc     eax                                     ;  指向数组中下一个元素的索引00821018  |.  83F8 0A       |cmp     eax, 0A                                 ;  数组的元素个数是100082101B  |.^ 72 F3         \jb      short 008210100082101D  |.  56            push    esi0082101E  |.  57            push    edi                                      ;  经过2个push后, 执行后, 数组首地址变为了 [esp + 8]0082101F  |.  8B3D 9C208200 mov     edi, dword ptr [<&MSVCR90.wprintf>]      ;  MSVCR90.wprintf00821025  |.  33F6          xor     esi, esi                                 ;  变址指针清零, 用来遍历数组00821027  |>  0FBE5434 08   /movsx   edx, byte ptr [esp+esi+8]               ;  [esp + 8] 为数组首地址, esi 为变址指针0082102C  |.  52            |push    edx0082102D  |.  56            |push    esi0082102E  |.  68 F4208200   |push    008220F4                                ;  UNICODE "*(pcArray + %d) = %d",CR,LF00821033  |.  FFD7          |call    edi                                     ;  调用wprintf 打印数组元素00821035  |.  46            |inc     esi                                     ;  指向下一个元素索引00821036  |.  83C4 0C       |add     esp, 0C                                 ;  call edi(msvcr90.wprintf)之后的堆栈平衡00821039  |.  83FE 0A       |cmp     esi, 0A                                 ;  总共要打印10次, 数组的元素个数为100082103C  |.^ 72 E9         \jb      short 00821027                          ;  JB命令只判断 C标志, 判断是否有进位0082103E  |.  FF15 A4208200 call    dword ptr [<&MSVCR90.getwchar>]          ; [getwchar00821044  |.  8B4C24 14     mov     ecx, dword ptr [esp+14]00821048  |.  5F            pop     edi                                      ;  堆栈平衡, 对应于 012a101d00821049  |.  5E            pop     esi0082104A  |.  33CC          xor     ecx, esp0082104C  |.  33C0          xor     eax, eax0082104E  |.  E8 04000000   call    __security_check_cookie                  ;  栈溢出检查, 用的参数是 012a100a 压入栈的参数00821053  |.  83C4 10       add     esp, 10                                  ;  堆栈平衡, 对应于012a100000821056  \.  C3            retn
可以看出: 在汇编中对数组访问, 采用的是[基址 + 变址]的方式.

结构的访问

源程序

// test1020.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#define ARRAY_SIZE 10 ///< 数组的元素个数typedef struct _tagInfo{ char cType; ///< 物品类型 size_t nCounter; ///< 物品数量 wchar_t cNote[_MAX_PATH]; ///< 备注}TAGINFO, *PTAGINFO;int _tmain(int argc, _TCHAR* argv[]){ TAGINFO tagInfo; ::ZeroMemory(&tagInfo, sizeof(TAGINFO)); tagInfo.cType = 1; tagInfo.nCounter = 100; _tcscpy_s(tagInfo.cNote, sizeof(tagInfo.cNote) / sizeof(wchar_t), L"note\r\n"); getwchar(); return 0;}
OD反汇编

00E61000 >/$  55            push    ebp00E61001  |.  8BEC          mov     ebp, esp                                 ;  esp = 0x003FF78C00E61003  |.  83E4 F8       and     esp, FFFFFFF8                            ;  栈空间字节对齐, esp = 0x003FF788, 对齐后, 更靠近小地址.00E61006  |.  81EC 18020000 sub     esp, 218                                 ;  esp = 0x003FF570, 分配218个字节栈空间, 前面是结构空间, 后面是栈溢出检查初始值00E6100C  |.  A1 0030E600   mov     eax, dword ptr [__security_cookie]00E61011  |.  33C4          xor     eax, esp00E61013  |.  898424 140200>mov     dword ptr [esp+214], eax                 ;  给栈溢出检查变量赋值00E6101A  |.  68 10020000   push    210                                      ; /结构长度为21000E6101F  |.  8D4424 04     lea     eax, dword ptr [esp+4]                   ; |此时, esp + 4 为结构首地址, 因为前面有push 21000E61023  |.  6A 00         push    0                                        ; |每个Bits要设置的值为0x000E61025  |.  50            push    eax                                      ; |结构首地址00E61026  |.  E8 33080000   call    memset                                   ; \memset00E6102B  |.  68 F420E600   push    00E620F4                                 ;  UNICODE "note",CR,LF00E61030  |.  8D4C24 18     lea     ecx, dword ptr [esp+18]                  ;  esp + 18 = 0x3ff578, 结构中的note部分起始地址。00E61034  |.  68 04010000   push    104                                      ;  长度为0x104(260)个宽字符00E61039  |.  51            push    ecx00E6103A  |.  C64424 18 01  mov     byte ptr [esp+18], 1                     ;  esp + 0x18 = 0x3ff570, 可以看出是结构首地址. 结构.byte值 = 100E6103F  |.  C74424 1C 640>mov     dword ptr [esp+1C], 64                   ;  esp + 1c = 0x3ff574, 结构.DWORD值 = 0x6400E61047  |.  FF15 A420E600 call    dword ptr [<&MSVCR90.wcscpy_s>]          ;  MSVCR90.wcscpy_s00E6104D  |.  83C4 18       add     esp, 18                                  ;  堆栈平衡, 执行后, esp = 0x3ff570, 又指向结构首地址.00E61050  |.  FF15 9C20E600 call    dword ptr [<&MSVCR90.getwchar>]          ; [getwchar00E61056  |.  8B8C24 140200>mov     ecx, dword ptr [esp+214]                 ;  栈溢出检查00E6105D  |.  33CC          xor     ecx, esp00E6105F  |.  33C0          xor     eax, eax00E61061  |.  E8 04000000   call    __security_check_cookie00E61066  |.  8BE5          mov     esp, ebp00E61068  |.  5D            pop     ebp00E61069  \.  C3            retn
可以看出, 结构的访问 是 基地址 + 偏移偏移(结构的成员地址偏移, 固定的).

结构数组的访问

源程序

// test1020.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#define ARRAY_SIZE 10 ///< 数组的元素个数typedef struct _tagInfo{ char cType; ///< 物品类型 size_t nCounter; ///< 物品数量 wchar_t cNote[_MAX_PATH]; ///< 备注}TAGINFO, *PTAGINFO;int _tmain(int argc, _TCHAR* argv[]){ size_t nIndex = 0; TAGINFO tagInfo[ARRAY_SIZE]; ::ZeroMemory(&tagInfo[0], sizeof(TAGINFO) * ARRAY_SIZE); for (nIndex = 0; nIndex < ARRAY_SIZE; nIndex++) { tagInfo[nIndex].cType = 1; tagInfo[nIndex].nCounter = rand(); wsprintf(tagInfo[nIndex].cNote, L"%s%d\r\n", L"note", nIndex); } getwchar(); return 0;}
OD反汇编

012F1000 >/$  B8 A4140000   mov     eax, 14A4012F1005  |.  E8 76080000   call    _chkstk012F100A  |.  A1 00302F01   mov     eax, dword ptr [__security_cookie]012F100F  |.  33C4          xor     eax, esp012F1011  |.  898424 A01400>mov     dword ptr [esp+14A0], eax012F1018  |.  53            push    ebx012F1019  |.  55            push    ebp012F101A  |.  56            push    esi012F101B  |.  57            push    edi012F101C  |.  68 A0140000   push    14A0                                        ; /结构数组总size = 0x14a0012F1021  |.  8D4424 14     lea     eax, dword ptr [esp+14]                     ; |结构数组首地址为 [esp + 14] = 0x0035e550012F1025  |.  6A 00         push    0                                           ; |c = 00012F1027  |.  50            push    eax                                         ; |s012F1028  |.  E8 7F080000   call    memset                                      ; \清空结构数组012F102D  |.  8B2D A4202F01 mov     ebp, dword ptr [<&MSVCR90.rand>]            ;  MSVCR90.rand012F1033  |.  8B1D B0202F01 mov     ebx, dword ptr [<&USER32.wsprintfW>]        ;  USER32.wsprintfW012F1039  |.  83C4 0C       add     esp, 0C                                     ;  堆栈平衡012F103C  |.  33FF          xor     edi, edi                                    ;  结构数组中的当前结构索引值清零.012F103E  |.  8D7424 14     lea     esi, dword ptr [esp+14]                     ;  esi = 结构数组第一个结构的地址012F1042  |>  C646 FC 01    /mov     byte ptr [esi-4], 1                        ;  结构[n].byteVal = 1012F1046  |.  FFD5          |call    ebp                                        ;  产生随机数, 随机数在eax中012F1048  |.  57            |push    edi012F1049  |.  68 04212F01   |push    012F2104                                   ;  UNICODE "note"012F104E  |.  8D4E 04       |lea     ecx, dword ptr [esi+4]                     ;  esi + 4 = 结构.cValueW, size = 0x210 - 0x4 - 0x4012F1051  |.  68 10212F01   |push    012F2110                                   ;  UNICODE "%s%d",CR,LF012F1056  |.  51            |push    ecx012F1057  |.  8906          |mov     dword ptr [esi], eax                       ;  当前结构.dwValue = rand(); 可以看出当前结构指针指到了结构.dwValue地址上012F1059  |.  FFD3          |call    ebx                                        ;  USER32.wsprintfW012F105B  |.  47            |inc     edi                                        ;  结构数组当前结构的位置索引, base0012F105C  |.  83C4 10       |add     esp, 10                                    ;  堆栈平衡, 对应于wsprintfW012F105F  |.  81C6 10020000 |add     esi, 210                                   ;  指向结构数组中的下一个结构, 当前 esi = 0x0035e974012F1065  |.  83FF 0A       |cmp     edi, 0A                                    ;  结构数组元素个数 = 0xA012F1068  |.^ 72 D8         \jb      short 012F1042012F106A  |.  FF15 A0202F01 call    dword ptr [<&MSVCR90.getwchar>]             ; [getwchar012F1070  |.  8B8C24 B01400>mov     ecx, dword ptr [esp+14B0]012F1077  |.  5F            pop     edi012F1078  |.  5E            pop     esi012F1079  |.  5D            pop     ebp012F107A  |.  5B            pop     ebx012F107B  |.  33CC          xor     ecx, esp012F107D  |.  33C0          xor     eax, eax012F107F  |.  E8 07000000   call    __security_check_cookie012F1084  |.  81C4 A4140000 add     esp, 14A4012F108A  \.  C3            retn
可以看出, 对结构数组成员的访问, 采用的是 变址 + 结构成员地址偏移的方法

转载地址:https://lostspeed.blog.csdn.net/article/details/4634182 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:asm source code note 1.10 nion 和 enum 的访问
下一篇:asm source code note 1.8_没有原文的asm to c

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年05月03日 04时10分06秒