C语言指针与结构体,示例代码
2015-06-11 13:21
531 查看
// testMemoryTrace.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <assert.h> #include <iostream> using namespace std; /* 标题:C语言指针与结构体,示例代码 Title:C language pointer and struct. Date:2015-6-11 Author:Kagula Environment:VS2013Update4,IDA Pro 6.6 Destination:测试IDA Pro对内存块的trace。 Reference: [1]使用Visual Studio2005进行C和汇编的混合编程 http://blog.csdn.net/crazii/article/details/2949374 */ //注意:这里的byte是四字节sizeof(unsigned char*)=4,不是单字节sizeof(unsigned char)=1。 // 所以指向byte的指针,移动单位为四字节。 typedef unsigned char* byte; struct structA{ byte *pA; byte *pB; } a; /* Change1、Change2、Change3在功能上是等价的。 都是为了修改结构体第二个元素对象所指向的内存块的值。 采用不同的语法,主要是为了演示指针的结构的关系。 */ void Change1(byte* pA); void Change2(byte* pA); void Change3(byte* pA); /* Change2_1、Change2_2在功能上是等价的。 都是为了修改结构体第二个元素对象所指向的内存块第二个数据单元的值。 采用不同的语法,主要是为了演示指针的使用。 */ void Change2_1(byte* pA); void Change2_2(byte* pA); void Change2_3(byte* pA); byte buf[22];//测试这块内存是否能被IDA Pro trace。 int _tmain(int argc, _TCHAR* argv[]) { cout << "测试IDAtrace内存区域,输入任意键继续。。。" << endl; cin.get(); //初始化样本 //“unsigned char*”是四字节,所以这里清空了4*22=88个字节。 //所以buf上分配的也是4*22节字节。 memset(buf, 0, sizeof(buf)); a.pA = nullptr; a.pB = buf; { /* Change1 function is modify the second pointer object reference data of the struct. Change1、Change2 and Change3 function 's effect is equality. Here is for illustrate different semantic C language statement. */ Change1((byte*)(&a)); cout << (char*)a.pB << endl; Change2((byte*)(&a)); cout << (char*)a.pB << endl; Change3((byte*)(&a)); cout << (char*)a.pB << endl; } cout << "=====================================================" << endl; { Change2_1((byte*)(&a)); cout << (char*)a.pB << endl; Change2_2((byte*)(&a)); cout << (char*)a.pB << endl; Change2_3((byte*)(&a)); cout << (char*)a.pB << endl; } //after input any key, the program will return! cin.get(); return 0; } //修改字符串的值 void Change1(byte* pA) { char array1[] = "apple"; int len = sizeof(array1); structA *p1 = (structA *)pA; memcpy(p1->pB, array1, len); } void Change2(byte* pA) { char array1[] = "banana"; int len = sizeof(array1); /* pA是指针对象,在32位下指针对象是四字节单位,所以(pA+1)实际上是偏移四个对象 即指向下一个byte元素。 */ byte* ppB = (pA + 1); //ppB指向的也是内存(地址),所以可以像下面的形式那样调用。 memcpy(*ppB, array1, len); } void Change3(byte* pA) { char array1[] = "pear"; int len = sizeof(array1); /* pA加1是地址,pA加1指向的也是地址 所以可以看成是指针的指针。 */ byte** pB = (byte**)(pA + 1); memcpy(*pB, array1, len); } //功能:修改字符串的第二个字符的值为'Y'。 void Change2_1(byte* pA) { char array1[] = "apple"; int len = sizeof(array1); structA *p1 = (structA *)pA; /* 编译器把“byte*”作为四字节为单位的数组, 所以索引[1]其实是加4, 所以实际修改的是字符串第五个字节的值 */ //p1->pB[1] = (byte)'Y'; /* 这里把“byte*”转为“char*” 编译器就会从“4字节单位”改为“单字节单位”增量。 这里正确的修改了字符串第二个字节的值。 */ char *pB = (char*)p1->pB; pB[1] = 'Y'; } //功能:修改字符串的第二个字符的值为'X'。 void Change2_2(byte* pA) { byte* ppB = (pA + 1); byte* pB = (byte*)(*ppB); //pB字符串的第五个字节(地址+4)的值为'X'。 //因为pB是指针对象,32位系统下,指针对象的大小为4。 //pB[1] = byte('X'); //*(pB + 1) = byte('X');//同上面等价 //如果不想转成char*来处理,那就只能用下面的ASM代码了。 //设置pB字符的第二个字符的值为'X'。 __asm inc dword ptr[pB] ; pB是局部存储空间,所以是pB指向的地址+1. __asm mov eax, dword ptr[pB]; 取出pB指向的地址,因为地址是四字节长度,所以得用“dword ptr”修饰。 __asm mov byte ptr[eax], 43h; 我们把pB当作指向单字节数据的指针,所以,这里用“byte ptr”修饰。 } void Change2_3(byte* pA) { byte** pB = (byte**)(pA + 1); //因为pB是指针对象,32位系统下,byte指针对象的大小为4 //所以这里改变的是第5个字节的值。 //(*pB)[1] = byte('Z'); //设置第二个字符的值为'e' //__asm mov ecx, dword ptr[pB] ; pB是局部存储空间,所以得取出pB指向的地址。 //__asm mov edx, dword ptr[ecx] ; 取地址的地址。 //__asm mov byte ptr[edx + 1], 'e'; 地址偏移一位,然后设置地址所指向的单字节内存块的值。 //这段C代码同上面的ASM代码等价 //“char*”是单字节为单位增量,不同于“byte*”四字节为单位增量。 //所以正确修改了字符串第二个元素的值。 char *pB_char = (char*)*pB; pB_char[1] = 'e'; }
相关文章推荐
- 创建Windows窗体
- 遍历二叉树,利用栈和只用固定存储空间,递归和非递归。
- C++ Prim算法构造可以使n个城市连接的最小生成树
- C++判断用户输入路径是否正确(判断盘符是否存在以及“\”与"/")
- C++ primer学习1:细节:标准化后C++中,定义在for循环内部的变量,循环外部不可使用
- C++细节5
- C++细节5
- C++ 迭代器(iterator)
- Google C++编程风格
- smo算法的c++实现
- C++中的virtual
- 【C语言】使用ODBC连接Microsoft SQL server数据库
- C/C++时间函数的使用
- c++STL的迭代器
- C语言详解 - 枚举类型
- Leetcode Problem.—Rotate List C++实现
- C语言-Makefile经典教程(掌握这些足够)
- C语言运算符优先级 详细列表
- LeetCode 之 Valid Parentheses — C++ 实现
- LeetCode 之 Longest Common Prefix — C++实现