1. Pointers and Arrays
C Source
The first two groups of printf () functions access the data in the array Narray as pointers, and the next two sets of printf () functions use array subscripts to access the data in the array Narray.
int _tmain(int argc, _TCHAR* argv[]){ // 数组赋值 int nArray[3] = {0x10,0x20,0x300}; // 数组地址赋值给指针 int *pPtr = nArray; // 输出指针中地址 printf("%x %x %x\r\n", pPtr+0, pPtr+1, pPtr+2); // 输出指针指向的值 printf("%x %x %x\r\n", *(pPtr+0), *(pPtr+1), *(pPtr+2)); // 输出数组中的地址 printf("%x %x %x\r\n", &nArray[0], &nArray[1], &nArray[2]); // 输出数组中的值 printf("%x %x %x\r\n", nArray[0], nArray[1], nArray[2]); return 0;}
Debug assembly
Compared to the assembly of pointer access and array access, it is found that using pointer access is to move backwards the length of an int size, which is 4 bytes.
The
Adds 8 because the pointer is based on the pointer type when it is being operated.
003CC55E mov [local.4],0x10003cc565 mov [local.3],0x20003cc56c mov [local.2],0x300003cc573 Lea eax,[local.4]003cc576 mov [local.7],eax003cc579 mov eax,[local.7]003cc57c add eax,0x8; Pptr+2 003cc57c; In C language, the operation of pointers is 003cc57c based on pointer type; An int pointer plus 1 means that the address it points to is moved backward in length to a 003cc57c; The distance of the int size, which is 4 bytes. If it's a word type, move backwards by 2 bytes. 003cc57f Push eax003cc580 mov ecx,[local.7]003cc583 add ecx,0x4; Pptr+1 003cc586 push ecx003cc587 mov edx,[local.7]003cc58a push edx; pptr+0 003cc58b push 9-44.00420c6c; ASCII "%x%x%x\r\n" 003cc590 call 9-44.003cb0b3003cc595 add esp,0x10003cc598 mov eax,[local.7]; * (pptr+2) 003cc59b mov ecx,dword ptr ds:[eax+0x8]003cc59e push ecx003cc59f mov edx,[local.7]; * (pptr+1) 003CC5A2 mov Eax,dwordPTR ds:[edx+0x4]003cc5a5 push eax003cc5a6 mov ecx,[local.7]003cc5a9 mov edx,dword ptr ds:[ecx]003cc5ab push Edx003CC5AC PU SH 9-44.00420c6c; ASCII "%x%x%x\r\n" 003cc5b1 call 9-44.003cb0b3003cc5b6 Add esp,0x10003cc5b9 Lea EAX,[LOCAL.2]; &NARRAY[2]003CC5BC push EAX003CC5BD Lea ECX,[LOCAL.3]; &NARRAY[1]003CC5C0 push ECX003CC5C1 Lea EDX,[LOCAL.4]; &NARRAY[0]003CC5C4 push edx003cc5c5 push 9-44.00420c6c; ASCII "%x%x%x\r\n" 003cc5ca call 9-44.003cb0b3003cc5cf add ESP,0X10003CC5D2 mov eax,[local.2]; NARRAY[2]003CC5D5 push EAX003CC5D6 mov ecx,[local.3]; NARRAY[1]003CC5D9 push ECX003CC5DA mov edx,[local.4]; NARRAY[0]003CC5DD push edx003cc5de push 9-44.00420c6c; ASCII "%x%x%x\r\n" 003cc5e3 call 9-44.003cb0b3003cc5e8 add Esp,0x10003cc5eb xor Eax,eax
Release compilation
The release version of the assembly instructions and debug version will do some optimization of the operation.
The disassembly code that uses the pointer to fetch data and array data is exactly the same.
011d1000 Sub esp,0xc011d1003 Lea Eax,dword PTR ss:[esp+0x8]; pptr+2 011d1007 push eax011d1008 Lea Ecx,dword PTR ss:[esp+0x8]; Pptr+1 011d100c push ecx011d100d Lea Edx,dword PTR ss:[esp+0x8]; Pptr+0 011d1011 push edx011d1012 push 9-44.011db384; ASCII, "x%x%x\r\n" 011d1017 mov dword ptr ss:[esp+0x10],0x10; Store value 011d101f mov dword ptr ss:[esp+0x14],0x20011d1027 mov dword ptr ss:[esp+0x18],0x300011d102f call 9-44.PRINTFC_ crttprocess4lockonfilt>011d1034 mov eax,dword ptr ss:[esp+0x18]; * (pptr+2) 011d1038 mov ecx,dword ptr ss:[esp+0x14]; * (pptr+1) 011d103c mov edx,dword ptr ss:[esp+0x10]; * (pptr+0) 011d1040 push eax011d1041 push ecx011d1042 push edx011d1043 push 9-44.011db384; ASCII, "x%x%x\r\n" 011d1048 call 9-44.printfc_crttprocess4lockonfilt>011d104d Lea Eax,dword PTR ss:[esp+0x28] ; &narray[2]011d1051 push eax011d1052 Lea Ecx,dword PTR sS:[ESP+0X28]; &narray[1]011d1056 push ecx011d1057 Lea Edx,dword PTR ss:[esp+0x28]; &narray[0]011d105b push edx011d105c push 9-44.011db384; ASCII, "x%x%x\r\n" 011d1061 call 9-44.printfc_crttprocess4lockonfilt>011d1066 mov eax,dword ptr ss:[esp+0x38] ; NARRAY[2]011D106A mov ecx,dword ptr ss:[esp+0x34]; NARRAY[1]011D106E mov edx,dword ptr ss:[esp+0x30]; narray[0]011d1072 push eax011d1073 push ecx011d1074 push edx011d1075 push 9-44.011db384; ASCII, "x%x%x\r\n" 011d107a call 9-44.printfc_crttprocess4lockonfilt>
1.1 Different ways to express arrays
Arrays in the disassembly of the expression generally divided into one-dimensional arrays, two-dimensional arrays, multidimensional arrays of three, where one-dimensional arrays and multidimensional arrays are more difficult to distinguish, but can be from the code structure and logic, and then analyze this is a multi-dimensional array.
The ability to control access to array member offsets is replaced by a register as a selector in the case of an array with circular access.
Access to the array follows the following formula:
Array member address = array start address + sizeof (array type) X array member subscript
2 Arrays and structs
The principle of storing data in an array is the same as that of a struct, which holds several data in a contiguous space, except that the data stored in the array is of the same type, while the struct may hold multiple types of data.
C Source Code
int _tmain(int argc, _TCHAR* argv[]){ struct _TEST { int nNum; double dFloat; char szStr[0x10]; }stcTEST; stcTEST.nNum = 0xAAAA; stcTEST.dFloat = 12.345; strcpy_s(stcTEST.szStr,"Hello World!"); printf("%X %f %s",stcTEST.nNum,stcTEST.dFloat,stcTEST.szStr); return 0;}
The code here doesn't look clear.
movsd xmm0, ds:qword_416490 ; 将12.345保存到浮点寄存器中lea eax, [esp+44h+var_18]add esp, 4mov [esp+40h+var_28], 0AAAAhmovsd [esp+40h+var_20], xmm0push offset aHelloWorld ; "Hello World!"push 10hpush eaxcall sub_403A3F ; strcpy函数movsd xmm0, [esp+4Ch+var_20]lea eax, [esp+4Ch+var_18]add esp, 0Chpush eaxsub esp, 8 ; 空出8字节空间保存doublemovsd [esp+4Ch+var_4C], xmm0push [esp+4Ch+var_28]push offset aXFS ; "%X %f %s"call sub_401090
An array is a contiguous set of data of the same type, and a struct may be the same as an array. The disassembly feature of the struct is consistent with the array. I understand that both are memory spaces that open up a contiguous set of storage space and then store the data according to the data type size.
"Hackers do not kill attack" Reading notes 12-pointers and arrays