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"#includeOD反汇编#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));}
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"#includeOD反汇编#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;}
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"#includeOD反汇编#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;}
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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2024年05月03日 04时10分06秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
代码整洁之道-编写 Pythonic 代码
2019-05-01
100行python代码,轻松完成贪吃蛇小游戏
2019-05-01
如何科学的刷 Leetcode
2019-05-01
树莓派程序开机自启动
2019-05-01
WiFi强力信号连接方案
2019-05-01
连锁门店无线通信方案
2019-05-01
ATM终端无线方案
2019-05-01
配置Lotus Domino集群视频详解
2019-05-01
Cisco PIX防火墙PPPoE拨号配置视频教学
2019-05-01
通过PXE安装Linux实况
2019-05-01
Linux / Windows应用方案不完全对照表
2019-05-01
Cisco交换机SPAN&RSPAN调试实录
2019-05-01
轻松掌握Ubuntu Linux的3D桌面快捷键使用
2019-05-01
通过视频展示如何通过Samba配置PDC
2019-05-01
OSSIM(开源安全信息管理系统)在企业网络管理中的应用
2019-05-01
网站及监控利器 Pandora FMS使用体验
2019-05-01
解决Esxi5下安装Windows 8的问题
2019-05-01
如何搭建Eclipse +Apache Tomcat配置Java开发环境
2019-05-01
开源计算机集群监控Ganglia应用视频
2019-05-01