回复 10楼 有容就大
1. 全是值传递2. 等晚上有时间我给详细写printf是怎么覆盖r的地址的
技术问题,请不要以短消息方式提问
#include <stdio.h> #include <stdlib.h> typedef struct link { int data; struct link* next; }node; node* p() { //what is ebp & esp? please google. node *head,*p,*q,r; //we suppose after push ebp, esp = 0x1000; just easy to explain //head address: ebp - 0x04 sizeof(head) = 4; //p addr: ebp - 0x08 sizeof(p) = 4; //q addr: ebp - 0x0C sizeof(q) = 4; //r addr: ebp - 0x10 sizeof(r) = sizeof(node) = 8; //so r addr: 0x1000 - 0x10 = 0xff0; remember this address 0xff0; //how this happen? //push ebp //mov ebp, esp //add esp, -(4 + 4 + 4 + 8) /just description/ // head=(node*)malloc(sizeof(node)); //head->addr which alloc from free heap_block p=(node*)malloc(sizeof(node)); //p->addr which alloc from free heap_block q=(node*)malloc(sizeof(node)); //q->addr which alloc from free heap_block head->next=p; p->next=q; p->data=1; q->data=3; q->next=&r; r.data=4; r.next=NULL; return head; //return head->addr; //head address: no longer valid //p addr: no longer valid //q addr: no longer valid //r addr: no longer valid //how this happen ? //mov esp, ebp or other instructions //pop ebp //release the local variables addr //esp return to 0x1000; } int main(int argc, char *argv[]) { node *head,*ptr; head=p(); ptr=head->next->next; while(ptr->next!=NULL) { printf("%4d",ptr->next->data); //inside printf alloc local variables again //push (ptr->next->data) //push "%4d" //call printf // push ebp // mov ebp, esp //still suppose ebp = 0x1000; // sub esp, 0Ch //means //local variables occupies // we didn't know printf will use how many local variables. // but only if //printf() //{ // int pa,pb,pc,pd,pe....; // pd and pe absolutely override the address 0xff0, and that's the r in function p //} ptr=ptr->next; } //conclusion: //different function will reuse the same stack in same process. //don't return stack address or depend on it. return 0; }简单的写了下
#include <stdio.h> #include <stdlib.h> typedef unsigned int uint32_t; typedef unsigned int size_t; typedef void*(*FUNC)(); typedef struct link { int data; struct link* next; }node; node* p() { node *head,*p,*q,r; return head; } node* q() { node *head,*p,*q,r; return head; } struct __StackEmulator { #define STACK_SIZE (512) uint32_t mapped_stack[STACK_SIZE]; uint32_t mapped_esp; uint32_t mapped_ebp; }stk = {{0}, STACK_SIZE, -1}; void dumpStack(void) { uint32_t curr = (&stk)->mapped_esp; while (curr < STACK_SIZE) { printf("TRACE OUT SYS_STACK:%d = 0x%x\n", curr++, (&stk)->mapped_stack[curr]); } } void func_loader(FUNC func, void *pram, size_t size) { (&stk)->mapped_stack[--(&stk)->mapped_esp] = (&stk)->mapped_ebp; //push ebp (&stk)->mapped_ebp = (&stk)->mapped_esp; //mov ebp, esp while (size-- > 0) { (&stk)->mapped_stack[--(&stk)->mapped_esp] = *(((uint32_t*)pram)++); //local variables } dumpStack(); //execute func; func(); //release process stack (&stk)->mapped_esp = (&stk)->mapped_ebp; //mov esp, ebp (&stk)->mapped_ebp = (&stk)->mapped_stack[(&stk)->mapped_esp++]; //pop ebp } int main(int argc, char *argv[]) { uint32_t pram1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; //emulator pram of func p uint32_t pram2[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60}; //emulator pram of func q func_loader(p, (void*)pram1, sizeof(pram1)/sizeof(pram1[0])); func_loader(q, (void*)pram2, sizeof(pram2)/sizeof(pram2[0])); return 0; }这样你能看懂?