“ 忠诚、笃学、严谨、守纪 ”

点击任意处进入
↓

| 终有一天我要把挂钩都开盒

颤抖吧,我胡曼使用了豆包复习了c语言的指针,豆包都夸我是学习天才

Day 1 c语言指针复习


1.工具准备

准备了一些可能会用到的工具,在win10镜像里共享了工具文件夹

2.熟悉指针,加强地址理解

%p -> 地址

%zu -> size_t(无符号整数类型)

#include <stdio.h>

size_t my_strlen (const char *s){   //const?只读属性,保证不修改原字符串
    size_t cnt = 0;
    while(*s != '\0'){
        cnt++;
        *s++;
    }
    return cnt;
}

void *my_memcpy(void *dest,const void *src, size_t n){
    char *d = (char *)dest;
    const char *s = (const char *)src;
    for(size_t i = 0;i<n;i++){
        d[i] = s[i];
        //*(d+i) = *(s+i); 
    }
    return dest;
}


void change_ptr(int **pp) //修改外部指针,注意为什么是**pp?
{
    static int val = 999;
    *pp = &val;
}



int main(){

//指针
    int a = 10;
    int *p = &a;

    printf("%d\n", *p);
    printf("%p\n", p);

    int arr[5] = {1,2,3,4,5};
    int *p2 = arr;            //指针退化:指针变量p2指向的是arr的首元素地址
                              //这里arr代表&arr[0]
    printf("%d\n", *(p2+3));
    printf("%d\n",arr[3]);
    printf("&arr = %p\n",&arr);      //这里取整个数组的地址,值和首元素地址一样
    printf("&arr+1 = %p\n", &arr+1); //整个数组地址+1,注意和*(arr+1)区别

    printf("%d\n",sizeof(arr));

    int b = 114;
    void *p3 = &b;
    int *p4 = (int*)p3;
    printf("%d\n",*p4);

//二级指针 举例
    int a1 = 10;
    int *p5 = &a1;
    int **pp = &p5;
    printf("%d\n",*p5);  //10
    printf("%p\n",p5);   //000000000061FE08
    printf("%d\n",*pp);  //6422024
    printf("%p\n",*pp);  //000000000061FE08
    printf("%d\n",**pp); //10
    printf("%p\n",pp);   //000000000061FE00
//逆向场景:函数内部修改外部指针变量本身的值的时候,需要传二级指针。

//my_strlen 统计字符串长度
    char str[] = "hurtingkai";
    size_t cnt = my_strlen(str);
    printf("字符串长度=%zu\n",cnt); // %zu对应size_t类型

    char dest[11];
    my_memcpy(dest,str,cnt);
    for (size_t i = 0; i < cnt; i++)
    {
        printf("%c\n",dest[i]);
    }
    //dest[10] = '\0';
    //printf("拷贝:%s",my_memcpy(dest,str,cnt));

//修改外部指针
    int *p6 = NULL;    
    change_ptr(&p6);//二级指针操作,函数内*pp改变p,*p随之改变
    printf("%d",*p);

    return 0;
}

3.dumpbin 反汇编

x64 Native Tools Command Prompt for VS

—>

# 查看PE头部
dumpbin /headers day1.exe

# 反汇编,输出保存到文本
dumpbin /disasm day1.exe > disasm_day1.txt

反编译出来一坨,101打开也是一坨,后面学学工具

1. **文件基本信息**:`day1.exe` 是 64 位 Windows 可执行镜像,
包含 `.text`(代码段)、`.data`、`.bss`、`.rdata`、CRT 运行时段、
各种 debug 调试段、导入段`.idata`等;
各段内存对齐大小大多 0x1000 (4KB)。
2. **输出内容构成**
   - 每一行格式:`RVA相对虚拟地址` + 机器码字节 + x64 汇编指令;
   - 大量是**MSVC CRT 运行时代码**:
     C 运行时初始化、PE 文件校验、全局构造 / 析构、异常处理、堆、线程局部存储`tls`、库函数内部实现;
   - 能看到 PE 头校验逻辑:检查`MZ`、`PE`签名,解析可选头;
   - 里面混杂大量`nop`对齐指令,用于 CPU 指令对齐,不做实际运算。
3. **关键问题:没看到 C 源码对应的 main/my_strlen/my_memcpy 清晰片段**

> 
> 原因:
> ① 虽然带 debug 段,但 dumpbin 静态反汇编**不会自动标注 main 符号名**,只有地址;
> ② CRT 启动函数`_CRT_main`占了绝大部分反汇编文本,你的用户代码被淹没在海量库代码里面。
4. **dumpbin 的局限(逆向学习注意)**

- 静态反汇编,**没有源码与函数符号名提示**,很难直接定位自己写的小函数;
- 输出会把整个`.text`全部导出,CRT 库代码占绝大多数;
- 只能看静态机器码,不能看寄存器、内存实时值,不能下断点。

汇编是一坨史,后面慢慢学

posted @ 2026-10-11 00:03  alonep  阅读(10)  评论(0)    收藏  举报
↑