首页
社区
课程
招聘
【读书笔记】C++反汇编与逆向分析技术揭秘2
发表于: 2022-11-27 23:51 22900

【读书笔记】C++反汇编与逆向分析技术揭秘2

2022-11-27 23:51
22900

常用快捷键

常用快捷键

以unsigned int为例

以int为例

SSE指令集

八个寄存器:XMM0-XMM8,每个寄存器占16字节(128bit)

图片描述

VS2019 Release版本

找main函数入口
图片描述
图片描述

release版

ida
图片描述

release

ida
图片描述

release

ida
图片描述

常用指令

release

ida
图片描述

release

ida
图片描述
图片描述

release

ida反汇编
图片描述
图片描述

release

ida
图片描述

图片描述

release

ida
图片描述

图片描述

release版

ida
图片描述

图片描述

release版

ida反汇编
图片描述

release

ida
图片描述

图片描述

release版

ida
图片描述

图片描述

release版

ida反汇编
图片描述

图片描述

图片描述

第一种,相差为1

release

ida
图片描述
第二种,相差大于1

release

ida
图片描述
第三种变量表达式

release

ida
图片描述
第四种表达式无优化使用分支

release

ida
图片描述

release

ida
图片描述

总结
图片描述

release

ida
图片描述

release

ida
图片描述
图片描述

会对case语句块制作地址表,以减少比较跳转次数

release

ida
图片描述
图片描述
图片描述

有两张表

release版

ida
图片描述
图片描述
图片描述

将每个case值作为一个节点,找到这些节点的中间值作为跟节点,形成一颗平衡二叉树,以每个节点作为判定值,大于和小于关系分别对应左子树和右子树。

release版

ida
图片描述
图片描述

release

ida
图片描述

release版

ida
图片描述

main.cpp

ida
图片描述

调用约定

release

ida
图片描述

图片描述

变量的作用域

全局变量和局部变量的区别

局部静态变量

作用域:所定义的函数

生命周期:持续到程序结束

release版

ida
图片描述

堆变量

release

ida
图片描述

在函数内定义数组

字符数组初始化为字符串

release

ida
图片描述

1.strlen()

release

ida
图片描述

2.strcpy()

在字符串初始化时,利用xmm寄存器初始化数组的值,一次可以初始化16字节,效率更高

release版

ida
图片描述

release

ida
图片描述

release

ida
图片描述

1.空类

2.内存对齐

3.静态数据成员

对象调用成员的方法以及取出数据成员的过程

利用寄存器ecx保存对象的首地址

以寄存器传参的方式将其传递到成员函数中

debug版

ida
图片描述
图片描述

debug

ida
图片描述
图片描述
含有数组数据成员的对象传参

debug

ida
图片描述

debug

ida
图片描述
getperson函数
图片描述

根据生命周期将对象进行分类,分析各类对象构造函数和析构函数的调用时机

debug

ida
图片描述

构造函数
图片描述
总结:局部对象构造函数的必要条件

debug

ida
图片描述
总结:

当对象作为函数参数时,会调用赋值构造函数

debug

ida
图片描述
调用赋值构造函数
图片描述

返回对象与参数对象类似,都会使用赋值构造函数。但是,两者使用时机不同

debug

ida
图片描述
调用getObject函数
图片描述

重点考察作用域的结束处,当对象所在作用域结束后,将销毁作用域所有变量的栈空间,此时便是析构函数出现的时机。析构函数同样属于成员函数,因此在调用的过程中也需要传递this指针。

debug

ida
图片描述

用detele释放对象所在的空间,delete的使用便是找到堆对象调用析构的关键点

debug

ida
图片描述
析构代理函数
图片描述

对于具有虚函数的类而言,构造函数和析构函数的识别过程更加简单。而且,在类中定义虚函数后,如果没有提供

构造函数,编译器会生成默认的构造函数。

对象的多态需要通过虚表和虚指针完成,虚表指针被定义在对象首地址处,因此虚函数必须作为成员函数使用。

当类中定义有虚函数,编译器会将给类中所有虚函数的首地址保存在一张地址表,这张表被称为虚函数地址表,简称虚表。同时还会在类中添加一个隐藏数据成员,称为虚表指针,该指针保存虚表的首地址,用于记录和查找虚函数。

debug

ida
图片描述
构造函数
图片描述

直接通过对象调用自身的成员虚函数,编译器使用了直接调用函数方式,没有访问虚表指针,而是间接获取虚函数地址。

debug

ida
图片描述
setAge函数
图片描述

执行析构函数时,实际上是在还原虚表指针,让其指向自身的虚表首地址,防止在析构函数中调用虚函数时取到非自身虚表,从而导致函数调用错误。

debug

ida析构函数分析
图片描述

判断是否为虚函数

debug

ida
图片描述

子类Derive构造函数
图片描述
子类Derive析构函数
图片描述
人类说话方法的多态模拟类结构

debug

speak函数分析,虚函数的调用过程是间接寻址方式
图片描述

debug

ida
图片描述
构造函数
图片描述
析构函数
图片描述
单继承类和多重继承类特征总结

单继承

多重继承

debug

ida
图片描述
子类构造函数
图片描述
抽象类构造函数
图片描述
抽象类的虚表信息
图片描述
在抽象类的虚表信息中,因为纯虚函数没有实现代码,所以没有首地址,编译器为了防止误调用虚函数,将虚表

中保存的纯虚函数的首地址项替换成函数__purecall,用于结束程序。在分析过程中,一旦在虚表中发现函数地址为__purecall函数时,就可以高度怀疑此虚表对应的类是一个抽象类。

#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n1 = argc;
    int n2 = argc;         //复写传播:n2等价于引用argc, n2则被删除
    n1 = n1 + 1;         //下一句n1重新赋值了,所以这句被删除了   
    n1 = 1 + 2;            //常量折叠:n1 = 3
    n1 = n1 + n2;        //常量传播和复写传播: n1 = 3 + argc
    printf("n1 = %d\n", n1);
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n1 = argc;
    int n2 = argc;         //复写传播:n2等价于引用argc, n2则被删除
    n1 = n1 + 1;         //下一句n1重新赋值了,所以这句被删除了   
    n1 = 1 + 2;            //常量折叠:n1 = 3
    n1 = n1 + n2;        //常量传播和复写传播: n1 = 3 + argc
    printf("n1 = %d\n", n1);
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n1 = argc;
    int n2 = 0;
    scanf_s("%d", &n2);
    n1 = n1 - 100;
    n1 = n1 + 5 - n2;       //n1 = n1 -95 - n2
    printf("n1 = %d \r\n", n1);
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n1 = argc;
    int n2 = 0;
    scanf_s("%d", &n2);
    n1 = n1 - 100;
    n1 = n1 + 5 - n2;       //n1 = n1 -95 - n2
    printf("n1 = %d \r\n", n1);
    return 0;
}
#include <stdio.h>
int main(int argc, char* argv[]) {
    int n1 = argc;
    int n2 = argc;
 
    printf("n1 * 15 = %d\n", n1 * 15);       //变量乘常量 ( 常量值为非 2 的幂 )
    printf("n1 * 16 = %d\n", n1 * 16);       //变量乘常量 ( 常量值为 2 的幂 )
    printf("2 * 2 = %d\n", 2 * 2);           //两常量相乘
    printf("n2 * 4 + 5 = %d\n", n2 * 4 + 5); //混合运算
    printf("n1 * n2 = %d\n", n1 * n2);       //两变量相乘
    return 0;
}
#include <stdio.h>
int main(int argc, char* argv[]) {
    int n1 = argc;
    int n2 = argc;
 
    printf("n1 * 15 = %d\n", n1 * 15);       //变量乘常量 ( 常量值为非 2 的幂 )
    printf("n1 * 16 = %d\n", n1 * 16);       //变量乘常量 ( 常量值为 2 的幂 )
    printf("2 * 2 = %d\n", 2 * 2);           //两常量相乘
    printf("n2 * 4 + 5 = %d\n", n2 * 4 + 5); //混合运算
    printf("n1 * n2 = %d\n", n1 * n2);       //两变量相乘
    return 0;
}
#include <stdio.h>
int main(unsigned argc, char* argv[]) {
 
    printf("a / 16 = %u", argc / 16);
 
    return 0;
}
#include <stdio.h>
int main(unsigned argc, char* argv[]) {
 
    printf("a / 16 = %u", argc / 16);
 
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    printf("argc / 3 = %u", (unsigned)argc / 3); //变量除以常量,常量为无符号非2的幂
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    printf("argc / 3 = %u", (unsigned)argc / 3); //变量除以常量,常量为无符号非2的幂
    return 0;
}
#include <stdio.h>
int main(unsigned argc, char* argv[]) {
 
    printf("a / 7 = %u", argc / 7);
 
    return 0;
}
#include <stdio.h>
int main(unsigned argc, char* argv[]) {
 
    printf("a / 7 = %u", argc / 7);
 
    return 0;
}
#include <stdio.h>
int main(int  argc, char* argv[]) {
 
    printf("a / 8 = %d", argc / 8);
 
    return 0;
}
#include <stdio.h>
int main(int  argc, char* argv[]) {
 
    printf("a / 8 = %d", argc / 8);
 
    return 0;
}
 
#include <stdio.h>
int main(int  argc, char* argv[]) {
 
    printf("a / 9 = %d", argc / 9);   ////变量除以常量,常量为非2的幂
 
    return 0;
}
#include <stdio.h>
int main(int  argc, char* argv[]) {
 
    printf("a / 9 = %d", argc / 9);   ////变量除以常量,常量为非2的幂
 
    return 0;
}
 
#include <stdio.h>
int main(int argc, char* argv[]) {
    printf("argc / 7 = %d", argc / 7); //变量除以常量,常量为非2的幂
    return 0;
}
#include <stdio.h>
int main(int argc, char* argv[]) {
    printf("argc / 7 = %d", argc / 7); //变量除以常量,常量为非2的幂
    return 0;
}
 
#include <stdio.h>
int main(int  argc, char* argv[]) {
 
    printf("a / -4 = %d", argc / -4);
 
    return 0;
}
#include <stdio.h>
int main(int  argc, char* argv[]) {
 
    printf("a / -4 = %d", argc / -4);
 
    return 0;
}
#include <stdio.h>
int main(int  argc, char* argv[]) {
 
    printf("a / -5 = %d", argc / -5);
 
    return 0;
}
#include <stdio.h>
int main(int  argc, char* argv[]) {
 
    printf("a / -5 = %d", argc / -5);
 
    return 0;
}
 
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    printf("argc / -7 = %d", argc / -7); //变量除以常量,常量为负非2的幂
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    printf("argc / -7 = %d", argc / -7); //变量除以常量,常量为负非2的幂
    return 0;
}
 
#include <stdio.h>
int main(int argc, char* argv[]) {
    printf("%d", argc % 8); //变量模常量,常量为2的幂
    printf("%d", argc % 9); //变量模常量,常量为非2的幂
    return 0;
}
#include <stdio.h>
int main(int argc, char* argv[]) {
    printf("%d", argc % 8); //变量模常量,常量为2的幂
    printf("%d", argc % 9); //变量模常量,常量为非2的幂
    return 0;
}
 
 
#include <stdio.h>
 
 
int main(int argc, char* argv[])
{
    printf("%d\r\n",argc == 5 ? 5:6);
 
    return 0;
}
#include <stdio.h>
 
 
int main(int argc, char* argv[])
{
    printf("%d\r\n",argc == 5 ? 5:6);
 
    return 0;
}
 
#include <stdio.h>
 
 
int main(int argc, char* argv[])
{
    printf("%d\r\n",argc == 5 ? 4:10);
 
    return 0;
}
#include <stdio.h>
 
 
int main(int argc, char* argv[])
{
    printf("%d\r\n",argc == 5 ? 4:10);
 
    return 0;
}
 
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n1, n2;
    scanf_s("%d %d", &n1, &n2);
    printf("%d\n", argc ? n1 : n2);
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n1, n2;
    scanf_s("%d %d", &n1, &n2);
    printf("%d\n", argc ? n1 : n2);
    return 0;
}
 
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n1, n2;
    scanf_s("%d %d", &n1, &n2);
    printf("%d\n", argc ? n1 : n2 + 3);
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n1, n2;
    scanf_s("%d %d", &n1, &n2);
    printf("%d\n", argc ? n1 : n2 + 3);
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    if (argc == 0) {
        printf("argc == 0");
    }
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    if (argc == 0) {
        printf("argc == 0");
    }
    return 0;
}
 
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    if (argc > 0) {
        printf("argc > 0");
    }
    else if (argc == 0) {
        printf("argc == 0");
    }
    else {
        printf("argc <= 0");
    }
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    if (argc > 0) {
        printf("argc > 0");
    }
    else if (argc == 0) {
        printf("argc == 0");
    }
    else {
        printf("argc <= 0");
    }
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n = 1;
    scanf_s("%d", &n);
    switch (n) {
    case 1:
        printf("n == 1");
        break;
    case 3:
        printf("n == 3");
        break;
    case 100:
        printf("n == 100");
        break;
    }
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n = 1;
    scanf_s("%d", &n);
    switch (n) {
    case 1:
        printf("n == 1");
        break;
    case 3:
        printf("n == 3");
        break;
    case 100:
        printf("n == 100");
        break;
    }
    return 0;
}
 
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n = 1;
    scanf_s("%d", &n);
    switch (n) {
    case 1:
        printf("n == 1");
        break;
    case 2:
        printf("n == 2");
        break;
    case 3:
        printf("n == 3");
        break;
    case 5:
        printf("n == 5");
        break;
    case 6:
        printf("n == 6");
        break;
    case 7:
        printf("n == 7");
        break;
    }
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n = 1;
    scanf_s("%d", &n);
    switch (n) {
    case 1:
        printf("n == 1");
        break;
    case 2:
        printf("n == 2");
        break;
    case 3:
        printf("n == 3");
        break;
    case 5:
        printf("n == 5");
        break;
    case 6:
        printf("n == 6");
        break;
    case 7:
        printf("n == 7");
        break;
    }
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n = 1;
    scanf_s("%d", &n);
    switch (n) {
    case 1:
        printf("n == 1");
        break;
    case 2:
        printf("n == 2");
        break;
    case 3:
        printf("n == 3");
        break;
    case 5:
        printf("n == 5");
        break;
    case 6:
        printf("n == 6");
        break;
    case 255:
        printf("n == 255");
        break;
    }
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n = 1;
    scanf_s("%d", &n);
    switch (n) {
    case 1:
        printf("n == 1");
        break;
    case 2:
        printf("n == 2");
        break;
    case 3:
        printf("n == 3");
        break;
    case 5:
        printf("n == 5");
        break;
    case 6:
        printf("n == 6");
        break;
    case 255:
        printf("n == 255");
        break;
    }
    return 0;
}
 
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n = 0;
    scanf_s("%d", &n);
    switch (n) {
    case 2:
        printf("n == 2\n");
        break;
    case 3:
        printf("n == 3\n");
        break;
    case 8:
        printf("n == 8\n");
        break;
    case 10:
        printf("n == 10\n");
        break;
    case 35:
        printf("n == 35\n");
        break;
    case 37:
        printf("n == 37\n");
        break;
    case 666:
        printf("n == 666\n");
        break;
    default:
        printf("default\n");
        break;
    }
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int n = 0;
    scanf_s("%d", &n);
    switch (n) {
    case 2:
        printf("n == 2\n");
        break;
    case 3:
        printf("n == 3\n");
        break;
    case 8:
        printf("n == 8\n");
        break;
    case 10:
        printf("n == 10\n");
        break;
    case 35:
        printf("n == 35\n");
        break;
    case 37:
        printf("n == 37\n");
        break;
    case 666:
        printf("n == 666\n");
        break;
    default:
        printf("default\n");
        break;
    }
    return 0;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int sum = 0;
    int i = 0;
    do {
        sum += i;
        i++;
    } while (i <= argc);
    return sum;
}
#include <stdio.h>
 
int main(int argc, char* argv[]) {
    int sum = 0;
    int i = 0;
    do {
        sum += i;
        i++;
    } while (i <= argc);
    return sum;
}
#include <stdio.h>
 
 
int main(int argc, char* argv[])
{
    int sum = 0;
    int i = 0;
    while (i <= 100)
    {
        sum = sum + i;
        i++;
    }
 
    printf("%d\r\n", sum);
 
    return 0;
}
#include <stdio.h>
 
 
int main(int argc, char* argv[])
{
    int sum = 0;
    int i = 0;
    while (i <= 100)
    {
        sum = sum + i;
        i++;
    }
 
    printf("%d\r\n", sum);
 
    return 0;
}
#include <stdio.h>
 
 
int main(int argc, char* argv[])
{
    int sum = 0;
 
    //内部会优化,把步长改为4,减少循环次数
    for (int n = 1; n <= 100; n++)
    {
        sum = sum + n;
    }
 
    printf("%d\r\n", sum);
 
    return 0;
}
#include <stdio.h>
 
 
int main(int argc, char* argv[])
{
    int sum = 0;
 
    //内部会优化,把步长改为4,减少循环次数
    for (int n = 1; n <= 100; n++)
    {
        sum = sum + n;
    }
 
    printf("%d\r\n", sum);
 
    return 0;
}
#include <stdio.h>
 
void addNumber(int n1) {
    n1 += 1;
    printf("%d\n", n1);
}
int main(int argc, char* argv[]) {
    int n = 0;
    scanf_s("%d", &n); // 防止变量被常量扩散优化
    addNumber(n);
    return 0;
}
#include <stdio.h>
 
void addNumber(int n1) {
    n1 += 1;
    printf("%d\n", n1);
}
int main(int argc, char* argv[]) {
    int n = 0;
    scanf_s("%d", &n); // 防止变量被常量扩散优化
    addNumber(n);
    return 0;
}
 
#include <stdio.h>
 
void showStatic(int n) {
    static int g_static = n;    //定义局部静态变量,赋值为参数
    printf("%d\n", g_static);    //显示静态变量
}
int main(int argc, char* argv[]) {
    for (int i = 0; i < 5; i++) {
        showStatic(i);        //循环调用显示局部静态变量的函数,每次传入不同值
    }
    return 0;
}
#include <stdio.h>
 
void showStatic(int n) {
    static int g_static = n;    //定义局部静态变量,赋值为参数
    printf("%d\n", g_static);    //显示静态变量
}
int main(int argc, char* argv[]) {
    for (int i = 0; i < 5; i++) {
        showStatic(i);        //循环调用显示局部静态变量的函数,每次传入不同值
    }
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
 
 
int main(int argc, char* argv[]) {
    char* buffer1 = (char*)malloc(10);    // 申请堆空间
    char* buffer2 = new char[10];    // 申请堆空间
    if (buffer2 != NULL) {
        delete[] buffer2;    // 释放堆空间
        buffer2 = NULL;
    }
    if (buffer1 != NULL) {
        free(buffer1);        // 释放堆空间
        buffer1 = NULL;
    }
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
 
 
int main(int argc, char* argv[]) {
    char* buffer1 = (char*)malloc(10);    // 申请堆空间
    char* buffer2 = new char[10];    // 申请堆空间
    if (buffer2 != NULL) {
        delete[] buffer2;    // 释放堆空间
        buffer2 = NULL;
    }
    if (buffer1 != NULL) {
        free(buffer1);        // 释放堆空间
        buffer1 = NULL;
    }
    return 0;
}
 
#include <stdio.h>
#include <stdlib.h>
 
 
int main(int argc, char* argv[]) {
    char s[] = "Hello World!";
    printf("%s",s);
 
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
 
 
int main(int argc, char* argv[]) {
    char s[] = "Hello World!";
    printf("%s",s);
 
    return 0;
}
 
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main(int argc, char* argv[]) {
    return strlen(argv[0]);
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main(int argc, char* argv[]) {
    return strlen(argv[0]);
}
 
 
 
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main(int argc, char* argv[]) {
    char buffer[20] = { 0 }; //字符数组定义
    strcpy(buffer, argv[0]); //字符串复制
    printf(buffer);
    return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main(int argc, char* argv[]) {
    char buffer[20] = { 0 }; //字符数组定义
    strcpy(buffer, argv[0]); //字符串复制
    printf(buffer);
    return 0;
}
#include <stdio.h>
#include <string.h>
 
int main(int argc, char* argv[]) {
    const char* ary[3] = { "Hello ", "World ", "!\n" };//字符串指针数组定义
        for (int i = 0; i < 3; i++) {
            printf(ary[i]); //显示输出字符串数组中的各项
        }
    return 0;
}
#include <stdio.h>
#include <string.h>
 
int main(int argc, char* argv[]) {
    const char* ary[3] = { "Hello ", "World ", "!\n" };//字符串指针数组定义
        for (int i = 0; i < 3; i++) {
            printf(ary[i]); //显示输出字符串数组中的各项
        }
    return 0;
}
#include <stdio.h>
 
int _stdcall show(int n) { //函数定义
    printf("show : %d\n", n);
    return n;
}
int main(int argc, char* argv[]) {
    int(_stdcall * pfn)(int) = show; //函数指针定义并初始化
    int ret = pfn(5); //使用函数指针调用函数并获取返回值
    printf("ret = %d\n", ret);
    return 0;
}
#include <stdio.h>
 
int _stdcall show(int n) { //函数定义
    printf("show : %d\n", n);
    return n;
}
int main(int argc, char* argv[]) {
    int(_stdcall * pfn)(int) = show; //函数指针定义并初始化
    int ret = pfn(5); //使用函数指针调用函数并获取返回值
    printf("ret = %d\n", ret);
    return 0;
}
#include <stdio.h>
 
class Person {
public:
    void setAge(int age) { //公有成员函数
        this->age = age;
    }
public:
    int age; //公有数据成员
};
int main(int argc, char* argv[]) {
    Person person;
    person.setAge(5); //调用成员函数
    printf("Person : %d\n", person.age); //获取数据成员
    return 0;
}
#include <stdio.h>
 
class Person {
public:
    void setAge(int age) { //公有成员函数
        this->age = age;
    }
public:
    int age; //公有数据成员
};
int main(int argc, char* argv[]) {
    Person person;
    person.setAge(5); //调用成员函数
    printf("Person : %d\n", person.age); //获取数据成员
    return 0;
}
#include <stdio.h>
 
class Person {
public:
    int age;
    int height;
};
 
void show(Person person) { //参数为类Person的对象
    printf("age = %d , height = %d\n", person.age,person.height);
}
 
int main(int argc, char* argv[]) {
    Person person;
    person.age = 1;
    person.height = 2;
    show(person);
    return 0;
}
#include <stdio.h>
 
class Person {
public:
    int age;
    int height;
};
 
void show(Person person) { //参数为类Person的对象
    printf("age = %d , height = %d\n", person.age,person.height);
}
 
int main(int argc, char* argv[]) {
    Person person;
    person.age = 1;
    person.height = 2;
    show(person);
    return 0;
}
 
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
class Person {
public:
    int age;
    int height;
    char name[32]; //定义数组类型的数据成员
};
void show(Person person) {
    printf("age = %d , height = %d name:%s\n", person.age,
        person.height, person.name);
}
int main(int argc, char* argv[]) {
    Person person;
    person.age = 1;
    person.height = 2;
    strcpy(person.name, "tom"); //赋值数据成员数组
    show(person);
    return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
class Person {
public:
    int age;
    int height;
    char name[32]; //定义数组类型的数据成员
};
void show(Person person) {
    printf("age = %d , height = %d name:%s\n", person.age,
        person.height, person.name);
}
int main(int argc, char* argv[]) {
    Person person;
    person.age = 1;
    person.height = 2;
    strcpy(person.name, "tom"); //赋值数据成员数组
    show(person);
    return 0;
}
#include <stdio.h>
#include <string.h>
 
class Person {
public:
    int count;
    int buffer[10]; //定义两个数据成员,该类的大小为44字节
};
 
Person getPerson() {
    Person person;
    person.count = 10;
    for (int i = 0; i < 10; i++) {
        person.buffer[i] = i + 1;
    }
    return person;
}
 
int main(int argc, char* argv[]) {
    Person person;
    person = getPerson();
    printf("%d %d %d", person.count, person.buffer[0],person.buffer[9]);
    return 0;
}
#include <stdio.h>
#include <string.h>
 
class Person {
public:
    int count;
    int buffer[10]; //定义两个数据成员,该类的大小为44字节
};
 
Person getPerson() {
    Person person;
    person.count = 10;
    for (int i = 0; i < 10; i++) {
        person.buffer[i] = i + 1;
    }
    return person;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-3-29 01:38 被zhang_derek编辑 ,原因: 上次pdf附件
上传的附件:
收藏
免费 28
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  K4NG   +1.00 2023/03/14
最新回复 (13)
雪    币: 6541
活跃值: (4501)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
感谢分享,很好的基础教程
2022-11-28 09:37
0
雪    币: 3534
活跃值: (3914)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习了,感谢分享。
2022-11-28 21:12
0
雪    币: 229
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2022-12-1 12:39
0
雪    币: 189
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2022-12-5 08:44
0
雪    币: 26136
活跃值: (1409)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2022-12-5 10:03
0
雪    币: 58
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
2019 有点高端
2022-12-5 10:07
0
雪    币: 38
活跃值: (1907)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
厉害厉害
2022-12-5 14:58
0
雪    币: 69
活跃值: (180)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Esc
9
感谢分享
2022-12-6 19:06
0
雪    币: 1795
活跃值: (3995)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
写得好,练习markdown也是不错
2022-12-6 22:37
0
雪    币: 188
活跃值: (336)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
除法部分实在太反人类了。
2022-12-13 19:00
0
雪    币: 6982
活跃值: (9179)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
12

上传pdf附件

最后于 2023-3-30 14:17 被zhang_derek编辑 ,原因:
2023-3-29 01:38
0
雪    币: 2055
活跃值: (418)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
感谢分享
2023-3-29 08:53
0
雪    币: 41
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
感谢分享
2023-4-3 09:49
0
游客
登录 | 注册 方可回帖
返回
//