| 终有一天我要把挂钩都开盒
颤抖吧,我胡曼使用了豆包复习了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 库代码占绝大多数;
- 只能看静态机器码,不能看寄存器、内存实时值,不能下断点。
汇编是一坨史,后面慢慢学

浙公网安备 33010602011771号